软件环境:EasyX 20210115, visual studio2019
参考代码:https://codebus.cn/aknoi/snake
效果展示:
当按下’s’键的时候会出现自己目前的得分。
展望:
由于只是一个简单的版本,所以还存在一些不足,下一步考虑使用链表而不是数组来作为存储结构;使用线程而不是延迟;使用mysql构建一个用户登录界面。
重点解释
存储位置的时候只是存储坐标点,但是当画的时候,显示的一个个矩形来表示蛇的一节节的身体。
代码结构:
主要由snake,food类构成,还有一个控制的main文件进行逻辑控制
代码:
snake.h
#ifndef SNAKE_H_
#define SNAKE_H_
#include<vector>
#include<graphics.h>
#include<conio.h>
#include"food.h"
using std::vector;
class snake
{
private:
struct Point
{
int x;
int y;
};
vector<Point> xy;
Point next;
vector<COLORREF> color;
int num;
int direction;
int grade;
bool live;
public:
static enum DIRECTION{UP, DOWN, LEFT, RIGHT};
snake();
void draw();
void move();
void eat(food &f);
void setDirection(DIRECTION dir) { direction = dir; }
int getPosX() { return xy[0].x; }
int getPosY() { return xy[0].y; }
int getDirection() { return direction; }
int getScore() { return grade; }
~snake() {};
};
#endif
snake.cpp
#include"snake.h"
snake::snake()
{
snake::Point pos;
pos.x = 20;
pos.y = 0;
xy.push_back(pos);
color.push_back(RGB(rand()%256, rand()%256, rand()%256));
pos.x = 10;
pos.y = 0;
xy.push_back(pos);
color.push_back(RGB(rand()%256, rand()%256, rand()%256));
pos.x = 0;
pos.y = 0;
xy.push_back(pos);
color.push_back(RGB(rand()%256, rand()%256, rand()%256));
num = 3;
direction = RIGHT;
grade = 0;
live = true;
}
void snake::draw()
{
for(int i=0; i<num; i++)
{
setfillcolor(color[i]);
fillrectangle(xy[i].x, xy[i].y, xy[i].x+10, xy[i].y+10);
}
}
void snake::move()
{
next = xy[num-1];
for(int i=num-1; i>=1; i--)
{
xy[i] = xy[i-1];
}
switch(direction)
{
case RIGHT:
xy[0].x += 10;
break;
case LEFT:
xy[0].x -= 10;
break;
case UP:
xy[0].y -= 10;
break;
case DOWN:
xy[0].y += 10;
break;
}
}
void snake::eat(food &f)
{
Point point;
point.x = f.getPosX();
point.y = f.getPosY();
if (xy[0].x == point.x && xy[0].y == point.y)
{
vector<Point>::iterator Phead = xy.begin();
vector<COLORREF>::iterator Chead = color.begin();
xy.insert(Phead, point);
color.insert(Chead, f.getColor());
grade += f.getGrade();
num++;
f.refresh();
}
}
food.h
#ifndef FOOD_H
#define FOOD_H
#include<graphics.h>
#include<cstdlib>
class food
{
private:
struct Point
{
int x;
int y;
};
Point pos;
int grade;
COLORREF color;
static const int grades[3];
static const COLORREF colors[3];
public:
food();
~food() {};
void draw();
int getPosX() { return pos.x; }
int getPosY() { return pos.y; }
COLORREF getColor() { return color; }
int getGrade() { return grade; }
void refresh();
};
#endif // !FOOD_H
food.cpp
#include"food.h"
//随机生成事物的时候需要使用的
const int food::grades[3] = { 100, 50, 10 };
const COLORREF food::colors[3] = { RED, GREEN, BLUE };
food::food()
{
int colorNum = rand() % 3;
color = colors[colorNum];
grade = grades[colorNum];
pos.x = rand() % 80 * 10;
pos.y = rand() % 60 * 10;
}
void food::draw()
{
setfillcolor(color);
fillrectangle(pos.x, pos.y, pos.x + 10, pos.y + 10);
}
void food::refresh()
{
int colorNum = rand() % 3;
color = colors[colorNum];
grade = grades[colorNum];
pos.x = rand() % 80 * 10;
pos.y = rand() % 60 * 10;
}
main.cpp
#include<graphics.h>
#include<ctime>
#include<conio.h>
#include<locale>
#include"snake.h"
bool checkLive(snake & s)
{
if (s.getPosX() >= 800 || s.getPosX()<0 || s.getPosY() >= 600 || s.getPosY() < 0)
{
return false;
}
return true;
}
void showScore(snake &s)
{
TCHAR text[100];
wsprintf(text, _T("分数: %d"), s.getScore());
settextcolor(BLACK);
RECT rect = { 600, 0, 800, 100 };
drawtext(text, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
}
bool keyDown(snake &s)
{
char userKey = _getch();
if(userKey == -32)
{
userKey = -_getch();
}
if (userKey == 's')
{
showScore(s);
return false;
}
switch(userKey)
{
case 'w':
case 'W':
case -72:
if (s.getDirection() != snake::DOWN)
s.setDirection(snake::UP);
else
return false;
break;
case 's':
case 'S':
case -80:
if (s.getDirection() != snake::UP)
s.setDirection(snake::DOWN);
else
return false;
break;
case 'a':
case 'A':
case -75:
if (s.getDirection() != snake::RIGHT)
s.setDirection(snake::LEFT);
else
return false;
break;
case 'd':
case 'D':
case -77:
if (s.getDirection() != snake::LEFT)
s.setDirection(snake::RIGHT);
else
return false;
break;
}
return true;
}
int main(void)
{
setlocale(LC_ALL, ".936");
initgraph(800, 600);
setbkcolor(RGB(95, 183, 72));
srand((unsigned)time(NULL));
snake s;
s.draw();
food f;
f.draw();
while(true)
{
if(_kbhit())
{
if (keyDown(s))
{
s.move();
}
}
s.draw();
f.draw();
Sleep(100);
s.eat(f);
s.move();
if (!checkLive(s))
{
break;
}
clearrectangle(0, 0, 800, 600);
}
_getch();
return 0;
}