跳轉到

第 2 步:小精靈出發

節奏練夠了,該讓小精靈出門了!這一步用方向鍵控制牠,按一下走一格,而且嘴巴會朝著前進的方向。

第 2 步的畫面:黑色畫面中,小精靈嘴巴朝下

完整程式

這一步不再需要節奏遊戲,所以程式反而變短了。

main.cpp
// 第 2 步:小精靈出發——用方向鍵控制小精靈。
#include "GridPlusPlus.h"

using gridpp::GameEngine;
using gridpp::GridObject;

void MovePacman(GameEngine game, GridObject self) {
    if (game.keyPressed(KEY_RIGHT)) {
        self.move(1, 0);
        self.setDirection(0);  // 0 右、1 上、2 左、3 下
    }
    if (game.keyPressed(KEY_UP)) {
        self.move(0, -1);
        self.setDirection(1);
    }
    if (game.keyPressed(KEY_LEFT)) {
        self.move(-1, 0);
        self.setDirection(2);
    }
    if (game.keyPressed(KEY_DOWN)) {
        self.move(0, 1);
        self.setDirection(3);
    }
}

int main() {
    GameEngine game(15, 11, 48);
    game.loadAssets("pacman.db");
    game.setBackgroundColor(BLACK);

    GridObject pacman = game.addObject("pacman", nullptr, MovePacman);
    pacman.setPosition(7, 5);

    game.run();
    return 0;
}

在專案資料夾的終端機編譯並執行(按 Up 鍵可以叫出上次的指令):

g++ -std=c++17 main.cpp -o game -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 && ./game
g++ -std=c++17 main.cpp -o game $(pkg-config --cflags --libs raylib) && ./game

程式怎麼運作

網格座標

Grid++ 把畫面切成一格一格的。這個遊戲有 15 欄、11 列,左上角是 (0, 0),x 往右變大,y 往下變大。

pacman.setPosition(7, 5);  // 第 8 欄、第 6 列,剛好在正中央

移動

self.move(1, 0);  // x 加 1,往右走一格

move(dx, dy) 讓物件從現在的位置移動 dx 欄、dy 列。往上是 move(0, -1),因為 y 往上是變小。

MovePacman 和上一步的 Dance 一樣,每一幀都會被執行,所以只要檢查四個方向鍵有沒有被按下就好。

試試看

  • 一直往右走,小精靈會跑出畫面嗎?(會!下一步會用牆壁把牠擋住。)
  • 讓按一次走兩格。
  • 把 keyPressed 改成 keyDown,按住不放會發生什麼事?為什麼小精靈一下子就跑不見了?(提示:一秒有 60 幀。)
跑不起來,或結果和圖片不一樣?

先確認整份程式都有貼上、而且有存檔。還是不行的話,可以直接執行這一步的參考答案,看看哪裡不同:專案的 steps/ 資料夾裡有每一步的完整程式。

想知道更多?

網格座標和像素座標的差別,請看理解核心模型。

第 3 步:迷宮