0.实现效果

模式选择:普通模式,穿墙模式,无敌模式。

贪吃蛇实现_初始化

进入游戏,有背景音乐。

贪吃蛇实现_初始化_02

1.准备工作:

easyx图形库安装,NSIS打包软件。

这两个在网上能找到教程安装。

2.关于贪吃蛇实现

在网上有很多教程,或多或少细节方面是有不同之处的,这里我借助easyx图形库进行实现,一是色彩不显得那么单调;二是不使用windows的光标控制函数等函数,这样就避免后面涉及线程的东西,上手方面会更简单一些。(线程这块不是太明白)

3.进入实战

注意:VS2019中.cpp才能运行easyx图形库,.c是不行的。

1.首先先绘个背景:

#include<iostream>
#include<easyx.h>
int main()
{
initgraph(640,480);//设置窗口大小,为640*480
setbkcolor(WHITE);//设置窗口背景色为白色
cleardevice();//刷新屏幕
setbkmode(TRANSPARENT); //设置字体背景色为透明
settextcolor(RED); //设置字体颜色为红色
outtextxy(200, 240, L"Enter键进入游戏");
outtextxy(200, 280, L"字母键 W,S,A,D 方向键 上下左右 控制方向");
getchar(); //按任意键继续
return 0;
}



关于函数怎么使用,网上有详细说明,这里就不一一具体说明了。

这里getchar()是为了不让图片加载就消失。

这样,我们就得到了一个窗口

贪吃蛇实现_初始化_03

当然,这个就比较单调,我们加个背景图(这个找张喜欢的图片)上去。

#include<iostream>
#include<easyx.h>
IMAGE img;
int main()
{
cleardevice(); //刷新屏幕
loadimage(&img, L"Image0.jpg", 640, 480); //保存图片
putimage(0, 0, &img); //显示图片
setbkmode(TRANSPARENT); //设置字体背景色为透明
settextcolor(WHITE); //设置字体颜色为红色
outtextxy(170, 200, L"模式选择");
outtextxy(170, 240, L"1.普通模式");
outtextxy(170, 280, L"2.穿墙模式");
outtextxy(170, 320, L"3.无敌模式");
outtextxy(380, 220, L"游戏说明:");
outtextxy(360, 280, L"Enter键进入游戏");
outtextxy(300, 320, L"字母键 W,S,A,D 方向键 上下左右 控制方向");
outtextxy(350, 360, L"长按方向加速,空格暂停");
getchar(); //按任意键继续
return 0;
}



loadimage里的Image.jpg我是放在了项目所在的位置,就可以直接调用了。写绝对路径也是可以的,有一点要注意,就是路径要\\,比如D:\要写成D:\\

这里我踩的一个坑就是putimage的前两个参数,这两个参数代表的是图片左上角的坐标,全部设为0,图片才能全部加载出来。

贪吃蛇实现_初始化_04

然后我们把上面这个图片代码放在start函数中,在main中调用这个函数。

2.模式选择

void chose()
{
while (1)
{
switch (_getch())
{
case '1':
start();
outtextxy(160, 240, L"->");
mode = 0; //全局变量mode表示模式
break;
case '2':
start();
outtextxy(160, 280, L"->");
mode = 1;
break;
case '3':
start();
outtextxy(160, 320, L"->");
mode = 2;
break;
case 13: //Enter键进入游戏
return;
deault:
break;
}
}
}



这里的13表示enter键对应的数字。这里我踩的大坑就是开始写的这个'1'是1,导致键盘上的1对应的数值不是1,也就是按不动。一定要注意,键盘上数字和对应的数字不是一回事。

贪吃蛇实现_初始化_05

然后就可以在这三个模式进行切换,按Enter键进入游戏。

3.初始化游戏数据

游戏数据的话,我们需要一个围墙,一条蛇,分数显示。

围墙这里我们借用Map元素把整个框框包含在里面,然后分四类,分别是SPACE(空地),墙(WALL),蛇身(SNAKE),蛇头(HEAD),食物(FOOD)。

enum {
SPACE, WALL, SNAKE, HEAD,FOOD //依次代表空地,墙,蛇身,头,食物
};
#define ROW 48
#define COL 64
int map[ROW][COL];
int mode; //模式
int score; //分数
void DrawMap();//绘画界面
void Init();//初始化游戏界面



绘画:

void DrawMap()
{
BeginBatchDraw(); //开始绘图
settextcolor(RGB(238, 0, 0)); //设置字体颜色为红色
cleardevice(); //刷新屏幕
loadimage(&img, L"Image.jpg", 640, 480); //保存图片
putimage(0, 0, &img); //显示图片
WCHAR arr[10]; //保存分数
wsprintf(arr, L"得分:%d", score); //分数放在arr中
outtextxy(0, 0, arr); //显示分数
for(int y=0;y<ROW;y++)
for (int x = 0; x < COL; x++)
{
switch (map[y][x])
{
case SPACE:
break;
case WALL:
setlinecolor(RED); //边框线条颜色
setfillcolor(RGB(187, 255, 255)); //填充颜色
fillrectangle(x*10, y*10, x*10 + 10, y*10 + 10); //画矩形
break;
case SNAKE:
setlinecolor(RGB(78, 238, 148));
setfillcolor(WHITE);
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case HEAD:
switch (rand() % 7)
{
case 0:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RED);
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case 1:
setlinecolor(RGB(78, 238, 148));
setfillcolor(WHITE);
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case 2:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(100,149,237));
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case 3:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(127,255,0));
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case 4:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(176,224,230));
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case 5:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(102,139,139));
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
case 6:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(46,139,87));
fillrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
break;
default:
break;
}
break;
}
}
EndBatchDraw(); //结束绘图
}



然后写初始化界面

void Init()
{
srand((unsigned)time(NULL));//随机种子,给后面DrawMap中画蛇头使用
memset(map, SPACE, sizeof(map));//初始化数组map为SPACE
for (int x =0; x < COL; x++)
map[0][x] = map[ROW - 1][x] = WALL;
for (int y = 0; y < ROW; y++)
map[y][0] = map[y][COL-1] = WALL;

}



先显示看看:贪吃蛇实现_数组_06

然后发现不对劲,怎么会怎样?这也是一个坑,坑在哪,在我们设置地图数组的时候,如果直接按原地就搬尺寸就会发现原来的得分被覆盖了,那怎么改?

一是把原来的DrawMap给Wall的初始坐标修改,二是对Init中的两个for进行调整,x,y不再是从0,0开始,而是从0,2开始。(注意:二维数组左边代表纵坐标,右边代表横坐标)。

void Init()
{
srand((unsigned)time(NULL));//随机种子,给后面DrawMap中画蛇头使用
memset(map, SPACE, sizeof(map));//初始化数组map为SPACE
for (int x =0; x < COL; x++)
map[2][x] = map[ROW - 1][x] = WALL;
for (int y = 2; y < ROW; y++)
map[y][0] = map[y][COL-1] = WALL;
}



这样改到也可以,至少目前来说是可以,但是产生食物需要一个边界。这里我们的map[1][]和map[2][]是浪费了的。所以为了后续更好使用,这里我们干脆来个大修改:

#define ROW 46
#define COL 64
...
void Init()
{
srand((unsigned)time(NULL));//随机种子,给后面DrawMap中画蛇头使用
memset(map, SPACE, sizeof(map));//初始化数组map为SPACE
for (int x =0; x < COL; x++)
map[0][x] = map[ROW - 1][x] = WALL;
for (int y = 0; y < ROW; y++)
map[y][0] = map[y][COL-1] = WALL;

}

void DrawMap()
{
BeginBatchDraw(); //开始绘图
settextcolor(RGB(238, 0, 0)); //设置字体颜色为红色
cleardevice(); //刷新屏幕
loadimage(&img, L"Image.jpg", 640, 480); //保存图片
putimage(0, 0, &img); //显示图片
WCHAR arr[10]; //保存分数
wsprintf(arr, L"得分:%d", score); //分数放在arr中
outtextxy(0, 0, arr); //显示分数
for (int y = 0; y < ROW; y++)
for (int x = 0; x < COL; x++)
{
switch (map[y][x])
{
case SPACE:
break;
case WALL:
setlinecolor(RED); //边框线条颜色
setfillcolor(RGB(187, 255, 255)); //填充颜色
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30); //画矩形
break;
case SNAKE:
setlinecolor(RGB(78, 238, 148));
setfillcolor(WHITE);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case HEAD:
switch (rand() % 7)
{
case 0:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RED);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 1:
setlinecolor(RGB(78, 238, 148));
setfillcolor(WHITE);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 2:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(100, 149, 237));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 3:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(127, 255, 0));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 4:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(176, 224, 230));
fillrectangle(x * 10, y * 10+20, x * 10 + 10, y * 10 + 30);
break;
case 5:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(102, 139, 139));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 +30);
break;
case 6:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(46, 139, 87));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 +30);
break;
default:
break;
}
break;
}
}
EndBatchDraw(); //结束绘图
}



这里特别要注意的是这个矩形四个角的坐标,要调对来。

贪吃蛇实现_数组_07

这样,就得到了一个进去后的游戏界面。

4.造蛇

那蛇呢?对,现在开始造蛇,造蛇的话?可以用数组,但是超过数组区间就会崩溃,这里我们使用链表。

struct snake
{
COORD pos; //typedef struct _COORD {SHORT X; SHORT Y;} COORD
struct snake* next; //连接结点
};
struct snake* Head; //表示蛇头
void AddPoint(int x, int y); //增加结点
...
void AddPoint(int x, int y)
{
struct snake* point = (struct snake*)malloc(sizeof(struct snake));
if (point == NULL)
{
return;
}
else
{
point->pos.X = x;//这里X,Y分别代表纵坐标,横坐标
point->pos.Y = y;
if (Head == NULL)
{
Head = point;
map[Head->pos.X][Head->pos.Y] = HEAD;
}
else
{
map[Head->pos.X][Head->pos.Y] = SNAKE;
point->next = Head;
Head = point;
map[Head->pos.X][Head->pos.Y] = HEAD;
}
}
}



然后就可以得到这样的:

贪吃蛇实现_数组_08

那蛇要怎么动呢,就是蛇头移动一个位置,然后那个新坐标就是蛇头,原蛇头为SNAKE,后面蛇尾释放置SPACE。

void DelPoint(); //删除结点
void ChangeDir(); //调整方向
void move(); //蛇动起来
char SnakeDir;//蛇的方向
int t1, t2; //代表时间

void DelPoint()
{
if (Head == NULL || Head->next == NULL)
{
return;
}
struct snake* p = (struct snake*)malloc(sizeof(struct snake));
struct snake* q = (struct snake*)malloc(sizeof(struct snake));
if (p == NULL || q == NULL)
{
return;
}
p = Head;
q = p->next;
while (q->next)
{
p = p->next;
q = p->next;
}
map[q->pos.X][q->pos.Y] = SPACE;
free(q);
q = NULL;
p->next = NULL;
}
void move()
{
struct snake* newpoint = (struct snake*)malloc(sizeof(struct snake));
if (newpoint == NULL)
{
return;
}
switch (SnakeDir)
{
case 'D':
newpoint->pos.X = Head->pos.X;
newpoint->pos.Y = Head->pos.Y + 1; //理清X,Y代表什么
break;
case 'A':
newpoint->pos.X = Head->pos.X;
newpoint->pos.Y = Head->pos.Y - 1;
break;
case 'W':
newpoint->pos.X = Head->pos.X - 1;
newpoint->pos.Y = Head->pos.Y;
break;
case 'S':
newpoint->pos.X = Head->pos.X + 1;
newpoint->pos.Y = Head->pos.Y;
break;
default:
break;
}
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
}
void ChangeDir()
{
switch (_getch())
{
case 'A':
case 'a':
case 75:
if (SnakeDir != 'D')
SnakeDir = 'A';
break;
case 'D':
case 'd':
case 77:
if (SnakeDir != 'A')
SnakeDir = 'D';
break;
case 'W':
case 'w':
case 72:
if (SnakeDir != 'S')
SnakeDir = 'W';
break;
case 'S':
case 's':
case 80:
if (SnakeDir != 'W')
SnakeDir = 'S';
break;
case 32: //空格
_getch();
break;
default:
break;
}
}



这里的键盘上上、下、左、右分别对应数值72,80,75,77.

因为蛇动起来,自然就是while循环内一直走,碰到限制条件结束,然后我们这里要让他动起来,借助GetTickCount()函数,这个函数精度高

int main()
{
initgraph(640, 480);
start();
outtextxy(160, 240, L"->");
chose();
Init();
while (1)
{
DrawMap();
if (_kbhit())
{
ChangeDir();
move();
t2 = GetTickCount();
t1 = t2;
}
t2 = GetTickCount();
if (t2 - t1 > 100)
{
move();
t1 = t2;
}
}
getchar();
closegraph();
return 0;
}



然后蛇就可以简单的动了。

5.加食物和模式选择

接下来就是造食物,顺便把限制条件给加上,就普通模式下撞墙或者撞到自己身体游戏结束,另外两个模式就是屏蔽游戏结束。

void Addfood()
{
int x, y;
do
{
x = rand() % (ROW-1)+1;
y = rand() % (COL - 1) + 1;
} while (map[x][y] != SPACE);
map[x][y] = FOOD;
}
void move()
{
struct snake* newpoint = (struct snake*)malloc(sizeof(struct snake));
if (newpoint == NULL)
{
return;
}
switch (SnakeDir)
{
case 'D':
newpoint->pos.X = Head->pos.X;
newpoint->pos.Y = Head->pos.Y + 1; //理清X,Y代表什么
break;
case 'A':
newpoint->pos.X = Head->pos.X;
newpoint->pos.Y = Head->pos.Y - 1;
break;
case 'W':
newpoint->pos.X = Head->pos.X - 1;
newpoint->pos.Y = Head->pos.Y;
break;
case 'S':
newpoint->pos.X = Head->pos.X + 1;
newpoint->pos.Y = Head->pos.Y;
break;
default:
break;
}
switch (map[newpoint->pos.X][newpoint->pos.Y])
{
case SPACE:
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
break;
case SNAKE:
if (mode==2)
{
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
}
else
{
PlaySound(NULL,0,0);
MessageBox(GetHWnd(), L"游戏结束,继续努力", L"结果", MB_OK);
exit(0);
}
break;
case WALL:
if (mode)
{
switch (SnakeDir)
{
case 'A':
newpoint->pos.Y = COL - 2;
break;
case 'D':
newpoint->pos.Y = 1;
break;
case 'W':
newpoint->pos.X = ROW - 2;
break;
case 'S':
newpoint->pos.X = 1;
break;
default:
break;
}
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
}
else
{
PlaySound(NULL,0,0);
MessageBox(GetHWnd(), L"游戏结束,继续努力", L"结果", MB_OK);
exit(0);
}
break;
case FOOD:
score++;
AddPoint(newpoint->pos.X, newpoint->pos.Y);
Addfood();
break;
default:
break;
}
}



然后就是把main函数中进行调用一下。

#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

int main()
{
initgraph(640, 480);
start();
outtextxy(160, 240, L"->");
chose();
Init();
while (1)
{
PlaySound(L"彩豆森林.wav", NULL, SND_FILENAME | SND_ASYNC | SND_NODEFAULT | SND_LOOP);
while (1)
{
DrawMap();
if (_kbhit())
{
ChangeDir();
move();
t2 = GetTickCount();
t1 = t2;
}
t2 = GetTickCount();
if (t2 - t1 > 100)
{
move();
t1 = t2;
}
}
}
getchar();
closegraph();
return 0;
}



然后加了个背景音乐进去,游戏结束把背景音乐停了。

6.源码

#include<iostream>
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<Windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
using namespace std;

void start(); //开始界面
void Init(); //初始化游戏数据
void chose(); //选择界面
void DrawMap();//绘画界面
void Init();//初始化游戏界面
void Addfood();//添加食物
enum {
SPACE, WALL, SNAKE, HEAD,FOOD //依次代表空地,墙,蛇身,头
};
IMAGE img;
#define ROW 46
#define COL 64
int map[ROW][COL];
int mode; //模式
int score; //分数
char SnakeDir;//蛇的方向
int t1, t2; //代表时间
struct snake
{
COORD pos; //typedef struct _COORD {SHORT X; SHORT Y;} COORD
struct snake* next; //连接结点
};
struct snake* Head; //表示蛇头
void AddPoint(int x, int y); //增加结点
void DelPoint(); //删除结点
void ChangeDir(); //调整方向
void move(); //蛇动起来
int main()
{
initgraph(640, 480);
start();
outtextxy(160, 240, L"->");
chose();
Init();
while (1)
{
PlaySound(L"彩豆森林.wav", NULL, SND_FILENAME | SND_ASYNC | SND_NODEFAULT | SND_LOOP);
while (1)
{
DrawMap();
if (_kbhit())
{
ChangeDir();
move();
t2 = GetTickCount();
t1 = t2;
}
t2 = GetTickCount();
if (t2 - t1 > 100)
{
move();
t1 = t2;
}
}
}
getchar();
closegraph();
return 0;
}
void start()
{
cleardevice();
loadimage(&img, L"Image0.jpg", 640, 480); //保存图片
putimage(0, 0, &img); //显示图片
setbkmode(TRANSPARENT); //设置字体背景色为透明
settextcolor(WHITE); //设置字体颜色为白色
outtextxy(170, 200, L"模式选择");
outtextxy(170, 240, L"1.普通模式");
outtextxy(170, 280, L"2.穿墙模式");
outtextxy(170, 320, L"3.无敌模式");
outtextxy(380, 220, L"游戏说明:");
outtextxy(360, 280, L"Enter键进入游戏");
outtextxy(300, 320, L"字母键 W,S,A,D 方向键 上下左右 控制方向");
outtextxy(350, 360, L"长按方向加速,空格暂停");
}
void chose()
{
while (1)
{
switch (_getch())
{
case '1':
start();
outtextxy(160, 240, L"->");
mode = 0;
break;
case '2':
start();
outtextxy(160, 280, L"->");
mode = 1;
break;
case '3':
start();
outtextxy(160, 320, L"->");
mode = 2;
break;
case 13: //Enter键进入游戏
return;
deault:
break;
}
}
}
void Init()
{
srand((unsigned)time(NULL));//随机种子,给后面DrawMap中画蛇头使用
memset(map, SPACE, sizeof(map));//初始化数组map为SPACE
for (int x =0; x < COL; x++)
map[0][x] = map[ROW - 1][x] = WALL;
for (int y = 0; y < ROW; y++)
map[y][0] = map[y][COL-1] = WALL;
SnakeDir = 'D';
AddPoint(5, 3);
AddPoint(5, 4);
AddPoint(5, 5);
AddPoint(5, 6);
Addfood();
}
void ChangeDir()
{
switch (_getch())
{
case 'A':
case 'a':
case 75:
if (SnakeDir != 'D')
SnakeDir = 'A';
break;
case 'D':
case 'd':
case 77:
if (SnakeDir != 'A')
SnakeDir = 'D';
break;
case 'W':
case 'w':
case 72:
if (SnakeDir != 'S')
SnakeDir = 'W';
break;
case 'S':
case 's':
case 80:
if (SnakeDir != 'W')
SnakeDir = 'S';
break;
case 32:
_getch();
break;
default:
break;
}
}
void AddPoint(int x, int y)
{
struct snake* point = (struct snake*)malloc(sizeof(struct snake));
if (point == NULL)
{
return;
}
else
{
point->pos.X = x;
point->pos.Y = y;
if (Head != NULL)
{
map[Head->pos.X][Head->pos.Y] = SNAKE; //这里X,Y分别代表纵坐标,横坐标
}
point->next = Head;
Head = point;
map[Head->pos.X][Head->pos.Y] = HEAD;
}
}
void DelPoint()
{
if (Head == NULL || Head->next == NULL)
{
return;
}
struct snake* p = (struct snake*)malloc(sizeof(struct snake));
struct snake* q = (struct snake*)malloc(sizeof(struct snake));
if (p == NULL || q == NULL)
{
return;
}
p = Head;
q = p->next;
while (q->next)
{
p = p->next;
q = p->next;
}
map[q->pos.X][q->pos.Y] = SPACE;
free(q);
q = NULL;
p->next = NULL;
}
void Addfood()
{
int x, y;
do
{
x = rand() % (ROW-1)+1;
y = rand() % (COL - 1) + 1;
} while (map[x][y] != SPACE);
map[x][y] = FOOD;
}
void move()
{
struct snake* newpoint = (struct snake*)malloc(sizeof(struct snake));
if (newpoint == NULL)
{
return;
}
switch (SnakeDir)
{
case 'D':
newpoint->pos.X = Head->pos.X;
newpoint->pos.Y = Head->pos.Y + 1; //理清X,Y代表什么
break;
case 'A':
newpoint->pos.X = Head->pos.X;
newpoint->pos.Y = Head->pos.Y - 1;
break;
case 'W':
newpoint->pos.X = Head->pos.X - 1;
newpoint->pos.Y = Head->pos.Y;
break;
case 'S':
newpoint->pos.X = Head->pos.X + 1;
newpoint->pos.Y = Head->pos.Y;
break;
default:
break;
}
switch (map[newpoint->pos.X][newpoint->pos.Y])
{
case SPACE:
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
break;
case SNAKE:
if (mode==2)
{
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
}
else
{
MessageBox(GetHWnd(), L"游戏结束,继续努力", L"结果", MB_OK);
exit(0);
}
break;
case WALL:
if (mode)
{
switch (SnakeDir)
{
case 'A':
newpoint->pos.Y = COL - 2;
break;
case 'D':
newpoint->pos.Y = 1;
break;
case 'W':
newpoint->pos.X = ROW - 2;
break;
case 'S':
newpoint->pos.X = 1;
break;
default:
break;
}
AddPoint(newpoint->pos.X, newpoint->pos.Y);
DelPoint();
}
else
{
MessageBox(GetHWnd(), L"游戏结束,继续努力", L"结果", MB_OK);
exit(0);
}
break;
case FOOD:
score++;
AddPoint(newpoint->pos.X, newpoint->pos.Y);
Addfood();
break;
default:
break;
}
}
void DrawMap()
{
BeginBatchDraw(); //开始绘图
settextcolor(RGB(238, 0, 0)); //设置字体颜色为红色
cleardevice(); //刷新屏幕
loadimage(&img, L"Image.jpg", 640, 480); //保存图片
putimage(0, 0, &img); //显示图片
WCHAR arr[10]; //保存分数
wsprintf(arr, L"得分:%d", score); //分数放在arr中
outtextxy(0, 0, arr); //显示分数
for (int y = 0; y < ROW; y++)
for (int x = 0; x < COL; x++)
{
switch (map[y][x])
{
case SPACE:
break;
case WALL:
setlinecolor(RED); //边框线条颜色
setfillcolor(RGB(187, 255, 255)); //填充颜色
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30); //画矩形
break;
case SNAKE:
setlinecolor(RGB(78, 238, 148));
setfillcolor(WHITE);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case HEAD:
switch (rand() % 7)
{
case 0:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RED);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 1:
setlinecolor(RGB(78, 238, 148));
setfillcolor(WHITE);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 2:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(100, 149, 237));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 3:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(127, 255, 0));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
break;
case 4:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(176, 224, 230));
fillrectangle(x * 10, y * 10+20, x * 10 + 10, y * 10 + 30);
break;
case 5:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(102, 139, 139));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 +30);
break;
case 6:
setlinecolor(RGB(78, 238, 148));
setfillcolor(RGB(46, 139, 87));
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 +30);
break;
default:
break;
}
break;
case FOOD:
setlinecolor(WHITE);
setfillcolor(RED);
fillrectangle(x * 10, y * 10 + 20, x * 10 + 10, y * 10 + 30);
}
}
EndBatchDraw(); //结束绘图
}



图片,歌曲要自己插入,图片格式要对,jpeg我试过不行,歌曲要是wav格式(直接修改没用,要借助格式转换器才行,这个搜一下就可以了)。

7.利用NSIS打包exe

就是把exe打包成一个小软件发给别人,然后他人就可以安装玩这个小游戏了,关于NSIS如何打包在网上有很多教程,自己找个能看懂的操作就行了。

8.感想

这个小游戏拖了好长时间,又是长时间摸鱼....还是有很多地方还是不足的,至于那个贪吃蛇自己找路吃食物...目前实现不了,bfs不会用呀...

慢慢来吧。



如有不对,欢迎指正。