项目:基于C++的贪吃蛇游戏

项目需求:

  1. 用easyx图形库开发实现基本界面

  1. 用STL标准容器库实现数据结构的存储

  1. 要对场景中对象的碰撞做出相应的处理(碰到食物时增加蛇的节数,碰到身体则游戏结束)

  1. 要对蛇类对象越界做出判断,越界时游戏结束

  1. 要有分数记录,每吃到1个食物增加10分

代码实现:

snake.cpp:

#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;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值