CodeGym /Java Blog /무작위의 /CodeGym의 게임 섹션: 유용한 이론
John Squirrels
레벨 41
San Francisco

CodeGym의 게임 섹션: 유용한 이론

무작위의 그룹에 게시되었습니다
CodeGym의 "게임" 섹션 에서 인기 있는 컴퓨터 게임 작성과 관련된 흥미로운 프로젝트를 찾을 수 있습니다. 인기 게임 2048, 지뢰 찾기, 뱀 및 기타 게임의 자신만의 버전을 만들고 싶습니까? 간단 해. 우리는 게임 작성을 단계별 프로세스로 전환했습니다. CodeGym의 "게임" 섹션: 유용한 이론 - 1게임 개발자로서의 능력을 테스트하기 위해 고급 프로그래머일 필요는 없지만 특정 Java 지식 세트가 필요합니다. 여기에서 게임 작성에 유용한 정보를 찾을 수 있습니다 .

1. 상속

CodeGym 게임 엔진 작업에는 상속 사용이 포함됩니다. 하지만 그것이 무엇인지 모른다면? 한편으로 이 주제를 이해해야 합니다. 레벨 11 에서 학습합니다.. 반면에 엔진은 매우 단순하도록 특별히 설계되었으므로 상속에 대한 피상적인 지식으로 벗어날 수 있습니다. 그렇다면 상속이란 무엇입니까? 간단히 말해서 상속은 두 클래스 간의 관계입니다. 그들 중 하나는 부모가 되고, 다른 하나는 자식(자식)이 됩니다. 더욱이 부모 클래스는 자손이 있다는 사실조차 모를 수 있습니다. 즉, 후손을 가짐으로써 특별한 이점을 얻지 못합니다. 그러나 상속은 후손에게 많은 이점을 제공합니다. 그리고 가장 중요한 것은 마치 부모 클래스의 코드를 자손 클래스에 복사한 것처럼 자손에 부모 클래스의 모든 변수와 메서드가 나타난다는 것입니다. 이것은 완전히 정확한 설명은 아니지만 상속을 간단하게 이해하는 데는 충분합니다. 예제 1: 가장 간단한 상속.

public class Parent {

}
Child 클래스는 extends 키워드 사용하여 Parent 클래스를 상속합니다 .

public class Child extends Parent {

}
예제 2: 상위 클래스의 변수 사용.

public class Parent {

   public int age;
   public String name;
}
Child 클래스 Parent 클래스 에서 선언된 것처럼 Parent 클래스의 연령이름 변수를 사용할 수 있습니다 .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
예제 3: 부모 클래스의 메서드 사용.

public class Parent {

   public int age;
   public String name;

   public getName() {
      return name;
  }
}
Child 클래스 Parent 클래스의 변수와 메서드를 Child 클래스에서 선언한 것처럼 사용할 수 있습니다 . 이 예제에서는 getName() 메서드를 사용합니다.

public class Child extends Parent {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
이것이 Child 클래스가 컴파일러에게 보이는 모습입니다.

public class Child extends Parent{

   public int age;  // Inherited variable
   public String name;  // Inherited variable

   public getName() {  // Inherited method.
      return name;
  }
   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}

2. 재정의 방법

때로는 Child 클래스가 모든 변수 및 메소드와 함께 매우 유용한 Parent 클래스를 상속하도록 하지만 일부 메소드가 원하는 대로 작동하지 않는 상황이 있습니다. 또는 우리가 원하는 방식이 전혀 아닙니다. 이 상황에서 우리는 무엇을 할 수 있습니까? 우리는 우리가 좋아하지 않는 방법을 무시할 수 있습니다. 이 작업은 매우 쉽습니다. Child 클래스에서 Parent 클래스의 메서드와 동일한 시그니처를 사용하여 메서드를 선언한 다음 자체 코드를 작성합니다. 예제 1: 메서드 재정의.

public class Parent {

   public String name;

   public void setName(String nameNew) {
       name = nameNew;
  }

   public getName() {
      return name;
  }
}
printInfo() 메서드는 "Luke, No!!!"를 표시합니다.

public class Child extends Parent{

   public void setName(String nameNew) {
       name = nameNew + ", No!!!";
  }

   public void printInfo() {
      setName("Luke");
      System.out.println(getName());
   }
}
이것이 Child 클래스가 컴파일러에게 보이는 모습입니다.

public Child extends Parent {

   public String name;  // Inherited variable

   public void setName(String nameNew)  // Overridden method instead of the inherited method {

       name = nameNew + ", No!!!";
   }
   public getName() {  // Inherited method.

      return name;
   }
   public void printInfo() {

     setName("Luke");
     System.out.println( getName());
   }
}
예 2: 일부 상속 마법(및 메서드 재정의).

public class Parent {

   public getName() {
      return "Luke";
  }
   public void printInfo() {

     System.out.println(getName());
   }
}

public class Child extends Parent {

   public getName() {
      return "Luke, I am your father";
  }
}
이 예에서 printInfo메서드(Parent 클래스의)가 Child 클래스에서 재정의되지 않은 경우 이 메서드가 Child 개체에서 호출될 때 해당 getName()메서드가 Parent 클래스의 메서드 대신 호출됩니다 getName().

Parent parent = new Parent ();
parent.printnInfo();
이 코드는 화면에 "Luke"를 표시합니다.

Child child = new Child ();
child.printnInfo();
이 코드는 화면에 "Luke, I am your father"를 표시합니다.
이것이 Child 클래스가 컴파일러에게 보이는 모습입니다.

public class Child extends Parent {

   public getName() {
      return "Luke, I am your father";
   }
   public void printInfo() {

     System.out.println(getName());
   }
}

3. 목록

아직 목록(목록)을 만나지 못한 경우 여기에 간략한 개요가 있습니다. CodeGym 과정의 레벨 6-7에서 완전한 정보를 찾을 수 있습니다 . 목록은 배열과 공통점이 많습니다.
  • 특정 유형의 많은 데이터를 저장할 수 있습니다.
  • 색인으로 항목을 얻을 수 있습니다.
  • 요소 인덱스는 0부터 시작합니다.
목록의 이점: 배열과 달리 목록은 크기를 동적으로 변경할 수 있습니다. 목록이 생성되면 크기는 0입니다. 목록에 항목을 추가하면 크기가 커집니다. 다음은 목록을 만드는 예입니다.

ArrayList<String> myList = new ArrayList<String>(); // Create a new ArrayList
꺾쇠 괄호 안의 값은 목록이 저장할 수 있는 데이터 유형을 나타냅니다. 다음은 목록 작업을 위한 몇 가지 방법입니다.
암호 코드가 수행하는 작업에 대한 간단한 설명
ArrayList<String> list = new ArrayList<String>(); 새 문자열 목록 만들기
list.add("name"); 목록 끝에 요소 추가
list.add(0, "name"); 목록의 시작 부분에 요소 추가
String name = list.get(5); 인덱스로 요소 가져오기
list.set(5, "new name"); 색인으로 요소 변경
int count = list.size(); 목록의 요소 수를 가져옵니다.
list.remove(4); 목록에서 요소 삭제
다음 문서에서 목록에 대해 자세히 알아볼 수 있습니다.
  1. ArrayList 클래스
  2. 사진의 ArrayList
  3. ArrayList에서 요소 삭제

4. 어레이

행렬이란 무엇입니까? 행렬은 데이터로 채울 수 있는 직사각형 테이블에 지나지 않습니다. 즉, 2차원 배열입니다. 아시다시피 Java의 배열은 객체입니다. 표준 1차원 int배열은 다음과 같습니다.

int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
다음과 같이 시각화할 수 있습니다.
0 1 2 4 5 6 7
12 32 43 54 15 36 67 28
맨 위 행은 셀의 주소를 나타냅니다. 즉, 숫자 67을 얻으려면 인덱스가 6인 배열 요소에 액세스해야 합니다.

int number = array[6];
모두 매우 간단합니다. 2차원 배열은 1차원 배열의 배열입니다. 이 소식을 처음 듣는다면 잠시 멈추고 머릿속으로 상상해 보세요. 2차원 배열은 다음과 같습니다.
0 1차원 배열 1차원 배열
1 1차원 배열
2 1차원 배열
1차원 배열
4 1차원 배열
5 1차원 배열
6 1차원 배열
7 1차원 배열
코드에서:

int [][] matrix = {
{65, 99, 87, 90, 156, 75, 98, 78}, {76, 15, 76, 91, 66, 90, 15, 77}, {65, 96, 17, 25, 36, 75, 54, 78}, {59, 45, 68, 14, 57, 1, 9, 63}, {81, 74, 47, 52, 42, 785, 56, 96}, {66, 74, 58, 16, 98, 140, 55, 77}, {120, 99, 13, 90, 78, 98, 14, 78}, {20, 18, 74, 91, 96, 104, 105, 77} }
0 0 1 2 4 5 6 7
65 99 87 90 156 75 98 78
1 0 1 2 4 5 6 7
76 15 76 91 66 90 15 77
2 0 1 2 4 5 6 7
65 96 17 25 36 75 54 78
0 1 2 4 5 6 7
59 45 68 14 57 1 9 63
4 0 1 2 4 5 6 7
81 74 47 52 42 785 56 96
5 0 1 2 4 5 6 7
66 74 58 16 98 140 55 77
6 0 1 2 4 5 6 7
120 99 13 90 78 98 14 78
7 0 1 2 4 5 6 7
20 18 74 91 96 104 105 77
값 47을 얻으려면 [4][2]에서 행렬 요소를 참조해야 합니다.

int number = matrix[4][2];
행렬 좌표가 고전적인 직각 좌표계(데카르트 좌표계)와 다르다는 것을 눈치채셨을 것입니다. 행렬에 액세스할 때 먼저 y 좌표를 지정한 다음 x 좌표를 지정합니다. 수학에서는 먼저 x 좌표, 즉 (x, y)를 지정하는 것이 일반적입니다. "행렬의 표현을 회전한 다음 (x, y)를 사용하여 일반적인 방법으로 요소에 액세스하는 것이 어떻습니까? 이렇게 하면 행렬의 내용이 변경되지 않습니다." 예, 아무것도 변하지 않을 것입니다. 그러나 프로그래밍 세계에서 허용되는 관행은 "처음에는 y로, 다음에는 x로" 행렬에 액세스하는 것입니다. 이것을 올바른 방법으로 받아들여야 합니다. 이제 행렬을 엔진에 투영하는 방법에 대해 이야기하겠습니다(Game수업). 아시다시피 엔진에는 특정 좌표에서 경기장의 셀을 변경하는 많은 방법이 있습니다. 예를 들어 setCellValue(int x, int y, String value)방법입니다. 값 매개변수와 동일한 좌표(x, y)로 특정 셀을 설정합니다. 이 방법은 고전적인 좌표계에서와 마찬가지로 x를 먼저 사용한다는 것을 눈치채셨을 것입니다. 엔진의 다른 방법도 비슷한 방식으로 작동합니다. 게임을 개발하다 보면 매트릭스의 상태를 화면에 재현해야 하는 경우가 많습니다. 어떻게 하죠? 먼저 루프의 모든 행렬 요소를 반복해야 합니다. 둘째, REVERSED 좌표를 사용하여 각각에 대한 표시 방법을 호출합니다. 예를 들어:

private void drawScene() {
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            setCellValue(j, i, String.valueOf(matrix[i][j]));
        }
    }
}
당연히 반전은 양방향으로 작동합니다. setCellValue(i, j) 를 메서드에 전달하고 동시에 행렬에서 요소 [j][i]를 가져올 수 있습니다 . 좌표를 뒤집는 것이 조금 어려워 보일 수 있지만 기억해야 합니다. 그리고 항상 문제가 발생하면 종이와 펜을 잡고 매트릭스를 그리고 매트릭스와 관련된 프로세스를 재현해야 합니다.

5. 난수

난수 생성기로 어떻게 작업합니까? 클래스 는 메서드를 Game정의합니다 getRandomNumber(int). 내부적으로는 Randomjava.util 패키지의 클래스를 사용하지만 난수 생성기로 작업하는 방식은 변경되지 않습니다. getRandomNumber(int)정수를 인수로 사용합니다. 이 숫자는 생성기가 반환할 수 있는 상한선입니다. 하한은 0입니다. 중요한! 생성기는 절대 상한값을 반환하지 않습니다. 예를 들어 를 호출하면 getRandomNumber(3)임의로 0, 1 또는 2를 반환합니다. 보시다시피 3을 반환할 수 없습니다. 생성기를 이런 방식으로 사용하는 것은 매우 간단하지만 많은 경우에 매우 효과적입니다. 어떤 범위에서 임의의 숫자를 가져와야 한다고 가정합니다. [100..999] 범위에서 세 자리 숫자가 필요하다고 가정합니다. 이미 알고 계시듯이 반환되는 최소 개수는 0입니다. 따라서 100을 더해야 합니다. 하지만 이 경우 상한을 초과하지 않도록 주의해야 합니다. 최대 임의 값으로 999를 얻으려면getRandomNumber(int)그러나 이제 우리는 결과에 100을 더한다는 것을 기억합니다. 이것은 상한이 100만큼 감소해야 함을 의미합니다. 즉, 임의의 3자리 숫자를 얻는 코드는 다음과 같습니다. :

int number = 100 + getRandomNumber(900);
그러나 이 절차를 단순화하기 위해 엔진은 getRandomNumber(int, int)첫 번째 매개변수가 반환할 최소 숫자인 메서드를 제공합니다. 이 방법을 사용하면 이전 예제를 다음과 같이 다시 작성할 수 있습니다.

int number = getRandomNumber(100, 1000);
임의의 숫자를 사용하여 임의의 배열 요소를 얻을 수 있습니다.

String [] names = {"Sarah", "Val", "Sergey"};
String randomName = names[getRandomNumber(names.length)]
일정 확률로 특정 이벤트 생성. 인간의 경우 아침은 몇 가지 가능한 시나리오로 시작됩니다. 늦잠 - 확률 50%; 제시간에 일어났다 – 40%의 확률; 한 시간 일찍 일어났습니다 – 10% 확률. 아침 결과 생성기를 작성한다고 상상해 보십시오. 일정 확률로 이벤트를 생성해야 합니다. 이렇게 하려면 난수 생성기를 다시 사용해야 합니다. 다른 구현이 가능하지만 가장 간단한 것은 다음 알고리즘을 기반으로 해야 합니다.
  1. 숫자를 생성하는 데 사용되는 한계를 설정합니다.
  2. 난수 생성;
  3. 얻은 번호를 처리합니다.
이 경우 최대값은 10입니다.getRandomNumber(10)반환할 수 있는지 분석하고 분석합니다. 각각 동일한 확률인 10%인 10개의 숫자(0에서 9까지)를 반환할 수 있습니다. 이제 가능한 모든 결과를 결합하여 가능한 이벤트에 매핑해야 합니다. 당신의 상상력은 가능한 많은 조합을 생각할 수 있지만 가장 분명한 조합은 다음과 같습니다. ..8], "Woke up on time" 이벤트가 있고 숫자가 9이면 "Woke up a hour early" 이벤트가 있습니다. 모두 매우 간단합니다. [0 범위에 5개의 숫자가 있습니다. ..4], 각각 10%의 확률로 총 50%가 반환될 수 있습니다. 범위 [5..8]에는 4개의 숫자가 있고 9는 10%의 확률.

int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Overslept");
} else if (randomNumber < 9) {
    System.out.println("Woke up on time");
} else {
    System.out.println("Woke up an hour early");
}
일반적으로 난수를 사용하는 방법은 무수히 많습니다. 당신은 당신의 상상력에 의해서만 제한됩니다. 그러나 반복적으로 결과를 얻어야 하는 경우 가장 효과적으로 사용됩니다. 그러면 새로운 결과가 이전 결과와 다를 것입니다. 물론 약간의 확률로. 지금은 여기까지입니다! "게임" 섹션에 대해 자세히 알아보려면 다음과 같은 유용한 문서를 참조하세요.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION