C++写简易贪吃蛇

以下是C++写简易贪吃蛇的具体源代码(求点赞):

#include <iostream>
#include <easyx.h>
#include <graphics.h>
#include <ctime>
#include <vector> //顺序表
using namespace std;
 
class Sprite
{
protected:
    int pos_x;
    int pos_y;
    COLORREF color;
 
public:
    Sprite() : Sprite(0, 0) {}
    Sprite(int x, int y, COLORREF c = RED) : pos_x(x), pos_y(y), color(c)
    {
    }
    virtual void show()
    {
        setfillcolor(color);
    }
    virtual void change_pos(int x, int y)
    {
        pos_x = x;
        pos_y = y;
    }
    virtual int get_pos_x()
    {
        return pos_x;
    }
    virtual int get_pos_y()
    {
        return pos_y;
    }
    // 发生碰撞
    bool collision(const Sprite &other)
    {
        return pos_x == other.pos_x && pos_y == other.pos_y;
    }
};
 
// 蛇类
class Snake : public Sprite
{
private:
    // 存放蛇的每个结点
    vector<Sprite> nodes;
    int dir;
 
public:
    Snake()
    {
        // 一开始默认方向朝右边,3个结点组成一条蛇
        dir = VK_RIGHT;
        nodes.push_back(Sprite(20, 0));
        nodes.push_back(Sprite(10, 0));
        nodes.push_back(Sprite(0, 0));
    }
    void show() override
    {
        for (int i = 0; i < nodes.size(); i++)
        {
            nodes[i].show();
            fillrectangle(nodes[i].get_pos_x(), nodes[i].get_pos_y(), nodes[i].get_pos_x() + 10, nodes[i].get_pos_y() + 10);
        }
    }
    // 蛇的移动
    void move()
    {
        for (int i = nodes.size() - 1; i > 0; i--)
        {
            nodes[i] = nodes[i - 1];
        }
        check_dir();
        switch (dir)
        {
        case VK_UP:
            nodes[0].change_pos(nodes[0].get_pos_x(), nodes[0].get_pos_y() - 10);
            break;
        case VK_DOWN:
            nodes[0].change_pos(nodes[0].get_pos_x(), nodes[0].get_pos_y() + 10);
            break;
        case VK_LEFT:
            nodes[0].change_pos(nodes[0].get_pos_x() - 10, nodes[0].get_pos_y());
            break;
        case VK_RIGHT:
            nodes[0].change_pos(nodes[0].get_pos_x() + 10, nodes[0].get_pos_y());
            break;
        }
    }
    // 方向的改变
    void check_dir()
    {
        ExMessage msg;
        if (peekmessage(&msg, EM_KEY) && msg.message == WM_KEYDOWN)
        {
 
            switch (msg.vkcode)
            {
            case VK_UP:
                if (dir != VK_DOWN)
                    dir = VK_UP;
                break;
            case VK_DOWN:
                if (dir != VK_UP)
                    dir = VK_DOWN;
                break;
            case VK_LEFT:
                if (dir != VK_RIGHT)
                    dir = VK_LEFT;
                break;
            case VK_RIGHT:
                if (dir != VK_LEFT)
                    dir = VK_RIGHT;
                break;
            }
        }
    }
    // 和食物的碰撞
    bool food_collision(const Sprite &other)
    {
        return nodes[0].collision(other);
    }
    // 和自己的碰撞或越界
    bool body_collision_or_over_pos()
    {
        for (int i = 1; i < nodes.size(); i++)
        {
            if (nodes[0].collision(nodes[i]))
            {
                return false;
            }
        }
        if (nodes[0].get_pos_x() < 0 ||
            nodes[0].get_pos_x() + 10 > 640 ||
            nodes[0].get_pos_y() < 0 ||
            nodes[0].get_pos_y() + 10 > 480)
        {
            return false;
        }
        return true;
    }
    // 增加结点
    void add_node()
    {
        nodes.push_back(Sprite());
    }
};
// 食物类
class Food : public Sprite
{
private:
public:
    Food() : Sprite(rand() % 64 * 10, rand() % 48 * 10, GREEN)
    {
    }
    void show() override
    {
        Sprite::show();
        solidellipse(pos_x, pos_y, pos_x + 10, pos_y + 10);
    }
};
// 场景类
class Scene
{
private:
    Snake snake;
    Food food;
    bool flag;
    int score;
 
public:
    Scene() : flag(true), score(0) {}
    void run()
    {
        // 双缓冲区绘图,取消闪屏
        BeginBatchDraw();
        cleardevice();
        snake.show();
        snake.move();
 
        food.show();
        if (snake.food_collision(food))
        {
            score += 10;
            // 刷新食物
            food.change_pos(rand() % 64 * 10, rand() % 48 * 10);
            // 增加蛇的结点
            snake.add_node();
        }
        flag = snake.body_collision_or_over_pos();
        set_text();
        EndBatchDraw();
    }
    bool get_flag()
    {
        return flag;
    }
    void set_text()
    {
        char s[20] = "score";
        sprintf(s, "%s%c%d", s, ':', score);
        settextcolor(WHITE);
        outtextxy(550, 440, (LPCTSTR)s);
    }
};
int main()
{
    // 绘制一个窗口
    initgraph(640, 480);
 
    // 设置随机数种子
    srand(time(NULL));
    // 绘制场景
    Scene scene;
    while (scene.get_flag())
    {
        scene.run();
        Sleep(150);
    }
    getchar();
    closegraph();
 
    return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的贪吃蛇游戏C++代码,注释已经解释了代码的基本原理: ```c++ #include <iostream> #include <conio.h> //用于控制台输入输出 #include <windows.h> //用于控制台窗口相关操作 using namespace std; bool gameOver; //游戏是否结束 const int width = 20; //地图宽度 const int height = 20; //地图高度 int x, y, fruitX, fruitY, score; //蛇头坐标、食物坐标、分数 int tailX[100], tailY[100]; //蛇身坐标 int nTail; //蛇身长度 enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN }; //方向枚举 eDirection dir; //方向变量 void Setup() //初始化 { gameOver = false; dir = STOP; x = width / 2; y = height / 2; fruitX = rand() % width; fruitY = rand() % height; score = 0; } void Draw() //绘制游戏界面 { system("cls"); //清屏 for (int i = 0; i < width + 2; i++) cout << "#"; //上边框 cout << endl; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (j == 0) cout << "#"; //左边框 if (i == y && j == x) cout << "O"; //蛇头 else if (i == fruitY && j == fruitX) cout << "F"; //食物 else { bool printTail = false; for (int k = 0; k < nTail; k++) { if (tailX[k] == j && tailY[k] == i) { cout << "o"; //蛇身 printTail = true; } } if (!printTail) cout << " "; } if (j == width - 1) cout << "#"; //右边框 } cout << endl; } for (int i = 0; i < width + 2; i++) cout << "#"; //下边框 cout << endl; cout << "Score:" << score << endl; //输出分数 } void Input() //输入操作 { if (_kbhit()) //如果有输入 { switch (_getch()) //获取输入字符 { case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': gameOver = true; break; } } } void Logic() //游戏逻辑 { int prevX = tailX[0]; int prevY = tailY[0]; int prev2X, prev2Y; tailX[0] = x; tailY[0] = y; for (int i = 1; i < nTail; i++) { prev2X = tailX[i]; prev2Y = tailY[i]; tailX[i] = prevX; tailY[i] = prevY; prevX = prev2X; prevY = prev2Y; } switch (dir) //根据方向移动蛇头 { case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; } //判断游戏是否结束 if (x > width || x < 0 || y > height || y < 0) gameOver = true; for (int i = 0; i < nTail; i++) { if (tailX[i] == x && tailY[i] == y) gameOver = true; } if (x == fruitX && y == fruitY) //如果吃到食物 { score += 10; fruitX = rand() % width; fruitY = rand() % height; nTail++; } } int main() { Setup(); while (!gameOver) { Draw(); Input(); Logic(); Sleep(100); //控制游戏速度 } return 0; } ``` 这个贪吃蛇游戏的实现原理非常简单,主要分为以下几个步骤: 1. 初始化游戏,包括设置蛇头初始位置、随机生成食物、初始化分数等。 2. 绘制游戏界面,包括绘制地图、绘制蛇头、绘制蛇身和绘制食物等。 3. 获取玩家输入操作,根据输入操作更新蛇头方向。 4. 根据蛇头方向移动蛇头和蛇身,并判断游戏是否结束。 5. 如果吃到食物,则加分并生成新的食物。 6. 循环执行步骤2到步骤5,直到游戏结束。 这个贪吃蛇游戏的实现比较简单,但是也有很多可以改进的地方,比如增加难度、增加音效、增加排行榜等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值