在CodeGym 的
“遊戲”部分,您會發現涉及編寫流行計算機遊戲的激動人心的項目。想要創建您自己的流行遊戲 2048、掃雷、貪吃蛇和其他遊戲的版本嗎?這很簡單。我們已經將游戲編寫變成了一個循序漸進的過程。
要測試您作為遊戲開發人員的能力,您不必是高級程序員,但需要具備一套特定的 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 類的age和name變量,就好像它們是在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); |
從列表中刪除一個元素 |
您可以從以下文章中了解有關列表的更多信息:
- 數組列表類
- 圖片中的ArrayList
- 從 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)
方法。在底層,它使用
Random
java.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% 的機率。想像一下,您正在編寫一個早晨結果生成器。您需要以一定的概率生成事件。為此,您再次需要使用隨機數生成器。不同的實現是可能的,但最簡單的應該基於以下算法:
- 設置用於生成數字的限制;
- 生成一個隨機數;
- 處理得到的數字。
在這種情況下,最大值為 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");
}
一般來說,有很多方法可以使用隨機數。你只受限於你的想像力。但是,如果您需要反复獲得某些結果,則最有效地使用它們。那麼新的結果將與之前的結果不同。當然,有一定的可能性。目前為止就這樣了!如果您想了解有關“遊戲”部分的更多信息,這裡有一些有用的文檔可以提供幫助:
GO TO FULL VERSION