实现思路
本贪吃蛇主要运用C++和EasyX图形库进行开发。 详细的设计: 1.场景设计 运用了EasyX Graphics Library和Windows函数进行了对本游戏的图形化设计,我们的蛇采用若干个圆连接的形式组成,食物也采用圆的形式随机生成在地图上。 2.蛇和食物的储存结构 蛇和食物分别用一个类来储存,并且在该类中会储存相应的坐标、方向、速度、半径、等一些成员和成员函数。 3.蛇的移动 这里运用的kbhit()和getch()函数来接收用户的输入,并根据用户的输入来定蛇的方向。 4.蛇吃食物的判定 这里里的蛇吃食物的判定是根据蛇头和食物的距离来判定的,因游戏里的蛇头和食物都是一个圆构成的,所以我只需判定两个圆是否相交即可。 5.食物的生成,本游戏的食物是运用随机函数随机生成的。 6.蛇的死亡,这里的蛇是有2钟方式判定为死亡,一种是蛇头撞到墙和蛇头撞到身体,我们只需根据蛇头的坐标和蛇身的坐标来判定即可。 7.音乐的播放,运用Windows函数里的mciSendString()函数来播放音乐。
ps:这里的蛇的移动,是根据蛇头的方向移动而移动的,然后蛇身跟着前一节蛇身的位置而移动。
运行截图
源代码(附注释)
头文件(head.h)
#include <iostream>
#include <Windows.h>
#define WIGHT 800
#define HEIGHT 600
#define Snake_Num 500
using namespace std;
class food;
void Time_Out();
void Bgm();
void Begin();
double Distance(int x1, int y1, int x2, int y2);
enum dir
{
UP, DOWN, LEFT, RIGHT
};
class snake
{
public:
snake();
bool Box();
bool Is_dead();
void GameDraw(food&);
void SnakeMove();
void KeyControl();
void EatFood(food&);
private:
int len;
int dir;
int r;
int grade;
int speed;
bool flag;
POINT coor[Snake_Num];
};
class food
{
public:
food();
void friend snake::GameDraw(food&);
void friend snake::EatFood(food&);
private:
int x, y;
int r;
bool flag;
};
源文件(snake.cpp)
#include "head.h";
#include <iostream>
#include <cmath>
#include <conio.h>
#include <stdlib.h>
#include <Windows.h>
#include <graphics.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
using namespace std;
food::food()
{
r = 5;
x = rand() % (WIGHT - 2 * r) + r;
y = rand() % (HEIGHT - 2 * r) + r;
flag = true;
}
snake::snake()
{
len = 3;
dir = RIGHT;
r = 5;
speed = 10;
grade = 0;
flag = true;
for (int i = 0; i <= len - 1; i++) {
coor[i].x = 10 * (len - 1 - i) + 20;
coor[i].y = 10;
}
}
void snake::GameDraw(food &f)
{
BeginBatchDraw();
setbkcolor(RGB(56, 147, 186));
cleardevice();
for (int i = 0; i < len; i++)
solidcircle(coor[i].x, coor[i].y, r);
if (f.flag)
solidcircle(f.x, f.y, f.r);
wchar_t s[20] = L"";
swprintf_s(s, L"分数:%d", grade);
outtextxy(700, 20, s);
EndBatchDraw();
}
void snake::KeyControl()
{
if (_kbhit())
{
switch (_getch())
{
case 'w':
case 'W':
case 72:
if (dir == DOWN) break;
dir = UP;
break;
case 's':
case 'S':
case 80:
if (dir == UP) break;
dir = DOWN;
break;
case 'a':
case 'A':
case 75:
if (dir == RIGHT) break;
dir = LEFT;
break;
case 'd':
case 'D':
case 77:
if (dir == LEFT) break;
dir = RIGHT;
break;
case ' ':
Time_Out();
while (_getch() == ' ') break;
break;
default:
break;
}
}
}
void snake::SnakeMove()
{
for (int i = len - 1; i > 0; i--)
{
coor[i].x = coor[i - 1].x;
coor[i].y = coor[i - 1].y;
}
switch (dir)
{
case UP:
coor[0].y -= speed;
break;
case DOWN:
coor[0].y += speed;
break;
case LEFT:
coor[0].x -= speed;
break;
case RIGHT:
coor[0].x += speed;
break;
default:
break;
}
if (coor[0].x < r || coor[0].x > WIGHT - r)
flag = false;
if (coor[0].y < r || coor[0].y > HEIGHT - r)
flag = false;
for (int i = 1; i < len; i++)
{
if (Distance(coor[0].x, coor[0].y, coor[i].x, coor[i].y) < 2 * r)
{
flag = false;
break;
}
}
}
void snake::EatFood(food &f)
{
if (f.flag && Distance(coor[0].x, coor[0].y, f.x, f.y) <= r + f.r)
{
f.flag = false;
len++;
grade += 10;
}
if (!f.flag)
{
f.r = 5;
f.x = rand() % (WIGHT - 2 * f.r) + f.r;
f.y = rand() % (HEIGHT - 2 * f.r) + f.r;
f.flag = true;
}
}
double Distance(int x1, int y1, int x2, int y2)
{
double t1 = x1 - x2;
double t2 = y1 - y2;
return sqrt(t1 * t1 + t2 * t2);
}
bool snake::Box()
{
wchar_t s[20] = L"";
swprintf_s(s, L"你的分数为:%d\n是否再来一次", grade);
HWND hWnd = GetHWnd();
int id = MessageBox(hWnd, s, L"snake", MB_YESNO);
if (id == IDYES) return true;
return false;
}
bool snake::Is_dead()
{
return flag;
}
void Begin()
{
IMAGE img;
loadimage(&img, L"./snack.jpg", WIGHT, HEIGHT);
putimage(0, 0, &img);
}
void Bgm()
{
mciSendString(L"open bgm.mp3", 0, 0, 0);
mciSendString(L"play bgm.mp3", 0, 0, 0);
}
void Time_Out()
{
HWND hWnd = GetHWnd();
MessageBox(hWnd, L"游戏暂停,按空格键继续", L"提示", MB_OKCANCEL);
}
主函数(main.cpp)
#include "head.h";
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>
#include <graphics.h>
using namespace std;
int main()
{
Bgm();
srand(GetTickCount());
initgraph(WIGHT, HEIGHT);
while (1)
{
Begin();
if (_kbhit()) break;
}
snake s;
food f;
while (1)
{
s.KeyControl();
s.SnakeMove();
s.EatFood(f);
s.GameDraw(f);
if (!s.Is_dead())
{
if (s.Box())
{
snake ds; s = ds;
food df; f = df;
}
else break;
}
Sleep(50);
}
return 0;
}
总结废话
总的来说这贪吃蛇做的并没有那么好,蛇和食物和背景都是非常的简陋,并且可玩性也不是非常的好,其实可以加速度选择,加关卡模式,还有界面的美化,甚至还可以和数据库进行链接,保存游戏的状态,但是作为一个课设,我觉得这样也够了,哈哈,懒是原罪。 好了,废话不多说了,如对大佬们有帮助,还请大佬们给个大拇指,哈哈
ps:这里在给大家一个打包教程:https://blog.csdn.net/qq_41506111/article/details/102777940 如果大家需要源码和课设报告,可以到这里下载: https://download.csdn.net/download/weixin_52068218/85485458
|