坦克世界大戰!大一小夥編寫嘗試

2021-02-20 賽博小姐

曾經的一個朋友當時剛學一點C++嘗試編寫坦克世界大戰,我們來看看他的戰國

那會他剛看完少戰,中二附體max手打像素矩陣歡樂の小曲兒穿甲爆炸燃燒 瞬間完成,事戰車中的豪傑

用txt文件儲存地圖,玩家可自己設計地圖,哈哈。當時還想弄地圖編輯器的,最後還是咕咕咕了

相當搞笑的一點:前面有段代碼是獲取地圖文件夾下所有文件名,存入字符數組。當時不知道字符串尾部要加結束符,導致後面使用該字符串讀入文件時屢屢崩潰(沒有結束符嘛)。

於是,宇宙大聰明答主寫了這麼一段處理代碼,大概思路是將這個字符串複製一遍,檢查複製後字符串的長度是否異常,如果異常則再複製一遍……(笑哭.jpg)

當時win7和現在win10的控制臺空格長度不相同,現在運行會字符錯位,地圖看上去亂糟糟。正常應該是沒有這些縫縫的。

穿甲彈,擊中牆壁後產生2格殺傷區

穿甲彈殺傷大,但是有機率跳彈。有效擊穿時會在對方炮塔處顯示「#」。

高爆彈,產生3x3爆炸範圍

「謝爾曼M1型」自帶速射主炮,每分鐘350發(大霧)。可惜為了平衡,並沒有採用原版APHEI(高爆穿甲燃燒彈),而是殺傷力很低的糖豆炮。

炮射飛彈,射出去能拐個彎。cd長 傷害低,但打掩體後的敵人是為一絕。

炸藥桶地圖塊,被擊中產生5x5爆炸範圍。灰色地圖塊無法被破壞,淺黃色的可以。

坦克被擊毀時有機率殉爆,產生5x5爆炸範圍,而且持續時間比炸藥桶長得多。

程序的穩定性相當差勁,截這些圖的時候答主n次卡死或控制臺彈窗報錯了……

是的,當時連printf都不知道,列印字符用效率奇低的cout;而且一幀裡邏輯處理和渲染混雜執行,導致畫面容易閃爍甚至掉幀……

這是敵人AI的一部分,用n個套娃循環實現類似A*算法的尋路。AI尋找能射擊到敵人的最近位置,還會根據自身血量等計算攻擊欲望,躲避可能傷害到自己的炮彈,拾取有用的道具。整套算法效率特別特別低,每幀都要完整執行一次;容易導致掉幀。所以場上只能有一隻精英怪使用完整的AI,其他小怪用隨機函數xjb亂逛。

小怪:不是很聰明的亞子

類似移動、碰撞檢測之類的部分,每一份代碼都要手動複製四次,對應上下左右四個方向。

再放開頭定義的一段吧:

#include <iostream>
#include <windows.h>
#include <fstream>
//#include <iomanip>
//#include <string.h>
//#include <stdio.h>
//#include <conio.h>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <io.h>//文件
#include <vector>//文件
#include<Mmsystem.h>//音頻相關
#pragma comment(lib,"winmm.lib")//音頻
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
using namespace std;

int map[38][55] = {0};//儲存地圖
int mapX = 55;//地圖x大小
int mapY = 38;//地圖y大小
int allX = 30;//整體x位移
int allY = 0;//整體y位移
int circlet = 0;//循環次數
int model;//當前遊玩模式
int buff[3] = {0};//0[儲存道具:1動能彈,2高爆彈,9生命值 ] ,1x,2y
int tank[10][8] = {0};//儲存坦克:[編號],[0朝向,1x,2y,3生命值,4武器,5移速,6外形,7開炮裝填時間]
//武器:0普通炮,1速射炮,2高爆彈,3破甲彈,4跟蹤彈
int shell[10][10][4] = {0};//儲存炮彈:[所屬坦克],[編號],[0朝向,1x,2y,3類型]
int smoke[100][3] = {0};//儲存硝煙"#":[編號],[0已殲滅時間,1x,2y]

//**********基礎功能**********
void ProgramBegin();//初始化程序
void FuZhi();//初始賦值
void gotoxy(int,int);//跳轉光標
void color(int);//顏色
void getFiles(string, vector<string>&);//獲取目標文件夾內所有文件名
void InMap(char*);//將地圖導入數組
void Tout(int);//列印地圖方塊
void PrintMap();//列印地圖
void PrintTank(int,int,int,int);//列印坦克,朝向,x,y,類型
void DelTank(int,int);//屏幕刪除坦克
void sound(int);//音效
//**********菜單界面**********
int MenuModel();//模式菜單
char* MenuMap();//選圖菜單
void MenuTank1vN();//選車菜單1vN模式
void MenuTank1v1();//選車菜單1v1模式
void Interface();//玩家狀態界面
void NewUI();//刷新狀態界面
int MenuPveWin(int);//結束人機戰局
int MenuPvpWin(int);//結束雙人戰局
//**********戰鬥功能**********
void CtrlTank(int,int);//坦克控制
void InShell(int);//載入炮彈
void SkyShell();//炮彈移動
bool HitTank(int,int,int);//判斷坦克是否受到傷害
void HitShell(int,int,int,int,int,int);//炮彈命中.朝向,x,y,彈藥類型,被命中者 ,發射者
void Boom(int,int,int);//爆炸。半徑,x,y
void InBuff();//載入道具
void OffBuff(int);//使用(消除)道具
void InSmoke(int,int);//載入硝煙
void OffSmoke();//刪除硝煙
//**********AI功能**********
int FindMap(int,int,int,int);//尋路。起點x,y,終點x,y。返回方向,1234上下左右。
void AiTank();//坦克AI
void XieTank(int);//屑AI
void Born(int,int);//生成新車,編號、難度
//**********模式**********
void annihilate();//殲滅模式
void pve();//人機
void pvp();//雙人對戰
//**********附加**********
void op();//片頭
void loading();//偽加載界面
void xy();//顯示硝煙參數
void pd();//顯示炮彈參數
void MenuZhanYi();//戰役


是不是已經想吐了~3.5k行代碼塞在一個.cpp裡

有沒有留意到,上面那一堆全局變量的數據結構只有int數組。怎麼用它儲存數量和參數不等的坦克、炮彈、粒子(爆炸火光、煙霧……)等東西的呢?答主「發明」了這樣一種方法:

一個數組儲存一種類的物體,第一維記錄該類所有物體。如坦克tank數組第一維長度是10,那地圖上最多只能同時存在10輛坦克;tank[5] 表示編號為5的坦克。數組第二維儲存這個物體的個體屬性。如tank[5][0]代表5號坦克的朝向,[1]、[2]代表其坐標,等。

遊戲中每一幀,依次遍歷坦克、炮彈、特效等數組,提取數組中每一位物體,根據玩家輸入和遊戲邏輯更新該物體的參數(也就是更新這個數組)。

關鍵的來了:怎麼實現生成和銷毀物體,比如炮彈命中時銷毀自身?很簡單,要銷毀物體,將那個物體所在的數組第二維清零就行了。刷新物體遍歷數組時,遇到這種「空槽」就跳過。要增加物體,也遍歷一遍該數組,找到一個「空槽」,將新物體的初始數據寫入。

一段時間後,答主知道了有種東西叫結構體,有門課叫數據結構,有種數據結構叫鍊表,有種對象叫面向對象。可惜到現在也沒找到對象,唉。

最爛的代碼果然還是自己寫的代碼,這簡直是個珠穆奧力給峰。好在沒有人需要為這個「項目」負責,沒有人需要維護它,它只需要靜靜地躺在硬碟深處的角落就行了。

總結:

後來呢我還是一直熱衷於遊戲開發。坦克大戰後不久,寫的第二個「大工程」是基於qt的2d海戰遊戲,有點類似頂視角的wows。為啥當時突然想學qt?也許是前一個學期寫作業用mfc太痛苦了吧。總之,按我的壞習慣,看了兩三天文檔就興衝衝開工寫demo了。後期的代碼和工程現在已經找不到了,只找到一些前期的素材:

按照艦船的真實頂視圖 用ps畫svg矢量圖精靈

代碼風格也是極其奧力給,回憶一下大概像這樣:

thisGuanQia->ui->myship->labelPao->setText("主炮0開火cd:"+QString::number(thisGuanQia->jianDui->ship->my->ship[0]->wuQiZu[0]->pao[0]->cd->nowCD));//在標籤上列印 我方艦隊 第一隻船 第一個武器組 第一門炮的cd 

thisGuanQia->ui->myship->labelKey->setText("W"+QString::number(ctrl.keyW)+"S"+QString::number(ctrl.keyS)+"A"+QString::number(ctrl.keyA)+"D"+QString::number(ctrl.keyD)+"↑"+QString::number(ctrl.keyUp)+"↓"+QString::number(ctrl.keyDown)+"←"+QString::number(ctrl.keyLeft)+"→"+QString::number(ctrl.keyRight)+"GN"+QString::number(ctrl.keyShift)+QString::number(ctrl.keyCtrl)+QString::number(ctrl.keyAlt)); //列印鍵盤事件


那時不會調編輯器縮進,現在也忘了qt原生編輯器是長啥樣的。反正基本上整段代碼寫在一行裡…………看代碼要按緊shift+滾輪,對小拇指可是個考驗。

終於會用隊列了,比如開炮時的火光就是將特效序列幀存入一個隊列,然後每幀讀取一張。還寫了一套幾何碰撞檢測,雖然只支持點、線、橢圓、長方形這四種元素。邏輯和渲染終於分開了。還寫了一段幀率控制算法,按本幀邏輯部分的執行時間決定接下來sleep多久,使幀率儘量穩定在30。(然而加這玩意使幀率更不穩定,後來全刪了)

最後先帝創業未半而中道崩黜,加了很多功能後幀率實在太低。用的應該是2代i5m集顯,幀率只有12不到……

相關焦點

  • 第二次世界大戰12輛坦克-戰爭機器回顧
    在20世紀20年代和30年代,人們對坦克的作用進行了大量的研究和理論分析,但相對較少的坦克被生產出來,直到第二次世界大戰期間,由於戰鬥人員每個月都爭先恐後地製造坦克,坦克成了地面戰爭的主要武器。與此同時,這場戰爭推翻了在兩次世界大戰期間關於坦克在現代戰爭中的預期作用的許多假設,許多迄今為止一直堅持的理論被拋棄,取而代之的是更適合現代戰場現實的理論。
  • 第一次世界大戰的新式武器,陸戰之王坦克和戰爭之神火炮的誕生!
    這回小編談的是第一次世界大戰出現的「陸戰之王」坦克和「戰爭之神」火炮中的重炮! 首先是「陸戰之王」坦克! 1915年,歐洲西線戰場激戰正酣,由於機槍的巨大威力,進攻的一方損失遠遠超過了防守方,在這種情況下,英法聯軍與德軍陷入了僵持的塹壕戰!
  • 《Pavlov VR》迎來重大更新,更多第二次世界大戰元素
    《Pavlov VR》迎來重大更新,更多第二次世界大戰元素 (映維網 2021年01
  • 第二次世界大戰
    第二次世界大戰這是一款以二戰為主題的戰爭策略類遊戲,玩家將在遊戲裡選擇盟軍和蘇軍的陣營加入進去,面對來自各方的敵人,招募更多的軍人,培養出最強大的軍隊,引進不同類型的裝甲車可以提升軍隊的戰鬥力,提升整體實力,在戰鬥中通過合理的排兵布陣取得戰鬥的勝利,喜歡戰爭的玩家趕快來下載吧!
  • 旨在支援步兵進攻的步兵坦克?步兵坦克在戰場上價值幾何?
    坦克,這種鋼鐵造物就如同古代的重騎兵,是陸戰中絕對的王者。在第二次世界大戰中,一場場波瀾壯闊的坦克戰,也絕對是戰史中最為耀眼的存在之一。這給了人們一種認知,那就是坦克本身就是為了進攻用的,快速突破敵方戰線,穿插合圍敵軍並將其殲滅。畢竟,第二次世界大戰中的坦克戰大多如此,所以人們也大多認為如此。
  • 水上重坦克:炮艇裝坦克炮,381毫米巨炮的「淺水艇」
    水上重坦克:炮艇裝坦克炮的那些事兒在內河炮艇上裝上坦克炮塔這件事兒,是很具有「蘇聯風格」的,比較有名的炮艇裝坦克炮,就是第二次世界大戰中,史達林格勒會戰期間,前蘇聯的1124型和1125型炮艇,這些裝備著T-34坦克76毫米坦克炮的小艇,在戰爭期間不僅成功的遲滯了德軍的進攻
  • 二戰坦克之德國虎式重型坦克
    看過美國電影《坦克大決戰》都對電影裡德軍坦克暴打美軍坦克的情景印象深刻吧,而德軍所使用的坦克就是可稱為二戰最強坦克的虎式重型坦克。 虎式重型坦克,也被稱為虎式坦克、虎Ⅰ坦克六號坦克,是德國軍隊在第二次世界大戰中裝備的一種重型坦克。虎式重型坦克的設計初衷是為與蘇聯的T34相匹敵,因當時的德軍裝甲部隊中沒有一款坦克能夠和T34坦克相抗衡,於是虎式重型坦克的設計方案應運而生。
  • 二戰性能最優秀的輕型坦克,攜帶75毫米坦克炮的M24輕型坦克
    如果說起第二次世界大戰中的輕型坦克,估計很多人都是沒什麼感覺的。畢竟輕型坦克裝甲薄弱,火力也很脆弱,考慮到第二次世界大戰裡中型坦克和重型坦克扎堆的情況下,人們總是容易忽略輕型坦克的存在。但這不代表輕型坦克就沒有作用了,作為裝甲部隊重要的組成部分,輕型坦克擔負著警戒巡邏,火力偵察等多項任務,因此在第二次世界大戰裡,輕型坦克仍舊有很大的地位。
  • 東北街頭驚現二戰英雄坦克?知道真相後有點感動
    ▲ 「從大白樓那邊來了一輛坦克,我出門的時候剛好開過去!」一位朋友在圈裡驚呼坦克?從他們家門口過去?這怎麼可能,我這位朋友當時正在東北綏芬河度假,就住在市政府對面,誰家的坦克敢往這兒開? T-34坦克是第二次世界大戰前夕由蘇聯哈爾科夫共產國際工廠設計的一型中型坦克,設計師米哈伊爾•伊裡奇•科什金。
  • 二戰時期,德國虎式坦克到底有多厲害?一輛就能擊潰蘇聯34輛坦克
    提到第2次世界大戰,德國之所以能夠所佔披靡,靠的就是他們當時先進的坦克裝備。而在眾多坦克之中,虎式坦克最為出名。只要虎式坦克一出現,盟軍就會高度緊張,因為要消滅一輛虎式坦克是非常困難的。那麼,今天小編就帶大家來了解一下虎式坦克到底有多厲害?虎式坦克,它是1942年德國亨舍爾公司所研製的一款重型坦克,機身整體重量為56噸,是一款非常典型的重型坦克。眾所周知,裝甲厚度的提升意味著坦克防禦力的提升。因此這款虎式坦克,可以說是具有跨時代的意義。
  • 二戰中蘇聯的王者重坦——IS-2重型坦克
    在第二次世界大戰中,蘇聯陸軍是唯一能夠和納粹德軍鐵騎相互抗衡而不落下風的軍隊,這完全得益於蘇聯紅軍那強悍的作戰能力以及蘇聯陸軍中強悍的坦克部隊,今天我們要看的就是二戰蘇聯坦克部隊中的一款主力坦克——IS-2重型坦克。
  • 二戰中的德國四號中型坦克,如何從支援坦克變成了德國主力坦克
    在第二次世界大戰中,德國開發了多款經典坦克,幾乎每一款都在二戰中立下了赫赫戰功。例如縱橫戰場的虎式重型坦克,至今都為人所津津樂道。但在當年的德軍裝甲部隊裡,長期擔任其裝甲部隊中堅力量的坦克,實際上是開發於戰前的四號中型坦克。可是四號中型坦克在開發之初並不是為了擔任裝甲部隊主力,而是為了以提供支援力量為主的支援坦克定位。
  • 坦克當教具!北京理工大學讓T-34老坦克在校園裡馳騁起來
    坦克當教具!2日,北京理工大學國防文化主題廣場在良鄉校區正式啟用,7臺國產、蘇制、美制和日制坦克車輛「組團」入駐。期間,T-34老坦克在主題廣場上再次發動馳騁。  據悉,這7臺珍貴的歷史坦克大都參加過第二次世界大戰或抗美援朝戰爭,車體上還留有明顯的戰爭痕跡,個別車輛保存有志願軍繳獲留跡。
  • 那些不得不說的喪屍題材電影《殭屍世界大戰》
    而《殭屍世界大戰》就是那個那個時代的代表作之一,劇情改編於馬克斯布魯克斯的同名小說,個人覺得原著比電影更有味道,畢竟電影只有那麼長,很多原著構思的精彩橋段展現不出來。電影開始便進入正題,前聯合國調查員蓋瑞雷恩(布拉德皮特飾)正駕車行駛在波士頓的大街上,突然就爆發了暴亂一些行人發了瘋一般撕咬周圍活人,蓋瑞一家四口得到了聯合國的支援得以脫困。
  • 史上最精彩10部坦克大戰電影!點擊觀看!
    重點推薦的還是本片中的坦克大戰,全片圍繞著德軍的白色的虎式坦克,簡稱虎P重型坦克,由於研發費用太大,最終全世界只生產了一輛虎P。此片上映於2014年,可以說這部片子是坦克電影最棒的一部。這部電影完全不糊弄觀眾,直接真傢伙上陣,4輛謝爾曼坦克VS1輛虎式坦克,場面實在是太熱血了。
  • 鋼鐵雄心4:盤點德意志第三帝國的幾種主戰坦克
    八號坦克鼠式(德語:Panzerkampfwagen VIII Maus,英語:Panzer VIII Maus)是由德國保時捷公司在第二次世界大戰末期設計的超重型坦克,戰鬥全重達188噸,是當時最重的坦克。也正是由於車身極重,使得鼠式坦克的越野能力極差,最終因缺少實戰價值而流產。
  • 流產的小豹2坦克,西班牙猞猁主戰坦克
    西班牙作為航海時代的大國,在近現代地位已經大不如從前,兩次世界大戰中均沒有露臉,在坦克技術上與他國差距越來越大,幾乎無主戰坦克開發能力,即便這樣,西班牙仍然希望引進外國技術,實現坦克自主生產。
  • 只有一輛坦克的國家紐西蘭:坦克對於我來說不過是個裝飾品
    該國曾參加了兩次世界大戰,雖然表現沒有什麼亮點,但也算為宗主國盡到了一點力。不過紐西蘭這樣一個發達國家,其國防部隊目前並沒有裝備坦克,只有一輛退役的二手百夫長坦克。 一戰結束之時,紐西蘭的鄰國澳大利亞從英國獲得了一些菱形坦克,並以此打下了一點坦克使用基礎。作為鄰國的紐西蘭對此也很羨慕,也展開了坦克的設計研發工作。
  • 工業革命孕育世界大戰,大量新式武器應運而生
    1917年的美國潛水艇 在作戰空間方面,由於坦克、飛機、潛艇的出現,使戰場維度呈現立體化態勢;在兵力機動方面,由於鐵路、飛機、裝甲車輛、航空母艦和大型艦船的發展
  • 《獵殺T34》曝「坦克肉搏」版預告 坦克戰吸睛
    《獵殺T34》曝「坦克肉搏」版預告 坦克戰吸睛 」版終極預告和海報,這場燃炸熱血的坦克對決一觸即發。