CodeGym /Java Blog /Toto sisi /CodeGym 上的遊戲部分:有用的理論
John Squirrels
等級 41
San Francisco

CodeGym 上的遊戲部分:有用的理論

在 Toto sisi 群組發布
在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 類的agename變量,就好像它們是在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類可以像在 Child 類中聲明的那樣使用Parent類的變量和方法。在此示例中,我們使用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 類中的方法具有相同簽名的方法,然後我們在其中編寫自己的代碼。 示例 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();
此代碼在屏幕上顯示“盧克,我是你父親” 。
這就是Child類在編譯器看來的樣子:

public class Child extends Parent {

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

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

3. 清單

如果你還沒有接觸過列表(List),這裡有一個簡單的概述。您可以在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. 數組列表類
  2. 圖片中的ArrayList
  3. 從 ArrayList 中刪除一個元素

4.數組

什麼是矩陣?矩陣只不過是一個可以填充數據的矩形表格。換句話說,它是一個二維數組。您可能知道,Java 中的數組是對象。標準的一維int數組如下所示:

int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
我們可以這樣想像它:
0 1個 2個 3個 4個 5個 6個 7
12 32 43 54 15 36 67 28
頂行表示單元格的地址。換句話說,要獲得數字 67,您需要訪問索引為 6 的數組元素:

int number = array[6];
這一切都非常簡單。二維數組是一維數組的數組。如果您是第一次聽說這個,請停下來在腦海中想像一下。二維數組如下所示:
0 一維數組 一維數組
1個 一維數組
2個 一維數組
3個 一維數組
4個 一維數組
5個 一維數組
6個 一維數組
7 一維數組
在代碼中:

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個 3個 4個 5個 6個 7
65 99 87 90後 156 75 98 78
1個 0 1個 2個 3個 4個 5個 6個 7
76 15 76 91 66 90後 15 77
2個 0 1個 2個 3個 4個 5個 6個 7
65 96 17 25 36 75 54 78
3個 0 1個 2個 3個 4個 5個 6個 7
59 45 68 14 57 1個 9 63
4個 0 1個 2個 3個 4個 5個 6個 7
81 74 47 52 42 785 56 96
5個 0 1個 2個 3個 4個 5個 6個 7
66 74 58 16 98 140 55 77
6個 0 1個 2個 3個 4個 5個 6個 7
120 99 13 90後 78 98 14 78
7 0 1個 2個 3個 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) 等於 value 參數的特定單元格。您可能已經註意到,此方法首先採用 x,就像在經典坐標系中一樣。引擎的其他方法以類似的方式工作。在開發遊戲時,經常需要在屏幕上重現矩陣的狀態。我們該怎麼做?首先,您需要循環遍歷所有矩陣元素。其次,使用 REVERSED 坐標為它們中的每一個調用 display 方法。例如:

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]));
        }
    }
}
自然地,逆轉是雙向的。您可以將 (i, j) 傳遞給該setCellValue方法,同時從矩陣中獲取元素 [j][i]。反轉坐標可能看起來有點困難,但你需要記住它。並且總是,如果你遇到任何問題,你應該拿一張紙和一支筆,畫出矩陣,並重現涉及矩陣的過程。

5.隨機數

您如何使用隨機數生成器?Game定義getRandomNumber(int)方法。在底層,它使用Randomjava.util 包中的類,但您使用隨機數生成器的方式並沒有改變。 getRandomNumber(int)接受一個整數作為參數。這個數字將是生成器可以返回的上限。下限為 0。 重要的! 生成器永遠不會返回上限數。例如,如果您調用getRandomNumber(3),它會隨機返回 0、1 或 2。如您所見,它不能返回 3。以這種方式使用生成器非常簡單,但在許多情況下非常有效。 假設您需要獲得某個範圍內的隨機數: 假設您需要一個 [100..999] 範圍內的三位數。如您所知,返回的最小數字為 0。因此您需要加 100。但在這種情況下,您需要注意不要超過上限。要獲得 999 作為最大隨機值,請調用getRandomNumber(int)帶有參數 1000 的方法。但現在我們記得我們在結果中加 100:這意味著上限應減去 100。換句話說,獲取隨機三位數的代碼如下所示:

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 個數字(從 0 到 9),每個數字都有相同的概率——10%。現在我們需要組合所有可能的結果並將它們映射到我們可能的事件。您的想像力可能會想出很多可能的組合,但最明顯的是:“如果隨機數在 [0..4] 範圍內,我們就會發生“睡過頭”事件;如果該數字在 [5] 範圍內..8],我們有“準時起床”事件;如果數字是 9,那麼我們有“提前一小時起床”事件。這一切都非常簡單。範圍內有 5 個數字 [0 ..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