2016年6月19日 星期日

用C++寫2D捲軸射擊遊戲_第二彈

緣起:
1.繼上次5月15號發表文章到現在,所做的事情就是重構當時所附的程式,依物件導向三大精神(封裝/繼承/多型)繼續擴充下去,將類別的程式從game.h移出,1個類別就單獨寫成1個檔案(*.h),
2.另外就是新增3條命(我機設定不再是無敵狀態)/計分/大絕招/Lv1新增怪物種類/Lv1 Boss/Lv1過場動畫/遊戲說明,
3.目前寫完第一關卡,大家可以參考這個更好的雛型修改成自己想要的模樣,本篇blog有不足之處,日後補上,請注意引用本篇blog不必註明出處,但程式部分有些參考網路上的資料而修改的,請注意智慧財產權,

程式參考網站:
1.C++實務班(http://garfstudio.blogspot.tw/2015/12/cyoutube.html),
2.DirectX教學網站(http://www.rastertek.com/dx11tut14.html),

程式細節:
1.先由game.h抽出基底類別circle,由此衍生出bullet類別跟unit類別:
 - bullet類別是所有子彈類別(例如:大絕招EMP)的基底類別,
 - unit類別是敵機(史萊姆slime,哥布林goblin,豆腐tofu)跟我機類別(hero)的基底類別,
 - 而用bullet類別建立的物件又是unit類別的成員,

2.將unit類別改為抽象類別,建立多型的架構:
 - 每個衍生類別各自覆寫draw函數/move函數/shoot函數,這樣就可以有各自的造型/移動模式/子彈類型,
 - 所有的不同種類的敵機,包含boss(tofu.h),通通被塞入vMonster的linked list當中,在game.h內用迭代器(同一介面)走訪linked list內所有的敵機,就可以有各種不同造型/移動模式/子彈的敵機,

3.同理,bullet類別也建立多型的架構,繼承bullet類別的迴力鏢boomerang跟EMP也都通通塞入vBullet的linked list當中,用同一介面走訪linked list內所有的子彈,

4.新增腳本類別script,這類別就像是扮演導演的角色,安排何時該由哪個敵機上場演出(由Score去劃分),
 - 亦即今天要新增新的敵機種類只要去改script.h跟新增新種敵機的.h檔即可,不需要改到走訪的介面(game.h),

本篇blog附上範例程式的使用方式:
1.在任何一種版本的Visual Studio建立C++ win32專案,專案名稱打"JustShootIt",專案建立後再修改專案->屬性->不使用Unicode字集,專案->屬性->C/C++->先行編譯標頭檔->不使用先行編譯標頭檔,開啟JustShootIt.cpp,清光內容,
2.將範例程式解壓縮,除了JustShootIt.cpp以外,其他檔案都放到專案的那個目錄內,用記事本打開JustShootIt.cpp,全部複製貼到Visual Studio編輯視窗的JustShootIt.cpp裡頭,
3.依序為專案加入*.h,soundclass.cpp,
4.build->Run,

遊戲操作方式:
1.射擊子彈:空白鍵,
2.上下左右方向鍵控制我機的移動方向,
3.大絕招EMP:Z鍵,

遊戲畫面:
範例程式:
https://drive.google.com/file/d/0B6EVEd5P2B9cTzlVNzAzTF9lRFE/view?usp=sharing

062516更新:
1.修正boomerang移動模式,
2.修正一些bug,
3.修改directSound每回play音效都先設定音量,改成初始化時就先設好音量,

範例程式:
https://drive.google.com/file/d/0B6EVEd5P2B9cN3BuN3R0alI5eXM/view?usp=sharing

082918更新:
提供底下新版的範例程式,編譯的方式請參考另一篇文章"用C#寫crawler(網路爬蟲)":
https://drive.google.com/file/d/1epY8jdeezFkcUH4l7nMf1jAKZghcmOr4/view?usp=sharing

2016年5月15日 星期日

用C++寫2D捲軸射擊遊戲

緣起:
學習C++多年,一直想自己寫個game,近日寫game的background knowledge已趨完整俱備,就寫了一個2D垂直向捲軸射擊game雛型,中文就叫"射擊就對了",這個game已具備2D捲軸射擊基本要素:我機(目前設定是無敵狀態)/敵機/子彈/場景/音效,目前改進的空間還很大,日後會補上計分系統/吃彈藥包等等,大家可以參考這個雛型修改成自己想要的模樣,本篇blog有不足之處,日後補上,請注意引用本篇blog不必註明出處,但程式的部分是參考網路上的資料而修改的,請注意智慧財產權,

程式參考網站:
1.C++實務班(http://garfstudio.blogspot.tw/2015/12/cyoutube.html),
2.DirectX教學網站(http://www.rastertek.com/dx11tut14.html),

程式細節:
1.我機/敵機/子彈:這部分的程式是參考底下這個網站修改而成:
http://garfstudio.blogspot.tw/2015/12/cyoutube.html
這位作者(Gary Lin老師)在youtube有放上完整教學影片_C++程式設計:(https://www.youtube.com/channel/UC6kvAnrYEXwE4tVG8zOdWvw),
建議初學者請先完整看完全部29小時的課程(29部影片),所以這部分程式不多作解釋,

2.背景捲軸:原本從天文網站抓一張星象圖裁成800*600的24-bit BMP無縫圖,每次向上捲動幾個pixel,結果原先只有白背景+我機+敵機+子彈時的fps還有1k~2k,加上背景後只剩4,最後換另一種做法,將背景圖切成10x10的小矩形,由這些小矩形來構成背景圖,然後每次捲動一列,fps可提升到幾百,但目前暫時限制住fps為30左右,

3.音效:由C++實務班的youtube影片中得知簡單播放音樂的函數是playsound(),但無法同時播放兩種以上的音效(這叫混音),在第一個背景音樂(重複播放)播放時,又播放第二個音效檔,會導致第一個音效停止播放,微軟論壇有人問過這個問題:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/de87d08e-dab6-4b4e-948a-3ef4142b7e04/how-could-i-mutiple-sounds-with-playsound?forum=vclanguage,
有人提出Direct Sound(DirectX SDK的一部份)這組api可以做出"混音"效果,先抓微軟官網的DirectX SDK回來安裝,其實只要安裝include(標頭檔)跟Lib即可讓程式編譯,在網路上有找到教學網站(DirectX教學網站:http://www.rastertek.com/dx11tut14.html),拿範例程式(soundclass.h,soundclass.cpp)來改成同時播三個音效,這三個音效檔是windows作業系統內建的,DS1.wav當背景音樂所以設成重複播放,DS2.wav當發射子彈的音效,DS3.wav當子彈打到敵機的音效,

本篇blog附上範例程式的使用方式:
1.在任何一種版本的Visual Studio建立C++ win32專案,專案名稱打"JustShootIt",專案建立後再修改專案->屬性->不使用Unicode字集,專案->屬性->C/C++->先行編譯標頭檔->不使用先行編譯標頭檔,開啟JustShootIt.cpp,清光內容,

2.將範例程式解壓縮,除了JustShootIt.cpp以外,其他檔案都放到專案的那個目錄內,用記事本打開JustShootIt.cpp,全部複製貼到Visual Studio編輯視窗的JustShootIt.cpp裡頭,

3.依序為專案加入game.h,dsound.h,fps_time.h,key_state.h,map.h,soundclass.h,soundclass.cpp,

4.build->Run,

遊戲操作方式:
1.射擊子彈(滑鼠游標跟我機連成一線的方向就是子彈的射出方向):Shift鍵+Z,
2.上下左右方向鍵控制我機的移動方向,

遊戲畫面:

範例程式:
https://drive.google.com/file/d/0B6EVEd5P2B9cVDhIaGFqRVI3OUk/view?usp=sharing