以下是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;
}