《太空战机实验报告》由会员分享,可在线阅读,更多相关《太空战机实验报告(56页珍藏版)》请在人人文库网上搜索。
1、太空战机实验报告1.实验截图图一开始游戏图二我方战机,敌方战机出现。敌方战机随机发射子弹,并上下浮动 背景音乐响起。图三射杀战机,积分增加。敌机与子弹碰撞,消失。图四被敌机射杀,血量减少为 02. 游戏功能游戏规则1. 按下空格键游戏开始。2. 通过WSA键控制玩家飞机移动上下左右移动,但不能飞出边境。3. 当玩家按下空格键时,玩家飞机发射子弹。4. 玩家飞机被敌机碰到后,生命值会减少,生命值变为0的时候,游戏结束。5. 在游戏右方会一直出现电脑飞机(敌机),敌机分为超大、大、中、 小四种类型,越大的飞机出现的几率越小。6. 敌机被玩家飞机击中后,生命值会减少,生命值变为0时,该敌机被摧毁,玩。
2、家得分。越大的飞机越难击毁,击毁后玩家得分也 越多。7. 敌机飞到界面左方时,删除敌机。8. 敌方飞机的子弹分为两种,一种为普通子弹,另一种子弹为高级子弹,当敌方飞机的普通子弹与玩家飞机的子弹碰撞时相互抵消,敌方飞机的高级子弹不会与玩家飞机的子弹抵消9. 在界面外用一个文本显示玩家游戏得分。3. 流程图4. 数据结构创建5个继承类:我方战机类 CMyFighter、子弹类CBullet、 敌方战机类 CEnemyFighter类、链表类 CSpriteList、精灵 父类 CGameSprite。1.我方战机类CMyFighter:m_fVelocityLeft;/控制飞机飞行的速度上下左右。。
3、m_fVelocityRight;m_fVelocityUp;m_fVelocityDow n;m_bCa nFire;2.子弹类 CBullet:/表示判断是否开火m_iType;/表示该子弹是谁发射的变量3. 敌方战机类 CEnemyFighter:m_fCreateTime;/创建敌机的时间见隔mCreatedSpriteCou nt;/表 示创建战机数量m_fCa nFireAfterCreated;判断敌机创建后能否开火子弹发射时间间隔/战机飞行时上下浮动的时间间隔/战机飞行时是上浮还是下浮/一个精灵结构体SpriteStruct;m_fBulletCreateTime; m_fFl。
4、oatTime; m_bFloatUp;4. 链表类 CSpriteList:struct SpriteStructCSprite *pSprite;SpriteStruct *pNext;SpriteStruct *pPrev;/ 一个头节点指针/表示链表节点数的私有成员变量精灵指针/get方法SpriteStruct *m_pListHeader; int mListSize; CSprite*m_pSpriteList;5. 精灵父类 CGameSpritevirtualCGameSprite();6esse n.x 类:mGameState;初始化2游戏进行中./游戏状态0:结束或者等。
5、待开始1:CSprite* m_pGameBegi n; 游戏开始文字精灵 CMyFighter* m_pMyFighter;战机类指针float mCreatedSpriteCou nt;创造精灵数量CSpriteList m_SpriteList;/ 链表类精灵CSpriteList diji;II 链表类敌机CEffect* die_texiao;特效类精灵5.算法描述在外星球上,玩家通过键盘 WSAD键控制己方战机,通过空格 键发射子弹消灭外星球的邪恶战机。游戏状态 mGameState分为三种状态0, 1,2 ,其中0表示游 戏结束状态,1表示游戏初始化,2则表示游戏运行状态;01的。
6、转换为“空格开始”,初始化函数为Gamelnit函数;播放背景音乐。12的转换自然发生,即游戏初始化函数后会自动将游戏状态从1置为22表示游戏运行状态,在该状态,敲击空格发射子弹消灭敌机,消灭敌机分数增加,被敌机打中自身的血量减少。20的转换是游戏结束。CGameMain:CGameMain()构造函数完成初始化工作初始化状态为0设置开始按钮我方战机初始化为空创造精灵数量初始化为0CGameMain:GameMainLoop(float fDeltaTime )游戏的主循环,根据游戏的状态切换逻辑1、当当游戏状态为0时,主循环一直循环,但不做处理,而是等 待空格键按下,开始游戏。调用背景音乐。。
7、2、当游戏状态为1时,调用Gamelnit()方法初始化游戏,然后置 游戏状态为2。当游戏状态为2时,调用GameRun(fDeltaTime) 方法,在CGameMain类的GameRun方法中,遍历链接中的每 个节点,获得所有敌方战机的节点,让战机执行LoopTick方法, 实现战机发射子弹和上下浮动。3、游戏结束时会执行GameEnd且置状态为0CGameMain:Gamelnit()完成对各种精灵的初始化1. 播放放在bin中的游戏背景音乐。2初始化我方战机为战机类指针” Co ntrolSprite”设计我方战机的世界 边界限制。3初始化分数为0.4.初始化血量为100.CGameM。
8、ain:GameRun(floatfDeltaTime )对于游戏进行的设置1. 如果是我的战机,我方战机初始化2. 敌方战机引用函数 CEnemyFighter:ClassTick( fDeltaTime )进行 引用。3. 当游戏状态为2时,调用 GameRun(fDeltaTime)方法,在CGameMain类的GameRun方法中,遍历链接中的每个节点,获 得所有敌方战机的节点,让战机执行LoopTick方法,实现战机发射子弹和上下浮动。CGameMain:OnKeyDown(constintiKey,constboolbAltPress, constboolbShiftPress, 。
9、constboolbCtrlPress )游戏开始和控制按钮1、 如果空格按下时,游戏未开始,即游戏状态为 0,则将游戏状 态改为1,运行游戏初始化函数(GameInit)。隐藏文字精灵“开始游 戏”2、 如果游戏状态是2时,设置战机移动,调用函数 On Move3、如果空格按下时,战机为空。则调用函数SetCanFire按下空格 键即可发送子弹。void CGameMain:OnSpriteColSprite( const char *szSrcName, const char *szTarName )设置碰撞的发送方与接收方1调用匹配函数 cemcmp(szSrcName” ”trien(。
10、 “”=0),如果对象是子 弹则继续判断2. 假若是我方战机被子弹击中则血量减少 0.5.显示当前血量。3. 假如是对方战机被击中,则得分增加 10分,更新显示我方分数。void CMyFighter:OnMove(bool bKeyDown, int iKey)设置战机飞行速度编写CMyFighter类OnMove方法代码。首先判断当前按键是按下还是松开的,其次判断是哪个按键的消息,根据这两个判断,为4个方向的速度矢量赋值。再次算出 X后和丫轴上的速度,并设 置战机的速度。m_pMyFighter-SetSpriteWorldLimit(WORLD_LIMIT_STICKY,CSystem:。
11、GetScreenLeft()-10 f,CSystem:GetScreenT op(),CSystem:GetScreenRight() + 200f,)设置战机的世界边界其次在构造函数中将m_pMyFighter赋予NULL的初始值。再次在Gamelnit方法中初始化 m_pMyFighter。因为我们用new方法创建了 m_pMyFighter对象,分配了内存,所以我们在CGameMain类的析构 函数中需要调用delete方法将m_pMyFighter使用的内存释放掉。m_CurScoreText-SetTextValue(0);m_MaxScoreText-SetTextValue(。
12、0);/更新当前等级/HP显示在CGameMain类的GameInit方法中显示当前积分和最高积分void CMyFighter:LoopTick( float fDeltaTime )/处理子弹的发射CMyFighter添加m_fBulletCreateTime,表示子弹的发射间隔,注意在 构造函数中初始化为0.3。然后添加LoopTick方法,处理子弹的发射。 参数为游戏的时间间隔;void CGameMain:CreateBullet( const float fPosX, const float fPosY )CGameMain类中添加 mCreatedSpriteCount属性,表示。
13、游戏中发射子弹的数目注意在构造函数中初始化为 0。然后添加CreateBullet方 法,参数为子弹的X轴和丫轴坐标。并在该方法中创建一个子弹类, 并设置子弹的位置和速度。因为模板子弹的方向是朝左,所以需要设 置子弹按X轴对称旋转;lntiPosBase=CSystem:RandomRange(int)CSystem:GetSc reenTop()+10,(int)CSystem:GetScreenBottom() - 10);创建战机时,只需要战机不显示在世界边界之外就可以,即 Y轴坐 标在比世界边界的上下边界稍微大一点的范围之间, 在此我们设置比 世界边界大10个世界坐标单位。void C。
14、EnemyFighter:LoopTick( float fDeltaTime )在函数中添加代码,当表示战机创建之后,隔多久才可以开始发射子 弹的变量递减到小于等于0时,开始可以创建子弹,然后开始递减子 弹的发射间隔变量,当递减到小于等于 0时,战机发射子弹。if( m_bFloatUp ) 添加战机上下浮动的代码。当战机浮动时,首先累计浮动的时间,当 浮动时间大于1和小于0时,修改上浮还是下浮的变量值。然后获得 战机此时的丫轴坐标,我们设置上下浮动的速度为6,这样就可以计 算出浮动后的丫轴坐标。void CGameMain:CreateBullet( int iType, const fl。
15、oat fPosX, const float fPosY)为CBullet添加一个表示该子弹是谁发射的变量if( 1 =iType ) 如果iType值为1,则说明子弹为敌方战机反射SpriteStruct *CSpriteList:AddSprite( CSprite *pSprite )为链接类添加增加节点的方法 void CSpriteList:DeleteSprite( const char *szName, bool bDeletelmage )添加根据精灵名称删除其在链接中的节点的方法。其中第二个参数表 示是否将其在游戏中的精灵也删除。CSprite *CSpriteList:Ge。
16、tSprite( const int iIndex ) 添加获得链接中某个节点的方法。首先根据索引获得精灵。void CSpriteList:DeleteSprite( const char *szName, bool bDeletelmage ) 根据名字删除精灵boolvoid CSpriteList:DeleteSprite( CSprite *pSprite, bDeleteImage )根据精灵对象删除精灵源代码Lessenx hpublic:CGameMai n();/ 析构函数/ Get方法intGetGameState() return mGameState; / Set方法v。
17、oidSetGameState( const int iState ) mGameState = iState; /游戏主循环等voidGameMa in Loop( floatfDeltaTime );voidGameI nit();voidGameR un( float fDeltaTime );voidGameE nd();/事件函数void OnM ouseMove( co nst float fMouseX, con st float fMouseY );void OnMouseClick( const int iMouseType, const float fMouseX, con。
18、st float fMouse Y );void On KeyDow n( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress );void On KeyUp( const int iKey );void OnSpriteColSprite( const char *szSrcName, const char *szTarName );void OnSpriteColWorldLimit( const char *szName, const int iColSide );void。
19、 CreateBullet( int iType, const float fPosX, const float fPosY );void AddSprite( CSprite *pSprite );CSprite*GetSprite(c onstchar *szName)returnm_SpriteList.GetSprite(szName);voidDeleteSprite( CSprite *pSprite,boolbDeletelmage )m_SpriteList.DeleteSprite(pSprite,bDeletelmage);;/extern CGameMai n g_Gam。
20、eMa in;#en dif / _LESSON_X_H_三三三三三三三三三三三三三三三三三三三三三三三三三三一_ Fa)po_dx 山 AQd.No匸山 0 M UHOQXS一 p *40匸山 CWQ恤唳低国 注CX J.oosxelAL)七d52x J_o m UJLX j_ 00sxelAII6 *9一d52x J_o =-CX 一 8sno七d$2x _L0 m UJLX -8snol6 *9一d52x -L0oHqoOLHe 茎一ALT64SV pnOUS!:茎6匚Auju山。QpnOUSi:a=n89 pnousUXUOSS _! pnous=lnsn 七dso.Qpnous=lr。
21、sseoUOLULUO9 pnous 仝OP4SV pnou 丑 三三三三三三三三三三三三三三三三三三三三三三三三三三三= 三三三三三三三三三三三三三三三三三三三三三三三三三三三dch.xuessej/CGameMai ng_GameMa in;二=/大体的程序流程为:GameMainLoop函数为主循环函数,在引擎每 帧刷新屏幕图像之后,都会被调用一次。/=/构造函数CGameMai n:CGameMai n()mGameState= 0;m_pGameBegi n= new CSprite(GameBegi n);m_pMyFighter=NULL;mCreatedSpriteCo un 。
22、t=0;二=/析构函数CGameMai n:CGameMai n()delete m_pMyFighter;/=/游戏主循环,此函数将被不停的调用,引擎每刷新一次屏幕,此函 数即被调用一次/用以处理游戏的开始、进行中、结束等各种状态 ./函数参数fDeltaTime :上次调用本函数到此次调用本函数的时间 间隔,单位:秒void CGameMa in:GameMai nLoop( float fDeltaTime )switch( GetGameState()/初始化游戏,清空上一局相关数据case 1:Gamel nit();SetGameState(2); /初始化之后,将游戏状态设置为进。
23、行中break;/游戏进行中,处理各种游戏逻辑case 2:/ TODO修改此处游戏循环条件,完成正确游戏逻辑if( true )GameRu n( fDeltaTime );else /游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态SetGameState(O);GameE nd();break;/游戏结束/等待按空格键开始case 0:default:break;;二=/每局开始前进行初始化,清空上一局相关数据void CGameMai n:Game In it()PlaySou nd(yi nyue,O,SND_FILENAME|SND_AS YNC|SND_LOOP);m_pM。
24、yFighter=NULL;if( NULL = m_pMyFighter )m_pMyFighter-SetSpriteWorldLimit(WORLD_LIMIT_STICKY ,CSyste m:GetScree nLeft()-10.f,CSystem:GetScree nTop(),CSystem:GetScreen Right() + 200.f, CSystem:GetScree nBottom();g_CurScoreText-SetTextValue(100); g_MaxScoreText-SetTextValue(0);二=/每局游戏进行中void CGameMa in:。
25、GameR un( float fDeltaTime )if( m_pMyFighter )m_pMyFighter-LoopTick( fDeltaTime );CEn emyFighter:ClassTick( fDeltaTime );int iListSize = m_SpriteList.GetListSize();for( int iLoop = 0; iLoop LoopTick( fDeltaTime );二=/本局游戏结束void CGameMai n:GameE nd()void CGameMain:OnMouseMove( const float fMouseX, con。
26、st floatfMouseY ) fMouseX, const float fMouse Y )void CGameMain:OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )if( KEY_SPACE = iKey & 0 = mGameState )mGameState= 1;m_pGameBegi n-SetSpriteVisible(0);if( 2 = GetGameState() ) /当游戏状态为 2 时m_pMyFighter- OnM。
27、 ove(true,iKey);if( KEY_SPACE = iKey & NULL != m_pMyFighter ) m_pMyFighter-SetCa nFire(true );if( 2 = GetGameState()m_pMyFighter- OnM ove(false,iKey);if( KEY_SPACE = iKey & NULL != m_pMyFighter ) m_pMyFighter-SetCa nFire( false ); void CGameMain:OnSpriteColSprite( const char *szSrcName, const char *。
28、szTarName )/如果子弹if(memcmp(szSrcName,Bullet1_,strle n(Bullet1_)=0)if(memcmp(szTarName,C on trolSprite,strle n(Co ntrolSprite)=0)a=a-0.5;g_CurScoreText-SetTextValue(a);/CSprite *pSrcSprite =g_GameMai n. GetSprite( szSrcName );m_SpriteList.DeleteSprite(pSrcSprite,true);if(memcmp(szTarName,Horiz on t,st。
29、rle n(Horiz on t)=0)b=b+1O;g_MaxScoreText-SetTextValue(b);g_GameMai n.DeleteSprite(g_GameMai n.GetSprite(szTarName),true);void CGameMain:OnSpriteColWorldLimit( const char *szName, constint iColSide )fPosY )char szNameMAX_NAME_LEN;MAX_NAME_LE为CommonClass.h中宏定义 值为128spr intf( szName, Bullet1_%d, m_iCr。
30、eatedSpriteCou nt );mCreatedSpriteCo un t+;CBullet *pBullet = new CBullet( iType,szName);pBullet-Clo neSprite( Bullet1_Template); pBullet-SetSpritePositio n( fPosX, fPos Y );pBullet-SetSpriteL in earVelocityX( 60 ); pBullet-SetSpriteWorldLimit(WORLD_LIMIT_NULL,CSystem:GetSc reen Left()-10.f,CSystem:。
31、GetScree nTop(),CSystem:GetScree nRight() + 200.f, CSystem:GetScree nBottom();if( 1 = iType ) /如果iType值为1,则说明子弹为敌方战机 反射。pBullet-SetSpriteLi nearVelocityX( -30 );else/其他情况说明为我方战机反射pBullet-SetSpriteFlipX( true );float CEn emyFighter:m_fCreateTime = O.f;int CEn emyFighter:mCreatedSpriteCo unt = 0;void 。
32、CGameMai n:AddSprite( CSprite *pSprite )m_SpriteList.AddSprite( pSprite );Myfighter.h#ifndef _CMY FIGHT_H#defi ne _CMY FIGHT_H#i nclude com mon class.hclass CMyFighter :public CSpriteprivate:floatm_fVelocityLeft;/控制飞机的上下左右速floatm_fVelocityUp;floatm_fVelocityDow n;floatm_fBulletCreateTime;boolm_bCa n。
33、Fire;public:CMyFighter (const char* szName);CMyFighter(void);void OnM ove(bool bKeyDow n, i nt iKey);m_bCa nFire =void SetCa nFire( const bool bCa n )bCan; void CMyFighter:LoopTick( float fDeltaTime );#en difMyfighter.cpp#in clude .HeaderCMyFighter.h#in cludeLesso nX.h构造函数进行实现/控制飞机的上下左右速floatm_fVelo。
34、cityLeft;度floatm_fVelocityRight;floatm_fVelocityUp;floatm_fVelocityDow n;m_fVelocityLeft =0.f;m_fVelocityRight =0.f;m_fVelocityUp =0.f; m_fVelocityDow n 二 O.f; m_f BulletCreateTime=0.3f;void CMyFighter:O nM ove(bool bKeyDow n, i nt iKey) if(bKeyDow n)switch(iKey)case KEY_A: / 左break;case KEY_D: / 右 。
35、m_fVelocityRight =3O.f;break;case KEY_W: / 上 m_fVelocityUp = 15.f; break;case KEY_S: / 下 m_fVelocityDown 二 15.f; break;elseswitch(iKey)case KEY_A: / 左m_fVelocityLeft = 0.f; break;case KEY_D: / 右 m_fVelocityRight =0.f;break;case KEY_W: / 上m_fVelocityUp = O.f;break;case KEY_S: / 下m_fVelocityDown 二 O.f。
36、;break;float fVelX = m_fVelocityRight - m_fVelocityLeft;float fVelY = m_fVelocityDow n - m_fVelocityUp;SetSpriteL in earVelocity( fVelX,fVel Y );/处理子弹的发射void CMyFighter:LoopTick( float fDeltaTime )m_fBulletCreateTime -= fDeltaTime;if( m_f BulletCreateTime #i ncludeLesso nX.h CEn emyFighter:CE nemyFi。
37、ghter(c onst char* szName):CSprite(szName) m_fBulletCreateTime=0.3; m_fFloatTime=0.5; m_bFloatUp二true;CEn emyFighter:CE nemyFighter(void)void CEn emyFighter:ClassTick( float fDeltaTime ) / 创建敌方战机/是否到时间创建m_fCreateTime -= fDeltaTime;if( m_fCreateTime Clo neSprite( Horizo ntalSprite_Template );/ 克隆模板in。
38、t iRa ndom = CSystem:Ra ndomRa nge( iPosBase - 10, iPosBase + 10 );float fPosX = (in t)CSystem:GetScree nRight() + 20.f;pSprite-SetSpritePositio n( fPosX, (float)iRa ndom ); pSprite-SetSpriteL in earVelocityX( -10.f ); pSprite-SetSpriteWorldLimit(WORLD_LIMIT_NULL,CSystem:GetScree nLeft()-10.f,CSyste。
39、m:GetScree nTop(),CSystem:GetScree nRight() + 200.f, CSystem:GetScree nBottom();在以下添加创建一架敌方战机的代码void CEn emyFighter:LoopTick( float fDeltaTime )m_fCa nFireAfterCreated -= fDeltaTime;if( m_fCa nFireAfterCreated = 1.f )m_bFloatUp = false;float fPosY = GetSpritePositio nY(); fPos Y+= 6.f * fDeltaTime;S。
40、etSpritePositio nY( fPos Y );elsem_fFloatTime -= fDeltaTime;if( m_fFloatTime pSprite = pSprite;pPtr-pNext = NULL;pPtr-pPrev = NULL;/插入链表表尾if( NULL = m_pListHeader )m_pListHeader = pPtr;elseSpriteStruct *pTemp = m_pListHeader;while( NULL != pTemp-pNext )pTemp-pNextpPtr;mListSize+;retur n pPtr;void CS。
41、priteList:DeleteSprite( const char *szName, bool bDeletelmage )SpriteStruct *pPtr = NULL;for( pPtr = m_pListHeader; NULL != pPtr; pPtr = pPtr-pNext )if( strcmp( szName, pPtr-pSprite-GetName() ) = 0 )/将本指针从链表中取出(即将链表中的前后指针重新指定)/假设目前链表如下:有ABC三个值,A B C,需要删除B/则需要将A的Next指向C,C的Prev指向A,删除后结果为A CpPtr-pNext-。
42、pPrev = pPtr-pPrev;if( NULL != pPtr-pPrev )pPtr-pPrev-pNext = pPtr-pNext;/如果是表头if( pPtr = m_pListHeader )m_pListHeader = m_pListHeader-pNext;/ 删除 Spriteif( bDeletelmage )pPtr-pSprite-DeleteSprite();/释放内存delete pPtr;mListSize-;return;CSprite *CSpriteList:GetSprite( co nst int iln dex )intiLoop = 0;Sp。
43、riteStruct *pPtr = m_pListHeader;while( NULL != pPtr )if( iLoop = iln dex )return pPtr-pSprite;iLoop+;pPtr = pPtr-pNext;return NULL;CSprite*CSpriteList:GetSprite( const char *szName )SpriteStruct *pPtr = m_pListHeader;while( NULL != pPtr )if( strcmp( pPtr-pSprite-GetName(), szName ) = 0 )retur n pPt。
44、r-pSprite;retur n NULL;*pSprite, boolpPtr-pNext )void CSpriteList:DeleteSprite( CSprite bDeletelmage )SpriteStruct *pPtr = NULL;for( pPtr = m_pListHeader; NULL != pPtr; pPtrif( pPtr-pSprite = pSprite )if( NULL != pPtr-pNext )pPtr-pNext-pPrev = pPtr-pPrev;if( NULL != pPtr-pPrev )pPtr-pPrev-pNext = pP。
45、tr-pNext;if( pPtr = m_pListHeader )if( bDeletelmage )pPtr-pSprite-DeleteSprite();delete pPtr;mListSize-;return;void CSpriteList:DeleteAIISprite( bool bDeleteImage )SpriteStruct *pPtr= NULL;SpriteStruct *pPtrhNext= m_pListHeader;while( NULL != pPtrhNext )pPtr= pPtrhNext;pPtrhNext = pPtrhNext-pNext;if。
46、( bDeletelmage )pPtr-pSprite-DeleteSprite();delete pPtr;CGameSprite h#i nclude com mon class.hclass CGameSprite :public CSpriteprivate: public:CGameSprite(c on st char *szName);virtualCGameSprite();/get方法;CGameSprite .cpp#i nclude .HeaderCGameSprite.hCGameSprite:CGameSprite(c onst char* szName):CSpr。
47、ite(szName)CGameSprite:CGameSprite() Main .cpp/#i nclude Com mon Class.h#i nclude Lesso nX.h/主函数入口/int PASCAL WinM ai n(H INSTANCE hln sta nee,HINSTANCE hPrevI nsta nee,LPSTRIpCmdLi ne,intn CmdShow)/初始化游戏引擎if( !CSystem:l nitGameE ngi ne( hln sta nee, IpCmdL ine ) return 0;/ To do :在此使用API更改窗口标题CSystem:SetWi ndowTitle(Lesso nX);/引擎主循环,处理屏幕图像刷新等工作while( CSystem:E ngin eMai nLoop(。