1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计

Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计

时间:2018-07-04 17:20:14

相关推荐

Easyx图形库+C++做一个贪吃蛇小游戏  数据结构课程设计

Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计

程序界面

①游戏开始界面(如下图):

显示游戏标题,提供“开始游戏”、“游戏模式”和“游戏关于”(用以查看游戏的相关信息)选项

②游戏界面(如下图):

显示“蛇”和“食物”的位置及“等级框”、“分数框”、“提示框”等。

并在蛇移动时,更新游戏信息

③ 游戏结束界面(如下图):

显示游戏结束的提示,并提供“restart”和“quit”按钮

附上代码

#include<iostream>#include<graphics.h>#include<time.h>#include<conio.h>#include<Mmsystem.h>#pragma comment(lib,"winmm.lib")#include"resource.h"using namespace std;#define initSize 4 //蛇的初始#define bgcBLACK//背景色#definegbgc RGB(43,215,225)//游戏界面的背景色#defineshc1 YELLOW //RGB(138,232,23)//蛇头边框色#defineshc2RED//蛇头色#definesbc1BLUE//蛇身边框色#definesbc2RGB(138,232,23)//蛇身色#definefc1 RGB(255,128,64)#definefc2 YELLOW#defineboxc RGB(70,226,205)//定义结构体点 这个点为游戏地图上的点,并非像素点typedef struct point {int x; //点的横坐标int y; //点的纵坐标point() {};point(int _x, int _y) {x = _x;y = _y;}}point;//蛇身typedef struct sBody{point _point; //位置sBody *next; //下一个sBody *pre;//上一个}sBody;//方向enum direction {up,down,left,right };typedef struct snake {sBody *head;//蛇头sBody *body;//蛇身sBody *tail;//蛇尾direction drc;snake() {head = new sBody;body = new sBody;tail = new sBody;}}snake;typedef struct food {point _point;bool flash;//闪烁的标志}food;snake *S = new snake;//主角food *Food = new food;int score;//分数int level;//级别int goal;int mode;//模式选择int pointWidth;int _end;//是否结束游戏的标志//---------------------------------------------------------------point部分void drawPoint(point p,int color=GREEN) {setfillcolor(color);int sx, sy, ex, ey;sx = 100 + pointWidth * p.x+1;sy = 100 + pointWidth * p.y+1;ex = sx + pointWidth-1;ey = sy + pointWidth-1;fillrectangle(sx,sy,ex,ey);}//高级版画点void drawPointPlus(point p,int color1 ,int color2){int x1 = 100 + pointWidth * p.x+1;int y1 = 100 + pointWidth * p.y+1;int x2 = x1 + pointWidth-1;int y2 = y1 + pointWidth-1;setfillcolor(color2);fillrectangle(x1, y1, x2, y2);setlinecolor(color1);rectangle(x1, y1, x2, y2);}void clearPoint(point p) {setlinecolor(gbgc);drawPoint(p,gbgc);}//---------------------------------------------------------------snakevoid initSnake(snake *S) {S->drc = up;S->head->_point.x = 10;//蛇头的初始位置S->head->_point.y = 10;S->body->_point.x = S->head->_point.x;S->body->_point.y = S->head->_point.y + 1;S->head->next = S->body; //指针域S->body->pre = S->head;sBody *q = S->head->next;for (int i = 1; i < initSize; i++) {sBody *p = new sBody;p->_point.x = q->_point.x;p->_point.y = q->_point.y + 1;//指针域q->next = p;p->pre = q;S->tail = p;q = p;}q->next = NULL;}//画蛇头void drawHead(snake *S) {setfillcolor(fc1);fillrectangle((S->head->_point.x)*pointWidth +100+1, (S->head->_point.y)*pointWidth +100+1, (S->head->_point.x)*pointWidth +100 + pointWidth-1, (S->head->_point.y)*pointWidth +100-1 + pointWidth);drawPointPlus(S->head->_point, shc1,shc2);}//画蛇身体void drawBody(sBody * a) {setfillcolor(sbc2);setlinecolor(YELLOW);fillrectangle((a->_point.x)*pointWidth +100+1, (a->_point.y)*pointWidth +100+1, (a->_point.x)*pointWidth +100-1 + pointWidth, (a->_point.y)*pointWidth +100-1 + pointWidth);drawPointPlus(a->_point, sbc1,sbc2);}//画蛇void drawSnake(snake *S) {drawHead(S);sBody *p = S->head->next;while (p!=S->tail->next) {drawBody(p);p = p->next;}}判断蛇是否撞到自己bool hitItself(snake *S) {int X, Y;X = S->head->_point.x;Y = S->head->_point.y;sBody *p = S->head->next;while (p!=S->tail->next) {if (p->_point.x == X && p->_point.y == Y) return true;p = p->next;}return false;}//判断蛇是否撞到边框bool hitEdge(snake *S) {int X = S->head->_point.x;int Y = S->head->_point.y;if (X < 0 || X>(480/ pointWidth-1) || Y < 0 || Y>(600/ pointWidth-1))return true;return false;}//判断蛇是否吃到食物bool getFood(snake *S, food *Food) {int X = S->head->_point.x;int Y = S->head->_point.y;int fx = Food->_point.x;int fy = Food->_point.y;if (X == fx && Y == fy) {return true; }return false;}//普通的移动void move(snake *S) {sBody *temp = new sBody;switch (S->drc){case direction::up:temp->_point.x = S->head->_point.x;temp->_point.y = S->head->_point.y - 1;break;case direction::down:temp->_point.x = S->head->_point.x;temp->_point.y = S->head->_point.y + 1;break;case direction::left:temp->_point.x = S->head->_point.x-1;temp->_point.y = S->head->_point.y;break;case direction::right:temp->_point.x = S->head->_point.x+1;temp->_point.y = S->head->_point.y;break;default:break;}temp->next =S->head;S->head->pre = temp;S->head = temp;drawHead(S);//重画蛇头drawBody(S->head->next);clearPoint(S->tail->_point);sBody *t = S->tail;S->tail = S->tail->pre;t = NULL;}//吃到食物的移动void growAndMove(snake * S) {sBody *temp = new sBody;switch (S->drc){case direction::up:temp->_point.x = S->head->_point.x;temp->_point.y = S->head->_point.y - 1;break;case direction::down:temp->_point.x = S->head->_point.x;temp->_point.y = S->head->_point.y + 1;break;case direction::left:temp->_point.x = S->head->_point.x - 1;temp->_point.y = S->head->_point.y;break;case direction::right:temp->_point.x = S->head->_point.x + 1;temp->_point.y = S->head->_point.y;break;default:break;}temp->next = S->head;S->head->pre = temp;S->head = temp;drawHead(S);clearPoint(S->head->next->_point);drawBody(S->head->next);}//---------------------------------------------------------------------food//判断该位置是否被蛇的身体占据bool isOccupied(snake *S, int fx, int fy) {sBody *p = S->head;while (p != S->tail->next) {if (p->_point.x == fx && p->_point.y == fy) {return true;}p = p->next;}return false;}//画一个新的食物void drawANewFood(food *Food) {int MAX_X = 480 / pointWidth;int MAX_Y = 600 / pointWidth;int fx = rand() % MAX_X;int fy = rand() % MAX_Y;while (isOccupied(S, fx, fy)) {fx = rand() % MAX_X;fy = rand() % MAX_Y;}Food->_point.x = fx;Food->_point.y = fy;Food->flash = 0;drawPointPlus(Food->_point, fc1, fc2);}//控制食物闪烁void flashFood(food *Food) {if (Food->flash) {clearPoint(Food->_point);Food->flash = 0;}else {drawPointPlus(Food->_point, fc1, fc2);Food->flash = 1;}}//---------------------------------------------------------------------gamevoid initGame(int mode) {//初始化蛇,画出蛇,画第一个食物,初始化级别和分数if (mode == 0) pointWidth = 20;else pointWidth = 10;initSnake(S);drawSnake(S);srand(unsigned(time(NULL))); //食物随机位置的种子level = 1;goal = level * 100;score = 0;_end = 0;}//画出模式切换箭头void drawLeftArrow(int x, int y) {POINT pts[] = {{x,(y + 10)}, {x + 20, y + 20}, {x + 20, y} };fillpolygon(pts, 3);}//画出模式切换箭头void drawRightArrow(int x, int y) {POINT pts[] = {{x + 20,(y + 10)}, {x, y}, {x , y + 20} };fillpolygon(pts, 3);}//绘制成绩框void drawScoreBox() {setlinecolor(BLACK);setfillcolor(boxc);fillroundrect(630,320,950,420,20,20);fillroundrect(630, 550, 950, 650, 20, 20);}//更新成绩显示void updateScore() {drawScoreBox();_TCHAR a[12],b[12];_stprintf_s(a,L"%d",score);settextcolor(BLACK);settextstyle(60,0,_T("Rosewood Std Regular"));outtextxy(760,345,a);_stprintf_s(b, L"%d", goal);outtextxy(760, 575, b);}//绘制等级框void drawRinkBox() {setlinecolor(BLACK);setfillcolor(boxc);fillroundrect(820, 100, 950, 200, 20, 20);}//更新等级显示void updateRank() {settextcolor(BLACK);drawRinkBox();_TCHAR a[4];_stprintf_s(a, L"%d", level);settextstyle(60, 0, _T("Rosewood Std Regular"));outtextxy(860, 125, a);}//游戏开始界面,开始播放背景音乐void startInterface(int &cmd,int &mode) {mciSendString(L"open C:\\Users\\TTODS\\source\\repos\\贪吃蛇\\贪吃蛇\\背景音乐.mp3 alias bgm", NULL, 0, NULL);mciSendString(L"play bgm repeat", NULL, 0, NULL);initgraph(1000, 800);setbkcolor(bgc);cleardevice();setlinecolor(RED);initgraph(1000, 800);setbkcolor(YELLOW);setfillcolor(RED);fillrectangle(0, 0, 1000, 800);setfillcolor(YELLOW);setbkmode(TRANSPARENT);IMAGE img;img.Resize(960, 760);loadimage(&img, _T("IMAGE"), MAKEINTRESOURCE(IDR_IMAGE1));putimage(20, 20, &img);//fillrectangle(120, 120, 930, 730);settextcolor(RED);settextstyle(64, 0, _T("Rosewood Std Regular"));outtextxy(270, 200, _T("GLUTTONOUS SNAKE"));settextstyle(45, 0, _T("Viner Hand ITC"));outtextxy(490, 450, _T("S T A R T"));outtextxy(470, 500, _T("STANDARD"));outtextxy(490, 550, _T("ABOUT"));setfillcolor(GREEN);drawLeftArrow(435, 510);drawRightArrow(650, 510);setfillcolor(RGB(158, 255, 142));setlinecolor(RGB(158, 255, 142));while (true) {MOUSEMSG m = GetMouseMsg();if (m.mkLButton&&m.x > 455 && m.x < 640 && m.y>450 && (m.y) < 490) {cmd = 1; break; }else if (m.mkLButton&&m.x > 455 && m.x < 640 && m.y>500 && (m.y) < 540) {cmd = 2; break; }else if (m.mkLButton&&m.x > 455 && m.x < 640 && m.y>550 && (m.y) < 590) {cmd = 3; break; }else if ((m.mkLButton&&m.x > 435 && m.x < 455 && m.y>510 && m.y < 530) || (m.mkLButton&&m.x > 650 && m.x < 670 && m.y>510 && m.y < 530)) {mode++;mode %= 2;if (mode == 0) {fillrectangle(470, 500, 640, 540); outtextxy(470, 500, _T("STANDARD")); }else {fillrectangle(470, 500, 640, 540);outtextxy(470, 500, _T("ENTERTAIN"));}}}}//游戏界面描绘void gameInterface() {setbkcolor(bgc);cleardevice();IMAGE img;img.Resize(1000, 800);loadimage(&img, _T("IMAGE"), MAKEINTRESOURCE(IDR_IMAGE3));putimage(0, 0, &img);int width = 6; //空心边界线的宽度setlinecolor(BLACK);//游戏界面setfillcolor(YELLOW);fillroundrect(99 - width, 99 - width, 581 + width, 701 + width, 20, 20);setfillcolor(gbgc);fillrectangle(99, 99, 581, 701);setlinecolor(BLACK);settextcolor(BLACK);settextstyle(80, 0, _T("Rosewood Std Regular"));outtextxy(600, 220, _T("Score:"));outtextxy(600, 450, _T("Goal:"));outtextxy(600, 100, _T("Level:"));drawScoreBox();//分数框updateScore();drawRinkBox();//等级框updateRank();drawANewFood(Food);//第一个食物//提示框setfillcolor(YELLOW);fillroundrect(95, 40, 586, 85, 5, 5);setfillcolor(gbgc);fillroundrect(101, 46, 580, 79, 5, 5);settextcolor(RED);settextstyle(20, 20, L"Adobe 仿宋 Std R");outtextxy(100, 48, L" Be careful not to hit yourself or the border");}//void gameOver(int &_end) {mciSendString(L"close bgm",NULL,0,NULL);PlaySound(L"C:\\Users\\TTOD\\source\\repos\\贪吃蛇\\贪吃蛇\\死亡.wav", NULL, SND_FILENAME | SND_ASYNC);setbkmode(TRANSPARENT);setfillcolor(YELLOW);fillroundrect(150, 300, 530, 500, 10, 10);setlinecolor(BLACK);fillroundrect(153, 303, 527, 497, 10, 10);settextcolor(BLACK);settextstyle(50, 0, _T("Rosewood Std Regular"));fillroundrect(220, 370, 470, 440, 10, 10);outtextxy(230, 380, _T("GAME OVER!"));settextstyle(30, 0, 0);fillroundrect(155, 465, 270, 495, 5, 5);fillroundrect(455, 465, 520, 495, 5, 5);outtextxy(160, 470, _T("Restart"));outtextxy(460, 470, _T("Quit"));MOUSEMSG m;while (true) {m = GetMouseMsg();if (m.mkLButton && m.x >= 155 && m.x <= 270 && m.y >= 465 && m.y <= 495) {_end = 0; break; }else if (m.mkLButton && m.x >= 455 && m.x <= 520 && m.y >= 465 && m.y <= 495) {_end = 1; break; }}}void game();//游戏关于界面,用以显示游戏的相关信息void drawAboutBox() {IMAGE img;img.Resize(1000,800);loadimage(&img,_T("IMAGE"),MAKEINTRESOURCE(IDR_IMAGE3));putimage(0, 0, &img);fillrectangle(100, 100, 100 + 20 * 20,100+25*20);point p(0, 0);for (int i = 0; i <= 20; i++) {p.y = 0;p.x = i;drawPointPlus(p,YELLOW,RED);p.y = 25;drawPointPlus(p, YELLOW, RED);}for (int i = 0; i <= 25; i++) {p.x = 0;p.y = i;drawPointPlus(p, YELLOW, RED);p.x =20 ;drawPointPlus(p, YELLOW, RED);}setlinecolor(RED);for (int i = 160; i < 600; i+=40) {line(130, i, 480, i);}setbkmode(TRANSPARENT);settextcolor(RED);settextstyle(20,20,L"Adobe 仿宋 Std R");outtextxy(130,130,L"ABOUT");outtextxy(130, 170, L" Gluttonous Snake is a fun game ,have");outtextxy(130, 210, L" a good time~~");outtextxy(130, 250, L"( click anywhere to back )");outtextxy(130, 490, L" The last updated time :");outtextxy(130, 530, L" .12.8");//cleardevice();MOUSEMSG m;while (1) {m = GetMouseMsg();if (m.mkLButton) break;}game();}//游戏过程void playGame() {while (true) {Sleep(120 - 5 * level);if (getFood(S, Food)) {growAndMove(S);drawANewFood(Food);score += 10*level;setlinecolor(BLACK);setfillcolor(YELLOW);fillroundrect(95, 40, 586, 85,5,5);setfillcolor(gbgc);fillroundrect(101, 46, 580, 79, 5, 5);updateScore();int temp = score%100;if (score == goal) {PlaySound(L"C:\\Users\\TTODS\\source\\repos\\贪吃蛇\\贪吃蛇\\关卡升级.wav", NULL, SND_FILENAME | SND_ASYNC);settextstyle(40, 0, _T("Rosewood Std Regular"));settextcolor(RED);outtextxy(240, 42, L"level up!!");level++;updateRank();goal += 100 * level;}else {settextcolor(RED);settextstyle(20, 20, L"Adobe 仿宋 Std R");PlaySound(L"C:\\Users\\TTODS\\source\\repos\\贪吃蛇\\贪吃蛇\\吃到食物.wav", NULL, SND_FILENAME | SND_ASYNC);switch (temp){case 0:outtextxy(100, 48, L" Be careful not to hit yourself or the border");break;case 10:case 40:case 70:outtextxy(100, 48, L"Press the ASDW keys to change the direction");break;case 20:case 50:case 80:outtextxy(100, 48, L"Speed increases with level");break;case 30:case 60:case 90:outtextxy(100, 48, L"It will grow long when you eat food");default:break;}}}elsemove(S);flashFood(Food);if (hitEdge(S) || hitItself(S)) {gameOver(_end);return;} //游戏结束标志//监听按键,w s a d 分别为上、下、左、右。空格为暂停(按下任意键继续)if (_kbhit()) {char ch = _getch();switch (ch){case 'A':case 'a':if (S->drc != direction::right) {S->drc = direction::left;break;}case 'W':case 'w':if (S->drc != direction::down) {S->drc = direction::up;break;}case 's':case 'S':if (S->drc != direction::up) {S->drc = direction::down;break;}case 'd':case 'D':if (S->drc != direction::left) {S->drc = direction::right;break;}case ' ':_getch();break;default:break;}}}}void restart() {mciSendString(L"open C:\\Users\\TTODS\\source\\repos\\贪吃蛇\\贪吃蛇\\背景音乐.mp3 alias bgm", NULL, 0, NULL);mciSendString(L"play bgm repeat", NULL, 0, NULL);initGame(mode);gameInterface();playGame();}void game() {int cmd = 0; mode = 0;startInterface(cmd,mode);initGame(mode);//cleardevice();switch (cmd){case 1:gameInterface();playGame();while (_end == 0) {restart();}return;break;case 2:break;case 3:drawAboutBox();break;default:break;}};int main() {game();return 0;}

符加说明:本程序使用了简单好用的easyx图形库:可以Easyx官网中下载安装,且Easyx官网提供的文档详细的介绍了各种函数的用法,很容易上手。

代码中可能会有一些本人电脑上的资源路径,导致直接copy代码不能成功运行代码,想要学习的童鞋可以将其换为自己电脑上的资源路径或者直接删除即可运行,游戏相关的资源文件链接:资源链接

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。