本篇文章在Linux下编译运行c++的PacMan吃豆人游戏。

首先下载Pacman.zip源代码。

//下载源代码
wget https://labfile.oss.aliyuncs.com/courses/1182/Pacman.zip

//解压源代码
unzip -q Pacman.zip

安装 openGL 库

sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install libgl1-mesa-dev
sudo apt-get install libglu1-mesa-dev
sudo apt-get install freeglut3-dev

进入src文件夹

这里可以选择两种编译方式,一种是make命令,一种是g++命令。

g++ *.cpp -std=c++11 -I../include -lglut - lGl -o ../bin/Pacman


//or


make

接下来就是游戏运行了。

项目分析

游戏中需要不同的模块,可以将Pacman拆分为角色设计、地图设计、怪物射击、食物设计、操作设计(控制设计)、界面设计。需要用到OpenGL。(备注:openGL 是一种图形界面处理库,提供了许多 API 给其他语言调用。我们的地图、角色和界面等等都需要调用它。)

提前准备

我们需要先创建游戏文件夹Pacman,命令如下。

mkdir Pacman

在Pacman文件夹下创建src include bin 这三个子文件夹。

mkdir src bin include

 并创建相关头文件

touch control.h createpacman.h food.h gameover.h gamestart.h init.h laberynth.h main.h monster.h

在src中创建.cpp文件。可以将include的文件复制到str中,rename改名。

cp *.cpp ../src
rename s/.h/.cpp/ *

预定义全局变量来方便所有模块访问,全局变量反应游戏的状态。并且在其中只需要赋值一次。首先在main.h中放入全局变量。

//main.h
#ifndef _MAIN_H_
#define _MAIN_H_
#include <vector>
#include <GL/glut.h>
#include <iostream>
#include <cstring>
#define _USE_MATH_DEFINES
#include <math.h>
#include <vector>
#include <deque>
#include <stdlib.h>
using namespace std;

extern bool replay;         //检查是否启动游戏
extern bool over;             //检查游戏是否结束
extern float squareSize;     //一个单元大小
extern float xIncrement;     // x坐标
extern float yIncrement;     // y坐标
extern int rotation;         // 方向
extern float* monster1;     //第一个怪物的坐标和方向
extern float* monster2;     //第二个怪物的坐标和方向
extern float* monster3;     //第三个怪物的坐标和方向
extern float* monster4;     //第四个怪物的坐标和方向
extern vector<int> border;     //墙坐标

//障碍物坐标 (为了清晰分为三部分)
extern vector<int> obstaclesTop;
extern vector<int> obstaclesMiddle;
extern vector<int> obstaclesBottom;
extern deque<float> food;
extern vector<vector<bool>> bitmap;     // 2d图像,可移动区域
extern bool* keyStates;                 // 按键状态
extern int points;                         // 得分
#endif

接下来将main.cpp改为Pacman.cpp ,并将上面的变量赋值,在其中写入如下代码:

//Pacman.cpp
#include "main.h"
#include "control.h"
#include "food.h"
#include "gameresult.h"
#include "gameover.h"
#include "gamestart.h"
#include "init.h"
#include "monster.h"
#include "createpacman.h"
#include "laberynth.h"

using namespace std;

bool replay = false;         //检查是否启动游戏
bool over = true;             //检查游戏是否结束
float squareSize = 50.0;     //一个单元大小
float xIncrement = 0;         // x坐标
float yIncrement = 0;         // y坐标
int rotation = 0;             // 方向
float* monster1 = new float[3] {10.5, 8.5, 1.0};     //第一个怪物的坐标和方向
float* monster2 = new float[3] {13.5, 1.5, 2.0};     //第二个怪物的坐标和方向
float* monster3 = new float[3] {4.5, 6.5, 3.0};     //第三个怪物的坐标和方向
float* monster4 = new float[3] {2.5, 13.5, 4.0};     //第四个怪物的坐标和方向
vector<int> border = { 0, 0, 15, 1, 15, 15, 14, 1, 0, 14, 15, 15, 1, 14, 0, 0 }; //墙坐标

//障碍物坐标 (为了清晰分为三个)
vector<int> obstaclesTop = { 2, 2, 3, 6, 3, 6, 4, 5, 4, 2, 5, 4, 5, 3, 6, 5, 6, 1, 9, 2, 7, 2, 8, 5, 9, 5, 10, 3, 10, 4, 11, 2, 11, 5, 12, 6, 12, 6, 13, 2 };
vector<int> obstaclesMiddle = { 2, 9, 3, 7, 3, 7, 4, 8, 4, 9, 5, 11, 5, 6, 6, 10, 6, 10, 7, 8, 7, 8, 8, 9, 6, 7, 7, 6, 8, 6, 9, 7, 10, 6, 9, 10, 9, 10, 8, 8, 11, 9, 10, 11, 11, 8, 12, 7, 12, 7, 13, 9 };
vector<int> obstaclesBottom = { 2, 10, 3, 13, 3, 13, 4, 12, 5, 12, 6, 13, 6, 13, 7, 11, 8, 11, 9, 13, 9, 13, 10, 12, 11, 12, 12, 13, 12, 13, 13, 10 };
deque<float> food = { 1.5, 1.5, 1.5, 2.5, 1.5, 3.5, 1.5, 4.5, 1.5, 5.5, 1.5, 6.5, 1.5, 7.5, 1.5, 8.5, 1.5, 9.5, 1.5, 10.5, 1.5, 11.5, 1.5, 12.5, 1.5, 13.5, 2.5, 1.5, 2.5, 6.5, 2.5, 9.5, 2.5, 13.5, 3.5, 1.5, 3.5, 2.5, 3.5, 3.5, 3.5, 4.5, 3.5, 6.5, 3.5, 8.5, 3.5, 9.5, 3.5, 10.5, 3.5, 11.5, 3.5, 13.5, 4.5, 1.5, 4.5, 4.5, 4.5, 5.5, 4.5, 6.5, 4.5, 7.5, 4.5, 8.5, 4.5, 11.5, 4.5, 12.5, 4.5, 13.5, 5.5, 1.5, 5.5, 2.5, 5.5, 5.5, 5.5, 10.5, 5.5, 11.5, 5.5, 13.5, 6.5, 2.5, 6.5, 3.5, 6.5, 4.5, 6.5, 5.5, 6.5, 7.5, 6.5, 10.5, 6.5, 13.5, 7.5, 5.5, 7.5, 6.5, 7.5, 7.5, 7.5, 9.5, 7.5, 10.5, 7.5, 11.5, 7.5, 12.5, 7.5, 13.5, 8.5, 2.5, 8.5, 3.5, 8.5, 4.5, 8.5, 5.5, 8.5, 7.5, 8.5, 10.5, 8.5, 13.5, 9.5, 1.5, 9.5, 2.5, 9.5, 5.5, 9.5, 10.5, 9.5, 11.5, 9.5, 13.5, 10.5, 1.5, 10.5, 4.5, 10.5, 5.5, 10.5, 6.5, 10.5, 7.5, 10.5, 8.5, 10.5, 11.5, 10.5, 12.5, 10.5, 13.5, 11.5, 1.5, 11.5, 2.5, 11.5, 3.5, 11.5, 4.5, 11.5, 5.5, 11.5, 6.5, 11.5, 8.5, 11.5, 9.5, 11.5, 10.5, 11.5, 11.5, 11.5, 13.5, 12.5, 1.5, 12.5, 6.5, 12.5, 9.5, 12.5, 13.5, 13.5, 1.5, 13.5, 2.5, 13.5, 3.5, 13.5, 4.5, 13.5, 5.5, 13.5, 6.5, 13.5, 7.5, 13.5, 8.5, 13.5, 9.5, 13.5, 10.5, 13.5, 11.5, 13.5, 12.5, 13.5, 13.5 };
vector<vector<bool>> bitmap;         // 2d图像,可移动区域
bool* keyStates = new bool[256];     // 按键记录
int points = 0;                     // 得分

//主函数
int main(int argc, char** argv){
    //初始化并创建屏幕
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);    //显示方式(双缓冲区,颜色索引方式)
    glutInitWindowSize(750, 750);                    //窗口大小
    glutInitWindowPosition(500, 50);                //窗口起始位置
    glutCreateWindow("Pacman - by HD");

    //定义所有控制功能
    glutDisplayFunc(display);            //显示窗口
    glutReshapeFunc(reshape);            //重置窗口
    glutIdleFunc(display);                //循环
    glutKeyboardFunc(keyPressed);        //按键盘操作
    glutKeyboardUpFunc(keyUp);

    //运行游戏
    init();
    glutMainLoop();
    return 0;
}

初始化地图。

头文件

//init.h
#ifndef _INIT_H_
#define _INIT_H_
void init(void);

#endif
//init.cpp
#include "init.h"
#include "main.h"
//初始化游戏
void init(void){
    //清除屏幕
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);//着色
    //重置按键
    for (int i = 0; i < 256; i++){
        keyStates[i] = false;
    }
    //用障碍物填充地图
    bitmap.push_back({ true, true, true, true, true, true, true, true, true, true, true, true, true, true, true });
    bitmap.push_back({ true, false, false, false, false, false, false, false, false, false, false, false, false, false, true });
    bitmap.push_back({ true, false, true, true, true, true, false, true, true, false, true, true, true, false, true });
    bitmap.push_back({ true, false, false, false, false, true, false, true, false, false, false, false, true, false, true});
    bitmap.push_back({ true, false, true, true, false, false, false, false, false, true, true, false, false, false, true});
    bitmap.push_back({ true, false, false, true, true, false, true, true, true, true, false, false, true, false, true});
    bitmap.push_back({ true, true, false, false, false, false, true, false, true, true, false, true, true, false, true});
    bitmap.push_back({ true, true, true, true, true, false, false, false, true, false, false, false, false, false, true});
    bitmap.push_back({ true, true, false, false, false, false, true, false, true, true, false, true, true, false, true });
    bitmap.push_back({ true, false, false, true, true, false, true, true, true, true, false, false, true, false, true });
    bitmap.push_back({ true, false, true, true, false, false, false, false, false, true, true, false, false, false, true });
    bitmap.push_back({ true, false, false, false, false, true, false, true, false, false, false, false, true, false, true });
    bitmap.push_back({ true, false, true, true, true, true, false, true, true, false, true, true, true, false, true });
    bitmap.push_back({ true, false, false, false, false, false, false, false, false, false, false, false, false, false, true });
    bitmap.push_back({ true, true, true, true, true, true, true, true, true, true, true, true, true, true, true });
}

 迷宫

头文件

//createpacman.h
#ifndef _CREATEPACMAN_H_
#define _CREATEPACMAN_H_
#include <GL/glut.h>

void drawPacman(float positionX, float positionY, float rotation);
#endif

.cpp文件

//createpacman.cpp
#include "createpacman.h"
#include "GL/gl.h"
#include "main.h"

void drawPacman(float positionX, float positionY, float rotation){
    int x, y;
    glBegin(GL_LINES);    //创建一条线
    glColor3f(1.0, 1.0, 0.0);
    for (int k = 0; k < 32; k++){
        x = (float)k / 2.0 * cos((30 + 90*rotation) * M_PI / 180.0) + (positionX*squareSize);
        y = (float)k / 2.0* sin((30 + 90 * rotation) * M_PI / 180.0) + (positionY*squareSize);
        for (int i = 30; i < 330; i++){
            glVertex2f(x, y);
            x = (float)k / 2.0 * cos((i + 90 * rotation) * M_PI / 180.0) + (positionX*squareSize);
            y = (float)k / 2.0* sin((i + 90 * rotation) * M_PI / 180.0) + (positionY*squareSize);
            glVertex2f(x, y);
        }
    }
    glEnd();//绘图结束
}

游戏角色

//createpacman.h
#ifndef _CREATEPACMAN_H_
#define _CREATEPACMAN_H_
#include <GL/glut.h>

void drawPacman(float positionX, float positionY, float rotation);
#endif

//createpacman.cpp
#include "createpacman.h"
#include "GL/gl.h"
#include "main.h"

void drawPacman(float positionX, float positionY, float rotation){
    int x, y;
    glBegin(GL_LINES);    //创建一条线
    glColor3f(1.0, 1.0, 0.0);
    for (int k = 0; k < 32; k++){
        x = (float)k / 2.0 * cos((30 + 90*rotation) * M_PI / 180.0) + (positionX*squareSize);
        y = (float)k / 2.0* sin((30 + 90 * rotation) * M_PI / 180.0) + (positionY*squareSize);
        for (int i = 30; i < 330; i++){
            glVertex2f(x, y);
            x = (float)k / 2.0 * cos((i + 90 * rotation) * M_PI / 180.0) + (positionX*squareSize);
            y = (float)k / 2.0* sin((i + 90 * rotation) * M_PI / 180.0) + (positionY*squareSize);
            glVertex2f(x, y);
        }
    }
    glEnd();//绘图结束
}

怪物设计

//monster.h
#ifndef _MONSTER_H_
#define _MONSTER_H_
void drawMonster(float positionX, float positionY, float r, float g, float b);
void updateMonster(float* monster, int id);

#endif
//monster.cpp
#include "monster.h"
#include "main.h"
//绘画怪物
void drawMonster(float positionX, float positionY, float r, float g, float b){
    int x, y;
    glBegin(GL_LINES);
    glColor3f(r, g, b);
    //头
    for (int k = 0; k < 32; k++){
        x = (float)k / 2.0 * cos(360 * M_PI / 180.0) + (positionX*squareSize);
        y = (float)k / 2.0* sin(360 * M_PI / 180.0) + (positionY*squareSize);
        for (int i = 180; i <= 360; i++){
            glVertex2f(x, y);
            x = (float)k / 2.0 * cos(i * M_PI / 180.0) + (positionX*squareSize);
            y = (float)k / 2.0* sin(i * M_PI / 180.0) + (positionY*squareSize);
            glVertex2f(x, y);
        }
    }
    glEnd();
    //身体
    glRectf((positionX*squareSize) - 17, positionY*squareSize, (positionX*squareSize) + 15, (positionY*squareSize) + 15);
    glBegin(GL_POINTS);
    glColor3f(0, 0.2, 0.4);
    //眼睛和腿
    glVertex2f((positionX*squareSize) - 11, (positionY*squareSize) + 14); //legs
    glVertex2f((positionX*squareSize) - 1, (positionY*squareSize) + 14); //legs
    glVertex2f((positionX*squareSize) + 8, (positionY*squareSize) + 14); //legs
    glVertex2f((positionX*squareSize) + 4, (positionY*squareSize) - 3); //eyes
    glVertex2f((positionX*squareSize) - 7, (positionY*squareSize) - 3); //eyes
    glEnd();
}

//怪物移动
void updateMonster(float* monster, int id){
        //找到当前位置
        int x1Quadrant = (int)((monster[0] - (2/squareSize)) - (16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        int x2Quadrant = (int)((monster[0] + (2/squareSize)) + (16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        int y1Quadrant = (int)((monster[1] - (2/squareSize)) - (16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        int y2Quadrant = (int)((monster[1] + (2/squareSize)) + (16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        //怪物移动和撞墙检测
        switch ((int)monster[2]){
        case 1:
            if (!bitmap.at(x1Quadrant).at((int)monster[1])){
                monster[0] -= 2 / squareSize;
            }else {
                int current = monster[2];
                do{
                    monster[2] =  (rand() % 4) + 1;
                } while (current == (int) monster[2]);
            }
            break;
        case 2:
            if (!bitmap.at(x2Quadrant).at((int)monster[1])){
                monster[0] += 2 / squareSize;
            }
            else {
                int current = monster[2];
                do{
                    monster[2] = (rand() % 4) + 1;
                } while (current == (int)monster[2]);
            }
            break;
        case 3:
            if (!bitmap.at((int)monster[0]).at(y1Quadrant)){
                monster[1] -= 2 / squareSize;
            }
            else {
                int current = monster[2];
                do{
                    monster[2] = (rand() % 4) + 1;
                } while (current == (int)monster[2]);
            }
            break;
        case 4:
            if (!bitmap.at((int)monster[0]).at(y2Quadrant)){
                monster[1] += 2 / squareSize;
            }
            else {
                int current = monster[2];
                do{
                    monster[2] = (rand() % 4) + 1;
                } while (current == (int)monster[2]);
            }
            break;
        default:
            break;
        }
}

食物设计

//food.h
#ifndef _FOOD_H_
#define _FOOD_H_
#include <deque>

bool foodEaten(int x, int y, float pacmanX, float pacmanY);
void drawFood(float pacmanX, float pacmanY);

#endif
//food.cpp
#include "food.h"
#include "main.h"

//检查食物是否被吃
bool foodEaten(int x, int y, float pacmanX, float pacmanY){
    if (x >= pacmanX - 16.0 *cos(359 * M_PI / 180.0) && x <= pacmanX + 16.0*cos(359 * M_PI / 180.0)){
        if (y >= pacmanY - 16.0*cos(359 * M_PI / 180.0) && y <= pacmanY + 16.0*cos(359 * M_PI / 180.0)){
            return true;
        }
    }
    return false;
}

//画上食物
void drawFood(float pacmanX, float pacmanY){
    deque<float> temp;
    //检查食物是否没有被吃掉
    for (deque<float>::size_type i = 0; i < food.size(); i = i + 2){
        if (!foodEaten(food.at(i)*squareSize, food.at(i + 1)*squareSize, pacmanX, pacmanY)){
            temp.push_back(food.at(i));
            temp.push_back(food.at(i + 1));
        }
        else {
            points++;
        }
    }
    food.swap(temp);
    glPointSize(5.0);
    glBegin(GL_POINTS);
    glColor3f(1.0, 1.0, 1.0);
    //画上食物
    for (deque<float>::size_type j = 0; j < food.size(); j = j + 2){
        glVertex2f(food.at(j)*squareSize, food.at(j + 1)*squareSize);//画点
    }
    glEnd();
}

角色移动命令

//control.h
#ifndef _CONTROL_H_
#define _CONTROL_H_
void keyPressed(unsigned char key, int x, int y);
void keyUp(unsigned char key, int x, int y);
void resetGame();
void keyOperations();

#endif
//control.cpp
#include "control.h"
#include "main.h"
//设置按键
void keyPressed(unsigned char key, int x, int y){
    keyStates[key] = true;
}

//释放按键
void keyUp(unsigned char key, int x, int y){
    keyStates[key] = false;
}

//重置所有元素并开始游戏
void resetGame(){
    over = false;
    xIncrement = 0;
    yIncrement = 0;
    rotation = 0;
    monster1 = new float[3] {10.5, 8.5, 1.0};
    monster2 = new float[3] {13.5, 1.5, 2.0};
    monster3 = new float[3] {4.5, 6.5, 3.0};
    monster4 = new float[3] {2.5, 13.5, 4.0};
    points = 0;
    for (int i = 0; i < 256; i++){
        keyStates[i] = false;
    }
    food = { 1.5, 1.5, 1.5, 2.5, 1.5, 3.5, 1.5, 4.5, 1.5, 5.5, 1.5, 6.5, 1.5, 7.5, 1.5, 8.5, 1.5, 9.5, 1.5, 10.5, 1.5, 11.5, 1.5, 12.5, 1.5, 13.5, 2.5, 1.5, 2.5, 6.5, 2.5, 9.5, 2.5, 13.5, 3.5, 1.5, 3.5, 2.5, 3.5, 3.5, 3.5, 4.5, 3.5, 6.5, 3.5, 8.5, 3.5, 9.5, 3.5, 10.5, 3.5, 11.5, 3.5, 13.5, 4.5, 1.5, 4.5, 4.5, 4.5, 5.5, 4.5, 6.5, 4.5, 7.5, 4.5, 8.5, 4.5, 11.5, 4.5, 12.5, 4.5, 13.5, 5.5, 1.5, 5.5, 2.5, 5.5, 5.5, 5.5, 10.5, 5.5, 11.5, 5.5, 13.5, 6.5, 2.5, 6.5, 3.5, 6.5, 4.5, 6.5, 5.5, 6.5, 7.5, 6.5, 10.5, 6.5, 13.5, 7.5, 5.5, 7.5, 6.5, 7.5, 7.5, 7.5, 9.5, 7.5, 10.5, 7.5, 11.5, 7.5, 12.5, 7.5, 13.5, 8.5, 2.5, 8.5, 3.5, 8.5, 4.5, 8.5, 5.5, 8.5, 7.5, 8.5, 10.5, 8.5, 13.5, 9.5, 1.5, 9.5, 2.5, 9.5, 5.5, 9.5, 10.5, 9.5, 11.5, 9.5, 13.5, 10.5, 1.5, 10.5, 4.5, 10.5, 5.5, 10.5, 6.5, 10.5, 7.5, 10.5, 8.5, 10.5, 11.5, 10.5, 12.5, 10.5, 13.5, 11.5, 1.5, 11.5, 2.5, 11.5, 3.5, 11.5, 4.5, 11.5, 5.5, 11.5, 6.5, 11.5, 8.5, 11.5, 9.5, 11.5, 10.5, 11.5, 11.5, 11.5, 13.5, 12.5, 1.5, 12.5, 6.5, 12.5, 9.5, 12.5, 13.5, 13.5, 1.5, 13.5, 2.5, 13.5, 3.5, 13.5, 4.5, 13.5, 5.5, 13.5, 6.5, 13.5, 7.5, 13.5, 8.5, 13.5, 9.5, 13.5, 10.5, 13.5, 11.5, 13.5, 12.5, 13.5, 13.5 };
}

//控制吃豆人移动
void keyOperations(){
    //获得当前位置
    float  x = (1.5 + xIncrement) * squareSize;
    float y = (1.5 + yIncrement) * squareSize;
    //更新按键
    if (keyStates['a']){
        x -= 2;
        int x1Quadrant = (int)((x - 16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        if (!bitmap.at(x1Quadrant).at((int)y/squareSize)){
            xIncrement -= 2 / squareSize;
            rotation = 2;
        }
    }
    if (keyStates['d']){
        x += 2;
        int x2Quadrant = (int)((x + 16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        if (!bitmap.at(x2Quadrant).at((int)y / squareSize)){
            xIncrement += 2 / squareSize;
            rotation = 0;
        }
    }
    if (keyStates['w']){
        y -= 2;
        int y1Quadrant = (int)((y - 16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        if (!bitmap.at((int)x/squareSize).at(y1Quadrant)){
            yIncrement -= 2 / squareSize;
            rotation = 3;
        }
    }
    if (keyStates['s']){
        y += 2;
        int y2Quadrant = (int)((y + 16.0 *cos(360 * M_PI / 180.0)) / squareSize);
        if (!bitmap.at((int)x / squareSize).at(y2Quadrant)){
            yIncrement += 2 / squareSize;
            rotation = 1;
        }
    }
    if (keyStates[' ']){
        if (!replay && over){
            resetGame();
            replay = true;
        }
        else if (replay && over){
            replay = false;
        }
    }
}

开始界面

//gamestart.h
#ifndef _GAMESTART_H_
#define _GAMESTART_H_
#include <iterator>

void welcomeScreen();
void display();
void reshape(int w, int h);
#endif
//gamestart.cpp
#include "gamestart.h"
#include "monster.h"
#include "createpacman.h"
#include "laberynth.h"
#include "main.h"
#include "gameover.h"
#include "food.h"
#include "gameresult.h"
#include "control.h"

//欢迎界面
void welcomeScreen(){
    glClearColor(0, 0.2, 0.4, 1.0);
    string message = "*************************************";
    string::iterator it = message.begin();
    glRasterPos2f(150, 200);
    while (it!=message.end())
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
    message = "Pacman - by HD";
    glColor3f(1, 1, 1);
    glRasterPos2f(225, 250);
    it = message.begin();
    while (it!=message.end())
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
    message = "*************************************";
    glRasterPos2f(150, 300);
    it = message.begin();
    while (it!=message.end())
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
    message = "To control Pacman use A to go right, D to go left, W to go up and S to go down.";
    glRasterPos2f(50, 400);
    it = message.begin();
    while (it!=message.end())
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *it++);
    message = "To start or restart the game, press the space key.";
    glRasterPos2f(170, 450);
    it = message.begin();
    while (it!=message.end())
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *it++);
}

//显示屏幕和元素
void display(){
    if (points == 1){
        over = false;
    }
    keyOperations();
    glClear(GL_COLOR_BUFFER_BIT);    //清除颜色缓冲区(当前被激活为写操作的颜色缓存)
    gameOver();
    if (replay){
        if (!over){
            drawLaberynth();
            drawFood((1.5 + xIncrement) * squareSize, (1.5 + yIncrement) * squareSize);
            drawPacman(1.5 + xIncrement, 1.5 + yIncrement, rotation);
            updateMonster(monster1, 1);
            updateMonster(monster2, 2);
            updateMonster(monster3, 3);
            updateMonster(monster4, 4);
            drawMonster(monster1[0], monster1[1], 0.0, 1.0, 1.0); //cyan
            drawMonster(monster2[0], monster2[1], 1.0, 0.0, 0.0); //red
            drawMonster(monster3[0], monster3[1], 1.0, 0.0, 0.6); //magenta
            drawMonster(monster4[0], monster4[1], 1.0, 0.3, 0.0); //orange
        }
        else {
            resultsDisplay();
        }
    }
    else {
        welcomeScreen();
    }
    glutSwapBuffers();
}

//重置窗口
void reshape(int w, int h){
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glOrtho(0, 750, 750, 0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

游戏结果判断

//gameover.h
#ifndef _GAME_OVER_H_
#define _GAME_OVER_H_
void gameOver();

#endif
//gameover.cpp
#include "gameover.h"
#include "main.h"
//游戏结束
void gameOver(){
    int pacmanX = (int)(1.5 + xIncrement);
    int pacmanY = (int)(1.5 + yIncrement);
    int monster1X = (int)(monster1[0]);
    int monster1Y = (int)(monster1[1]);
    int monster2X = (int)(monster2[0]);
    int monster2Y = (int)(monster2[1]);
    int monster3X = (int)(monster3[0]);
    int monster3Y = (int)(monster3[1]);
    int monster4X = (int)(monster4[0]);
    int monster4Y = (int)(monster4[1]);
    if (pacmanX == monster1X && pacmanY == monster1Y){
        over = true;
    }
    if (pacmanX == monster2X && pacmanY == monster2Y){
        over = true;
    }
    if (pacmanX == monster3X && pacmanY == monster3Y){
        over = true;
    }
    if (pacmanX == monster4X && pacmanY == monster4Y){
        over = true;
    }
    if (points == 106){
        over = true;
    }
}

游戏结束界面

//gameresult.h
#ifndef _GAMERESULT_H_
#define _GAMERESULT_H_
#include <cstring>
#include <iterator>
void resultsDisplay();

#endif
//gameresult.cpp
#include "gameresult.h"
#include "main.h"
//游戏结果
void resultsDisplay(){
    if (points == 106){
        //胜利
        string message = "*************************************";
        string::iterator it = message.begin();
        glRasterPos2f(170, 250);
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "CONGRATULATIONS, YOU WON! ";
        glColor3f(1, 1, 1);
        glRasterPos2f(200, 300);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "*************************************";
        glRasterPos2f(170, 350);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "To start or restart the game, press the space key.";
        glRasterPos2f(170, 550);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *it++);
    }else {
        //Lost
        string message = "*************************************";
        string::iterator it = message.begin();
        glRasterPos2f(210, 250);
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "SORRY, YOU LOST ... ";
        glColor3f(1, 1, 1);
        glRasterPos2f(250, 300);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "*************************";
        glRasterPos2f(210, 350);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "You got: ";
        glRasterPos2f(260, 400);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        string result = to_string(points);
        message = (char*)result.c_str();
        glRasterPos2f(350, 400);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = " points!";
        glRasterPos2f(385, 400);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *it++);
        message = "To start or restart the game, press the space key.";
        glRasterPos2f(170, 550);
        it = message.begin();
        while (it!=message.end())
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *it++);
    }
}

两种编译方式

前面提到可以选择g++的 方式

另一个是makefile

#编译方式
CC = g++
#C++版本,显示所有警告
VERSION = -g -std=c++11 -Wall
#头文件和库文件
INCLUDE = -I../include -lglut -lGL
#目标文件,最后生成文件
TARGET = ../bin/Pacman
#源代码路径
SRCS = $(wildcard *.cpp)
#编译为.o文件
OBJS = $(patsubst %cpp,%o,$(SRCS))

all:$(TARGET)
#执行编译
$(TARGET):$(OBJS)
    $(CC) $(OBJS) $(VERSION) $(INCLUDE) -o $(TARGET)

%.o:%.cpp
    $(CC) $(VERSION) $(INCLUDE) -c $<
#清除
.PHONY:clean
clean:
    rm -rf $(OBJS) $(TARGET)

然后游戏可以正常玩起来了。

Logo

更多推荐