一、簡介

如果我們只能用它在屏幕上畫東西,遊戲引擎就沒什麼用了。要編寫一個成熟的遊戲,我們需要它與用戶互動!更準確地說,我們的程序應該跟踪用戶操作並對其做出響應。

為此,CodeGym 遊戲引擎具有特殊的方法,當用戶單擊鼠標按鈕或鍵盤鍵時,它會調用這些方法。

類的要點是你自己寫這些方法,然後CodeGym遊戲引擎負責調用它們。您只需在代碼中聲明這些方法即可。這做起來比聽起來容易。


2.使用鼠標

遊戲引擎有兩種使用鼠標的方法:

void onMouseLeftClick(int x, int y)
void onMouseRightClick(int x, int y)

您只需在繼承該類的自己的類中聲明這些方法Game。然後在這些方法中編寫任何你想要的代碼。當用戶單擊鼠標按鈕時,遊戲引擎將調用這些方法。

onMouseLeftClick(int x, int y)單擊鼠標左鍵時由引擎調用。它的參數是發生點擊的運動場單元格的坐標。左上角單元格的坐標是(0,0)。要使用此方法,您需要覆蓋它,將@Override註釋放在方法名稱之前。

onMouseRightClick(int x, int y)單擊鼠標右鍵時調用。它的工作原理類似於該onMouseLeftClick(int x, int y)方法。

使用這些方法的示例:

import com.codegym.engine.cell.Color;
import com.codegym.engine.cell.Game;
import com.codegym.engine.cell.Key;

public class MySuperGame extends Game {
   @Override
   public void initialize() {
      // Set the size of the playing field to 3x3
      setScreenSize(3, 3);

      // Paint the playing field white
      for (int x = 0; x < 3; x++) {
         for (int y = 0; y < 3; y++) {
            setCellColor(x, y, Color.WHITE);
         }
      }
   }

   @Override
   public void onMouseLeftClick(int x, int y) {
      // Put a "X" in the cell that was clicked with the left mouse button
      setCellValue(x, y, "X");
   }

   @Override
   public void onMouseRightClick(int x, int y) {
      // Clear the cell that was clicked with the right mouse button
      setCellValue(x, y, "");
   }
}

在上面的例子中,我們聲明了兩個方法:onMouseLeftClick()onMouseRightClick()。當用戶在運動場的單元格上單擊鼠標左鍵時,將調用第一個方法。當單擊鼠標右鍵時將調用第二個方法。

作為參數,CodeGym 遊戲引擎將傳遞單擊(x, y)鼠標的運動場單元格的坐標。



3. 使用鍵盤

遊戲引擎有兩種使用鍵盤的方法:

void onKeyPress(Key key);
void onKeyReleased(Key key);

如果你想在用戶按下某個鍵時做一些事情,你只需要在繼承該類的類中聲明這些方法Game

您在這些方法中編寫代碼,遊戲引擎將在用戶按下(或鬆開)某個鍵時調用它們。

onKeyPress(Key key)按下任意鍵時調用。按下的鍵(或 )的值作為參數傳遞給該方法。要使用此方法,您需要覆蓋它,將註釋放在方法名稱之前。Key.UNKNOWNkey@Override

onKeyReleased(Key key)釋放任何鍵時調用。相應鍵(或)的值被分配給參數。要使用此方法,您需要覆蓋它,將註釋放在方法名稱之前。Key.UNKNOWNkey@Override

使用這些方法的示例:

import com.codegym.engine.cell.Color;
import com.codegym.engine.cell.Game;
import com.codegym.engine.cell.Key;

public class MySuperGame extends Game {
   @Override
   public void initialize() {
      // Set the size of the playing field to 3x3
      setScreenSize(3, 3);

      // Paint the playing field white
      for (int x = 0; x < 3; x++) {
         for (int y = 0; y < 3; y++) {
            setCellColor(x, y, Color.WHITE);
         }
      }
   }

   @Override
   public void onKeyPress(Key key) {
      // When the spacebar is pressed, the center cell turns yellow
      if (key == Key.SPACE) {
         setCellColor(1, 1, Color.YELLOW);
      }
   }

   @Override
   public void onKeyReleased(Key key) {
      // When the spacebar is released, the center cell returns to white
      if (key == Key.SPACE) {
         setCellColor(1, 1, Color.WHITE);
      }
   }
}


4.所有支持的按鍵列表

當 CodeGym 引擎調用onKeyPress()onKeyReleased()方法時,它會將有關按下(釋放)鍵的信息傳遞給它們。為此,CodeGym 引擎有一個名為Key.

在當前版本的引擎中,該Key類型僅支持一組有限的 9 個值:

價值 用戶按下了什麼
Key.ENTER
用戶按下了回車
Key.ESCAPE
用戶按下了Esc
Key.PAUSE
用戶按下了暫停鍵
Key.SPACE
用戶按下了空格
Key.LEFT
用戶按下左箭頭
Key.RIGHT
用戶按下右箭頭
Key.UP
用戶按下向上箭頭
Key.DOWN
用戶按下了向下箭頭
Key.UNKNOWN
上面列出的以外的任何鍵

如果玩家按下空格鍵,則該方法將作為參數onKeyPress()被調用。Key.SPACE如果用戶按下向左箭頭,則參數將為Key.LEFT. 如果用戶按下不在上面列表中的任何鍵,則將onKeyPress()調用該方法並將其Key.UNKNOWN作為參數。

這裡的問題是現有的 CodeGym 遊戲是為在手機上運行而設計的。我們有 8 個虛擬按鈕,而不是標準鍵盤:


5.使用定時器

許多遊戲是實時發生的,即用戶可能什麼都不做,但遊戲中仍然會發生某些事件。為了讓您能夠實現此類游戲,我們在遊戲引擎中添加了一個計時器。

它是這樣工作的:你打開定時器並設置它應該被觸發的時間。例如,500 毫秒。然後,每隔半秒,CodeGym 遊戲引擎將調用該onTurn()方法。無數次——直到定時器被關閉。

你如何使用定時器?

1.開啟定時器

要打開定時器,我們有方法void setTurnTimer(int timeMs)。該方法將回調之間的間隔持續時間(以毫秒或 1/1000 秒為單位)作為參數。您只需要調用一次該方法,遊戲引擎將開始onTurn()timeMs毫秒調用一次該方法。

2.重寫onTurn(int)方法

為此,您必須void onTurn(int step)在繼承該類的類中聲明一個方法Game。遊戲引擎將調用此方法。每次調用時,引擎都會傳遞一個標識方法調用的序列號 ( 1, 2, 3, ...)。

3.關閉定時器

如果不再需要計時器,例如因為用戶已經完成遊戲,則可以將其關閉。為此,只需調用該stopTurnTimer()方法。

4 加速/改變定時器

在一些遊戲中,事件的頻率有規律地增加,因此能夠加快我們的計時器會很方便,即減少回調之間的時間。沒有比這更簡單的了——只要setTurnTimer(int timeMs)用新值再次調用,調用之間的時間onTurn()就會改變。

例子:

import com.codegym.engine.cell.Color;
import com.codegym.engine.cell.Game;

public class MySuperGame extends Game {
   ...
   @Override
   public void initialize() {
      // Create a 3x3 playing field
      setScreenSize(3, 3);
      showGrid(false);
      setCellValueEx(1, 1, Color.BLUE, "X", Color.ORANGE, 50);

      setTurnTimer(500); // Turn on the timer. The interval between callbacks is 500ms.
   }

   @Override
   public void onTurn(int step) {
      if (step == 100) {
         stopTurnTimer(); // If this is the 100th callback, then turn off the timer
      }

      if (step % 2 == 1) {
         // If this is an odd calllback, then set the cell background to red
         setCellColor(1, 1, Color.RED);
      } else {
         // If this is an even callback, then set the cell background to blue
         setCellColor(1, 1, Color.BLUE);
      }
   }
   ...
}

在這個簡單的示例中,我們創建了一個 3 乘 3 單元格的字段。onTurn()然後我們打開一個定時器,每半秒調用一次該方法。

在這裡,中央單元格的顏色每半秒改變一次。單元格的文本不會改變。50 秒(100 次回調)後,顏色將停止變化,計時器將關閉。