贪吃蛇c++版(easyx图形库)(vs2022编译并附完整代码)

Y O L O. 2024-07-18 10:05:02 阅读 68

目录

1.总设计要求

2.方案设计

3.C++的类图设计分析

4.游戏内的画面截图(如果需要材料包请私信我)

1.用户操作主界面

2.用户登录界面

3.用户注册界面

4.游戏主界面

 5.游戏帮助界面

6.游戏内部分数据的设置界面

7.游戏运行界面

8.游戏结束的界面

5.游戏全部过程的视频分享(如果需要材料包请私信我)

6.完整代码附上(如果需要材料包请私信我)

Ps:

若没有完整的材料包,游戏内的画面无法显示。

若未下载Easyx图形库程序代码可能无法正常运行。


1.总设计要求

设计一个贪吃蛇小游戏蛇能通过键盘操作进行上下左右移动,能够躲避障碍物吃到食物,如果碰到墙壁或者自己身体会死亡。游戏界面,设置界面和帮助界面可以通过鼠标操作进行操控。

游戏规则:控制一条贪吃蛇在游戏区域内移动,吃到食物会变长,碰到墙壁或自己的身体会游戏结束。

游戏功能:包括账户认证登录,贪吃蛇的移动、食物的生成、得分统计、游戏难度设置等基本功能。

数据结构和算法:使用c++中的vector容器存储贪吃蛇的身体,使用随机数生成食物的位置,使用循环算法检测是否碰撞到自己的身体。

异常处理:当贪吃蛇碰到墙壁或自己的身体时,游戏结束,显示得分并让用户选择重新开始或退出游戏。

操作说明和注意事项:使用方向键控制贪吃蛇的移动方向,注意避免碰到墙壁或自己的身体,游戏内的食物和障碍物会根据得分增加而增多。

2.方案设计

游戏的图形界面通过Easyx图形库来设计,通过Easyx生成的新窗口来进行游戏,摆脱window的控制台界面,让画面更加精美。游戏中的蛇的数据结构是c++中STL模板库里面的vector容器,用push_back实现自增的操作。游戏中的蛇,食物,障碍物均可以由Basic的基类继承而来,继承Basic中的 x,y坐标和打印函数,完美体现c++的封装,继承和多态的思想。游戏内的键盘操作,鼠标感应,音乐播放均通过Easyx图形库中函数进行设计,轻松便捷的便可以得到想要的效果。

3.C++的类图设计分析

Ps:我使用的是ProcessOn的软件进行设计,网页版也可以使用,推荐大家使用这个来画类图。

类图分析:

1.我设计了一个Basic的基类,内有成员坐标m_x和m_y,附有构造函数,析构函数和纯虚的打印函数,体现了c++的多态的思想。

2.Snack类,Food类,Obstacle类(障碍物类)都是由继承基类而来,节省了不必要的代码,体现了 c++的继承的思想。

3.AccountOpeartion类内有一个成员Account结构体,这使得c++的封装思想进一步体现。

4.File类是为了保存数据在文件中,方便玩家记录他的最高分,账户名,密码等数据。

4.有三大类外加AccountOpeartion类和File类全部封装成Game的大类,在Game类中附有运行游戏所需的所有函数,这样的封装使得我只需要在main函数中仅需一两行代码,便可以操作所有的内容。

4.游戏内的画面截图(如果需要材料包请私信我)

1.用户操作主界面

2.用户登录界面

3.用户注册界面

4.游戏主界面

 5.游戏帮助界面

6.游戏内部分数据的设置界面

 

7.游戏运行界面

8.游戏结束的界面

 

5.游戏全部过程的视频分享(如果需要材料包+2946473607

贪吃蛇游戏

6.完整代码附上(如果需要材料包请+2946473607

Ps:

若没有完整的材料包,游戏内的画面无法显示。

若未下载Easyx图形库程序代码可能无法正常运行。

<code>#include<iostream>

#include<graphics.h>

#include <windows.h>

#include<mmsystem.h>

#pragma comment(lib,"WINMM.LIB")

#include<string>

#include<vector>

#include<stdio.h>

#include<conio.h>

#include<ctime>

#include<stdlib.h>

#include<fstream>

using namespace std;

const int FOOD_MAX = 15;//食物最多有15个

const int OBSTACLE_MAX = 15;//障碍物最多15个

#define VK_F 0x46 // F键盘

#define VK_G 0x47 // G键盘

const int MAX = 100;

int food_flag = 0;

int obstacle_flag = 0;

//抽象基类

class Basic

{

public:

Basic()

{

m_x = 50;

m_y = 50;

}

Basic(int x, int y)

{

m_x = x;

m_y = y;

}

//打印操作

virtual void show()

{

setlinecolor(BLACK);

setfillcolor(RGB(255, 128, 0));

fillcircle(m_x, m_y, 5);

}

//移动操作

void move(int x, int y)

{

m_x = m_x + x;

m_y = m_y + y;

}

int m_x, m_y;//坐标位置

};

//蛇类

class Snake : public Basic

{

public:

static int snake_len;

vector<Basic> nodes;//蛇的所有节点

char direction;//蛇的移动方向

int Speed;//蛇的移动速度

//蛇的初始化

Snake()

{

direction = 'd';//蛇默认向右移动

nodes.push_back((Basic(200, 50)));

nodes.push_back((Basic(190, 50)));

nodes.push_back((Basic(180, 50)));

Speed = 100;//蛇初始化速度100

}

//蛇的身体打印

void show()

{

for (int i = 0; i < nodes.size(); i++)

{

nodes[i].show();

}

}

//蛇的方向移动

void direction_move()

{

if (GetAsyncKeyState(VK_UP))//上键

{

if (direction != 's' && direction != 'S' && direction != 80)

{

direction = 'w';

}

}

if (GetAsyncKeyState(VK_DOWN))//下键

{

if (direction != 'w' && direction != 'W' && direction != 72)

{

direction = 's';

}

}

if (GetAsyncKeyState(VK_LEFT))//左键

{

if (direction != 'd' && direction != 'D' && direction != 77)

{

direction = 'a';

}

}

if (GetAsyncKeyState(VK_RIGHT))//右键

{

if (direction != 'a' && direction != 'A' && direction != 75)

{

direction = 'd';

}

}

if (GetAsyncKeyState(VK_F))//F加速

{

if (Speed >= 50)

{

Speed = Speed - 50;

}

}

if (GetAsyncKeyState(VK_G))//G减速

{

if (Speed < 100)

{

Speed = Speed + 50;

}

}

}

//蛇的身体移动

void body_move()

{

for (int i = nodes.size() - 1; i > 0; i--)//蛇身跟随蛇头移动

{

nodes[i] = nodes[i - 1];

}

direction_move();//方向移动判定

//判断方向

if (direction == 'w')

{

nodes[0].move(0, -10);

}

else if (direction == 's')

{

nodes[0].move(0, 10);

}

else if (direction == 'a')

{

nodes[0].move(-10, 0);

}

else if (direction == 'd')

{

nodes[0].move(10, 0);

}

}

//蛇增加一节

void addsnake()

{

nodes.push_back((Basic()));

snake_len++;

}

//设置蛇的初始长度

void setSnake_len(int n)

{

this->snake_len = n;

if (n >= 3)

{

nodes.push_back((Basic()));

}

else

{

for (int i = 0; i < 3 - n; i++)

{

nodes.pop_back();

}

}

}

};

int Snake::snake_len = 3;//蛇的初始化长度为3

//食物类

class Food : public Basic

{

public:

static int Food_num;

Food() : Basic(0, 0)

{

m_x = (1 + rand() % 50) * 10 + 10;

m_y = (1 + rand() % 40) * 10 + 10;

}

//改变食物位置

void change()

{

m_x = (1 + rand() % 50) * 10 + 10;

m_y = (1 + rand() % 40) * 10 + 10;

}

//输出食物位置

void show()

{

setfillcolor(RGB(255, 215, 0));

fillcircle(m_x, m_y, 5);

}

//设置食物个数

void set_foodnum(int n)

{

Food_num = n;

}

};

int Food::Food_num = 3;

//障碍物类

class Obstacle : public Basic

{

public:

static int obstacle_num;

Obstacle() : Basic(0, 0)

{

m_x = (1 + rand() % 50) * 10 + 10;

m_y = (1 + rand() % 40) * 10 + 10;

}

//改变障碍物位置

void change_obstacle()

{

m_x = (1 + rand() % 50) * 10 + 10;

m_y = (1 + rand() % 40) * 10 + 10;

}

//输出障碍物(根据身体长度来增加障碍物)

void add_obstacle()

{

setfillcolor(BLACK);

fillrectangle(m_x, m_y, m_x+10, m_y -10);

}

//设置障碍物个数

void set_obstacle(int n)

{

obstacle_num = n;

}

};

int Obstacle::obstacle_num = 3;

//文件类

class File

{

public:

string Name;

string Id;//记录当前登录用户的用户名和id

File()

{

Name = "0";

Id = "0";

}

//记录最高分

void saveMax_mark(string Name,int mark)

{

ofstream ofs;

string tmp = Name + "-Max_mark.txt";

ofs.open(tmp, ios::out);

if (!ofs.is_open())

{

return;

}

ofs << mark;

ofs.close();

}

//读出最高分

int outMax_mark(string Name)

{

ifstream ifs;

string tm = Name + "-Max_mark.txt";

ifs.open(tm, ios::in);

if (!ifs.is_open())

{

return 0;

}

string tmp;

getline(ifs, tmp);

int t = 0;

for (int i = 0; i < tmp.size(); i++)

{

t = t * 10 + (tmp[i] - '0');

}

ifs.close();

return t;

}

};

//用户账户

struct Account

{

string name;//用户名

string id;//账号

string password;//密码

};

//用户账户操作

class Accountoperation

{

private:

Account a[MAX];//最多MAX人

public:

//用户注册or登录界面

void Surface(string &Id, string &Name)

{

while (1)

{

system("color 9E");

system("cls");

cout << " ****************************************************************" << endl;

cout << " | |" << endl;

cout << " | 欢迎游玩贪吃蛇 |" << endl;

cout << " | |" << endl;

cout << " | S N A K E |" << endl;

cout << " | |" << endl;

cout << " | 1 . 用户登录 |" << endl;

cout << " | |" << endl;

cout << " | 2 . 用户注册 |" << endl;

cout << " | |" << endl;

cout << " ****************************************************************" << endl;

int n;

cout << "*请输入你想进行的操作:";

cin >> n;

while (n != 1 && n != 2)

{

cout << "*抱歉, 输入错误,请重新输入* " << endl;

cin >> n;

}

if (n == 1)

{

Register(Name, Id);

return;

}

else if (n == 2)

{

Createaccount();

}

}

}

//用户注册

void Createaccount()

{

while (1)

{

system("cls");

cout << "---------------当前为用户注册界面-----------------" << endl;

string name, id, pass;

cout << "*请输入您的账号(id):* ";

cin >> id;

cout << "*请输入您的用户名:* ";

cin >> name;

cout << "*请输入密码:* ";

cin >> pass;

cout << "--------------------------------------------------" << endl;

if (Repeatcheck(id))

{

cout << "*很抱歉,当前账号(id)已经有人使用,请重新注册您的账号(id)*" << endl;

cout << "*是否需要重新注册(y/Y or n/N):* ";

char h;

cin >> h;

while (h != 'y' && h != 'Y' && h != 'n' && h != 'N')

{

cout << "*输入错误,请重新输入* " << endl;

cin >> h;

}

if (h == 'y' || h == 'Y')

{

continue;

}

else if (h == 'n' || h == 'N')

{

system("cls");

return;

}

}

else

{

cout << "*注册成功,请返回登录*" << endl;

ofstream ofs;

ofs.open("Account.txt", ios::app);

if (!ofs.is_open())

{

cout << "*文件打开失败,程序即将退出*" << endl;

exit(0);

}

ofs << "\n";

ofs << id;

ofs << ' ';

ofs << name;

ofs << ' ';

ofs << pass;

ofs.close();

system("pause");

return;

}

}

}

//用户注册时查重ID

bool Repeatcheck(string id)

{

string n[MAX], i[MAX], p[MAX];

ifstream ifs;

ifs.open("Account.txt", ios::in);

if (!ifs.is_open())

{

cout << "*文件打开失败,程序即将退出*" << endl;

exit(0);

}

for (int j = 0; j < MAX; j++)

{

ifs >> i[j];

ifs >> n[j];

ifs >> p[j];

}

ifs.close();

for (int j = 0; j < MAX; j++)

{

if (id == i[j])

{

return true;

}

}

return false;

}

//用户登录

void Register(string &Name, string &Id)

{

system("cls");

string n[MAX], i[MAX], p[MAX];

ifstream ifs;

ifs.open("Account.txt", ios::in);

for (int j = 0; j < MAX; j++)

{

ifs >> i[j];

ifs >> n[j];

ifs >> p[j];

}

ifs.close();

while (1)

{

cout << "---------------当前为用户登录界面-----------------" << endl;

string name, id, pass;

cout << "*请输入您的账号(id):* ";

cin >> id;

cout << "*请输入昵称:* ";

cin >> name;

cout << "*请输入密码:* ";

cin >> pass;

int flag = 0;

cout << "--------------------------------------------------" << endl;

for (int h = 0; h < MAX; h++)

{

if (id == i[h] && name == n[h] && pass == p[h])

{

cout << "*用户认证成功*" << endl;

flag = 1;

Name = name;

Id = id;

system("pause");

return;

}

}

if (flag == 0)

{

cout << "*用户认证失败,请重新输入*" << endl;

system("pause");

system("cls");

}

}

}

};

//游戏地图操作类

class Game

{

private:

Accountoperation account;//账户

Snake snake;//蛇

Food food[FOOD_MAX];//食物(最多有10个,身体每增加三节,食物增加一个)

Obstacle obstacle[OBSTACLE_MAX];//随机障碍物生成(最多15个)

File f;//文件

static int mark;//当前分数

int max_mark = 0;//历史最高分

public:

//蛇是否吃到了食物

void eatfood()

{

for (int i = 0; i < food[0].Food_num; i++)

{

if (snake.nodes[0].m_x == food[i].m_x && snake.nodes[0].m_y == food[i].m_y)

{

mciSendString(L"close ./吃金币.mp3", NULL, 0, NULL);

mciSendString(L"open ./吃金币.mp3", NULL, 0, NULL);

mciSendString(L"play ./吃金币.mp3", NULL, 0, NULL);

mark++;

//蛇变长

snake.addsnake();

//食物重新生产

food[i].change();

food_flag++;

obstacle_flag++;

return;

}

}

}

//从文件中获取最高得分

void maxMark()

{

max_mark = f.outMax_mark(f.Name);

}

//蛇的死亡判定

void snake_die()

{

int flag = 0;

if (snake.nodes[0].m_x + 5 >= 590 || snake.nodes[0].m_x - 5 <= 10 || snake.nodes[0].m_y + 5 >= 500 || snake.nodes[0].m_y - 5 <= 10)

{

flag = 1;

}

for (int j = 0; j < obstacle[0].obstacle_num; j++)

{

if (snake.nodes[0].m_x + 5 >= obstacle[j].m_x && snake.nodes[0].m_x + 5 <= obstacle[j].m_x + 10 && snake.nodes[0].m_y >= obstacle[j].m_y - 10 && snake.nodes[0].m_y <= obstacle[j].m_y)

{

flag = 1;

break;

}

if (snake.nodes[0].m_x - 5 <= obstacle[j].m_x + 10 && snake.nodes[0].m_x - 5 >= obstacle[j].m_x && snake.nodes[0].m_y >= obstacle[j].m_y - 10 && snake.nodes[0].m_y <= obstacle[j].m_y)

{

flag = 1;

break;

}

if (snake.nodes[0].m_y + 5 >= obstacle[j].m_y - 10 && snake.nodes[0].m_y + 5 <= obstacle[j].m_y && snake.nodes[0].m_x >= obstacle[j].m_x && snake.nodes[0].m_x <= obstacle[j].m_x + 10)

{

flag = 1;

break;

}

if (snake.nodes[0].m_y - 5 <= obstacle[j].m_y && snake.nodes[0].m_y - 5 >= obstacle[j].m_y - 10 && snake.nodes[0].m_x >= obstacle[j].m_x && snake.nodes[0].m_x <= obstacle[j].m_x + 10)

{

flag = 1;

break;

}

}

for (int i = 1; i < snake.nodes.size(); i++)

{

if (snake.nodes[0].m_x == snake.nodes[i].m_x && snake.nodes[0].m_y == snake.nodes[i].m_y)

{

flag = 1;

}

}

if (flag == 1)

{

EndBatchDraw();//双缓冲

mciSendString(L"stop ./Bgm.mp3", NULL, 0, NULL);

mciSendString(L"close ./失败音效.mp3 ", NULL, 0, NULL);

mciSendString(L"open ./失败音效.mp3", NULL, 0, NULL);

mciSendString(L"play ./失败音效.mp3 ", NULL, 0, NULL);

Sleep(1500);

cleardevice();

IMAGE img;

cleardevice();

loadimage(&img, L"./游戏结束.png", 1000, 600);

putimage(0, 0, &img);

settextcolor(RED);

settextstyle(40, 0, L"华文隶书");

outtextxy(310, 250, L"---------游戏结束----------");

settextcolor(BLACK);

settextstyle(40, 0, L"黑体");

outtextxy(300, 330 , L"您的得分为:");

TCHAR s[5];

settextcolor(RED);

_stprintf_s(s, _T("%d"), mark);

outtextxy(550, 330, s);

if (mark > max_mark)

{

f.saveMax_mark(f.Name, mark);

settextcolor(RGB(255, 128, 0));

settextstyle(50, 0, L"华文隶书");

outtextxy(250, 450, L"恭喜你打破最高纪录!");

}

HWND hwnd = GetHWnd();

while (1)//弹窗

{

ExMessage tmp;

peekmessage(&tmp, EM_MOUSE);

if (tmp.message == WM_LBUTTONDOWN)

{

if (tmp.x >= 0 && tmp.y >= 0)

{

int isok = MessageBox(hwnd, L"很遗憾,游戏失败,请问您是否需要重新开始", L"提示", MB_YESNOCANCEL);

if (isok == IDYES)

{

srand(time(nullptr));//随机数种子

closegraph();

Game b;

b.mark = 0;

b.food->Food_num = 3;

b.snake.snake_len = 3;

b.obstacle->obstacle_num = 3;

b.start(1);

}

else if (isok == IDNO)

{

exit(0);

}

}

}

}

}

}

//游戏帮助

void help()

{

IMAGE img;

cleardevice();

loadimage(&img, L"./帮助界面.png", 1000, 600);

putimage(0, 0, &img);

settextstyle(20, 0, L"黑体");

settextcolor(BLACK);

outtextxy(200, 70, L"---本游戏的键盘操控规则---");

outtextxy(110, 90, L"w or W or ↑ 为向上移动");

outtextxy(110, 110, L"a or A or ← 为向左移动");

outtextxy(110, 130, L"s or S or ↓ 为向下移动");

outtextxy(110, 150, L"d or D or → 为向右移动");

outtextxy(110, 180, L"F or f 为加速按钮 按下蛇的移动速度会变快 会有一个上限");

outtextxy(110, 210, L"G or g 为减速按钮 按下蛇的移动速度会变慢 会有一个下限");

outtextxy(200, 240, L"---本游戏的死亡规则---");

outtextxy(110, 270, L"当您的蛇超过了边界范围或者蛇头碰到自己的身体或者碰到障碍物 游戏就会结束");

outtextxy(110, 300, L"障碍物初始有3个 蛇的长度增加为五的倍数就多一个障碍物 最多15个");

outtextxy(110, 330, L"食物初始有3个 蛇的长度每增加三节就多一个食物 最多10个");

setbkmode(TRANSPARENT);

setfillcolor(BROWN);

fillroundrect(0, 0, 50, 50, 50, 50);

settextstyle(15, 0, L"黑体");

int width = textwidth(L"返回");

int high = textheight(L"返回");

outtextxy(0 + (50 - width) / 2, 0 + (50 - high) / 2, L"返回");

while (1)

{

ExMessage tmp;

if (peekmessage(&tmp, EM_MOUSE))

{

switch (tmp.message)

{

case WM_LBUTTONDOWN:

if (tmp.x >= 0 && tmp.x <= 50 && tmp.y >= 0 && tmp.y <= 50)

{

Menu();

return;

}

}

}

}

}

//游戏界面

void Menu()

{

cleardevice();

IMAGE img;

loadimage(&img, L"./贪吃蛇开始界面.jpg", 1000, 600);

putimage(0, 0, &img);

setbkmode(TRANSPARENT);

setfillcolor(BROWN);

fillroundrect(400, 300, 400 + 200, 300 + 80, 10, 10);

settextstyle(30, 0, L"黑体");

int width = textwidth(L"开始游戏");

int high = textheight(L"开始游戏");

outtextxy(400 + (200 - width) / 2, 300 + (80 - high) / 2, L"开始游戏");

fillroundrect(400, 400, 400 + 200, 400 + 80, 10, 10);

settextstyle(30, 0, L"黑体");

width = textwidth(L"游戏帮助");

high = textheight(L"游戏帮助");

outtextxy(400 + (200 - width) / 2, 400 + (80 - high) / 2, L"游戏帮助");

fillroundrect(400, 500, 400 + 200, 500 + 80, 10, 10);

settextstyle(30, 0, L"黑体");

width = textwidth(L"游戏设置");

high = textheight(L"游戏设置");

outtextxy(400 + (200 - width) / 2, 500 + (80 - high) / 2, L"游戏设置");

}

//游戏设置按钮控制

void Set_botton()

{

int flag_food = 0;

int flag_obstacle = 0;

while (1)

{

ExMessage tmp;

ExMessage t;

BeginBatchDraw();//双缓冲

Set();

if (peekmessage(&tmp, EM_MOUSE))

{

switch (tmp.message)

{

case WM_LBUTTONDOWN:

if (tmp.x >= 0 && tmp.x <= 50 && tmp.y >= 0 && tmp.y <= 50)

{

botton();

return;

}

if (tmp.x >= 330 && tmp.x <= 370 && tmp.y >= 105 && tmp.y <= 145)//蛇长减

{

if (snake.snake_len > 1)

{

int n = snake.snake_len - 1;

snake.setSnake_len(n);

}

}

if (tmp.x >= 630 && tmp.x <= 670 && tmp.y >= 105 && tmp.y <= 145)//蛇长加

{

int n = snake.snake_len + 1;

snake.setSnake_len(n);

}

if (tmp.x >= 330 && tmp.x <= 370 && tmp.y >= 180 && tmp.y <= 225)//食物减

{

if (food[0].Food_num > 1)

{

int n = food[0].Food_num - 1;

food->set_foodnum(n);

}

}

if (tmp.x >= 630 && tmp.x <= 670 && tmp.y >= 180 && tmp.y <= 225)//食物加

{

if (food[0].Food_num < 15)

{

int n = food[0].Food_num + 1;

food->set_foodnum(n);

}

}

if (tmp.x >= 330 && tmp.x <= 370 && tmp.y >= 265 && tmp.y <= 305)//障碍物减

{

if (obstacle[0].obstacle_num > 1)

{

int n = obstacle[0].obstacle_num - 1;

obstacle->set_obstacle(n);

}

}

if (tmp.x >= 630 && tmp.x <= 670 && tmp.y >= 265 && tmp.y <= 305)//障碍物加

{

if (obstacle[0].obstacle_num < 15)

{

int n = obstacle[0].obstacle_num + 1;

obstacle->set_obstacle(n);

}

}

}

}

if (peekmessage(&t, EM_MOUSE))

{

switch (t.message)

{

case WM_MOUSEMOVE:

if (t.x >= 400 && t.x <= 600 && t.y >= 180 && t.y <= 230)

{

flag_food = 1;

}

else

{

flag_food = 0;

}

if (t.x >= 400 && t.x <= 600 && t.y >= 260 && t.y <= 310)

{

flag_obstacle = 1;

}

else

{

flag_obstacle = 0;

}

}

}

if (flag_food == 1)

{

setbkmode(TRANSPARENT);

setfillcolor(YELLOW);

fillroundrect(t.x, t.y, t.x + 200, t.y + 50, 10, 10);

settextstyle(15, 0, L"黑体");

settextcolor(BLACK);

int width = textwidth(L"食物的最大数量为:");

int high = textheight(L"食物的最大数量为:");

outtextxy(t.x + (200 - width) / 2, t.y + (50 - high) / 2, L"食物的最大数量为:");

TCHAR s[5];

_stprintf_s(s, _T("%d"), FOOD_MAX);

outtextxy(t.x + (200 - width) / 2 + width, t.y + (50 - high) / 2, s);

}

if (flag_obstacle == 1)

{

setbkmode(TRANSPARENT);

setfillcolor(YELLOW);

fillroundrect(t.x, t.y, t.x + 200, t.y + 50, 10, 10);

settextstyle(15, 0, L"黑体");

settextcolor(BLACK);

int width = textwidth(L"障碍物的最大数量为:");

int high = textheight(L"障碍物的最大数量为:");

outtextxy(t.x + (200 - width) / 2, t.y + (50 - high) / 2, L"障碍物的最大数量为:");

TCHAR s[5];

_stprintf_s(s, _T("%d"), FOOD_MAX);

outtextxy(t.x + (200 - width) / 2 + width, t.y + (50 - high) / 2, s);

}

EndBatchDraw();//双缓冲

}

}

//游戏设置

void Set()

{

IMAGE img;

cleardevice();

loadimage(&img, L"./设置界面.jpg", 1000, 600);

putimage(0, 0, &img);

//设置蛇的初始长度

setbkmode(TRANSPARENT);

setfillcolor(LIGHTBLUE);

fillroundrect(400, 100, 400 + 200, 100 + 50, 10, 10);

settextstyle(15, 0, L"黑体");

settextcolor(BLACK);

int width = textwidth(L"蛇的初始长度为:");

int high = textheight(L"蛇的初始长度为:");

outtextxy(400 + (200 - width) / 2, 100 + (50 - high) / 2, L"蛇的初始长度为:");

TCHAR s[5];

_stprintf_s(s, _T("%d"), snake.snake_len);

outtextxy(400 + (200 - width) / 2 + width, 100 + (50 - high) / 2, s);

setfillcolor(BROWN);

fillcircle(350, 125, 20);//减

outtextxy(340, 120, L"一");

setfillcolor(BROWN);

fillcircle(650, 125, 20);//加

outtextxy(642, 120, L"十");

//设置食物初始个数

setbkmode(TRANSPARENT);

setfillcolor(LIGHTBLUE);

fillroundrect(400, 180, 400 + 200, 180 + 50, 10, 10);

settextstyle(15, 0, L"黑体");

settextcolor(BLACK);

width = textwidth(L"食物的初始个数为:");

high = textheight(L"食物的初始个数为:");

outtextxy(400 + (200 - width) / 2, 180 + (50 - high) / 2, L"食物的初始个数为:");

_stprintf_s(s, _T("%d"), food[0].Food_num);

outtextxy(400 + (200 - width) / 2 + width, 180 + (50 - high) / 2, s);

setfillcolor(BROWN);

fillcircle(350, 205, 20);//减

outtextxy(340, 195, L"一");

setfillcolor(BROWN);

fillcircle(650, 205, 20);//加

outtextxy(642, 195, L"十");

//设置障碍物初始个数

setbkmode(TRANSPARENT);

setfillcolor(LIGHTBLUE);

fillroundrect(400, 260, 400 + 200, 260 + 50, 10, 10);

settextstyle(15, 0, L"黑体");

settextcolor(BLACK);

width = textwidth(L"障碍物的初始个数为:");

high = textheight(L"障碍物的初始个数为:");

outtextxy(400 + (200 - width) / 2, 260 + (50 - high) / 2, L"障碍物的初始个数为:");

_stprintf_s(s, _T("%d"), obstacle[0].obstacle_num);

outtextxy(400 + (200 - width) / 2 + width, 260 + (50 - high) / 2, s);

setfillcolor(BROWN);

fillcircle(350, 285, 20);//减

outtextxy(340, 275, L"一");

setfillcolor(BROWN);

fillcircle(650, 285, 20);//加

outtextxy(642, 275, L"十");

//返回按钮

setbkmode(TRANSPARENT);

setfillcolor(BROWN);

fillroundrect(0, 0, 50, 50, 50, 50);

settextstyle(15, 0, L"黑体");

width = textwidth(L"返回");

high = textheight(L"返回");

outtextxy(0 + (50 - width) / 2, 0 + (50 - high) / 2, L"返回");

}

//设置地图

void setMap()

{

for (int i = 0; i < 600; i++)

{

setlinecolor(BLACK);

fillrectangle(i, 15, i + 1, 0);

}

for (int i = 0; i < 500; i++)

{

setlinecolor(BLACK);

fillrectangle(0, 15 + i, 15, 15 + i);

}

for (int i = 0; i < 500; i++)

{

setlinecolor(BLACK);

fillrectangle(585, 15 + i, 600, 15 + i);

}

for (int i = 0; i < 600; i++)

{

setlinecolor(BLACK);

fillrectangle(i, 515, i + 1, 500);

}

//图片加载

IMAGE img;

loadimage(&img, L"./贪吃蛇.jpg", 400, 380);

putimage(610, 0, &img);

settextstyle(20, 15, _T("Consolas"));

wchar_t A[] = L"您的游戏当前得分为:";

settextcolor(BLACK);

outtextxy(620, 400, A);

TCHAR s[5];

_stprintf_s(s, _T("%d"), mark);

settextcolor(MAGENTA);

outtextxy(910, 400, s);

wchar_t B[] = L"您的游戏最高得分为:";

settextcolor(BLACK);

outtextxy(620, 450, B);

_stprintf_s(s, _T("%d"), max_mark);

settextcolor(LIGHTGREEN);

outtextxy(910, 450, s);

wchar_t C[] = L"您的蛇移动速度为: 档";

settextcolor(BLACK);

outtextxy(620, 490, C);

_stprintf_s(s, _T("%d"), (150 - snake.Speed) / 50);

settextcolor(RED);

outtextxy(900, 490, s);

settextstyle(80, 90, _T("华文隶书"));

settextcolor(RGB(241, 158, 194));

outtextxy(10, 520, _T("SNAKE"));

}

//播放音乐

void BGM()

{

mciSendString(L"open ./Bgm.mp3", NULL, 0, NULL);

mciSendString(L"play ./Bgm.mp3 repeat", NULL, 0, NULL);

}

//按钮点击判定

bool botton()

{

EndBatchDraw();//双缓冲

cleardevice();

Menu();

ExMessage msg;

while (1)

{

if (peekmessage(&msg, EM_MOUSE))

{

switch (msg.message)

{

case WM_LBUTTONDOWN:

//帮助界面

if (msg.x >= 400 && msg.x <= 400 + 200 && msg.y >= 400 && msg.y <= 400 + 80)

{

help();

}

//设置界面

if (msg.x >= 400 && msg.x <= 400 + 200 && msg.y >= 500 && msg.y <= 500 + 80)

{

Set();

Set_botton();

}

//游戏开始

if (msg.x >= 400 && msg.x <= 400 + 200 && msg.y >= 300 && msg.y <= 300 + 80)

{

return true;

}

}

}

}

}

//游戏的开始

void start(int flag)

{

if (flag == 0)

{

system("cls");

account.Surface(f.Id, f.Name);

system("cls");

}

system("cls");

system("color 9E");

cout << "\n\n\n\n\n";

cout << " ****************************************************************" << endl;

cout << " | |" << endl;

cout << " | 祝您游戏愉快 |" << endl;

cout << " | |" << endl;

cout << " ****************************************************************" << endl;

maxMark();

initgraph(1000, 600, 1);

cleardevice();

setbkcolor(WHITE);

BGM();

if (botton())//按钮点击了才清屏进入下一步

{

cleardevice();

while (1)

{

run();

Sleep(snake.Speed);

}

}

}

//游戏的运行

void run()

{

BeginBatchDraw();//双缓冲

cleardevice();

setMap();

//食物初始有3个 蛇的长度每增加三节就多一个食物 最多15个

if (food[0].Food_num < FOOD_MAX && food_flag == 3)

{

food[0].Food_num = food[0].Food_num++;

food_flag = 0;

}

for (int i = 0; i < food[0].Food_num && i < FOOD_MAX; i++)

{

food[i].show();

}

//障碍物初始有3个 蛇的长度增加为五的倍数就多一个障碍物 最多15个

if (obstacle[0].obstacle_num < OBSTACLE_MAX && obstacle_flag == 5)

{

obstacle[0].obstacle_num = obstacle[0].obstacle_num++;

obstacle_flag = 0;

}

for (int j = 0; j < OBSTACLE_MAX && j < obstacle[0].obstacle_num; j++)

{

obstacle[j].add_obstacle();

}

snake.show();

snake_die();//死亡判定

snake.body_move();

eatfood();//食物碰撞判定

EndBatchDraw();//双缓冲

}

};

int Game::mark = 0;

int main()

{

srand(time(nullptr));//随机数种子

Game game;

game.start(0);

closegraph();

return 0;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。