貪吃蛇游戲大家應該都不陌生了,要說沒玩過的話,可能你是15后吧?
貪吃蛇游戲最初為單機模式,后續(xù)又陸續(xù)推出團戰(zhàn)模式、賞金模式、挑戰(zhàn)模式等多種玩法。
用游戲把子上下左右控制蛇的方向,尋找吃的東西,每吃一口就能得到一定的積分,而且蛇的身子會越吃越長,身子越長玩的難度就越大,不能碰墻,不能咬到自己的身體,更不能咬自己的尾巴,等到了一定的分數,就能過關,然后繼續(xù)玩下一關。
貪吃蛇的唯一的目標就是長成最長的一條蛇!滑動搖桿控制小蛇走位,吃掉地圖上彩色的小圓點,就會變長。
效果展示:
改變此款游戲的特別多。比如在蛋的方面,可能放上帶道具的蛋,使蛇吃完后具有保護,穿墻等特種功能,而且難度逐漸變難。如果有編程技術比較強大的伙伴也可以去嘗試一下哦!做出一個趨近完美的貪吃蛇那可就是能力的展現啦~
本項目編譯環(huán)境:Visual Studio 2019/2022,EasyX插件
代碼展示:
?
#include?? #include #include #include #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 //////////////////////////////////////////// //格子類,定義一個格子的屬性及行為 //////////////////////////////////////////// class Cell { public: friend class GameArea; //設置友元函數 void setxy(short x, short y) //設置格子左上角坐標 { m_x = x, m_y = y; } void setfull(short full) //設置格子屬性,0為空,1為障礙,2為食物 { m_full = full; } void display(COLORREF color) //設置格子顏色并顯示 { m_color = color; setfillstyle(m_color); bar(m_x, m_y, m_x+7, m_y+7); } void LaserDisplay() //顯示鐳射狀態(tài)的格子 { IMAGE image(10,10); SetWorkingImage(&image); DWORD* pMem = GetImageBuffer(&image); for(int i = 0; i < 10 * 10; i++) pMem[i] = BGR(RGB(0, 0, i * 256 / (10*10) )); SetWorkingImage(NULL); putimage(m_x,m_y,&image); } short ReturnFull() //返回格子狀態(tài) { return m_full; } Cell() //構造函數 { m_x = 0,m_y = 0,m_full = 0; m_color = BLACK; } private: short m_x; //格子的左上角X坐標 short m_y; //格子的左上角Y坐標 short m_full; //0為空,1為阻擋,2為食物 COLORREF m_color; //格子顏色 }; //////////////////////////////////////////// //游戲區(qū)類,編寫有關游戲區(qū)的一些操作 //////////////////////////////////////////// class GameArea //游戲區(qū)域 { public: Cell m_game[60][60]; //定義游戲區(qū)域(由360個格子組成) friend void MessageDispose(); //設置友元函數 bool CreatFood() //產生隨機食物 { srand(time(NULL)); //初始化隨機數種子 m_random1 = rand()%58+1; //隨機生成一個0 - 58的整數 m_random2 = rand()%58+1; //隨機一個0 - 58的整數 if(m_game[m_random2][m_random2].m_full == 0) //檢查生成的食物坐標是否在障礙上 { m_game[m_random1][m_random2].display(GREEN); m_game[m_random1][m_random2].m_full = 2; return true; } //如果隨機的食物正好出現在蛇身上,則進入下面的循環(huán)尋找可以生成食物的地方 for(m_random1 = 1;m_random1 < 59;m_random1++) { for(m_random2 = 1;m_random2 < 59;m_random2++) { if(m_game[m_random2][m_random2].m_full == 0) { m_game[m_random1][m_random2].display(GREEN); m_game[m_random1][m_random2].m_full = 2; return true; } } } //如果沒有找到可以生成食物的地方,則通關 return false; //返回false即表示通關 } void DelFood() //刪除食物 { m_game[m_random1][m_random2].m_full = 0; //設置為0即代表格子屬性為空 } void ChangeColor(int flag1,int flag2,COLORREF color) //設置指定格子的顏色 { m_game[flag1][flag2].display(color); } void Init() //初始化GAME區(qū)域 { int flag1,flag2; //標識變量 BeginBatchDraw(); //開始批量繪圖 setfillstyle(BLACK); //設置當前顏色 bar(0,0,600,600); //畫無邊框填充矩形(在這里的用途是用黑色清空游戲區(qū)域) for(flag1 = 0;flag1 < 60;flag1++) { for(flag2 = 0;flag2 < 60;flag2++) { if(flag1 == 0 || flag1 == 59 || flag2 == 0 || flag2 == 59) //創(chuàng)建邊界 { m_game[flag1][flag2].setfull(1); m_game[flag1][flag2].setxy(flag1*10,flag2*10); m_game[flag1][flag2].display(RGB(237,28,36)); } else //創(chuàng)建游戲區(qū)域 { m_game[flag1][flag2].setfull(0); m_game[flag1][flag2].setxy(flag1*10,flag2*10); m_game[flag1][flag2].display(BLACK); } } } CreatFood(); EndBatchDraw(); } private: int m_random1, m_random2; }; //////////////////////////////////////////// //蛇類,定義蛇的數據結構以及蛇的行為 //////////////////////////////////////////// class Snake { public: int toward; //蛇頭朝向 friend void MessageDispose(); friend int HitDetect(); friend void ReInit(); Snake() { head = NULL; last = NULL; now = NULL; } void Init() //初始化蛇的結構 { if(head!=NULL) //重玩游戲時,釋放原先的鏈表所有結點 { for(now = head->next;now->next != NULL;now = now->next) { free(now->prior); } } head = (struct node*)malloc(sizeof(struct node)); //為蛇頭分配內存 head->prior = NULL; head->m_x = 300; head->m_y = 300; now = (struct node*)malloc(sizeof(struct node)); head->next = now; now->prior = head; now->next = NULL; now->m_x = 300; now->m_y = 290; last = now; toward = DOWN; } void SnakeAdd() { now = head; //當前指向蛇頭 now->prior = (struct node*)malloc(sizeof(struct node)); //為新增的結點分配內存 now = now->prior; //讓當前指向新分配的結點 now->prior = NULL; //置空當前結點的前趨 now->next = head; //讓當前結點的后繼指向蛇頭 switch(toward) //根據當前蛇頭方向確定新增部分的坐標 { case UP: now->m_x = head->m_x; now->m_y = head->m_y -10; break; case DOWN: now->m_x = head->m_x; now->m_y = head->m_y + 10; break; case LEFT: now->m_x = head->m_x - 10; now->m_y = head->m_y; break; case RIGHT: now->m_x = head->m_x + 10; now->m_y = head->m_y; break; } head = now; //設置當前結點為蛇頭 } void SnakeDel() //釋放蛇尾結點(刪除蛇尾) { last = last->prior; free(last->next); last->next = NULL; } void SnakeMove() //蛇身移動一格 { SnakeAdd(); //增加蛇頭 SnakeDel(); //刪除蛇尾 } private: struct node //蛇身鏈表 { int m_x; int m_y; struct node *next; //下個結點 struct node *prior; //上個結點 }; struct node *head; struct node *last; struct node *now; }; //////////////////////////////////////////// //游戲類,用來初始化游戲的參數,及實現其他游戲操作 //////////////////////////////////////////// class Game { public: void Init() { closegraph(); initgraph(800,600); setbkmode(TRANSPARENT); //設置輸出文字背景為透明 LOGFONT f; getfont(&f); // 獲取當前字體設置 f.lfHeight = 50; // 設置字體高度為 48(包含行距) _tcscpy(f.lfFaceName, _T("黑體")); // 設置字體為“黑體” f.lfQuality = ANTIALIASED_QUALITY; // 設置輸出效果為抗鋸齒 setfont(&f); // 設置字體樣式 } void FailGame() //游戲失敗顯示的畫面 { setcolor(RED); setfont(70, 0, _T("微軟雅黑")); outtextxy(150, 265, _T("YOU LOSE!")); } void WinGame() //游戲勝利時顯示的畫面 { setcolor(RED); setfont(70, 0, _T("微軟雅黑")); outtextxy(150, 265, _T("YOU WIN!")); FlushBatchDraw(); Sleep(10000); exit(0); } }; //////////////////////////////////////////// //管理區(qū)類,定義管理區(qū)域的相關操作 //////////////////////////////////////////// class ManageArea { public: friend void MessageDispose(); void TimeAdd(double add) //增加時間(可在類外直接調用實現動態(tài)刷新時間) { m_time += add; DisplayTime(); } void ScoreAdd(short add) //增加分數(可在類外直接調用實現動態(tài)刷新分數) { m_score += add; DisplayScore(); } void DisplayPause() //顯示暫?;蛘唛_始 { BeginBatchDraw(); _stprintf(m_str_score, _T("%d"), m_score); setfont(25, 0, _T("微軟雅黑")); setfillstyle(m_bgcolor); bar(625,490,800,515); setcolor(BLUE); if(m_pause) outtextxy(625, 490, _T("開始(P鍵)")); else outtextxy(625, 490, _T("暫停(P鍵)")); EndBatchDraw(); } void Init() //初始化管理界面 { m_time = 0.0; m_score = 0; m_leave = 1; m_pause = false; _stprintf(m_str_score, _T("%d"), m_score); //格式化轉換類型 _stprintf(m_str_time, _T("%.1lf"), m_time); m_bgcolor = BLACK; BeginBatchDraw(); setfillstyle(BLACK); bar(601,0,800,600); setfont(60, 0, _T("微軟雅黑")); setcolor(GREEN); outtextxy(625, 30, _T("貪吃蛇")); setfont(30, 0, _T("微軟雅黑")); setcolor(RGB(128,0,255)); outtextxy(625, 140, _T("制作:輕雨漫步")); setfont(25, 0, _T("微軟雅黑")); setcolor(BLUE); outtextxy(625, 430, _T("時間:")); outtextxy(625, 460, _T("分數:")); outtextxy(625, 490, _T("暫停(P鍵)")); outtextxy(625, 520, _T("重新游戲(R鍵)")); setcolor(RED); outtextxy(720, 400, m_str_leave); outtextxy(680, 460, m_str_score); outtextxy(680, 430, m_str_time); EndBatchDraw(); } private: double m_time; short m_score; short m_leave; bool m_pause; TCHAR m_str_leave[2], m_str_time[33], m_str_score[5]; COLORREF m_bgcolor; void DisplayTime() //顯示當前耗時 { BeginBatchDraw(); _stprintf(m_str_time, _T("%.1lf"), m_time); setfont(25, 0, _T("微軟雅黑")); setfillstyle(m_bgcolor); bar(680,430,800,455); setcolor(RED); outtextxy(680,430,m_str_time); EndBatchDraw(); } void DisplayScore() //顯示當前分數 { BeginBatchDraw(); _stprintf(m_str_score, _T("%d"), m_score); setfont(25, 0, _T("微軟雅黑")); setfillstyle(m_bgcolor); bar(680,460,800,485); setcolor(RED); outtextxy(680,460,m_str_score); EndBatchDraw(); } }; //////////////////////////////////////////// //聲明游戲需要的類 //////////////////////////////////////////// Game game; //用于初始化游戲、設置游戲相關參數 GameArea a; //用于初始化游戲區(qū)域,設置,改變游戲區(qū)域相關參數 ManageArea manager; //用于初始化管理區(qū)域,設置管理區(qū)相關參數 Snake s; //用于初始化蛇,數據化蛇,操作蛇 //////////////////////////////////////////// //游戲的消息控制,流程控制函數 //////////////////////////////////////////// void MessageDispose() //消息處理函數 { char c; s.now = NULL; bool Keepdown = false; while(true) { Keepdown = false; //是否持續(xù)按W A S D 中的一個按鍵 if(kbhit()) { switch(c = getch()) //處理按鍵消息(W A S D) { case 'w': case 'W': if(s.toward == UP)Keepdown = true; else if(s.toward != DOWN&&s.toward != UP)s.toward = UP; break; case 's': case 'S': if(s.toward == DOWN)Keepdown = true; else if(s.toward != UP&&s.toward != DOWN)s.toward = DOWN; break; case 'a': case 'A': if(s.toward == LEFT)Keepdown = true; else if(s.toward != RIGHT&&s.toward != LEFT)s.toward = LEFT; break; case 'd': case 'D': if(s.toward == RIGHT)Keepdown = true; else if(s.toward != LEFT&&s.toward != RIGHT)s.toward = RIGHT; break; case 'p': case 'P': manager.m_pause = !manager.m_pause; //設置暫停或開始 manager.DisplayPause(); //顯示暫?;蜷_始 break; case 'r': case 'R': ReInit(); break; } } if(true == manager.m_pause) //如果暫停,直接進行下次循環(huán) { continue; } BeginBatchDraw(); switch(a.m_game[s.head->m_x/10][s.head->m_y/10].ReturnFull()) //檢測蛇頭遇到的情況 { case 2: //遇到食物,蛇身加長 a.ChangeColor(s.head->m_x/10,s.head->m_y/10,BLUE); s.SnakeAdd(); //蛇增長 a.ChangeColor(s.head->m_x/10,s.head->m_y/10,BLUE); a.DelFood(); //刪除食物 if(a.CreatFood() == false) //創(chuàng)建新食物,并檢查是否通關 { game.WinGame(); //游戲通關(當地圖沒地方創(chuàng)建食物時) } manager.ScoreAdd(1); //加一分 break; case 0: a.m_game[s.last->m_x/10][s.last->m_y/10].setfull(0); //設置蛇尾經過處無障礙 a.ChangeColor(s.last->m_x/10,s.last->m_y/10,BLACK); s.SnakeMove(); //蛇移動一次 a.ChangeColor(s.head->m_x/10,s.head->m_y/10,BLUE); a.m_game[s.head->next->m_x/10][s.head->next->m_y/10].setfull(1); //設置蛇頭經過處有障礙 break; case 1: //遇到障礙物 game.FailGame(); a.ChangeColor(s.head->m_x/10,s.head->m_y/10,RGB(255,127,39)); FlushBatchDraw(); { char c = ' '; while(c != 'r' && c != 'R') //當游戲失敗時,按R鍵可重新進行游戲 { if(kbhit()) { c = getch(); } Sleep(10); } } ReInit(); //重新開始游戲 break; } EndBatchDraw(); if(Keepdown==false) { Sleep(100); manager.TimeAdd(0.1); //增加時間 } else //當持續(xù)按下按方向鍵時 { Sleep(40); //適當休眠可以增加游戲流暢性 manager.TimeAdd(0.04); //增加時間 } } } //////////////////////////////////////////// //游戲初始化函數 //////////////////////////////////////////// void ReInit() { a.Init(); //初始化游戲區(qū) s.Init(); //初始化蛇 manager.Init(); //初始化管理區(qū) //繪制蛇的開始狀態(tài) s.now = s.head; a.ChangeColor(s.now->m_x/10,s.now->m_y/10,BLUE); s.now = s.last; a.ChangeColor(s.now->m_x/10,s.now->m_y/10,BLUE); } //////////////////////////////////////////// //main函數,程序入口 //////////////////////////////////////////// int main(void) { game.Init(); //初始化游戲參數、設置 ReInit(); //初始化其他 MessageDispose(); //消息處理函數 return 0; }
?
大家趕緊去動手試試吧!
審核編輯:湯梓紅
評論
查看更多