使用EasyX图形库绘制,在VC中安装,EasyX官网:EasyX Graphics Library for C++
EasyX官方文档:EasyX 文档 - 使用教程
#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;
}