小編給大家分享一下C++怎么實(shí)現(xiàn)坦克大戰(zhàn)小游戲EGE圖形界面,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
10年積累的成都做網(wǎng)站、成都網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有平城免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。因?yàn)橛羞^一次用EGE寫小游戲的經(jīng)驗(yàn),所以這一次寫坦克大戰(zhàn)快了很多。并且使用對象編程也簡化了很多編程時繁瑣的步驟。
寫出坦克大戰(zhàn)使我在學(xué)習(xí)編程的道路上又邁出了一大步。
如果您需要圖片素材的,我可以單獨(dú)發(fā)給您。
技術(shù)環(huán)節(jié):
編譯環(huán)境:Windows VS2019
需求:
控制坦克移動發(fā)射炮彈,炮彈可以消滅敵軍坦克,且可以消滅磚塊。坦克遇到方塊會被擋住。敵軍消滅我軍三次或基地被毀則游戲失敗,共摧毀十次敵方坦克游戲勝利。
思路:
先寫出坦克的父類,我方坦克類和敵方坦克類繼承坦克父類,實(shí)例化我方坦克和敵方坦克。地圖使用list容器存儲。
在代碼注釋中標(biāo)注了每一步是怎么實(shí)現(xiàn)的。
注意:
因?yàn)槲以诔绦蛑杏昧艘恍┎灰?guī)范的寫法,所以要在VS中正常編譯運(yùn)行,需要右鍵源文件->屬性->C/C+±>符合模式,改為否。
包含<graphics.h>圖形庫需要提前配置EGE圖形庫。
如要在其他graphics圖形庫下編譯,可能需要修改某些地方。
運(yùn)行效果:
代碼:
#include <graphics.h> //圖形庫 #include <ctime> //time(); #include <list> //list容器 using namespace std; //標(biāo)準(zhǔn)命名空間 list等 //設(shè)置圖片對象中圖片的寬高 全局函數(shù) //參數(shù):寬、高、對象名 void setimage(int pwidth, int pheight, PIMAGE img_1); //地圖全局結(jié)構(gòu) struct mapstr { int m_x; //xy坐標(biāo) int m_y; int prop; //屬性 }; //地圖類 class Mymap { private: list<mapstr> listmap; //地圖容器,存儲全地圖信息,全地圖1350個20*20的格子 public: //設(shè)置地圖 Mymap() { mapstr temp; //構(gòu)造函數(shù)為鏈表容器中的地圖賦值 //全地圖橫向45個格子 豎向30個格子 //基地部分 { temp.prop = 0; for (int i = 0; i < 4; i++) { temp.m_x = 380 + i * 20; temp.m_y = 540; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 380 + i * 20; temp.m_y = 520; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 380; temp.m_y = 560 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 360; temp.m_y = 520 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 440; temp.m_y = 560 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 460; temp.m_y = 520 + i * 20; listmap.push_back(temp); } temp.prop = 4, temp.m_x = 400, temp.m_y = 560; listmap.push_back(temp); } //左上角部分 { temp.prop = 0; //左上角單獨(dú)磚塊 for (int i = 0; i < 2; i++) { temp.m_x = 40 + i * 20; temp.m_y = 80; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 40 + i * 20; temp.m_y = 100; listmap.push_back(temp); } //豎鐵塊 for (int i = 0; i < 4; i++) { temp.m_x = 160; temp.m_y = i * 20; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 180; temp.m_y = i * 20; listmap.push_back(temp); } //磚塊 for (int i = 0; i < 4; i++) { temp.m_x = 160; temp.m_y = 160 + i * 20; temp.prop = 0; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 180; temp.m_y = 160 + i * 20; listmap.push_back(temp); } //草塊 for (int i = 0; i < 4; i++) { temp.m_x = 0; temp.m_y = 200 + i * 20; temp.prop = 2; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 20; temp.m_y = 200 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 40 + i * 20; temp.m_y = 240; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 40 + i * 20; temp.m_y = 260; listmap.push_back(temp); } } //中上部分 { //鐵塊 for (int i = 0; i < 2; i++) { temp.m_x = 320; temp.m_y = i * 20; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 340; temp.m_y = i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 280 + i * 20; temp.m_y = 160; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 280 + i * 20; temp.m_y = 180; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 400 + i * 20; temp.m_y = 200; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 400 + i * 20; temp.m_y = 220; listmap.push_back(temp); } //磚塊 for (int i = 0; i < 4; i++) { temp.m_x = 320; temp.m_y = 40 + i * 20; temp.prop = 0; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 340; temp.m_y = 40 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 240; temp.m_y = 200 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 260; temp.m_y = 200 + i * 20; listmap.push_back(temp); } } //右上部分 { //磚塊 for (int i = 0; i < 4; i++) { temp.m_x = 480; temp.m_y = 40 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 500; temp.m_y = 40 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 480; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 500; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 600; temp.m_y = 40 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 620; temp.m_y = 40 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 600; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 620; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 680 + i * 20; temp.m_y = 200; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 680 + i * 20; temp.m_y = 220; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 760; temp.m_y = 0 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 780; temp.m_y = 0 + i * 20; listmap.push_back(temp); } //草塊 for (int i = 0; i < 6; i++) { temp.m_x = 560; temp.m_y = 160 + i * 20; temp.prop = 2; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 580; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 520; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 540; temp.m_y = 160 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 860; temp.m_y = 80 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 880; temp.m_y = 80 + i * 20; listmap.push_back(temp); } //鐵塊 for (int i = 0; i < 4; i++) { temp.m_x = 520 + i * 20; temp.m_y = 80; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 520 + i * 20; temp.m_y = 100; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 640 + i * 20; temp.m_y = 160; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 640 + i * 20; temp.m_y = 180; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 800 + i * 20; temp.m_y = 200; listmap.push_back(temp); } for (int i = 0; i < 6; i++) { temp.m_x = 800 + i * 20; temp.m_y = 220; listmap.push_back(temp); } } //左下部分 { //鐵塊 for (int i = 0; i < 2; i++) { temp.m_x = i * 20; temp.m_y = 360; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = i * 20; temp.m_y = 380; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 160; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 180; temp.m_y = 320 + i * 20; listmap.push_back(temp); } //磚塊 for (int i = 0; i < 12; i++) { temp.m_x = 40; temp.m_y = 360 + i * 20; temp.prop = 0; listmap.push_back(temp); } for (int i = 0; i < 12; i++) { temp.m_x = 60; temp.m_y = 360 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 40 + i * 20; temp.m_y = 280; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 40 + i * 20; temp.m_y = 300; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 160; temp.m_y = 400 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 180; temp.m_y = 400 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 160; temp.m_y = 560 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 180; temp.m_y = 560 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 240 + i * 20; temp.m_y = 240; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 240 + i * 20; temp.m_y = 260; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 280; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 300; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 320; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 340; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 360; temp.m_y = 400 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 380; temp.m_y = 400 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 400; temp.m_y = 400 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 420; temp.m_y = 400 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 440; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 460; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 480; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 500; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 520; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 540; temp.m_y = 320 + i * 20; listmap.push_back(temp); } //草塊 for (int i = 0; i < 10; i++) { temp.m_x = 200 + i * 20; temp.m_y = 280; temp.prop = 2; listmap.push_back(temp); } for (int i = 0; i < 10; i++) { temp.m_x = 200 + i * 20; temp.m_y = 300; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 200 + i * 20; temp.m_y = 320; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 200 + i * 20; temp.m_y = 340; listmap.push_back(temp); } } //右下部分 { //磚塊 for (int i = 0; i < 8; i++) { temp.m_x = 600; temp.m_y = 320 + i * 20; temp.prop = 0; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 620; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 560; temp.m_y = 520 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 580; temp.m_y = 520 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 600 + i * 20; temp.m_y = 560; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 600 + i * 20; temp.m_y = 580; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 680 + i * 20; temp.m_y = 520; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 680 + i * 20; temp.m_y = 540; listmap.push_back(temp); } for (int i = 0; i < 7; i++) { temp.m_x = 760 + i * 20; temp.m_y = 320; listmap.push_back(temp); } for (int i = 0; i < 7; i++) { temp.m_x = 760 + i * 20; temp.m_y = 340; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 800; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 8; i++) { temp.m_x = 820; temp.m_y = 320 + i * 20; listmap.push_back(temp); } //鐵塊 for (int i = 0; i < 4; i++) { temp.m_x = 640; temp.m_y = 320 + i * 20; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 660; temp.m_y = 320 + i * 20; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 680; temp.m_y = 320 + i * 20; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 2; i++) { temp.m_x = 700; temp.m_y = 320 + i * 20; temp.prop = 1; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 820 + i * 20; temp.m_y = 480; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 820 + i * 20; temp.m_y = 500; listmap.push_back(temp); } //草塊 for (int i = 0; i < 4; i++) { temp.m_x = 560; temp.m_y = 360 + i * 20; temp.prop = 2; listmap.push_back(temp); } for (int i = 0; i < 4; i++) { temp.m_x = 580; temp.m_y = 360 + i * 20; listmap.push_back(temp); } } } //顯示地圖 void printmap(list<mapstr>& listmap) { PIMAGE mapprop_0 = newimage(); getimage(mapprop_0, "坦克大戰(zhàn)完整素材\\磚塊.png"); setimage(20, 20, mapprop_0); PIMAGE mapprop_1 = newimage(); getimage(mapprop_1, "坦克大戰(zhàn)完整素材\\鐵塊.png"); setimage(20, 20, mapprop_1); PIMAGE mapprop_2 = newimage(); getimage(mapprop_2, "坦克大戰(zhàn)完整素材\\草塊.png"); setimage(20, 20, mapprop_2); PIMAGE mapprop_4 = newimage(); getimage(mapprop_4, "坦克大戰(zhàn)完整素材\\老鷹_1.png"); setimage(40, 40, mapprop_4); PIMAGE mapprop_5 = newimage(); getimage(mapprop_5, "坦克大戰(zhàn)完整素材\\老鷹_2.png"); setimage(40, 40, mapprop_5); for (list<mapstr>::iterator it = listmap.begin(); it != listmap.end(); it++) { switch (it->prop) { case 0: putimage(it->m_x, it->m_y, mapprop_0); break; case 1: putimage(it->m_x, it->m_y, mapprop_1); break; case 2: putimage(it->m_x, it->m_y, mapprop_2); break; case 4: putimage(it->m_x, it->m_y, mapprop_4); break; case 5: putimage(it->m_x, it->m_y, mapprop_5); break; } } delimage(mapprop_0); delimage(mapprop_1); delimage(mapprop_2); delimage(mapprop_4); delimage(mapprop_5); } //獲取地圖容器 list<mapstr> getmapves() { return listmap; } }; //坦克父類 class Tank { public: virtual void move(const list<mapstr>& tempves) = 0; //坦克移動函數(shù) int getlauch_x() //獲取子彈x坐標(biāo) { return b_m_x; } int getlauch_y() //獲取子彈y坐標(biāo) { return b_m_y; } void setlauch_xy() //設(shè)置子彈坐標(biāo) { b_m_x = m_x + 18; //重置位置為坦克中間 b_m_y = m_y + 18; key1 = key2; //key1 = key2避免炮彈一直發(fā)射 } int getTank_x() //獲取坦克x坐標(biāo) { return m_x; } int getTank_y() //獲取坦克y坐標(biāo) { return m_y; } char getkey2() //返回發(fā)射時的坦克方向信息 { return key2; } //坦克攻擊子彈位置爆炸 void exploed() { PIMAGE explimg_1 = newimage(); getimage(explimg_1, "坦克大戰(zhàn)完整素材\\爆炸效果1.png"); setimage(10, 10, explimg_1); PIMAGE explimg_2 = newimage(); getimage(explimg_2, "坦克大戰(zhàn)完整素材\\爆炸效果2.png"); setimage(20, 20, explimg_2); PIMAGE explimg_3 = newimage(); getimage(explimg_3, "坦克大戰(zhàn)完整素材\\爆炸效果3.png"); setimage(40, 40, explimg_3); PIMAGE explimgarr[3] = { explimg_1, explimg_2, explimg_3 }; for (int i = 0; i < 3; i++) { if (key2 == 'd' || key2 == 'a')//根據(jù)坦克的攻擊朝向確定爆炸的位置 putimage(b_m_x, b_m_y - 6 * i, explimgarr[i]); else putimage(b_m_x - 6 * i, b_m_y, explimgarr[i]); delay_fps(42); } delimage(explimg_1); delimage(explimg_2); delimage(explimg_3); } //構(gòu)造函數(shù) Tank() { m_x = 0; m_y = 0; m_health = 0; m_damage = 0; path_1 = NULL; path_2 = NULL; path_3 = NULL; path_4 = NULL; b_m_x = 0; b_m_y = 0; key1 = '0'; key2 = '0'; } protected: //從文件中獲取坦克圖片 void gettank(const char *path) { PIMAGE tankimg = newimage(); //創(chuàng)建圖片對象 getimage(tankimg, path); //在文件中獲取圖片到圖片對象 setimage(40, 40, tankimg); //設(shè)置圖片對象大小 putimage(this->m_x, this->m_y, tankimg);//在坐標(biāo)處輸出圖片 delimage(tankimg); //釋放圖片對象 } //輸出顯示坦克 void printtank(const char key2) { //根據(jù)當(dāng)前的鍵值,輸出坦克 switch (key2) { case 'w': gettank(path_1); break; //輸出坦克 case 's': gettank(path_2); break; case 'a': gettank(path_3); break; case 'd': gettank(path_4); break; } } //發(fā)射子彈 void launch() { printtank(key2); setfillcolor(WHITE); switch (key2) { case 'w': b_m_y -= 10; bar(b_m_x, b_m_y, b_m_x + 4, b_m_y + 8); break; case 'a': b_m_x -= 10; bar(b_m_x, b_m_y, b_m_x + 8, b_m_y + 4); break; case 's': b_m_y += 10; bar(b_m_x, b_m_y, b_m_x + 4, b_m_y + 8); break; case 'd': b_m_x += 10; bar(b_m_x, b_m_y, b_m_x + 8, b_m_y + 4); break; } //子彈越界目標(biāo)則子彈坐標(biāo)刷新 if (b_m_x >= 900 || b_m_x <= 0 || b_m_y >= 600 || b_m_y <= 0) setlauch_xy(); //重置子彈位置 } int m_x; //坦克xy坐標(biāo) int m_y; int m_health; //坦克血量 int m_damage; //子彈傷害量 char* path_1; //四張不同方向的坦克圖片,由派生類決定圖片路徑 char* path_2; char* path_3; char* path_4; int b_m_x; //子彈坐標(biāo)xy int b_m_y; char key1; //用于接收鍵盤信息 char key2; //用于存儲上一條鍵值,也是發(fā)射時的坦克的朝向 }; //游戲失敗結(jié)束全局函數(shù) 在生命為0 和 基地被攻擊時調(diào)用 void gameoverfalse() { cleardevice(); PIMAGE gameoverbackimg = newimage(); getimage(gameoverbackimg, "坦克大戰(zhàn)完整素材\\游戲結(jié)束背景.jpg"); setimage(900,600,gameoverbackimg); putimage(0, 0, gameoverbackimg); //輸出背景圖片 PIMAGE gameoverimg = newimage(); getimage(gameoverimg, "坦克大戰(zhàn)完整素材\\游戲結(jié)束.png"); setimage(200, 200, gameoverimg); putimage_withalpha(NULL, gameoverimg, 350, 200); //透明格式輸出游戲結(jié)束圖片 delimage(gameoverbackimg); delimage(gameoverimg); //釋放內(nèi)存 getch(); getch(); } //我方坦克,可被操控移動 class TankFriend :public Tank { private: int Fridienum = 0; public: //構(gòu)造函數(shù)初始化坦克坐標(biāo) TankFriend() { m_x = 300; //我方坦克的初始坐標(biāo)為屏幕中下方 m_y = 560; m_health = 100; //坦克血量 m_damage = 90; //坦克傷害 b_m_x = m_x + 18; b_m_x = m_x + 18; path_1 = "坦克大戰(zhàn)完整素材\\己方坦克上.png"; //賦值需要將源文件屬性語言中符合模式改為否 path_2 = "坦克大戰(zhàn)完整素材\\己方坦克下.png"; path_3 = "坦克大戰(zhàn)完整素材\\己方坦克左.png"; path_4 = "坦克大戰(zhàn)完整素材\\己方坦克右.png"; key1 = 'w'; //初始化key1用于輸出初始的坦克 } int getTankdamage() //獲取坦克傷害 { return m_damage; } int getTankhealth() //獲取坦克血量 { return m_health; } void setTankhealth(const int health) //設(shè)置坦克血量 { m_health = health; } int getFridienumfun() //獲取我方坦克被消滅次數(shù) { return Fridienum; } //坦克被操控移動 virtual void move(const list<mapstr>& tempves) { if (key1 != 'j') key2 = key1; //key2記錄上一個key1的值 if (kbhit()) { //用臨時變量接收鍵值,如果鍵值為wasdj中的一個則賦給使用的變量 char tempkey = getch(); switch (tempkey) { case 'w': case 'a': case 's': case 'd': case 'j': key1 = tempkey; break; //接收的鍵盤值不是wasdj直接return default: return; } //判斷坦克撞墻情況,坦克撞墻可以改變方向,但不會移動坐標(biāo) for (list<mapstr>::const_iterator it = tempves.begin(); it != tempves.end(); it++) { switch (tempkey) { //這里的大于小于號一個都不能錯 case 'w': if ( ( //判斷坦克原xy點(diǎn) (m_x >= it->m_x && m_x < it->m_x + 20) && (m_y - 20 == it->m_y) || //判斷坦克右xy點(diǎn) (m_x + 40 > it->m_x&& m_x + 40 <= it->m_x + 20) && (m_y - 20 == it->m_y) ) //判斷方塊屬性 && (it->prop == 0 || it->prop == 1) //判斷地圖邊界范圍 || (m_y - 20 < 0) ) return; break; case 'a': if ( ( //判斷坦克原xy點(diǎn) (m_y >= it->m_y && m_y < it->m_y + 20) && (m_x - 20 == it->m_x) || //判斷坦克右xy點(diǎn) (m_y + 40 > it->m_y && m_y + 40 <= it->m_y + 20) && (m_x - 20 == it->m_x) ) //方塊屬性 && (it->prop == 0 || it->prop == 1) //判斷地圖邊界范圍 || (m_x - 20 < 0) ) return; break; case 's': if ( ( //判斷坦克原xy點(diǎn) (m_x >= it->m_x && m_x < it->m_x + 20) && (m_y + 40 == it->m_y) || //判斷坦克右xy點(diǎn) (m_x + 40 > it->m_x&& m_x + 40 <= it->m_x + 20) && (m_y + 40 == it->m_y) ) //判斷方塊屬性 && (it->prop == 0 || it->prop == 1) //判斷地圖邊界范圍 || (m_y + 60 > 600) ) return; break; case 'd': if ( ( //判斷坦克原xy點(diǎn) (m_y >= it->m_y && m_y < it->m_y + 20) && (m_x + 40 == it->m_x) || //判斷坦克右xy點(diǎn) (m_y + 40 > it->m_y&& m_y + 40 <= it->m_y + 20) && (m_x + 40 == it->m_x) ) //方塊屬性 && (it->prop == 0 || it->prop == 1) //判斷地圖邊界范圍 || (m_x + 60 > 900) ) return; break; } } //根據(jù)key1值修改坦克坐標(biāo) switch (key1) { case 'w': m_y -= 20; break; case 'a': m_x -= 20; break; case 's': m_y += 20; break; case 'd': m_x += 20; break; } } //如果鍵值為j則發(fā)射炮彈,如果鍵值為wasd則移動坦克 if (key1 == 'j') launch(); else { printtank(key1); //根據(jù)鍵值輸出顯示坦克 b_m_x = m_x + 18; //移動時也重置子彈坐標(biāo) b_m_y = m_y + 18; //這里key1值不能重置為key2值 } //如果我軍坦克被消滅,則被消滅次數(shù)+1,并重置坦克 if (m_health <= 0) { Fridienum++; m_x = 300; //坐標(biāo) m_y = 560; m_health = 100; //血量 } } }; //統(tǒng)計(jì)所有敵軍坦克次數(shù)全局變量 int Endienum; //敵軍坦克 class TankEnemy :public Tank { private: int pathsch; //路線方案 int contdir; bool Entankdie = true; //標(biāo)記敵軍坦克的死亡狀態(tài) public: //構(gòu)造函數(shù)接收初始坦克坐標(biāo) TankEnemy(const int x ,const int y, const int pathsch) //構(gòu)造函數(shù)初始化坦克坐標(biāo) { m_x = x; //敵方坦克初始坐標(biāo) m_y = y; b_m_x = m_x + 18; //坦克子彈坐標(biāo) b_m_x = m_x + 18; m_health = 300; //坦克血量 m_damage = 90; //坦克傷害 contdir = 0; this->pathsch = pathsch; //路線 path_1 = "坦克大戰(zhàn)完整素材\\敵方坦克上.png"; //賦值需要將源文件屬性語言中符合模式改為否 path_2 = "坦克大戰(zhàn)完整素材\\敵方坦克下.png"; path_3 = "坦克大戰(zhàn)完整素材\\敵方坦克左.png"; path_4 = "坦克大戰(zhàn)完整素材\\敵方坦克右.png"; gettank(path_1);//輸出一個坦克圖片 } int getTankdamage() //獲取坦克傷害 { return m_damage; } int getTankhealth() //獲取坦克血量 { return m_health; } void setTankhealth(const int health) //設(shè)置坦克血量 { m_health = health; } bool getEntadist() //獲取坦克的死亡狀態(tài) { return Entankdie; } void setpathsch(const int tanknum) //修改坦克行動路線 { switch (tanknum) //判斷坦克編號 { case 1: pathsch = 5; //坦克1路線切換為路線2 break; case 2: pathsch = 6; break; case 3: pathsch = 7; break; case 4: pathsch = 8; break; } } //重置坦克 void setEntank(const int tanknum) { if (Entankdie == false && (pathsch == 5 || pathsch == 6 || pathsch == 7 || pathsch == 8)) return; //如果這個坦克的路線已經(jīng)被修改過,且再次死亡,則不再重置 switch (tanknum) { case 1: m_x = 200, m_y = 40; contdir = 2; break; case 2: m_x = 720, m_y = 120; contdir = 3; break; case 3: m_x = 560, m_y = 120; contdir = 2; break; case 4: m_x = 80, m_y = 360; contdir = 2; } m_health = 300; Entankdie = true; } //坦克1第二路線 //直接攻擊基地 void pathschfun5_1_2() { static bool temp = true; //臨時變量用作標(biāo)記 if(temp == true) contdir = 2; if (m_y == 560 && temp == true) //往右 contdir = 4; if (m_y == 560 && m_x == 240) { m_y = 560, m_x = 240; contdir = 0; temp = false; } } //坦克2路線2 void pathschfun6_2_2() { //720, 120 //需要改變兩次方向 static bool temp = true; static bool temp2 = true; if (temp == true && temp2 == true) contdir = 3; //往左 if (m_x == 200 && temp == true && temp2 == true) //往下 contdir = 2; if (m_x == 200 && m_y == 560 && temp == true) { contdir = 4; //往右 temp2 = false; } if (m_y == 560 && m_x == 280) { m_y = 560, m_x = 280; contdir = 0; temp = false; } } //坦克3路線2 void pathschfun7_3_2() { static bool temp = true; if (temp == true) contdir = 2; //往下 if (m_y == 560 && temp == true) //往左 contdir = 3; if (m_y == 560 && m_x == 480) { m_y = 560, m_x = 480; contdir = 0; temp = false; } } //坦克4路線2 void pathschfun8_4_2() { static bool temp = true; if(temp == true) contdir = 2; if (m_y == 560 && temp == true) contdir = 4; if (m_x == 200 && m_y == 560) { m_x = 200, m_y = 560; contdir = 0; temp = false; } } //正常路線1 void pathschfun_1() { static bool temp = false; //臨時變量輔助控制坦克行走路線 if (m_y == 480 && m_x == 200 && temp == true) //上 { b_m_x = m_x + 18; //重置子彈位置為坦克中間 b_m_y = m_y + 18; contdir = 1; return; } else if (m_y == 40 && m_x == 200) //下 { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 2; temp = false; return; } else if (m_y == 480 && m_x == 200 && temp == false) //右 { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 4; temp = true; return; } else if (m_x == 700 && m_y == 480) //左 { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 3; return; } } //正常路線2 void pathschfun_2() { if (m_x == 720) { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 3; return; } if (m_x <= 140) { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 4; return; } } //正常路線3 void pathschfun_3() { if (m_y == 120) { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 2; return; } if (m_y >= 480) { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 1; return; } } //正常路線4 void pathschfun_4() { if (m_y == 360) { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 2; return; } if (m_y >= 560) { b_m_x = m_x + 18; b_m_y = m_y + 18; contdir = 1; return; } } //敵軍坦克自動移動 virtual void move(const list<mapstr>& tempves) { //根據(jù)contdir值,向不同方向移動 switch (contdir) { case 1: key2 = 'w'; //方向 gettank(path_1); //坦克圖片 m_y -= 4; break; case 2: key2 = 's'; gettank(path_2); m_y += 4; break; case 3: key2 = 'a'; gettank(path_3); m_x -= 4; break; case 4: key2 = 'd'; gettank(path_4); m_x += 4; break; } launch(); //發(fā)射子彈 //不同pathsch不同路線 一個坦克兩條路線 switch (pathsch) { case 1: pathschfun_1(); break; case 2: pathschfun_2(); break; case 3: pathschfun_3(); break; case 4: pathschfun_4(); break; case 5: pathschfun5_1_2(); break; case 6: pathschfun6_2_2(); break; case 7: pathschfun7_3_2(); break; case 8: pathschfun8_4_2(); } //敵軍坦克被消滅 //如果坦克血量小于等于0,則將坦克從界面內(nèi)移除 if (m_health <= 0) { Endienum++; //敵軍坦克被消滅次數(shù)自增 Entankdie = false; //死亡狀態(tài)為false m_x = -40,m_y = -40;//坦克被移除至頁面外 b_m_x = m_x, b_m_y = m_y;//子彈跟隨坦克 } } }; //敵軍坦克數(shù)量 const int N = 4; //子彈命中檢測 bool hittest(TankFriend& tank_f, TankEnemy* Etankarr, list<mapstr>& listmap) //參數(shù):我方坦克對象,敵軍坦克對象數(shù)組,地圖list容器 { const int tanfirlau_x = tank_f.getlauch_x(); //友軍坦克子彈x坐標(biāo) const int tanfirlau_y = tank_f.getlauch_y(); //友軍坦克子彈y坐標(biāo) const int firtank_x = tank_f.getTank_x(); //友軍坦克x坐標(biāo) const int firtank_y = tank_f.getTank_y(); //友軍坦克y坐標(biāo) const int tankfirdam = tank_f.getTankdamage(); //友軍坦克傷害 const int tankfirhea = tank_f.getTankhealth(); //友軍坦克血量 for (int i = 0; i < N; i++) { //發(fā)射子彈需要判斷兩個點(diǎn) //如果友軍子彈和敵軍坦克重合,敵軍坦克血量減少,且友軍坦克子彈坐標(biāo)重置 if ((tanfirlau_x >= Etankarr[i].getTank_x() && tanfirlau_x <= Etankarr[i].getTank_x() + 40 && tanfirlau_y >= Etankarr[i].getTank_y() && tanfirlau_y <= Etankarr[i].getTank_y() + 40) || (tanfirlau_x + 4 >= Etankarr[i].getTank_x() && tanfirlau_x <= Etankarr[i].getTank_x() + 4 + 40 && tanfirlau_y >= Etankarr[i].getTank_y() + 4 && tanfirlau_y + 4 <= Etankarr[i].getTank_y() + 40)) { Etankarr[i].setTankhealth(Etankarr[i].getTankhealth() - tankfirdam); //血量減少 tank_f.exploed(); //友方坦克攻擊導(dǎo)致子彈遇到對方的位置爆炸 tank_f.setlauch_xy(); //友軍的炮彈坐標(biāo)重置 } //如果敵軍子彈和友軍坦克重合,友軍坦克血量減少,且敵軍坦克子彈坐標(biāo)重置 if ((Etankarr[i].getlauch_x() >= firtank_x && Etankarr[i].getlauch_x() <= firtank_x + 40 && Etankarr[i].getlauch_y() >= firtank_y && Etankarr[i].getlauch_y() <= firtank_y + 40) || (Etankarr[i].getlauch_x() + 4 >= firtank_x && Etankarr[i].getlauch_x() + 4 <= firtank_x + 40 && Etankarr[i].getlauch_y() + 4 >= firtank_y && Etankarr[i].getlauch_y() + 4 <= firtank_y + 40)) { tank_f.setTankhealth(tankfirhea - Etankarr[i].getTankdamage()); //友軍坦克本身血量 - 敵軍坦克傷害 Etankarr[i].exploed(); Etankarr[i].setlauch_xy(); //敵軍的炮彈坐標(biāo)重置 } //判斷墻的狀態(tài) //包括我軍坦克和敵軍坦克子彈和墻的狀態(tài) for (list<mapstr>::iterator it = listmap.begin(); it != listmap.end(); it++) { //子彈碰到墻壁需要判斷兩個點(diǎn) if ((tank_f.getlauch_x() >= it->m_x && tank_f.getlauch_x() <= it->m_x + 20 && tank_f.getlauch_y() >= it->m_y && tank_f.getlauch_y() <= it->m_y + 20) || (tank_f.getlauch_x() + 4 >= it->m_x && tank_f.getlauch_x() + 4 <= it->m_x + 20 && tank_f.getlauch_y() + 4 >= it->m_y && tank_f.getlauch_y() + 4 <= it->m_y + 20)) { switch (it->prop) { case 0: //磚塊可以被刪除 tank_f.exploed(); //子彈處發(fā)生爆炸 tank_f.setlauch_xy(); //子彈重置 listmap.erase(it); //刪除被子彈擊中的墻壁數(shù)據(jù) break; case 1: //鐵塊會爆炸不會被刪除 tank_f.exploed(); //子彈處發(fā)生爆炸 tank_f.setlauch_xy(); //子彈重置 break; case 2: //草塊不會有作用 break; case 4: mapstr temp; temp.m_x = it->m_x; temp.m_y = it->m_y; temp.prop = 5; listmap.insert(it, temp); listmap.erase(it); //老鷹被攻擊游戲結(jié)束 return true; } //最后break break; } if ((Etankarr[i].getlauch_x() >= it->m_x && Etankarr[i].getlauch_x() <= it->m_x + 20 && Etankarr[i].getlauch_y() >= it->m_y && Etankarr[i].getlauch_y() <= it->m_y + 20) || (Etankarr[i].getlauch_x() + 4 >= it->m_x && Etankarr[i].getlauch_x() + 4 <= it->m_x + 20 && Etankarr[i].getlauch_y() + 4 >= it->m_y && Etankarr[i].getlauch_y() + 4 <= it->m_y + 20)) { switch (it->prop) { case 0: //磚塊可以被刪除 Etankarr[i].exploed(); //子彈處發(fā)生爆炸 Etankarr[i].setlauch_xy(); //子彈重置 listmap.erase(it); //刪除被子彈擊中的墻壁數(shù)據(jù) break; case 1: //鐵塊會爆炸不會被刪除 Etankarr[i].exploed(); //子彈處發(fā)生爆炸 Etankarr[i].setlauch_xy(); //子彈重置 break; case 2: //草塊不會有作用 break; case 4: mapstr temp; temp.m_x = it->m_x; temp.m_y = it->m_y; temp.prop = 5; listmap.insert(it, temp); listmap.erase(it); return true; } //最后break break; } } } return false; } //游戲開始界面 void initgamebegin() { //開始背景 PIMAGE gabegbaimg = newimage(); getimage(gabegbaimg,"坦克大戰(zhàn)完整素材\\開始游戲背景.jpg"); setimage(1000,600,gabegbaimg); putimage(0, 0, gabegbaimg); //開始按鈕 PIMAGE gabegimg = newimage(); getimage(gabegimg, "坦克大戰(zhàn)完整素材\\開始游戲.png"); setimage(290, 210, gabegimg); putimage_withalpha (NULL, gabegimg, 305, 440); setfont(120,0,"楷體"); //設(shè)置字號,字體 setcolor(YELLOW); //設(shè)置文字顏色 setbkmode(1); //文字背景色透明 outtextxy(210, 100, "坦克大戰(zhàn)"); //輸出文字 mouse_msg msg; //接收開始游戲的鼠標(biāo)信息 while (true) { msg = getmouse(); if (msg.is_left()) if (msg.x >= 305 && msg.y >= 440 && msg.x <= 305 + 290 && msg.y <= 440 + 210) break; delay_fps(50); } } //游戲勝利結(jié)束,全局函數(shù) void gameovertrue() { cleardevice(); PIMAGE gameoverbackimg = newimage(); getimage(gameoverbackimg, "坦克大戰(zhàn)完整素材\\游戲勝利結(jié)束背景.jpg"); setimage(1000, 600, gameoverbackimg); putimage(0, 0, gameoverbackimg); //輸出背景圖片 PIMAGE gameoverimg = newimage(); getimage(gameoverimg, "坦克大戰(zhàn)完整素材\\勝利文字.png"); setimage(206, 107, gameoverimg); putimage_withalpha(NULL, gameoverimg, 347, 220); //透明格式輸出游戲結(jié)束圖片 delimage(gameoverbackimg); delimage(gameoverimg); //釋放內(nèi)存 getch(); getch(); } //主函數(shù) int main() { initgraph(900, 600, INIT_RENDERMANUAL); //初始化圖形界面 setcaption("C++ EGE坦克大戰(zhàn)"); //設(shè)置窗口標(biāo)題 initgamebegin(); //游戲開始界面 TankFriend tank_f; //我方坦克 TankEnemy tank_e_1(200, 40, 1); //敵方坦克 1 TankEnemy tank_e_2(720, 120, 2); //敵方坦克 2 TankEnemy tank_e_3(560, 120, 3); //敵方坦克 3 TankEnemy tank_e_4(80, 360, 4); //敵方坦克 4 //敵軍坦克數(shù)組 TankEnemy Etankarr[N] = { tank_e_1, tank_e_2,tank_e_3,tank_e_4 }; Mymap map_1; //地圖 //獲取地圖信息 list<mapstr> listmap = map_1.getmapves(); bool gameoverstat = false; //判斷游戲結(jié)束狀態(tài)變量,默認(rèn)失敗 bool basestat = false; //判斷基地老鷹的狀態(tài),為真則游戲失敗 //游戲循環(huán) while (true) { cleardevice(); //清屏 //三條生命 被消滅三次時結(jié)束游戲 if (tank_f.getFridienumfun() < 3) tank_f.move(listmap); else break; //敵軍坦克數(shù)組循環(huán) for (int i = 0; i < N; i++) { if(Etankarr[i].getEntadist() == true) //坦克必須存活時才會調(diào)用移動函數(shù) Etankarr[i].move(listmap); //敵方坦克 else { switch (Endienum) { case 3: //坦克死亡時,且敵軍總被消滅次數(shù)為3時,已被消滅坦克復(fù)活 Etankarr[i].setEntank(i + 1); //重置已坦克被消滅 break; case 4: case 6: case 8: case 10: Etankarr[i].setEntank(i + 1); //重置坦克 Etankarr[i].setpathsch(i + 1); //修改坦克路線 } } } map_1.printmap(listmap); //輸出地圖 basestat = hittest(tank_f, Etankarr ,listmap); //子彈命中坦克檢測 if (basestat) break; //如果basestat為true則游戲按失敗break if (Endienum > 10) //消滅敵軍達(dá)10則游戲勝利 { gameoverstat = true; break; } delay_fps(62); } //根據(jù)游戲結(jié)束狀態(tài),調(diào)用結(jié)束函數(shù) gameoverstat ? gameovertrue(): gameoverfalse(); //游戲結(jié)束 return 0; } //設(shè)置圖片寬高全局函數(shù) void setimage(int pwidth, int pheight, PIMAGE img_1) { int whidth = getwidth(img_1), height = getheight(img_1);//獲取當(dāng)前img圖像對象的寬高 PIMAGE img_2 = newimage(pwidth, pheight); //創(chuàng)建一個新的圖像對象,這個新的圖像對象的寬高為 //要重新設(shè)置的圖像的寬高 putimage(img_2, 0, 0, pwidth, pheight, img_1, 0, 0, whidth, height); //將原本img中的圖像拉伸繪制到img_2中 getimage(img_1, img_2, 0, 0, pwidth, pheight); //img再獲取img_2中的圖像 delimage(img_2); //使用完畢將釋放掉 }
不足之處:
參照標(biāo)準(zhǔn)的坦克大戰(zhàn),子彈在攻擊磚塊時,如果子彈正好打中兩個磚塊,則兩個磚塊同時被消滅,這個效果我在程序中做不出來。只能是用一個一個地消滅代替了。
在按下鍵鍵值不是wasdj時和坦克碰到墻壁時坦克會閃的問題,也暫時沒有找到解決辦法。
因?yàn)槌鯇W(xué)C++,所以我在類和對象的使用上面還有著很多很多的缺陷和不規(guī)范的地方。
還有關(guān)于地圖的問題,因?yàn)槲覜]有經(jīng)驗(yàn),所以不知道該怎么簡便地創(chuàng)造一個游戲地圖,在剛開始的時候還在為用什么實(shí)現(xiàn)地圖而猶豫過,最后還是選擇了list容器逐個將地圖元素塞進(jìn)去,因?yàn)榭紤]到list容器插入和刪除數(shù)據(jù)很快。
我知道在程序中很多地方我都寫的極為地不合理,以至于程序運(yùn)行效率非常低(從我的CPU占用看出來的),但是我會繼續(xù)努力,繼續(xù)學(xué)習(xí),爭取早日解決這些問題。
以上是“C++怎么實(shí)現(xiàn)坦克大戰(zhàn)小游戲EGE圖形界面”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.rwnh.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)頁標(biāo)題:C++怎么實(shí)現(xiàn)坦克大戰(zhàn)小游戲EGE圖形界面-創(chuàng)新互聯(lián)
網(wǎng)頁路徑:http://www.rwnh.cn/article40/dgsdeo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、網(wǎng)站收錄、小程序開發(fā)、商城網(wǎng)站、面包屑導(dǎo)航、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)