使用EasyX图形库绘制,在VC中安装,EasyX官网:EasyX Graphics Library for C++
EasyX官方文档:EasyX 文档 - 使用教程
cpp
#include<iostream>
#include<easyx.h>
#include<vector>//顺序表,容器
#include<ctime>
class Sprite {
public:
//委托构造函数
Sprite():Sprite(0,0) {}
Sprite(int x, int y) :m_x(x), m_y(y),m_color(RED) {}
//绘制精灵
virtual void draw()
{
//设置填充颜色
setfillcolor(m_color);
//绘制矩形
fillrectangle(m_x, m_y, m_x+10, m_y+10);
}
//移动
void moveBy(int dx, int dy)
{
m_x += dx;
m_y += dy;
}
//碰撞检测
bool collision(const Sprite& ohter)
{
return m_x == ohter.m_x && m_y == ohter.m_y;
}
bool coollisionWall()
{
return m_x > 640 || m_x < 0 || m_y>480 || m_y < 0;
}
protected:
int m_y;
int m_x;
COLORREF m_color;//颜色
};
//蛇类
class Snake:public Sprite
{
public:
Snake():Snake(0,0) {}
Snake(int x, int y) :Sprite(x, y),dir(VK_RIGHT)
{
//初始化三节蛇
nodes.push_back(Sprite(20, 0));
nodes.push_back(Sprite(10, 0));
nodes.push_back(Sprite(0, 0));
}
void draw() override//绘制蛇
{
for (int i = 0; i < nodes.size(); i++)
{
nodes[i].draw();
}
}
//蛇移动
void bodyMove()
{
//身体跟蛇头移动
for (size_t i = nodes.size()-1; i >0; i--)
{
nodes[i] = nodes[i - 1];
}
//蛇头移动
switch (dir)
{
case VK_UP://上移
nodes[0].moveBy(0, -10);
break;
case VK_DOWN://下移
nodes[0].moveBy(0, 10);
break;
case VK_LEFT://左移
nodes[0].moveBy(-10, 0);
break;
case VK_RIGHT://右移
nodes[0].moveBy(10, 0);
break;
}
}
//吃食物,蛇碰撞
bool collision(const Sprite& other)
{
return nodes[0].collision(other);
}
//碰撞墙壁
bool die()
{
return nodes[0].coollisionWall();
}
//蛇增加一节
void incrment()
{
nodes.push_back(Sprite());
}
private:
std::vector<Sprite>nodes;//蛇的所有结点
public:
int dir;//蛇的方向
};
//食物
class Food :public Sprite
{
public:
Food():Sprite(0,0)
{
changePos();
}
//绘制食物
void draw()override
{
setfillcolor(m_color);
solidellipse(m_x, m_y, m_x + 10, m_y + 10);
}
//产生食物的坐标
void changePos()
{
//生成随机坐标
m_x = rand() % 64 * 10;//食物坐标为10的整数倍
m_y = rand() % 48 * 10;
}
};
//游戏场景
class GameScene
{
public:
GameScene()
{
}
void run()
{
//开启双缓冲
BeginBatchDraw();
//清屏
cleardevice();
//绘制蛇
snake.draw();
//绘制食物
food.draw();
EndBatchDraw();
//移动蛇,改变蛇的坐标
snake.bodyMove();
//是否吃到食物
snakeEatFood();
//获取消息
ExMessage msg = { 0 };
if(peekmessage(&msg, EX_KEY))
{
onMsg(msg);
}
}
//响应消息:鼠标消息,键盘消息
void onMsg(const ExMessage& msg)
{
//如果有按键按下
if (msg.message == WM_KEYDOWN)
{
//判断具体是那个按键按下 virtual key code 虚拟键码
//判断上时不能按下,左时不能按右
switch (msg.vkcode)
{
case VK_UP:
if(snake.dir!=VK_DOWN)
snake.dir = msg.vkcode;
break;
case VK_DOWN:
if (snake.dir != VK_UP)
snake.dir = msg.vkcode;
break;
case VK_LEFT:
if (snake.dir != VK_RIGHT)
snake.dir = msg.vkcode;
break;
case VK_RIGHT:
if (snake.dir != VK_LEFT)
snake.dir = msg.vkcode;
break;
}
}
}
//判断蛇能否吃到食物
void snakeEatFood()
{
if (snake.collision(food))//如果蛇和食物产生碰撞
{
//蛇的节数增加
snake.incrment();
//产生新的食物
food.changePos();
}
}
//判断蛇是否碰到墙壁,如果碰到了游戏结束
bool snakeDie()
{
if (snake.die())
{
cleardevice();//清除屏幕
outtextxy(250, 200, L"GAME OVER!");
return true;
}
return false;
}
private:
Snake snake;//创建蛇
Food food;//食物
};
int main() {
//绘制窗口
initgraph(640, 480);
//设置随机数种子
srand(time(nullptr));
GameScene scene;
while (true)
{
scene.run();
//是否死亡
if (scene.snakeDie())
{
break;
}
Sleep(100);
}
getchar();
return 0;
}