一、简介

如果我们只能用它在屏幕上画东西,游戏引擎就没什么用了。要编写一个成熟的游戏,我们需要它与用户互动!更准确地说,我们的程序应该跟踪用户操作并对其做出响应。

为此,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 次回调)后,颜色将停止变化,计时器将关闭。