Try   HackMD

程式設計期末專案 書面報告

此書面報告由顧寬証增修、校訂、排版、遷移至HackMD

組別資訊

組內成員與分工

系級與姓名
學號
組別
資管一顧寬証
B10705016
開發組、事務組
資管一賴旻
B10705055
開發組
資管一黃偉翔
B10705006
設計組
資管一陳禹翰
B10705050
設計組
生機一鄭力維
B10602053
設計組
資管一蔡可亮
B10705010
事務組

期末專案資訊

簡短文字介紹

在這個期末專案中,你和你的隊友將針對一個自選的主題自行設計並實作一個資訊系統(或軟體,或程式,看你喜歡怎麼稱呼它)。你的系統可能含有一或多個程式。

除了只能使用C++以外,基本上沒有任何限制。

我們期待看到的是:

  • 你們能設定一個有趣又不失挑戰性的題目
  • 你們能分析問題並且制定出好的系統架構和分工
  • 你們能編寫正確、有效且容易維護的C++程式
  • 你們能清楚生動地展示你們的想法和成果

各組必須自選主題並且實作一個資訊系統。雖然主題沒有任何限制,但理想上它應該適合被資訊化,並且可以在合理時間內被班上的大家理解。如果你不確定你的主題好不好,歡迎隨時找助教或教師討論。有一些常見且通常適合的主題類型如下:

  • (最佳化)你可以針對一個困難的最佳化問題設計演算法,並且將演算法實作出來;這跟期中專案的型態蠻類似的。
  • (資料分析與處理)若你手上有一家零售店的歷史交易記錄,你能做一個系統讓人們能輕鬆地查詢嗎?還是你能將大量資料有效地視覺化呢?又或者,你能否從這批資料中發現什麼令人意想不到的事實?你發現的事情對這個零售商能帶來什麼行銷或作業管理上的意涵?如果是臺鐵的列車到站時間記錄呢?如果是公共單車的借還記錄呢?
  • (遊戲)你可以寫個網路對戰的五子棋,或是介面精美、操控流暢的射擊遊戲。你可以使用<windows.h>、SFML之類的library來實現更好的介面設計。不管怎樣,寫個好玩的遊戲吧!
    台大資管系孔令傑老師

參考資料


專案簡介

作品名稱

《 IM TANKER》

遊戲介紹

《 IM TANKER》是一款單機雙人對戰的坦克遊戲。

遊戲採五戰三勝制,每回合提供九張地圖給玩家自由選擇,首先獲得三勝者為最終贏家!

每張地圖都有不同的主題,其中有許多可以與玩家互動的物件:舉凡讓玩家生命值無意間減少的岩漿地塊、可推動或摧毀掉落道具的箱子。

因為地圖甚大,為了讓玩家有更好的遊戲體驗,兩玩家有各自的分割畫面。

玩家會面後,這時就是考驗操縱的熟練度了!除了高超的槍法外,還需要能巧妙地躲開對方的攻擊。若覺得實力懸殊的話,也可以藉由箱子掉落的各種道具增強能力。趕快找朋友來玩一局吧!

完整工作目錄

IM TANKER GitHub Repo

組員向家長展示的紀錄片

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Made by 賴旻

Presentation簡報

簡報連結


完整書面報告

遊戲介面

主畫面

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

遊戲說明

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

選擇地圖

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

戰鬥畫面

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

小地圖

方便兩玩家了解目前的位置,小地圖位於螢幕正上方中間。

為了提高遊戲體驗,我們在小地圖上將玩家以較顯目的箭頭取代,使玩家們在作戰時能看清自己與對手的相對位置。

兩玩家分割視角

遊戲地圖甚大,為了要讓兩玩家能更清楚周遭環境,兩玩家各自的分割視野會隨著玩家的移動動態追蹤。

兩玩家生命值條

位於畫面左上角和右上角,分別為兩玩家的生命值。

為了讓玩家能一目瞭然,在畫面採生命條顯示,沒有實際數字。

玩家狀態燈

玩家狀態包含回血、子彈增強、速度提升。

吃到道具會後,相對應狀態燈會在固定時間內亮起,並在效果結束後熄燈。

玩家狀態燈

遊戲採回合制,首先達到三勝的玩家就是最終勝利者。因此,我們在上方顯示了三顆燈,亮著的燈數代表了玩家的勝場數。

戰鬥暫停畫面

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

繼續按鈕

按下後可繼續暫停的遊戲

倒退按鈕

按下後可以重新開始「當個回合」

退出按鈕

按下後將回到主畫面,遊戲紀錄不會保存

回合勝利畫面

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

勝利者頭像

若回合結束,畫面中央會顯示贏家的放大頭像

繼續按鈕

按下後,進到下一回合的地圖選擇畫面

最終勝利畫面

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

退出按鈕

按下後回到主畫面


遊戲物件

玩家(坦克)

種類

共有玩家一與玩家二,分別為藍色坦克與紅色坦克。

樣式

玩家一

玩家二

設計者:陳禹翰

操作方式
  • 前進與後退
    • 玩家一:W、S
    • 玩家二:上箭頭、下箭頭
  • 車身旋轉
    • 玩家一:A、D
    • 玩家二:左箭頭、右箭頭
  • 發射砲彈
    • 玩家一:V
    • 玩家二:空白鍵
相關參數
  • 預設移動速度:
    .5f
  • 預設砲彈傷害:
    20.f
  • 最大血量:
    100.f
  • 換彈速度:
    1.f
    (秒)
  • 旋轉角速度:
    3.f
  • 補血道具每幀回復量:
    .32f

投射物(砲彈)

樣式

玩家一

玩家二

設計者:陳禹翰、黃偉翔

生成方式

當玩家按下攻擊鍵,一枚相對應砲彈會產生在玩家砲管前,且面相玩家切線方,並等速飛行。

相關參數
  • 預設飛行速度:
    .8f

地磚

種類
  • 玩家一重生點
  • 玩家二重生點
  • 石頭地板
  • 草地
  • 木板(未出現在任一張地圖)
樣式

玩家重生點

石頭地板
(由於此地磚有隨機生成材質之設計,共有9種,在此只展示其中一種)

草地
(由於此地磚有隨機生成材質之設計,共有62種,在此只展示其中一種)

箱子

樣式

互動方式
  • 玩家可推擠、碰撞
  • 玩家可射擊箱子並擊毀
  • 玩家可推擠箱子至岩漿中並摧毀之
  • 玩家可拾取箱子破壞後掉落的隨機道具
道具掉落

箱子被破壞後會隨機產生至多三樣最少零樣的隨機種類道具,此設計利用了Generator類別,下部分系統設計會提到

相關參數
  • 箱子血量:
    40
  • 最大掉落物數量:
    3

岩漿

樣式

互動模式

玩家若觸碰到此方塊會立即損血

相關參數
  • 傷害:
    15
  • 傷害間隔:
    3
    (秒)

牆壁

樣式

此遊戲物件也有隨機材質生成,共兩種

道具

種類
  • 回血藥水
  • 加速道具
  • 子彈增強
樣式

回血藥水

加速道具

子彈增強

互動模式

玩家觸碰到道具會自動拾取,拾取後:

  • 回血藥水
    • 在5秒內回復定量血量
  • 加速道具
    • 在7秒內加速
  • 子彈增強
    • 在7秒內砲彈變得更大、傷害更高
相關參數
  • 子彈增強倍率:
    .8f
  • 速度提升倍率:
    1.f

介面元素

封面戰車

種類

封面坦克分為兩部分,如此可透過程式操控造成坦克砲管上下擺動效果

  • 藍色戰車車身
  • 紅色戰車車身
  • 藍色戰車砲管
  • 紅色戰車砲管
樣式

設計者:陳禹翰

按鈕

動畫

按鈕在被使用者點擊後會有按壓動畫

設計者:VOiD1 Gaming

UX設計

遊戲中的按鈕有貼心設計:
若玩家在點後立刻後悔,將鼠標移至按鈕外再方開,則不會觸發事件;唯有在按鈕上點擊並放開才會觸發事件。

玩家血條

樣式

設計者:陳禹翰、顧寬証

動畫

血條會追蹤相對應玩家血量比例,並依比例縮放長度。

玩家狀態燈

樣式




動畫

玩家狀態燈會追蹤玩家狀態並以暗、亮表示未激活、被激活。


系統設計

重點類別(Class)

  • Game,包裝整個遊戲的最外層類別
  • SceneManger,掌管各種與場景相關事宜
  • MapManager,讀取文字檔並轉換成二維整數陣列
  • Map,讀取二維陣列並產生相對應的地圖與遊戲物件
    • Tile,非互動性地磚
    • Box,可推動、破壞並掉落道具的箱子
    • Lava,可對玩家造成傷害的岩漿方塊
    • Wall,玩家、投射物皆不可穿透的牆壁
  • Entity,所有遊戲物件類別的母類別
    • Player,遊戲玩家(坦克)
    • Item,道具(箱子掉落物)
    • Projectile,投射物(砲彈)
  • Collider,可加裝於欲有碰撞效果的遊戲類別中
  • SoundManager,管理各種音效相關事宜
  • Generator,有數個亂數相關函式
  • UIElement,非互動性的使用者介面元素
  • Button,可互動並有觸發事件能力的按鈕元素

其他開發細節

分檔

這次專案原始碼非常龐大,因此分成數個檔案(hpp/cpp)並且交互include。在這極為複雜的include關係下,為了避免重新定義類別,使用#ifndef #define #endif等preprocessors。

遊戲物件的更新

因為執行此遊戲的電腦效能不盡相同,為了要讓每個用戶的體驗都可以在一個相同的標準。我們在每一次的遊戲跌代外執行Update這個函數,計算出上一次到此次的時間差(deltaTime)並依此作為更新遊戲物件程度的依據,因此在效能不同的電腦上執行也不會有太大差異。

地圖的讀取與渲染

初期,設計組在發想地圖的時候,為了更好的視覺化,採用excel的30*30格子,並填滿顏色來表示各種功能的地圖。另外,方便之後資料的轉換,因此除了在每個格子加上顏色,還有編上代號,例如:0-玩家一起始位置、1-玩家二起始位置、2-石頭地板、3-草地、4-岩漿、5-牆壁、6-箱子。

最後,將excel檔案轉成文字檔,再匯入MapManager,將文字檔讀取成二維陣列,後再傳入Map::loadMap生成相對應遊戲物件後渲染。

地圖中的幾種地磚,還有隨間產生材質的設計,例如草地、石頭地板等,因此每次打開同一張地圖都會長得不一樣。

地圖設計Excel連結


組內分工

開發組

系統設計與開發、介面設計。

  • B10705016 顧寬証
  • B10705055 賴 旻

設計組

遊戲素材蒐集與製作、遊戲模式設計。

  • B10705006 黃偉翔
  • B10705050 陳禹翰
  • B10602053 鄭力維

事務組

書面報告、開會場地安排。

  • B10705010 蔡可亮
  • B10705016 顧寬証

組員心得感想

B10705016 顧寬証

這次的程設專案對我來說意義重大,很多事情、經驗都是第一次。這是我第一次以C++開發遊戲、第一次接觸SFML、第一次一起與同學開發大型專案、第一次感受到期末壓力使我無法專注於專案。雖然過程不免有挫折,但我認我成長了很多。不僅在開發能力、團隊合作、介面設計等等方面,我認為更重要的是「解決未遇過問題」的能力大幅增進了。

我們期末專案選擇SFML函式庫作為主要開發工具,但我在專案之前從未接觸過SFML、也沒有以C++開發過非終端機的軟體,幾乎所有技術都是從頭學起。許多開發中遇到的問題也不是google一下就可以解決的,因此需要透過觀看教學影片、觀摩他人作品、邏輯推理與不斷的嘗試。這次最大的收穫是,現在的我遇到沒見過的問題不會慌張,而是理性思考並嘗試提出各種解決方案,立刻透過行動驗證想法,並以結果找到更好的解決方案。雖然開發過程遇到種種問題,但很幸運的是,我在暑假自學Python後,曾利用Pygame開發了自己的一款2D地牢射擊遊戲。很感謝當初的自己,雖然SFML並不是一個專門開發遊戲的函式庫,但是在過程中多少有感受到許多地方是大同小異。完成這次專案後,重新看了一次自己的code,雖說比上次開發遊戲的程式碼模組化做得更深、更簡潔,但因為時間有限,為了提高開發效率,我犧牲了良好的系統設計,很多地方仍有非常大的進步空間。期許自己日後不只要寫出能執行的程式碼,更要寫出乾淨、易懂、易維護、易擴充的程式碼。

此外,雖然最終有在期限內完成作品,但是我仍應該檢討為什麼自己在微積分期末考完後才開始開發,希望日後自己在時間控管、分配上可以做得更好。

最後,很感謝隊友們在這次專案的支持與協助,特別感謝設計組的各位,有你們製作、設計的素材,遊戲才能有這樣的視覺體驗。

顧寬証

B10705006 黃偉翔

在這次的期末專案中,我是設計組的成員。這個遊戲的發展可說是峰迴路轉,我們原本想要寫出類似爆爆王的遊戲,但後來在設計出的兩個遊戲方式中,我們選擇了坦克遊戲。由於受限於機體,我們不能像市面上大多的坦克遊戲一樣使用滑鼠瞄準,在一開始有點卡關,還好後來有成功想出替代方案用左移(A)跟右移(D)鍵控制旋轉、上(W)下(S)負責前進、後退,結果效果也不錯。

在這次的專案中,我們的組長顧寬証絕對是最大的功臣。靠著他優異的程式能力,我們設計的點子都被一一實現,並在短短幾天內就完成了令人驚豔的遊戲。我這次最大的收穫,應該是藉由讀他寫的程式碼,加深對OOP的了解:不僅有依照功能完整分檔,他還充分體現了OOP的精神繼承與多型。在這個寒假,我也想藉由這個學習所學習的知識,試著透過這些套件,嘗試寫出一個有趣的遊戲。

黃偉翔

B10705010 蔡可亮

這次身為事務組的成員,理論上應該需要幫我們這組安排所有的進度,但是這次的專案時間橫跨到各科的期末,因此時間安排上非常吃緊。我對其他小組成員感到非常抱歉,沒有妥善安排導致進度延宕到報告當天。

雖然我都沒有參與許多細項討論,關於遊戲的主體安排,舉凡遊戲的進行模式、遊戲的視覺效果,但是我後來仔細研讀開發組的code,發現真的非常有條理。分檔井然有序,可以模組化的部分都會盡可能的模組化,如此一來在未來的維護或是想要更加一步的開發都會變得很淺顯易懂。相較其他組別的系統,我非常佩服我們的組長—顧寬証,他真的在這點發揮他的所長到淋漓盡致,很多檔案互相include甚至是inheritance,他真的非常厲害,設計組的要求他都能完整的呈現。當然其他開發組組員和設計組組員都十分投入,才會有最後完美的成果,這點我非常佩服,並且深刻體會到一個小組的合作是如此的重要。

另外,值得提的一點就是我在畫分檔的關係圖時,隨然我沒辦法畫到非常的清楚,但是我盡可能的展現各個檔案的相互關係。由此也可以發現,如果沒有分檔的話,整個code將會是更混亂,而且可能也不容易debug或是維護修改。這點使我深刻體化到小傑老師時時刻刻無不提醒「模組化」的重要。

蔡可亮

B10705050 陳禹翰

這次的期末專案真的很趕,我們甚至到當天報告的前兩個小時才做完。但首先,我非常感謝我們的組長顧寬証,因為有他,我們才能在短短時間內把一個又一個想完成的想法付諸實行。我對我們的成果非常滿意,甚至比我想像中還要好,甚感欣慰。

經過這次的期末專案,我了解到要做出一個遊戲並不是單純只用到寫程式的技術。應該說寫程式固然是關鍵性的因素,但要讓一個遊戲看起來是有吸引力的,我們必須要顧及視覺效果、音效、使用者體驗等種種細節。因此,跟顧寬証合作,我已經預期到他寫程式的level跟我們是天差地遠,如果要大家把程式分攤寫,最後再合併的話,勢必是事倍功半而且會拖到他的進度的!因此我們一樣把寫程式的重責大任交給寬証(主將)和賴旻(副手),我清楚知道我能做的事就是除了寫程式的其他所有事,而我因為不想躺分,希望對小組有貢獻,所以我決定幫他打理所有雜事。這些雜事包括畫美術圖、討論遊戲進行模式、遊戲介面、設計地圖、在寬証忙不過來時幫他做PPT、在寬証需要任何圖檔的時候在最短時間內畫給他…等等,以讓小組持續維持生產力。而我為了保持我們的原創性,我畫了我們這組的所有坦克車還有設計玩家頭像。雖然這是我第一次用電腦繪圖(可以很明顯看到一張比一張好的進步軌跡),但我覺得在這麼短時間做出來的成果其實比我預期中還要好,希望之後能修一些美術相關的課程XD。

最後,看了我們組長的精彩表現之後,我真的覺得我應該多利用課餘時間來好好地精進我的C++,希望有一天能夠跟他一起分攤寫code的壓力QQ。

陳禹翰

B10705055 賴旻

在這次的專案中我擔任開發組的工作,原本以為高中時寫過小遊戲、小專案的經驗可以讓我很快上手,但是我在開始看我們初步程式的架構時卻深深感受到自己的不足,過去我寫過的專案因為規模較小,不需要分這麼多檔案來執行,OOP的觀念也十分薄弱,讓我光是在理解整個程式構造時就很吃力,檔案之間的交互影響也讓我很頭痛,常常搞不清楚狀況或把程式搞砸,最後都是顧寬証幫我解決問題,真的很感謝他的包容,讓我能學到很多製作大型專案的重要概念例如模組化、要如何控管不同類別的class和函式等等,讓我獲益良多。另外,我還想感謝設計組的組員們,畫出很多精緻的圖案以及設計有趣的地圖,這些素材使我們整個遊戲的介面看起來很專業。我希望我在期末專案結束之後,我可以試著用這次學習到的觀念,自己做出一個有系統、架構清楚的小作品(看著這次專案的程式,再看看以前的我覺得自己寫得很好的code,內心無比淒涼x_x),也期待以後有能力寫出更好的程式。

賴旻

B10602053 鄭力維

這次的期末報告不像期中報告,有一題目可以做延伸,是真的要我們一路從發想、分工再到時做出來。其中的難度我認為差了很多。這次我擔任的是我們坦克遊戲的設計組,我們的工作是要設計出遊戲方式、遊戲美術、遊戲音效和其餘眼睛看得到的東西。我從來沒有想過,設計一款遊戲會如此費時、費腦袋。除了一些直觀上的操控要以程式邏輯跟開發組溝通之外,很多小細節若沒做好,整個遊戲也會變得窒礙難行,更別說是遊戲美術。還好我有一群很罩的組員,能夠起美術,並且完美甚至超越我們原本構思的畫面。這次是我第一次,認真分工完成一組專案,大家各司其職的完成自己份內的工作,有種說不出的成就感,且遊戲的未來性,也讓我感到自豪與期待。感謝這次的組員們凱瑞我,並且讓我見識到了兩、三天生出一款遊戲的實力,有夠鬼,希望未來還能再一起合作。期末報告真是好玩👍。

鄭力維