Funcode坦克大战:10个核心功能模块的C++类设计解析与实现
Funcode坦克大战10个核心功能模块的C类设计解析与实现1. 游戏架构与类设计总览在Funcode坦克大战项目中面向对象设计是构建游戏逻辑的核心。我们通过抽象出关键游戏实体形成清晰的类层次结构classDiagram class CWeapon{ int m_iDir float m_fSpeedX, m_fSpeedY int m_iHp SetHp() GetHp() OnMove() OnSpriteColSprite() } class CBullet{ int m_iOwner OnMove(int iDir) SetOwner() } class CTank{ OnFire() trackMove() } class CTankPlayer{ int key OnMove(int iKey, bool bPress) } class CTankEnemy{ float m_fChangeDirTime OnMove(float fDeltaTime) } CWeapon |-- CBullet CWeapon |-- CTank CTank |-- CTankPlayer CTank |-- CTankEnemy核心基类CWeapon作为所有战斗单元的父类封装了以下通用属性运动方向(m_iDir)运动速度(m_fSpeedX/Y)生命值(m_iHp)碰撞检测接口(OnSpriteColSprite)2. 武器系统实现策略子弹系统采用继承与多态设计CBullet类通过重写基类方法实现特殊行为// 子弹运动方向控制 void CBullet::OnMove(int iDir) { SetDir(iDir); switch(GetDir()) { case 0: // 上 SetSpeedY(m_iOwner1 g_GameMain.speedStatus1 ? -20 : -10); break; case 1: // 右 SetSpeedX(m_iOwner1 g_GameMain.speedStatus1 ? 20 : 10); break; // 其他方向处理... } SetSpriteRotation(90*GetDir()); SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY()); }子弹类型转换通过tranFish()方法实现动态切换void CGameMain::tranFish() { fish !fish; // 切换子弹形态标志 // 实际渲染时根据fish值选择bullet或fishBullet精灵 }3. 敌方坦克AI设计敌方坦克通过状态机实现行为控制主要包含三种行为模式行为模式触发条件核心逻辑巡逻模式默认状态定时改变移动方向追踪模式trackStatus1计算玩家位置并追击静止模式changelessStatus1速度设为0追踪算法实现示例void CTankEnemy::trackMove() { float playerX g_GameMain.m_pTankPlayer-GetSpritePositionX(); float playerY g_GameMain.m_pTankPlayer-GetSpritePositionY(); if(GetSpritePositionX() playerX-2) { SetDir(1); // 右 SetSpeedX(8); } else if(GetSpritePositionX() playerX2) { SetDir(3); // 左 SetSpeedX(-8); } // 其他方向处理... }4. 特殊功能模块实现游戏包含10个可激活的特殊功能通过状态机模式管理void CGameMain::handle(int status) { switch(status) { case 0: transmit(); break; // 传送 case 1: invincible(); break; // 无敌 case 2: tranFish(); break; // 子弹变鱼 // 其他功能... } }典型功能实现细节无敌模式void CGameMain::invincible() { invincibleStatus !invincibleStatus; m_pTankPlayer-SetHp(invincibleStatus ? 10000 : 2); }穿墙功能void CTankPlayer::OnSpriteColSprite(CWeapon* pSprite) { if(g_GameMain.crossStatus1 strstr(pSprite-GetName(),wall)) { return; // 忽略墙体碰撞 } // 正常碰撞处理... }5. 对象管理系统优化游戏采用对象池模式管理所有战斗单元通过vectorCWeapon*实现// 添加子弹到对象池 void CGameMain::AddBullet(int iDir, float fPosX, float fPosY, int iOwner) { CBullet* pBullet new CBullet( CSystem::MakeSpriteName(bullet,m_iBulletNum)); pBullet-SetOwner(iOwner); m_vWeapon.push_back(pBullet); m_iBulletNum; } // 定时清理无效对象 void CGameMain::GameRun(float fDeltaTime) { for(auto itm_vWeapon.begin(); it!m_vWeapon.end(); ) { if((*it)-IsDead()) { DeleteWeaponByName((*it)-GetName()); it m_vWeapon.erase(it); } else { it; } } }6. 碰撞检测体系采用分层碰撞检测策略基础碰撞通过Funcode引擎的OnSpriteColSprite回调特殊处理友方子弹忽略基地碰撞敌方子弹忽略其他敌方坦克穿墙模式下的特殊穿透逻辑碰撞响应示例void CBullet::OnSpriteColSprite(CWeapon* pSprite) { if(GetOwner() 1 strstr(pSprite-GetName(),aim_nor)) return; // 友方子弹忽略基地 pSprite-SetHp(pSprite-GetHp()-2); // 造成伤害 if(strstr(pSprite-GetName(),enemy)) { pSprite-SetHp(0); // 秒杀敌方坦克 g_GameMain.m_iScore; // 计分 } SetHp(0); // 子弹消失 }7. 地图系统设计采用13x11的二维数组定义关卡布局int g_iMap[11][13] { {0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,0,1,0,1,1,1,1,0,0,1,0}, // 其他行数据... };地图加载时动态创建墙体对象void CGameMain::LoadMap() { for(int i0; i11; i) { for(int j0; j13; j) { if(g_iMap[i][j]1) { CWeapon* pWall new CWeapon( CSystem::MakeSpriteName(wall,ji*13)); pWall-SetSpritePosition(-244*j, -204*i); m_vWeapon.push_back(pWall); } } } }8. 游戏状态管理通过m_iGameState控制游戏流程void CGameMain::GameMainLoop(float fDeltaTime) { switch(m_iGameState) { case 1: GameInit(); break; // 初始化 case 2: GameRun(fDeltaTime); break; // 运行 case 0: GameEnd(); break; // 结束 } }关键游戏数据包括玩家分数m_iScore敌方坦克数量m_iEnemy游戏时间m_fDeltaTime9. 输入控制系统采用命令模式处理用户输入void CGameMain::OnKeyDown(int iKey, bool bAltPress, ...) { if(m_iGameState 2) { m_pTankPlayer-OnMove(iKey, true); if(iKey KEY_J) m_pTankPlayer-OnFire(); else if(iKeyKEY_0 iKeyKEY_9) chooseStatus iKey - KEY_0; else if(iKey KEY_K) handle(chooseStatus); } }控制映射表按键功能WASD移动控制J发射子弹0-9选择功能K执行功能10. 性能优化技巧对象池优化预生成子弹对象重用已销毁对象内存碰撞检测优化void CTankEnemy::OnSpriteColSprite(CWeapon* pSprite) { if(strstr(pSprite-GetName(),enemy)) return; // 仅处理非同类碰撞 }渲染优化不可见对象跳过渲染使用精灵批处理通过这10个模块的系统化设计Funcode坦克大战实现了代码复用率高、扩展性强的游戏架构。每个功能模块保持独立性的同时通过基类接口实现高效交互为后续功能扩展奠定了良好基础。