c语言课程设计坦克大战,funcodec++课程设计_坦克大战
《funcodec++課程設計_坦克大戰》由會員分享,可在線閱讀,更多相關《funcodec++課程設計_坦克大戰(24頁珍藏版)》請在人人文庫網上搜索。
1、課程設計一 坦克大戰一、游戲介紹相信大部分同學都玩過或看過“坦克大戰”這款經典游戲。現在, 就由我們自己動手來開發它。只要大家具備了 C+語言和面向對象的基礎知識,然后按照實驗指南的指導一步一 步進行下去,相信我們每個同學都能把這款經典游戲做出來。、實驗目標綜合運用C+及其面向對象的知識開發一款小游戲。三、實驗內容在一個戰場上, 玩家控制坦克, 消滅敵方坦克,并防止敵方坦克摧毀我方基地。游戲的 具體要求如下:1、游戲有一個初始頁面,如下圖。2、按下任意鍵開始游戲,玩家控制坦克在戰場上穿梭,碰到墻時,不能通過。3、敵方坦克自由移動,每隔 2 秒改變一個方向,每隔 3 秒發射一發子彈。4、敵方坦克。
2、每隔 5 秒出現一輛,從屏幕上方的左、中、右三個位置依次出現。5、 當玩家被消滅或者我方基地被摧毀或者游戲時間大于30 秒的時候,游戲結束。游戲開始前進入游戲四、游戲的整體框架五、實驗指南實驗準備打開Fun Code,創建一個新的 C+項目。注意:項目名稱必須為英文和數字,且不能有 空格。點擊“項目”7“導入地圖模板”,從對話框中選取名稱為Ta nkWar的模板導入。導入成功后,界面如下:實驗一游戲開始【實驗內容】1、設置游戲標題2、按空格鍵,提示圖片消失,游戲進入開始狀態【實驗運行結果】游戲開始前按下空格鍵后【實驗思路】按下空格鍵是鍵盤按下事件,可在CSystem:OnKeyDown函數中編。
3、寫響應代碼。 為了保證程序結構的清晰、一致,更好的辦法是在CGameMair類中添加一個相應的鍵盤按下事件處理 函數,然后在 CSystem:O nM ouseClick函數中進行調用。g_GameMain是CGameMair類的對象,它是全局變量,在程序運行時最先被創建。【實驗指導】1、 C+程序的執行入口是主函數。FunCode的主函數名稱叫WinMain,寫在文件中。CSystem:SetWi ndowTitle是設置程序運行窗口標題的函數,修改如下:CSystem:SetWindowTitle(坦克大戰”);2、參考 CSystem:OnKeyDown 函數,為 CGameMain類創。
4、建一個 OnKeyDown函數。CGameMain類的頭文件是文件,實現代碼寫在文件中。因此,先在文件對函數進行 聲明。函數的返回值和參數列表都與CSystem:OnKeyDown函數保持一致。訪問權限應該是public。代碼如下:void On KeyDow n( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress );3、接著,在文件中對該函數進行定義:void CGameMa in :0 nKeyDow n( const int iKey, const bool bAltP。
5、ress, const bool bShiftPress, const bool bCtrlPress )4、 在 CSystem:OnKeyDown函數(文件中)調用CGameMain:OnKeyDown函數,并將自己的參數傳遞給該函數。g_GameMain是是CGameMair類的對象,它是全局變量,在 程序運行時最先被創建。因此,我們可以用g_GameMain調用自己的成員函數OnKeyDown(iKey, bAltPress, bShiftPress, bCtrlPress);5、Fu nCode程序運行時,當發生鍵盤按下事件,程序首先調用并執行CSystem:OnKeyDown 函數。
6、,然后由 CSystem:OnKeyDown 函數調用 并執行 CGameMain:OnKeyDown函數。因此,鍵盤按下事件的響應代碼我們在 CGameMai n:O nKeyDown函數中編寫即可。6、 我們要處理的兩個精靈如下圖,它們的名稱分別是splash和start。我們需要創建兩個CSprite類對象與這兩個精靈綁定。7、在CGameMair類中聲明兩個 CSprite*類型,根據面向對象的封裝性原理,成員變量的訪問權限應該是 private。代碼應該寫在哪個文件,請參看前面的實驗步驟。CSprite* m_pSplash;CSprite* m_pStart;在CGameMair類。
7、的構造函數中,對上面兩個指針變量進行初始化。通過調用CSprite 的構造函數,將精靈和精力對象綁定在一起。m_pSplash= new CSprite(splash);m_pStart= new CSprite(start);8、最后,我們在 CGameMai n: :O nKeyDown函數中處理空格鍵按下事件。if( 0 =GetGameState()if(iKey =KEY_SPACE)mi_iGameState = 1;KEY_SPAC是枚舉變量 KeyCodes的成員,表示空格鍵。 KeyCodes定義在文件中。 該枚舉變量定義了全部的鍵盤值。注意:必須將 m_iGameState。
8、的值改為1。當GameMainLoop函數再次執行時,根據mGameState的值調用并執行Gamelnit函數, 游戲進入開始狀態。進入游戲開始狀態時,調用CSprite類的SetSpriteVisible 函數將精靈圖片設置為不可見。在Gamelnit函數中添加代碼:m_pSplash-SetSpriteVisible(false); m_pStart-SetSpriteVisible(false);9、程序執行完 CGameMain:Gamelnit 函數后,執行 CGameMain: SetGameState(2),將mGameState的值改為2,游戲進入運行狀態。10、 在CGam。
9、eMain類的析構函數中delete本實驗創建的指針對象,以釋放分配的內存。CGameMain:CGameMain()delete m_pSplash;delete m_pStart;11、編譯并運行程序,然后按下空格鍵,看看運行效果。實驗二 坦克運動【實驗內容】1、創建坦克類 CTankPlayer ;2、游戲開始時,將坦克放置于 (0,0) 的坐標上;3、通過按鍵WSAD控制坦克上下左右運動;4、坦克運行到黑色區域邊界時不能繼續前進。實驗運行結果】在區域內運動運動到區域邊界【實驗思路】 坦克也是精靈, 但是它具備一些自己獨特的功能, 比如通過鍵盤控制運動、 開炮等。因 此我們可以創建一個新。
10、的類 CTankPlayer 類,并讓它繼承 CSprite 類。通過WASD鍵,控制坦克做相應的的上左下右運動。按下某個鍵,給坦克設置相應方向 的運動速度;松開時,將該方向的速度設為0,表示停止運動。屏幕上最內部的黑色區域為玩家坦克的活動區域,左上角坐標為(-26,-22) ,右下角坐標為 (26,22) 。當坦克運動到該區域邊界時,坦克不能繼續前進。【實驗指導】1、通過類向導創建 CTankPlayer 類,其繼承于 CSprite 類。以 VC+ 為例: 第一步、點擊菜單“插入” - “新建類”。第二步、在“ New Class ”對話框中輸入類名和父類名。第三步、點擊Change”按鈕。
11、,在新對話框中修改 CTankPlayer類的頭文件和 cpp 文件的路徑。將頭文件保存到項目文件夾的 SourceCodeHeader 文件夾中,將 cpp 文件保 存到項目文件夾下的 SourceCodeSrc 文件夾中。這里需要特別注意的是創建文件路徑的問題,所有的 .h 頭文件應該在項目文件夾 SourceCodeHeader 中 , 所 有 的 .cpp 源 文 件 應 該 放 在 項 目 文 件 夾 下 的 SourceCodeSrc 文件夾中。2、為 CTankPlayer 類添加 m_iDir,m_fSpeedX,m_fSpeedY , m_iHp 四個成員變量(成員 變量。用。
12、來表示坦克在 X軸和Y軸方向上的速度以及運行的方向,并且在構造函數中 初始化為 0。這里規定, m_iDir 的值為 0、 1、 2、 3,分別表示上、右、下、左。成員函數的聲明和定義如何添加,訪問權限是什么,可參考實驗一,下文不再繼續 提示),分別表示運動方向、X軸、Y軸速度以及血量值。本文檔的命名采用匈牙利 命名法,m_表示類成員變量,i表示整型,f表示float型,sz表示字符指針,g_ 表示全局變量等。同時需要在public權限下定義獲取和設置這些變量的Get和Set方法:/set方法void SetHp(i nt hp)mHp = hp;void SetDir(i nt dir)m_。
13、iDir = dir;void SetSpeedX(float speedX) m_fSpeedX = speedX;void SetSpeedY(float speedY) m_fSpeedY = speedY;/get方法int GetHp()return mHp;int GetDir()return m_iDir;float GetSpeedX()return m_fSpeedX;float GetSpeedY()return m_fSpeedY;3、 CTa nkPlayer的父類是CSprite類(具體聲明查看),構造函數為CSprite( con st char *szName )。
14、。4、 所以通過上邊方法自動生成的類,如果系統自動生成構造函數CTa nkPlayer(void),刪除掉它以及在中自動生成的對構造函數實現的代碼:CTa nkPlayer:CTa nkPlayer(void) 再為 CTankPlayer 類添加新的構造函數:CTankPlayer(const char* szName) 。CTa nkPlayer:CTa nkPlayer(c on st char* szName):CSprite(szName) /對構造函數進行實現mDir=0;m_fSpeedX=;m_fSpeedY=;mHp=2;|子類對象創建時,要先調用父類的構造函數完成父類部分的。
15、構造。如果父類沒有默 認構造函數,子類的構造函數必須顯示調用父類的構造函數。CTankPlayer構造函數調用CSprite類構造函數,并將參數szName的值傳遞給它,從而將名稱為szName 的精靈圖片與CTankPlayer對象綁定起來。5、為CTa nkPlayer類添加In it函數,該函數主要用來完成該類的初始化工作。這里,先調用setHp方法設置血量。然后調用父類的SetSpritePosition 函數將坦克精靈設置在屏幕中央(0,0)處。接下來給坦克精靈設置時間邊界的大小,與世界邊界的碰撞模式為WORLD_LIMIT_NULL表示精靈與世界邊界碰撞的響應由代碼完成,同時設置坦。
16、克碰撞模式為發送碰撞和接收碰撞。void CTa nkPlayer:l ni t()SetHp(2);SetSpritePositio n,;SetSpriteWorldLimit(WORLD_LIMIT_NULL, -26, -22, 26, 22);SetSpriteCollisio nActive(1,1);設置為可以接受和發生碰撞SetSpriteVisible(true);6、在CGameMain類中增加一個私有成員變量m_pTankplayer,類型為 CTankPlayer* 。注意在添加頭文件:#i nclude7、按下空格鍵后,程序會調用鍵盤按下事件響應函數,將mGameSt。
17、ate的值改為1,游戲進入開始狀態(見實驗一)。程序再次執行 CGameMai n:GameMai nLoop函數時, 根據mGameState的值調用并執行 CGameMain:Gamelnit函數。因此,可以在該 函數中創建我方坦克,并調用CTankPlayer:Init函數來完成該類對象的初始化工作。m_pTa nkPlayer =new CTan kPlayer(myplayer);新建一個名字是myPlayer的我方坦克對象m_pTa nkPlayer-Clo neSprite(player);我方坦克克隆在 fun code模板中存在的名字為player的坦克,表示新建的坦克對象有。
18、現在精靈的所有屬性m_pTa nkPlayer-l nit();8、 接下來,我們為CTankPlayer類添加On Move函數,參數iKey、bPress分別表示按下的是哪個按鍵和按鍵是否按下。首先聲明該函數,訪問權限為public :void OnMove(int iKey, bool bPress);9、接著,完成 OnMove方法。void CTa nkPlayer:O nMove(i nt iKey, bool bPress)if(bPress)switch (iKey)case KEY_WSetDir(O);SetSpeedX(O);SetSpeedY(-8);break;cas。
19、e KEY_D:SetDir(1);SetSpeedX(8);SetSpeedY(0);break;case KEY_S:SetDir(2);SetSpeedX(O);SetSpeedY(8); break; | case KEY_A:SetDir(3);SetSpeedX(-8);SetSpeedY(O); break;轉度數SetSpriteLi nearVelocity(GetSpeedX(),GetSpeedY();else |if(iKey = KEY_W | iKey = KEY_D | iKey = KEY_S | iKey = KEY_A)SetSpeedX(O);SetSpe。
20、edY(O);SetSpriteLi nearVelocity(GetSpeedX(),GetSpeedY();|用參數bPress來判斷鍵盤是按下還是彈起。如果bPress為false ,表示鍵盤彈起,且彈起的鍵是 WAS鍵時,設置坦克的X軸和Y軸移動速度都為0。如果bPress為true,表示鍵盤按下,根據按下的鍵,為mDir,m_fSpeedX,m_fSpeedY 賦予相應的值。SetSpriteRotation 和SetSpriteLinearVelocity函數用來設置精靈的角度和線性速度,具體含義參考文件。10、 在CGameMair類的OnKeyDown函數中,通過調用 CTan。
21、kPlayer類的OnMove方法, 根據按下的鍵,控制坦克朝指定方向運動。只有游戲進入開始狀態,按鍵才有效。注意:On Move參數bPress的值為true。在On KeyDown數中添加代碼如下: if(mGameState = 2)m pTankPlayer-OnMove(iKey, true);11、 編譯并運行程序。按空格鍵開始,按WASDt,坦克會向規定的方向運動。但是松 開按鍵后,坦克繼續前進,不會停止下來。12、 參考CSystem:OnKeyUp函數,給 CGameMair類聲明并定義一個OnKeyUp函數,用來處理按鍵彈起事件,然后在CSystem:OnKeyUp函數中調。
22、用它。關于這個函數如何聲明、定義以及調用參考實驗一。13、在 CGameMain:OnKeyUp函數中調用 CTankPlayer 的 OnMove方法,參數 bPress 的 值為false 。void CGameMain:OnKeyUp(const int iKey)if(m iGameState = 2)m pTankPlayer-OnMove(iKey, false);14、 編譯并運行程序,按下WASDt,坦克運行;松開按鍵,坦克停止。接下來,我們 來實現坦克運行到黑色區域邊界停止運動的效果。15、 參考 CSystem:OnSpriteColWorldLimit函數,給 CGame。
23、Main類聲明并定義一個On SpriteColWorldLimit函數,用來處理精靈與世界邊界的碰撞事件,然后在CSystem: O nSpriteColWorldLimit函數中調用它。關于這個函數如何聲明、定義以及調用參考實驗一。16、當坦克精靈碰到邊界時,將精靈的速度都設為0,精靈停止運動。用字符串處理函數 strstr() 來判斷碰到世界邊界的精靈是否為我方坦克。當碰到世界邊界的精靈名字中含有” player ”的時候,strstr 會返回一個非空值。因此代碼 如下:void CGameMai n:O nSpriteColWorldLimit(const char *szName, 。
24、con st int iColSide )if(strstr(szName,player)!= NULL) /判斷碰到世界邊界的坦克是否為我方坦克|m_pTa nkPlayer-SetSpriteLi nearVelocity(0,0);|實驗三坦克開炮【實驗內容】1、創建子彈類CBullet ;2、通過按鍵J控制坦克開炮;【實驗運行結果】【實驗思路】創建子彈類,該類應具備子彈的運動方向、起始位置、X軸速度、Y軸速度等屬性,其中運動方向和起始位置由坦克的方向和位置決定。通過按鍵控制坦克發射子彈,因此在CGameMair類的OnKeyDowr方法中實現該需求。此 時我們為CTan kPlayer。
25、類添加發射子彈的方法On Fire。當按下J鍵后,坦克發射子彈,在OnFire方法中,我們需要告訴子彈的方向和初始位置。而創建子彈我們由CGameMain類來完成。這樣減少了類之間的耦合。【實驗指導】1、 通過類向導創建 CBullet類,其繼承于 CSprite類,具體做法參考實驗一;2、 為 CBullet 類添加 mDir,m_fSpeedX,m_fSpeedY,mHp ,m_iOwner 五個成員,分別 表示方向、X軸、Y軸速度、子彈血量以及發射子彈歸屬坦克,0表示地方坦克,1表示我方坦克,并參考實驗二添加變量的get和set方法。3、為CTankPlayer類添加構造函數和析構函數。。
26、參照實驗二,把構造函數中將所有變量進行初始化。4、為CBullet類添加On Move方法,參數為iDir表示子彈的運動方向。5、 完成OnMove方法。根據方向 mDir,首先設置 m_fSpeedX,m_fSpeedY的值,然后設置根據方向設置旋轉角度,最后設置子彈的運動速度。void CBullet:OnMove(int iDir) SetDir(iDir);switch(GetDir()case 0:SetSpeedX(0);SetSpeedY(-10);break;case 1:SetSpeedX(10);SetSpeedY(0);break;case 2:SetSpeedX(0);。
27、SetSpeedY(IO); break;case 3:SetSpeedX(-IO); SetSpeedY(O);break;SetSpriteRotatio n( 90*GetDir();SetSpriteLi nearVelocity(GetSpeedX(),GetSpeedY();6、在CGameMair類中添加表示子彈數目的成員變量mBulletNum(注意初始化為0)。然后添加 AddBullet方法。方法中有iDir、fPosX、fPosY、iOwner四個參數分別 表示子彈方向、子彈初始位置的X軸Y軸坐標以及子彈所屬坦克。由于地圖上只有一個子彈模板,所以我們需要先復制這個模板,然。
28、后設置該精靈的世界邊界。void CGameMain:AddBullet( int iDir,float fPosX,float fPosY ,int iOwner)char* szName = CSystem:MakeSpriteName(bullet,mBulletNum);/創建坦克名字CBullet* pBullet = new CBullet(szName);pBullet-Clo neSprite(bullet);pBullet-SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26, -22, 26, 22); /設置世界邊界pBullet-SetSpr。
29、itePositio n( fPosX,fPosY);pBullet-SetSpriteCollisio nSe nd(true); /設置接收碰撞pBullet- OnM ove(iDir);mBulletNum+; /子彈個數加1if(iOw ner = 1)pBullet-SetOw ner(1);/1表示我方坦克發射的子彈 else |pBullet-SetOw ner(0); 0表示地方坦克發射的子彈7、為CTankPlayer類增加OnFire方法,實現發射子彈的功能。在根據坦克的運動狀態, 得到子彈的相關屬性后,通過AddBullet方法在游戲中增加一發子彈。void CTa n。
30、kPlayer:O nF ire()float x,y;x = GetSpritePositio nX();y = GetSpritePositio nY();switch(GetDir()case 0:y=y-GetSpriteHeight()/2-1;break;case 1:x=x+GetSpriteWidth()/2+1;break;case 2:y=y+GetSpriteHeight()/2+1;break; case 3:x=x-GetSpriteWidth()/2-1;break;(GetDir(),x,y,1);因為用到g_GameMain這個全局對象,所以需要在中聲明頭文件:。
31、#include ”8、按 J 鍵發射子彈。在 CGameMair類的 OnKeyDown函數 if(m_iGameState = 2) 下添 加if(iKey = KEY_J)判斷按下鍵是夠為J鍵m_pTa nkPlayer-OnFire();實驗四敵方坦克【實驗內容】1、創建 CTankEnemy類;2、創建一個敵方坦克實例,實現坦克從上方左中右三個位置隨機出現。3、實現坦克隔2秒,隨機改變一個方向。4、實現坦克隔5秒發射一發子彈;5、當坦克與世界邊界碰撞時,改變方向;【實驗運行結果】【實驗思路】同我方坦克一樣,敵方坦克運動,也需要有運動方向、X軸Y軸速度三個基本屬性。為了實現坦克能自由運。
32、動,即坦克運動一段時間后改變方向, 需增加一個改變方向的時間間隔。 同時為了實現坦克自動發射子彈,需增加一個發射子彈的時間間隔。然后為敵方坦克增加移動和發射子彈的方法。最后我們在CGameMain類的GameRur方法中調用敵方坦克移動和發射子彈的方法。【實驗指導】1、通過類向導創建 CTa nkEn emy類;2、 為類 CTankEnemy添加 mDir,m_fSpeedX,m_fSpeedY,mHp 四個成員,分別表示方向、X軸、Y軸速度和血量;3、參照前面的實驗,為 CTa nkE nemy類添加構造函數和析構函數。4、 為類CTa nkEn emy添加In it方法初始化敵方坦克。設。
33、置血量為2,位置坐標為上方 左中右的隨機位置,然后函數中給坦克精靈設置時間邊界的大小,與世界邊界的碰撞模式為WORLD_LIMIT_NULL表示精靈與世界邊界碰撞的響應由代碼完成。最后設置方向和速度代碼如下:int iPos = CSystem:Ra ndomRa nge(0,2);float fPosX;SetDir(2);SetHp(2);switch (iPos)case 0:SetSpritePositio n( fPosX,;SetSpriteL in earVelocity,;SetSpriteCollisi on Active(1,1); II設置可以接受和發送碰撞SetSpri。
34、teRotatio n(float(90*GetDir();SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26, -22, 26, 22);5、為類CTankEnemy添加OnMove方法,實現坦克順時針旋轉90度運動。然后根據方向設置子彈的運動速度m_fSpeedX,m_fSpeedY的值。與CTankPlayer類的OnMove方法類似。設置速度方向與原來方向旋轉90度的代碼如下:int iDir=0;if(GetDir()=0 | GetDir()=1 | GetDir()=2)iDir = GetDir()+1;Else /如果方向值等于3,設為0通過方向。
35、設置速度參考前邊實驗。6、為類CTankEnemy添加帶參的 OnMove方法,參數fDeltaTime,為游戲的時間差,實現隔一段時間隨機改變方向。在CTa nkEn emy類中添加成員變量m_fCha ngeDirTime在構造函數中初始化為0,并添加get和set方法。void CTa nkEn emy:O nM ove(float fDeltaTime)m_fCha ngeDirTime+=fDeltaTime;if(m_fCha ngeDirTime _OnM ove(); m_fCha ngeDirTime =; 一|7、 為類CTa nkEn emy添加On Fire方法,參數也。
36、為fDeltaTime,實現隔一段時間自動發 射子彈。在CTankEnemy類中添加成員 m_fBulletCreateTime變量并在構造函數中 初始化為0。void CTa nkE nemy:O nFire(float fDeltaTime)m fBulletCreateTime+=fDeltaTime;if(m_fBulletCreateTimem fBulletCreateTime =;float x,y;x = GetSpritePositio nX(); y = GetSpritePositio nY(); switch(GetDir()case 0:y=y-GetSpriteHe。
37、ight()/2-1;break;case 1:x=x+GetSpriteWidth()/2+1;break;case 2:y=y+GetSpriteHeight()/2+1; |break;case 3:x=x-GetSpriteWidth()/2-1;break;(GetDir(),x,y,O);因為用到全局對象 G_GameMain所以需要在中聲明頭文件:#i nclude8、 在CGameMair類中添加 CTankEnemy類指針變量 m_pTankEnemy注意在中聲明頭文件:#i nclude然后在Game In it中創建并初始化。m pTa nkEn emy = new CT。
38、a nkEn emy(e nemy);m_pTa nkEn emy-I nit();9、在CGameMair類的GameRun方法中實現敵方坦克自由移動和發射子彈。void CGameMai n:GameRu n( float fDeltaTime )if(m_pTa nkEn emy)m pTa nkEn emy- OnMo ve(fDeltaTime);m_pTa nkEn emy- On Fire(fDeltaTime);10、 在CGameMair類的OnSpriteColWorldLimit方法中添加敵方坦克與世界邊界碰撞的 檢測。if(m_pTa nkEnemy&strcmp(m_。
39、pTa nkEn emy-GetName(),szName)=0)m_pTa nkEn emy-OnMove();實驗五加載地圖【實驗內容】1、加載游戲地圖;【實驗運行結果】【實驗思路】在CGameMain類中添加方法 LoadMap實現地圖加載。地圖數據是已知的,數據中的0表示此處為空;1表示的是地圖中此處為墻;2表示此處為玩家指揮部。每塊墻大小為 4*4。【實驗指導】0表示沒有墻塊,1表示1、首先在中定義一個表示地圖的二維數組來表示地圖,其中有墻塊:in t g_i Map1113=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,。
40、1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0, 0,0,0,0,0,1,0,1,0,0,0,0,0;2、在CGameMair類中添加LoadMap方法,實現加載地圖。在方法中用 for循環遍歷地圖二維數組,當二維數組中的某個值為1時表。
41、示該處是一堵墻。void CGameMai n:LoadMap()char* szName;int i,j;float x,y;for(i=0;iClo neSprite(wall); /克隆墻塊pWall-SetSpriteCollisionActive(0,1); /設置為接受碰撞pWall-SetSpriteCollisio nRespo nse(COL_RESPONSE_CUSTOM);x =float(-24+4*j);y =float(-20+4*i); pWall-SetSpritePositio n(x,y);|3、在Gamelnit中調用加載地圖的函數:LoadMap();實。
42、驗六創建父類-CWeapon類【實驗內容】1、添加 CWeapor類,使 CBullet、CTankPlayer、CTankEnemy類繼承 CWeapor類。2、 將三個子類OnFire和On Move方法中相同的功能抽取出來,在父類中創建相應方法。子類調用父類方法進行改進。3、創建一個容器,用來存放所有精靈。【實驗運行結果】【實驗思路】1、CBullet、CTankPlayer、CTankEnemy類中有許多共同的屬性和方法,或者為了方便管 理,我們添加父類 CWeapon2、把所有創建的精靈存入到容器中,增加從容器中查找和刪除精靈的函數。在此基礎上,對整個項目進行大改。注意此步驟對于下方。
43、實驗非常重要,需要理解繼承的用法,根據自己的理解把該刪除和更改的地方做好。此實驗會創建一個包含內容為CWeap on*的容器,把創建的我方坦克,敵方坦克,墻塊,子彈,全部存入到這個容器中進行管理。【實驗指導】1、通過類向導添加 CWeapor類,其繼承于 CSprite類。2、 根據分析為CWeapon類添加表示方向、血量、X軸Y軸速度、四個變量。int mDir;int mHp;float m_fSpeedX;float m_fSpeedY;添加get和set方法;3、 仿照前面的實驗添加構造函數,在構造函數中對這些數值初始化,其中mHp初始化為2,其他初始化為0;4、添加函數以及虛函數:b。
44、ool IsDead(); /判斷精靈是否死亡_|virtual void In it(); /初始化函數virtual void OnM ove(float fDeltaTime); /敵方坦克移動函數virtual void On Move();virtual void OnF ire(float deltaTime); /發射子彈函數virtual void On SpriteColSprite(CWeapo n* pSprite); /精靈與精靈碰撞時處理函數在CWeapon類中實現lsDead()函數,此函數的作用是判斷精靈是否死亡,在游戲 運行時,會根據這個函數的返回值來確定是否此。
45、精靈:boolCWeapo n:lsDead()if(mHp = 0)return true;return false;5、 將 CBullet、CTankPlayer、CTankEnemy類的父類改為 CWeapon例如在中把 class CTankPlayer :public CSprite 改為 class CTankPlayer :public CWeapon注意需要、包含頭文件:#i nclude6、 注意同時修改構造函數。把繼承類的名稱由 CSprite改為Cweapon刪除與CWeapon定義重復的變量聲明,原來的get和set方法,以及在構造函數中對這些變量賦初值的代碼。特別主。
46、要要設置Hp=27、 在CGameMair類中添加一個成員變量m_vWeapon用來存儲所有精靈:vectorvCWeap on* m_vWeap on;注意用到容器,添加頭文件聲明和命名空間:#in cludeusing n amespace std;8、然后聲明和定義查找和刪除容器成員的兩個函數Fin dWeapo nByName和DeleteWeapo nByNameCWeapo n* CGameMa in:Fi ndWeapo nByName(c on st char* szName)/根據名字查找到對象for(int i=0; iGetName() = 0)retur n m_vWe。
47、ap on i;|void CGameMa in:DeleteWeapo nByName(c onst char* szName)/根據名字把精靈從容器中刪除for(vector:iterator it=();it!=();)CWeap on* cw =*it; if(strcmp(szName,cw-GetName() = 0)I(it);cw-DeleteSprite();delete cw;break;elseit+;9、在前邊創建子彈、我方坦克、以及地圖的地方用()函數把精靈添加到容器中。1) 我方精靈添加容器中方法為,在Gamel ni t()函數中創建我方坦克的代碼:m_pTa n。
48、kPlayer =new CTan kPlayer(myplayer);m_pTa nkPlayer-Clo neSprite(player);m_pTa nkPlayer-In it();下邊添加如下代碼:(m_pTa nkPlayer);2) 子彈添加到容器,在 AddBullet函數最后添加一行代碼:(pBullet);3) 地圖添加容器,在LoadMap()函數中,把 CSprite* pWall = new CSprite(szName); 改為:CWeapo n* pWall = new CWeap on (szName);然后在 pWall-SetSpritePositio n(。
49、x,y);下添加:(pWall);實驗七游戲整體正常運行【實驗內容】1、 創建敵方坦克每隔5秒出現一輛,從屏幕上方的左、中、右三個位置隨機出現。2、當子彈與游戲中的任何東西碰撞時,雙方都消失;3、當我方坦克與敵方坦克碰撞時,我方坦克靜止不動,敵方坦克改變方向;4、當我方坦克被消滅或者我方軍營被擊中時,游戲結束。【實驗運行結果】【實驗思路】3、創建一個函數生成坦克的函數產生坦克。4、 在 OnSpriteColSprite方法中添加碰撞檢測。5、 更改在OnSpriteColWorldLimit中與世界邊界的碰撞檢測。【實驗指導】1、注釋掉實驗四中,在 CGameMai類中添加的聲明和創建一個敵。
50、方坦克對象的代碼。 中:/CTankEn emy* m_pTa nkEn emy; 在文件Gamelnit函數:m_pTa nkEn emy = new CTankEn emy(e nemy);m_pTankEn emy-l nit();同時注釋在 GameRuni數中添加的使敵方坦克運動的代碼。/*if(m_pTa nkEn emy)m_pTa nkEn emy- OnMo ve(fDeltaTime); m_pTa nkEn emy- On Fire(fDeltaTime);*/2、在CGameMai中創建一個不斷產生地方坦克的函數AddTankEnemy先在 CGameMai中添加一個成。
51、員變量 m_fTankEnemyTime和 m_iTankEnemyNumber分別代表創建坦克時間,以及坦克數量(注意將兩數進行初始化)。當時間m_fTankEnemyTime 大于5時,創建敵方坦克,設置屬性,并進行調用初始化函數in it來設置敵方坦克的初始位置以及碰撞模式等內容。voidCGameMai n:AddTa nkE nemy(float fDeltaTime)m fTa nkEn emyTime += fDeltaTime;if(m_fTa nkEn emyTime 5) char* szName = CSystem:MakeSpriteName(e nemy,m_iTa 。
52、nkEn emyNumber);CTankEn emy* m_pTa nkEn emy = new CTa nkEn emy(szName);m pTa nkEn emy-Clo neSprite(e nemy);m_pTa nkEn emy-I nit(); m_iTa nkEn emyNumber+;(m pTa nkEn emy); /把創建的敵方坦克插入到容器中m fTa nkEn emyTime=;在CGameMain類的GameRun函數中調用增加敵方坦克的函數:AddTa nkE nemy(fDeltaTime);此時運行游戲可以看到,每五秒有一輛敵方坦克從下方隨機生成并向下運動。
53、。3、在GameRun中添加代碼遍歷容器,調用精靈移動以及發射函數(子彈和墻沒有對這兩個 函數進行實現,因此不會產生效果),把已死亡的精靈進行刪除,使游戲運行正常。for(int i=0;ilsDead()m vWeapo ni- OnM ove(fDeltaTime); m_vWeapo ni-O nF ire(fDeltaTime);elseDeleteWeapo nByName(m vWeapo ni-GetName();4、更改精靈世界邊界碰撞時間函數中的代碼,更改判斷敵方坦克與世界邊界碰撞和子彈與 世界邊界碰撞的代碼:else if(strstr(szName,e nemy) != 。
54、NULL) CWeap on* pEn emy = Fi ndWeap on ByName(szName); pEn emy-SetSpriteLi nearVelocity,;pEn emy- OnM ove();else if(strstr(szName,bullet) != NULL)CWeapo n* pBullet = Fin dWeapo nByName(szName); pBullet-SetHp(O);5、在CGameMain中添加對 CWeapon *類型對象 m_pAim_nor表示我方軍營在GameInit中創建我方軍營精靈,把軍營精靈插入到容器中,設置接收碰撞以及坐標。。
55、m_pAim_nor = new CWeap on (myaim _n or);m_pAim_n or-Clo neSprite(aim _n or);(m_pAim _no r);m pAim n or-SetSpriteCollisi on Receive(true);m_pAim_n or-SetSpritePositi on,;6、在CTankPlayer類中添加我方坦克與其他精靈碰撞的處理函數,使我方坦克碰到子彈后,血量設為0,碰到墻后,設置速度為0:void CTa nkPlayer:O nSpriteColSprite(CWeapo n* pSprite)if(pSprite =。
56、 NULL)return;else if(strstr(pSprite-GetName(),bullet) != NULL)SetHp(0);else if(strstr(pSprite-GetName(),wall) != NULL)SetSpeedX(O);SetSpeedY(O);7、在SetSpriteLi nearVelocity(GetSpeedX(),GetSpeedY();CBullet類中添加子彈與其他精靈碰撞后的判斷代碼,判斷子彈與其他精靈碰撞發生的反應,當我方子彈與軍營發生碰撞,地方坦克發射的子彈與敵方坦克發送碰撞時,只 設置子彈血量為0,其他不做處理。其他情況,設置被碰。
57、撞精靈血量為0:void CBullet:OnSpriteColSprite(CWeapon* pSprite)if(pSprite = NULL)return;SetHp(O);if(GetOw ner() = 1 & strstr(pSprite-GetName(),aim _n or) != NULL) /我方坦克子彈與軍營發生碰撞return;if(GetOw ner() = 0 & strstr(pSprite-GetName(),e nemy) != NULL) /敵方坦克子彈打中地方坦克return;pSprite-SetHp(0);8、 在CTankEnemy類中添加地方坦克與。
58、其他精靈碰撞的處理函數,設置速度為0,并設置轉換方向的時間 m_fChangeDirTime為,在 CGameMair類GameRur函數中,當m_fChangeDirTime2時,敵方坦克轉向。所以在秒之后,這個坦克會自動轉向。void CTa nkE nemy:O nSpriteColSprite(CWeapo n* pSprite)if(pSprite = NULL)return;SetSpriteLi nearVelocity,;m_fCha ngeDirTime =;9、 在CGameMain中添加事件函數 OnSpriteColSprite,表示精靈與精靈碰撞事件。然后OnSpriteColSprite中添加碰撞檢測。進行的檢測順序是,首先判斷發送碰撞方為誰,然后調用發送碰撞對象的碰撞處理函數,代碼如下:voidCGameMai n:O nSpriteColSprite(c on st char *szSrcName, const char *szTarName)CWeapo n* tarSprite = Fin dWeap on ByName(szTarName); if(strstr(szSrcName,bullet) != NULL)。
總結
以上是生活随笔為你收集整理的c语言课程设计坦克大战,funcodec++课程设计_坦克大战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 天猫188积分兑换520消费券可以一次性
- 下一篇: html抽取正文内容 c++,如何用C/