Funcode实现坦克大战(十个需求)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Funcode实现坦克大战(十个需求)相关的知识,希望对你有一定的参考价值。


 【写在前言】

        1、操作 先按数字 表示选择某一需求(对应文件的需求) 再按K 表示执行该需求

        2、写此文为方便大家的学习,希望不要一抄了事,真心希望!!!

        3、文章中设计到方法的多态,有些需求需要重写方法

        4、复制的时候,CSDN自动少了一些/,编译着删去就行,不是问题


2022年5月27日补充:有人反映有问题,我自己重新试了一遍,可以运行。至于错误的原因,应该是.h文件放错了地方。新建的.h文件要放在Header文件里面去,不会的可以看我上一篇文章,【致敬童年】Funcode实现坦克大战,只需要看一下怎么把文件放到Header文件里即可,继承什么的不用关注。

一、需求展示

1、传送

Funcode实现坦克大战(十个需求)_Funcode

Funcode实现坦克大战(十个需求)_游戏_02

编辑

2、无敌

Funcode实现坦克大战(十个需求)_游戏_03

Funcode实现坦克大战(十个需求)_Funcode_04

编辑

3、子弹变成鱼

Funcode实现坦克大战(十个需求)_Funcode_05

Funcode实现坦克大战(十个需求)_Funcode_06

编辑

4、穿墙

Funcode实现坦克大战(十个需求)_Funcode_07

Funcode实现坦克大战(十个需求)_Funcode_08

编辑

5、加固老巢

Funcode实现坦克大战(十个需求)_游戏_09

Funcode实现坦克大战(十个需求)_Funcode_10

编辑

6、敌方坦克静止

Funcode实现坦克大战(十个需求)_Funcode_11

Funcode实现坦克大战(十个需求)_游戏_12

编辑

7、敌方坦克全部死亡

Funcode实现坦克大战(十个需求)_Funcode_13

Funcode实现坦克大战(十个需求)_游戏_14

编辑

8、 坦克复制

Funcode实现坦克大战(十个需求)_游戏_15

Funcode实现坦克大战(十个需求)_游戏_16

编辑

 9、敌方坦克追踪

Funcode实现坦克大战(十个需求)_游戏_17

Funcode实现坦克大战(十个需求)_Funcode_18

编辑

10、加速

Funcode实现坦克大战(十个需求)_游戏_19

Funcode实现坦克大战(十个需求)_Funcode_20

编辑

 二、设置

随便找到一个鱼,碰撞体改的紧密一些,防止子弹把自己打死

Funcode实现坦克大战(十个需求)_Funcode_21

Funcode实现坦克大战(十个需求)_游戏_22

编辑

 属性设置

Funcode实现坦克大战(十个需求)_Funcode_23

Funcode实现坦克大战(十个需求)_游戏_24

编辑

 三、代码

CBullet.h

#ifndef CBULLET_H
#define CBULLET_H

#include <CommonClass.h>
#include "CWeapon.h"

class CBullet : public CWeapon

public:
CBullet();
CBullet(const char* szName);
// 分别表示方向、X轴、Y轴速度、子弹血量以及发射子弹归属坦克,0表示地方坦克,1表示我方坦克
int m_iDir;
float m_fSpeedX,m_fSpeedY;
int m_iHp;
int m_iOwner;
virtual void OnMove(int iDir);
//set方法
void SetDir(int Dir);
void SetOwner(int Owner);
void SetHp(int Hp);
void SetSpeedX(float SpeedX);
void SetSpeedY(float SpeedY);
//get方法
int GetDir();
int GetOwner();
int GetHp();
float GetSpeedX();
float GetSpeedY();
//初始化方法
virtual void Init();
virtual void OnMove(int iKey, bool bPress);
void OnSpriteColSprite(CWeapon* pSprite);

virtual ~CBullet();

protected:

private:
;

#endif // CBULLET_H

Funcode实现坦克大战(十个需求)_游戏_25

CBullet.cpp

#include "CBullet.h"
#include <iostream>
using namespace std;
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
#include <LessonX.h>
CBullet::CBullet(const char* szName):CWeapon(szName) //对构造函数进行实现

m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;

m_iOwner = 0;


void CBullet::OnMove(int iDir)

SetDir(iDir);
switch(GetDir())

case 0:
if(m_iOwner==1&&g_GameMain.speedStatus==1)

SetSpeedX(0);
SetSpeedY(-20);

else
SetSpeedX(0);
SetSpeedY(-10);


break;
case 1:
if(m_iOwner==1&&g_GameMain.speedStatus==1)

SetSpeedX(20);
SetSpeedY(0);
else
SetSpeedX(10);
SetSpeedY(0);


break;
case 2:
if(m_iOwner==1&&g_GameMain.speedStatus==1)

SetSpeedX(0);
SetSpeedY(20);
else
SetSpeedX(0);
SetSpeedY(10);


break;
case 3:
if(m_iOwner==1&&g_GameMain.speedStatus==1)

SetSpeedX(-20);
SetSpeedY(0);
else
SetSpeedX(-10);
SetSpeedY(0);


break;

SetSpriteRotation(90*GetDir());
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

void CBullet::SetDir(int Dir)

m_iDir = Dir;


void CBullet::SetOwner(int Owner)

m_iOwner = Owner;


void CBullet::SetHp(int Hp)

m_iHp = Hp;


void CBullet::SetSpeedX(float SpeedX)


m_fSpeedX = SpeedX;

void CBullet::SetSpeedY(float SpeedY)


m_fSpeedY = SpeedY;

//get方法
int CBullet::GetDir()

return m_iDir;


int CBullet::GetOwner()


return m_iOwner;

int CBullet::GetHp()


return m_iHp;

float CBullet::GetSpeedX()

return m_fSpeedX;


float CBullet::GetSpeedY()

return m_fSpeedY;


void CBullet::Init()



void CBullet::OnMove(int iKey, bool bPress)



void CBullet::OnSpriteColSprite(CWeapon* pSprite)

if(pSprite == NULL)

return;


if(GetOwner() == 1 && strstr(pSprite->GetName(),"aim_nor") != NULL) //我方坦克子弹与军营发生碰撞



return;

if(GetOwner() == 0 && strstr(pSprite->GetName(),"enemy") != NULL) //敌方坦克子弹打中地方坦克


return;

if(strstr(pSprite->GetName(),"wall")==NULL)

// mciSendString(TEXT("open D:\\\\图片\\\\坦克大战素材\\\\boom.wav alias Mysong"), NULL, 0,NULL);
//
// mciSendString(TEXT("play MySong"), NULL, 0, NULL);
PlaySound("D:\\\\C++\\\\TankWar - 副本\\\\paoji.wav",NULL,SND_FILENAME|SND_ASYNC );


// cout<<pSprite->GetName()<<"的HP:"<<pSprite->GetHp()<<endl;
pSprite->SetHp(pSprite->GetHp()-2);
if(strstr(pSprite->GetName(),"enemy")!=NULL)

pSprite->SetHp(0);

SetHp(0.f);


Funcode实现坦克大战(十个需求)_Funcode_26

CTankEnemy.h

#ifndef CTANKENEMY_H
#define CTANKENEMY_H
#include <CommonClass.h>
#include "CWeapon.h"

class CTankEnemy : public CWeapon

public:
CTankEnemy(const char* szName);
CTankEnemy();
int m_iDir;
int iDir;
float m_fSpeedX;
float m_fSpeedY;
float m_fChangeDirTime;
float m_fBulletCreateTime;
int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
void SetChangeDirTime(float ChangeDirTime);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
float GetChangeDirTime();
void OnFire(float fDeltaTime);
//初始化方法
void Init();
void OnMove();
//处理世界边界的碰撞
void OnMove(int dir);
void OnMove(float fDeltaTime);
void OnSpriteColSprite();
void OnSpriteColSprite(CWeapon* pSprite);
//追踪
void trackMove();
virtual ~CTankEnemy();

protected:

private:
;

#endif // CTANKENEMY_H

Funcode实现坦克大战(十个需求)_游戏_27

CTankEnemy.cpp

#include "CTankEnemy.h"
#include "LessonX.h"
#include <iostream>
using namespace std;
CTankEnemy::CTankEnemy(const char* szName):CWeapon(szName)
//对构造函数进行实现

iDir = 0;
m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;
m_fBulletCreateTime = 0.f;
m_fChangeDirTime = 0.f;


CTankEnemy::~CTankEnemy()

//dtor

void CTankEnemy::SetHp(int hp)m_iHp = hp;
void CTankEnemy::SetDir(int dir)m_iDir = dir;
void CTankEnemy::SetSpeedX(float speedX)m_fSpeedX = speedX;
void CTankEnemy::SetSpeedY(float speedY)m_fSpeedY = speedY;
void CTankEnemy::SetChangeDirTime(float ChangeDirTime)m_fChangeDirTime = ChangeDirTime;
//get方法
int CTankEnemy::GetHp()return m_iHp;
int CTankEnemy::GetDir()return m_iDir;
float CTankEnemy::GetSpeedX()return m_fSpeedX;
float CTankEnemy::GetSpeedY()return m_fSpeedY;
float CTankEnemy::GetChangeDirTime()return m_fChangeDirTime;
void CTankEnemy::Init()

int iPos = CSystem::RandomRange(0,2);
float fPosX;
SetDir(2);
SetHp(2);
switch (iPos)

case 0:
fPosX = -24.f;
break;
case 1:
fPosX = 0.f ;
break;
case 2:
fPosX = 24.f;
break;
default:
break;

SetSpritePosition(fPosX,-20.f);
SetSpriteLinearVelocity(0.f,8.f);
SetSpriteCollisionActive(1,1); //设置可以接受和发送碰撞
SetSpriteRotation(float(90*GetDir()));
SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26, -22, 26, 22);


void CTankEnemy::OnMove()




switch (iDir)

case 0://上

SetSpeedX(0);
SetSpeedY(-8);
break;
case 1://右

SetSpeedX(8);
SetSpeedY(0);
break;
case 2://下

SetSpeedX(0);
SetSpeedY(8);
break;
case 3://左

SetSpeedX(-8);
SetSpeedY(0);
break;


SetDir(iDir);
SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());
if(GetDir()==0 || GetDir()==1 || GetDir()==2)

iDir = GetDir()+1;

else //如果方向值等于3,设为0

iDir = 0;


void CTankEnemy::trackMove()

int Dir = 0;
if(GetSpritePositionX()<g_GameMain.m_pTankPlayer->GetSpritePositionX()-2)

SetSpeedX(8);
SetSpeedY(0);
Dir = 1;
SetDir(Dir);
else if(GetSpritePositionX()>g_GameMain.m_pTankPlayer->GetSpritePositionX()+2)
SetSpeedX(-8);
SetSpeedY(0);
Dir = 3;
SetDir(Dir);

else if(GetSpritePositionY()<g_GameMain.m_pTankPlayer->GetSpritePositionY()-2)

SetSpeedX(0);
SetSpeedY(8);
Dir = 2;
SetDir(Dir);


else if(GetSpritePositionY()>g_GameMain.m_pTankPlayer->GetSpritePositionY()+2)
SetSpeedX(0);
SetSpeedY(-8);
Dir = 0;
SetDir(Dir);

SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

void CTankEnemy::OnMove(float fDeltaTime)

m_fChangeDirTime+=fDeltaTime;
if(m_fChangeDirTime>2.0f)

OnMove();
m_fChangeDirTime = 0.f;


void CTankEnemy::OnMove(int dir)

if(dir==0)

SetDir(2);
SetSpeedX(0);
SetSpeedY(8);
else if(dir==1)

SetDir(3);
SetSpeedX(-8);
SetSpeedY(0);
else if(dir==2)

SetDir(0);
SetSpeedX(0);
SetSpeedY(-8);
else
SetDir(1);
SetSpeedX(8);
SetSpeedY(0);

SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

void CTankEnemy::OnFire(float fDeltaTime)



m_fBulletCreateTime+=fDeltaTime;
if(m_fBulletCreateTime>3.0f)

//cout<<"地方发射子弹了"<<endl;
m_fBulletCreateTime = 0.0f;
float x,y;
x = GetSpritePositionX();
y = GetSpritePositionY();
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;

g_GameMain.AddBullet(GetDir(),x,y,0);


void CTankEnemy::OnSpriteColSprite(CWeapon* pSprite)

if(pSprite == NULL)

return;


if(strstr(pSprite->GetName(),"enemy")!=NULL)return;
if(strstr(pSprite->GetName(),"wall")!=NULL)

SetSpriteLinearVelocity(0.f,0.f);
m_fChangeDirTime = 3.8;


SetSpriteLinearVelocity(0.f,0.f);
m_fChangeDirTime = 3.8;

void CTankEnemy::OnSpriteColSprite()

if(g_GameMain.destroyStatus==1)



// PlaySound("D:\\\\C++\\\\TankWar - 副本\\\\paoji.wav",NULL,SND_FILENAME|SND_ASYNC );



SetSpriteLinearVelocity(0.f,0.f);

Funcode实现坦克大战(十个需求)_游戏_28

CTankFriend.h

#ifndef CTANKFRIEND_H
#define CTANKFRIEND_H

#include <CWeapon.h>


class CTankFriend : public CWeapon

public:

CTankFriend();
CTankFriend(const char* szName);
int m_iDir;
float m_fSpeedX;
float m_fSpeedY;

int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
void Init();
void OnMove();
// 开火,发射子弹
void OnFire();
void OnSpriteColSprite(CWeapon* pSprite);
virtual ~CTankFriend();

protected:

private:
;

#endif // CTANKFRIEND_H

Funcode实现坦克大战(十个需求)_Funcode_29

CTankFriend.cpp

#include "CTankFriend.h"
#include <LessonX.h>
CTankFriend::CTankFriend(const char* szName):CWeapon(szName)

//ctor


CTankFriend::~CTankFriend()

//dtor

void CTankFriend::SetHp(int hp)
m_iHp = hp;


void CTankFriend::SetDir(int dir)m_iDir = dir;
void CTankFriend::SetSpeedX(float speedX)m_fSpeedX = speedX;
void CTankFriend::SetSpeedY(float speedY)m_fSpeedY = speedY;
//get方法
int CTankFriend::GetHp()return m_iHp;
int CTankFriend::GetDir()return m_iDir;
float CTankFriend::GetSpeedX()return m_fSpeedX;
float CTankFriend::GetSpeedY()return m_fSpeedY;
void CTankFriend::Init()

SetHp(2);
SetSpritePosition(-26+1.7,22-1.7);
SetSpriteWorldLimit(WORLD_LIMIT_NULL, -26, -22, 26, 22);
SetSpriteCollisionActive(1,1);//设置为可以接受和发生碰撞
SetSpriteVisible(true);


void CTankFriend::OnMove()


float x = g_GameMain.m_pTankPlayer->GetSpeedX();
float y = g_GameMain.m_pTankPlayer->GetSpeedY();
switch (g_GameMain.m_pTankPlayer->key)

case KEY_W:
SetDir(2);
SetSpeedX(x);
SetSpeedY(-y);
break;
case KEY_D:
SetDir(3);
SetSpeedX(-x);
SetSpeedY(y);
break;
case KEY_S:
SetDir(0);
SetSpeedX(x);
SetSpeedY(-y);
break;
case KEY_A:
SetDir(1);
SetSpeedX(-x);
SetSpeedY(y);
break;

SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());



void CTankFriend::OnFire()

float x,y;
x = GetSpritePositionX();
y = GetSpritePositionY();
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;

g_GameMain.AddBullet(GetDir(),x,y,1);

void CTankFriend::OnSpriteColSprite(CWeapon* pSprite)

if(pSprite == NULL)

return;

else if(strstr(pSprite->GetName(),"bullet") != NULL)

SetHp(0);

else if(strstr(pSprite->GetName(),"wall") != NULL)

if(g_GameMain.crossStatus==1)

return;

SetSpeedX(0);
SetSpeedY(0);
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

Funcode实现坦克大战(十个需求)_游戏_30

CTankPlayer.h

#ifndef CTANKPLAYER_H
#define CTANKPLAYER_H
#include <CommonClass.h>
#include "CWeapon.h"


class CTankPlayer : public CWeapon

public:
CTankPlayer();
CTankPlayer(const char* szName);
int m_iDir;
float m_fSpeedX;
float m_fSpeedY;
int key;
int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
//初始化方法
void Init();
void OnMove(int iKey, bool bPress);
// 开火,发射子弹
void OnFire();
void OnSpriteColSprite(CWeapon* pSprite);
virtual ~CTankPlayer();


protected:

private:
;

#endif // CTANKPLAYER_H

Funcode实现坦克大战(十个需求)_Funcode_31

CTankPlayer.cpp

#include "CTankPlayer.h"
#include "LessonX.h"
#include <iostream>
using namespace std;
CTankPlayer::CTankPlayer(const char* szName):CWeapon(szName) //对构造函数进行实现

m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;

CTankPlayer::~CTankPlayer()

//dtor

void CTankPlayer::SetHp(int hp)
m_iHp = hp;
// cout<<"我的血量变成了"<<m_iHp<<endl;

void CTankPlayer::SetDir(int dir)m_iDir = dir;
void CTankPlayer::SetSpeedX(float speedX)m_fSpeedX = speedX;
void CTankPlayer::SetSpeedY(float speedY)m_fSpeedY = speedY;
//get方法
int CTankPlayer::GetHp()return m_iHp;
int CTankPlayer::GetDir()return m_iDir;
float CTankPlayer::GetSpeedX()return m_fSpeedX;
float CTankPlayer::GetSpeedY()return m_fSpeedY;

void CTankPlayer::Init()

SetHp(2);
SetSpritePosition(0.f,0.f);
SetSpriteWorldLimit(WORLD_LIMIT_NULL, -26, -22, 26, 22);
SetSpriteCollisionActive(1,1);//设置为可以接受和发生碰撞
SetSpriteVisible(true);

void CTankPlayer::OnMove(int iKey, bool bPress)

key = iKey;
if(bPress)

switch (iKey)

case KEY_W:
SetDir(0);
if(g_GameMain.speedStatus==1)

SetSpeedX(0);
SetSpeedY(-16);
else
SetSpeedX(0);
SetSpeedY(-8);


break;
case KEY_D:
SetDir(1);
if(g_GameMain.speedStatus==1)

SetSpeedX(16);
SetSpeedY(0);
else
SetSpeedX(8);
SetSpeedY(0);


break;
case KEY_S:
SetDir(2);
if(g_GameMain.speedStatus==1)

SetSpeedX(0);
SetSpeedY(16);
else

SetSpeedX(0);
SetSpeedY(8);

break;
case KEY_A:
SetDir(3);
if(g_GameMain.speedStatus==1)

SetSpeedX(-16);
SetSpeedY(0);
else
SetSpeedX(-8);
SetSpeedY(0);


break;

SetSpriteRotation(float(90*GetDir())); //用方向值乘于90得到精灵旋转度数
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

else

if(iKey == KEY_W || iKey == KEY_D || iKey == KEY_S || iKey == KEY_A)

SetSpeedX(0);
SetSpeedY(0);
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());



void CTankPlayer::OnFire()

float x,y;
x = GetSpritePositionX();
y = GetSpritePositionY();
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;

g_GameMain.AddBullet(GetDir(),x,y,1);

void CTankPlayer::OnSpriteColSprite(CWeapon* pSprite)

if(pSprite == NULL)

return;

else if(strstr(pSprite->GetName(),"bullet") != NULL)

SetHp(0);

else if(strstr(pSprite->GetName(),"wall") != NULL)

if(g_GameMain.crossStatus==1)

return;

SetSpeedX(0);
SetSpeedY(0);
SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

Funcode实现坦克大战(十个需求)_游戏_32

CWeapon.h

#ifndef CWEAPON_H
#define CWEAPON_H

#include <CommonClass.h>


class CWeapon : public CSprite

public:
CWeapon();
CWeapon( const char *szName );
CWeapon( const char *szName, const char *szCloneName );
// CWeapon(const char* szName);
int m_iDir;
float m_fSpeedX;
float m_fSpeedY;
int m_iHp;
//set方法
void SetHp(int hp);
void SetDir(int dir);
void SetSpeedX(float speedX);
void SetSpeedY(float speedY);
//get方法
int GetHp();
int GetDir();
float GetSpeedX();
float GetSpeedY();
bool IsDead(); //判断精灵是否死亡
virtual void Init(); //初始化函数
virtual void OnMove(float fDeltaTime); //敌方坦克移动函数
virtual void OnMove();
virtual void trackMove();
virtual void OnFire(float deltaTime); //发射子弹函数
virtual void OnSpriteColSprite(CWeapon* pSprite); //精灵与精灵碰撞时处理函数
virtual void OnSpriteColSprite();
virtual ~CWeapon();


protected:

private:
;

#endif // CWEAPON_H

Funcode实现坦克大战(十个需求)_Funcode_33

CWeapon.cpp

#include "Cweapon.h"

CWeapon::CWeapon( const char *szName ):CSprite(szName) //对构造函数进行实现

m_iDir=0;
m_fSpeedX=0.f;
m_fSpeedY=0.f;
m_iHp=2;


CWeapon::~CWeapon()

//dtor

void CWeapon::SetHp(int hp)m_iHp = hp;
void CWeapon::SetDir(int dir)m_iDir = dir;
void CWeapon::SetSpeedX(float speedX)m_fSpeedX = speedX;
void CWeapon::SetSpeedY(float speedY)m_fSpeedY = speedY;
//get方法
int CWeapon::GetHp()return m_iHp;
int CWeapon::GetDir()return m_iDir;
float CWeapon::GetSpeedX()return m_fSpeedX;
float CWeapon::GetSpeedY()return m_fSpeedY;
bool CWeapon::IsDead()

if(m_iHp == 0)

return true;

return false;

Funcode实现坦克大战(十个需求)_Funcode_34

LessonX.h

/////////////////////////////////////////////////////////////////////////////////
//
//
//
//
/////////////////////////////////////////////////////////////////////////////////
#ifndef _LESSON_X_H_
#define _LESSON_X_H_
//
#include <Windows.h>
//在此类中增加该头文件
#include <CTankPlayer.h>
#include "CBullet.h"
#include "CTankEnemy.h"
#include <CTankFriend.h>
#include<vector>
using namespace std;

/////////////////////////////////////////////////////////////////////////////////
//
// 游戏总管类。负责处理游戏主循环、游戏初始化、结束等工作
class CGameMain

private:
int m_iGameState; // 游戏状态,0:结束或者等待开始;1:初始化;2:游戏进行中
CSprite* m_pSplash; //标题
CSprite* m_pStart;//按任意键开始

//子弹的数量
int m_iBulletNum;
// CTankEnemy* m_pTankEnemy;
void LoadMap();
vector<CWeapon*> m_vWeapon;
float m_fTankEnemyTime;
int m_iTankEnemyNumber;
CWeapon* m_pAim_nor;
CTextSprite* m_pScore; //表示分数的文本精灵
CTextSprite* m_pHight; //表示最高分的文本精灵
CTextSprite* m_pEnemy;//表示敌人数量的文本精灵
int m_iScore;//分数
int m_iEnemy;//敌人数量
int m_iHight;//几局最高分
float m_fDeltaTime;//表示游戏时间
int chooseStatus;//0~9分别代表9个需求
CTankFriend *m_friend_Tank;


public:
CGameMain(); //构造函数
//增加一个私有成员变量
CTankPlayer* m_pTankPlayer;
//添加子弹方法
void AddBullet( int iDir,float fPosX,float fPosY ,int iOwner);
CWeapon* FindWeaponByName(const char* szName);//根据名字查找到对象
void DeleteWeaponByName(const char* szName);
void AddTankEnemy(float fDeltaTime);
void DeleteAllSprite();
void handle(int status);
//传送函数
void transmit();
//无敌函数
int invincibleStatus;//无敌状态
void invincible();
//炮弹变成鱼
int fish;
void tranFish();
int crossStatus;
void crossWall();
//加固老巢
int strengtheningStatus;
void strengthening();
int changelessStatus;

void changeless();
//地方坦克全部被摧毁
int destroyStatus;
void destroy();
//复制一个我方坦克
int copyTankStatus;

void copyTank();
//加速
int speedStatus;
void speedTank();
//追踪
int trackStatus;
void trackTank();

~CGameMain(); //析构函数

// Get方法
int GetGameState() return m_iGameState;

// Set方法
void SetGameState( const int iState ) m_iGameState = iState;

// 游戏主循环等
void GameMainLoop( float fDeltaTime );
void GameInit();
void GameRun( float fDeltaTime );
void GameEnd();
void OnMouseMove( const float fMouseX, const float fMouseY );
void OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY );
void OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY );
void OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress );
void OnKeyUp( const int iKey );
void OnSpriteColSprite( const char *szSrcName, const char *szTarName );
void OnSpriteColWorldLimit( const char *szName, const int iColSide );
;

/////////////////////////////////////////////////////////////////////////////////
//
extern CGameMain g_GameMain;

#endif // _LESSON_X_H_

Funcode实现坦克大战(十个需求)_Funcode_35

LessonX.cpp

/////////////////////////////////////////////////////////////////////////////////
//
//
//
//
/////////////////////////////////////////////////////////////////////////////////
#include <Stdio.h>
#include "CommonClass.h"
#include "LessonX.h"
#include <iostream>
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
//mciSendString(TEXT("open D:\\C++\\TankWar - 副本\\background.wav"),NULL,NULL, NULL); //打开音乐文件
//
//mciSendString(TEXT("play D:\\C++\\TankWar - 副本\\background.wav"),NULL,NULL,NULL); //播放音乐文件
//
//mciSendString(TEXT("D:\\C++\\TankWar - 副本\\background.wav"),NULL,NULL, NULL); //关闭音乐


using namespace std;
////////////////////////////////////////////////////////////////////////////////
//
//
CGameMain g_GameMain;
//地图初始化,1代表砖块
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,
0,1,0,1,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,1,1,1,1,0,0,0,0,
0,1,0,1,0,0,0,0,0,0,0,1,0,
0,1,0,1,0,1,1,1,1,0,0,1,0,
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,
0,1,0,1,0,0,0,0,0,0,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
;
// int g_iMap[11][13]=
//
// 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,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
// ;
//==============================================================================
//
// 大体的程序流程为:GameMainLoop函数为主循环函数,在引擎每帧刷新屏幕图像之后,都会被调用一次。

//==============================================================================
//
// 构造函数
CGameMain::CGameMain()

m_iGameState = 0;
m_iBulletNum = 0;
m_pSplash = new CSprite("splash");//与精灵进行绑定
m_pStart = new CSprite("start");
m_pScore = new CTextSprite("score");
m_pHight = new CTextSprite("hight");
m_pEnemy = new CTextSprite("enemyNum");
m_iScore=0;//分数
m_iEnemy=0;//敌人数量
m_iHight = 0;
m_fDeltaTime = 0.f;


//==============================================================================
//
// 析构函数
CGameMain::~CGameMain()

//析构函数中删除两个精灵
delete m_pSplash;
delete m_pStart;



//==============================================================================
//
// 游戏主循环,此函数将被不停的调用,引擎每刷新一次屏幕,此函数即被调用一次
// 用以处理游戏的开始、进行中、结束等各种状态.
// 函数参数fDeltaTime : 上次调用本函数到此次调用本函数的时间间隔,单位:秒
void CGameMain::GameMainLoop( float fDeltaTime )

switch( GetGameState() )

// 初始化游戏,清空上一局相关数据
case 1:

GameInit();
SetGameState(2); // 初始化之后,将游戏状态设置为进行中

break;

// 游戏进行中,处理各种游戏逻辑
case 2:

// TODO 修改此处游戏循环条件,完成正确游戏逻辑
if(!m_pTankPlayer->IsDead() && !m_pAim_nor->IsDead() && m_fDeltaTime<300)

GameRun( fDeltaTime );

else // 游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态

SetGameState(0);
GameEnd();


break;

// 游戏结束/等待按空格键开始
case 0:
default:
break;
;

//=============================================================================
//
// 每局开始前进行初始化,清空上一局相关数据
void CGameMain::GameInit()

m_pSplash->SetSpriteVisible(false);
m_pStart->SetSpriteVisible(false);
// 实例化我方坦克
m_pTankPlayer=new CTankPlayer("myplayer");//新建一个名字是myPlayer的我方坦克对象
m_pTankPlayer->CloneSprite("player");//我方坦克克隆在funcode模板中存在的名字为player的坦克,表示新建的坦克对象有现在精灵的所有属性
m_pTankPlayer->Init();
m_pTankPlayer->SetSpritePositionX(-26+2);
m_pTankPlayer->SetSpritePositionY(22-2);
m_vWeapon.push_back(m_pTankPlayer);
// 初始化地方坦克
// m_pTankEnemy = new CTankEnemy("enemy");
// m_pTankEnemy->Init();
LoadMap();
m_iTankEnemyNumber = 0;
m_fTankEnemyTime = 0.f;
m_pAim_nor = new CWeapon("myaim_nor");
m_pAim_nor->CloneSprite("aim_nor");
m_vWeapon.push_back(m_pAim_nor);
m_pAim_nor->SetSpriteCollisionReceive(true);
m_pAim_nor->SetSpritePosition(0.f,20.f);
m_iBulletNum = 0;
m_iTankEnemyNumber = 0;
m_fTankEnemyTime = 4.f;
m_iScore = 0;
m_iHight = 0;
m_iEnemy = 0;
m_fDeltaTime = 0.f;

FILE * fp =fopen("save.dat","r+");
if(fp)

fread(&m_iHight,sizeof(int),1,fp);
fclose(fp);

m_pHight = new CTextSprite("hight");
m_pHight->SetTextValue(m_iHight);
// PlaySound("D:\\\\C++\\\\TankWar - 副本\\\\background.wav",NULL,SND_FILENAME|SND_ASYNC); //播放
// PlaySound(NULL,NULL,SND_FILENAME); //暂停当前音乐,其实就是放空音乐
// sndPlaySound("D:\\\\C++\\\\TankWar - 副本\\\\background.wav", SND_ASYNC | SND_NODEFAULT|SND_LOOP); //播放
// string str = "D:\\\\C++\\\\TankWar - 副本\\\\background.wav";
// mciSendString(("open D:\\\\C++\\\\TankWar - 副本\\\\background.wav"),NULL,NULL, NULL); //打开音乐文件
// mciSendString(("play movie"),"open D:\\\\C++\\\\TankWar - 副本\\\\background.wav",NULL,NULL); //播放音乐文件
// mciSendString(TEXT("open D:\\\\图片\\\\tank.mp3 alias Mysong"), NULL, 0,NULL);
//
// mciSendString(TEXT("play MySong"), NULL, 0, NULL);
chooseStatus = 10;
//无敌状态初始为0
invincibleStatus = 0;
fish = 0;
//穿墙的状态
crossStatus = 0;
//加固老巢
strengtheningStatus = 0;
//敌人不动
changelessStatus = 0;
//敌人全部摧毁
destroyStatus = 0;
//复制一个坦克
copyTankStatus = 0;
m_friend_Tank = NULL;
//加速
speedStatus = 0;
//追踪
trackStatus = 0;

//=============================================================================
//
// 每局游戏进行中
void CGameMain::GameRun( float fDeltaTime)

// if(m_pTankEnemy)
//
// m_pTankEnemy->OnMove(fDeltaTime);
// m_pTankEnemy->OnFire(fDeltaTime);
//

m_fDeltaTime += fDeltaTime;
m_pScore->SetTextValue(m_iScore);
m_pHight->SetTextValue(m_iHight);
m_pEnemy->SetTextValue(m_iEnemy);
AddTankEnemy(fDeltaTime);

// mciSendString("open D:\\\\C++\\TankWar - 副本\\\\background.wav alias mymusic", NULL, 0, NULL); // 打开音乐
// mciSendString("setaudio mymusic volume to 600",NULL,0,NULL); //设置音量大小
// mciSendString("play mymusic", NULL, 0, NULL); //开始音乐
// mciSendString("play mymusic repeat", NULL, 0, NULL); //循环播放
//PlaySound(NULL,NULL,SND_FILENAME); //暂停当前音乐,其实就是放空音乐



for(int i=0;i<m_vWeapon.size();i++)

if(strstr(m_vWeapon[i]->GetName(),"bullet")!=NULL)

if(m_vWeapon[i]->GetHp()==0)

// cout<<"进来了"<<endl;
DeleteWeaponByName(m_vWeapon[i]->GetName());
continue;


if(!m_vWeapon[i]->IsDead())

if(strstr(m_vWeapon[i]->GetName(),"enemy")!=NULL&&changelessStatus==1)

m_vWeapon[i]->SetSpeedX(0);
m_vWeapon[i]->SetSpeedY(0);
m_vWeapon[i]->SetSpriteLinearVelocity(0.f,0.f);
else
if(strstr(m_vWeapon[i]->GetName(),"myfriend")!=NULL)

m_vWeapon[i]->OnMove();
else if(strstr(m_vWeapon[i]->GetName(),"enemy")!=NULL)
if(trackStatus==1)

m_vWeapon[i]->trackMove();
m_vWeapon[i]->OnFire(fDeltaTime);
else
m_vWeapon[i]->OnMove(fDeltaTime);
m_vWeapon[i]->OnFire(fDeltaTime);

else
m_vWeapon[i]->OnMove(fDeltaTime);
m_vWeapon[i]->OnFire(fDeltaTime);








else

if(strstr(m_vWeapon[i]->GetName(),"myfriend")!=NULL)

m_friend_Tank = NULL;
// mciSendString(TEXT("close fs"), NULL, 0, NULL);
copyTankStatus = 0;

//死了之后就删除
DeleteWeaponByName(m_vWeapon[i]->GetName());


// cout<<m_pTankPlayer->GetName()<<"坦克的血量为:"<<m_pTankPlayer->GetHp()<<endl;

//=============================================================================
//
// 本局游戏结束
void CGameMain::GameEnd()

FILE * fp =fopen("save.dat","w+");
if(m_iScore>m_iHight)
fwrite(&m_iScore,sizeof(int),1,fp);
fclose(fp);
m_pSplash->SetSpriteVisible(true);
m_pStart->SetSpriteVisible(true);
SetGameState(0);
//mciSendString(TEXT("close D:\\\\C++\\\\TankWar - 副本\\\\background.wav"),NULL,NULL, NULL); //关闭音乐

//==========================================================================
//
// 鼠标移动
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseMove( const float fMouseX, const float fMouseY )



//==========================================================================
//
// 鼠标点击
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )



//==========================================================================
//
// 鼠标弹起
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void CGameMain::OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )



//==========================================================================
//
// 键盘按下
// 参数 iKey:被按下的键,值见 enum KeyCodes 宏定义
// 参数 iAltPress, iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)
void CGameMain::OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )


if( 0 ==GetGameState() )

//如果按下空格,而且现在的运行状态是0,就把他设置为1
if(iKey == KEY_SPACE)

m_iGameState = 1;


if(m_iGameState == 2)

m_pTankPlayer->OnMove(iKey, true);
if(iKey == KEY_J)//判断按下键是够为J键

m_pTankPlayer->OnFire();
if(m_friend_Tank!=NULL)

m_friend_Tank->OnFire();

// PlaySound("D:\\\\C++\\\\TankWar - 副本\\\\boom.wav",NULL,SND_FILENAME|SND_ASYNC );
else if(iKey==KEY_0)

chooseStatus = 0;

else if(iKey==KEY_1)

chooseStatus = 1;

else if(iKey==KEY_2)

chooseStatus = 2;

else if(iKey==KEY_3)

chooseStatus = 3;

else if(iKey==KEY_4)

chooseStatus = 4;

else if(iKey==KEY_5)

chooseStatus = 5;

else if(iKey==KEY_6)

chooseStatus = 6;

else if(iKey==KEY_7)

chooseStatus = 7;



else if(iKey==KEY_8)

chooseStatus = 8;

else if(iKey==KEY_9)

chooseStatus = 9;

else if(iKey==KEY_K)

handle(chooseStatus);




//==========================================================================
//
// 键盘弹起
// 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
void CGameMain::OnKeyUp( const int iKey )



//===========================================================================
//
// 精灵与精灵碰撞
// 参数 szSrcName:发起碰撞的精灵名字
// 参数 szTarName:被碰撞的精灵名字
void CGameMain::OnSpriteColSprite( const char *szSrcName, const char *szTarName )


CWeapon* tarSprite = FindWeaponByName(szTarName);

if(strstr(szSrcName,"bullet") != NULL)//发送碰撞为子弹

// cout<<"tarSprite的名字是"<<tarSprite->GetName()<<" HP是"<<tarSprite->GetHp()<<endl;
if(strstr(tarSprite->GetName(),"myplayer")!=NULL)

int hp = m_pTankPlayer->GetHp();
tarSprite->SetHp(hp);
else if(strstr(tarSprite->GetName(),"myaim_nor")!=NULL)

int hp = m_pAim_nor->GetHp();
tarSprite->SetHp(hp);


CBullet *tmpBullet = (CBullet*)FindWeaponByName(szSrcName);
tmpBullet->OnSpriteColSprite(tarSprite);
if( tmpBullet->GetOwner()==1 && strstr(szTarName,"enemy") != NULL)

m_iScore++;
m_iEnemy--;

CWeapon* pBullet = FindWeaponByName(szSrcName);
pBullet->SetHp(0);

else if(strcmp(szSrcName,"myplayer")==0) //发送碰撞为我方坦克

m_pTankPlayer->OnSpriteColSprite(tarSprite);

else if(strstr(szSrcName,"enemy") != NULL)//发送碰撞为敌方坦克

CTankEnemy* tmpEnemy = (CTankEnemy*)FindWeaponByName(szSrcName);
tmpEnemy->OnSpriteColSprite(tarSprite);
else if(strstr(szSrcName,"myfriend")!=NULL)

m_friend_Tank->OnSpriteColSprite(tarSprite);




//===========================================================================
//
// 精灵与世界边界碰撞
// 参数 szName:碰撞到边界的精灵名字
// 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int iColSide )

// cout<<"触碰到世界边界"<<endl;

// 此处有BUG:不能够这样,必须重新设置一下位置
if(strstr(szName,"myplayer") != NULL) //判断碰到世界边界的坦克是否为我方坦克

//处理超出边界的情况
// cout<<"触碰到边界"<<endl;
if(iColSide==0)

m_pTankPlayer->SetSpritePositionX(-26+2);

else if(iColSide==1)

m_pTankPlayer->SetSpritePositionX( 26-2);
else if(iColSide==3)

m_pTankPlayer->SetSpritePositionY( 22-2);
else if(iColSide==2)

m_pTankPlayer->SetSpritePositionY(-22+2);

m_pTankPlayer->SetSpriteLinearVelocity(0,0);
// 不先处理了,需要判断四个方向
// float x = m_pTankPlayer->GetSpritePositionX();
// float y = m_pTankPlayer->GetSpritePositionY();
// m_pTankPlayer->SetSpritePosition(x-0.01,y-0.01);
else if(strstr(szName,"enemy") != NULL)

CWeapon* pEnemy = FindWeaponByName(szName);
if(iColSide==0)

pEnemy->SetSpritePositionX(-26+2);

else if(iColSide==1)

pEnemy->SetSpritePositionX( 26-2);
else if(iColSide==3)

pEnemy->SetSpritePositionY( 22-2);
else if(iColSide==2)

pEnemy->SetSpritePositionY(-22+2);


pEnemy->SetSpriteLinearVelocity(0.f,0.f);
pEnemy->OnMove(pEnemy->GetDir());

else if(strstr(szName,"bullet") != NULL)

CWeapon* pBullet = FindWeaponByName(szName);
pBullet->SetHp(0);
else if(strstr(szName,"myfriend")!=NULL)


if(iColSide==0)

m_friend_Tank->SetSpritePositionX(-26+2);

else if(iColSide==1)

m_friend_Tank->SetSpritePositionX( 26-2);
else if(iColSide==3)

m_friend_Tank->SetSpritePositionY( 22-2);
else if(iColSide==2)

m_friend_Tank->SetSpritePositionY(-22+2);

m_friend_Tank->SetSpriteLinearVelocity(0.f,0.f);


// cout<<"此时坦克的速度是"<<m_pTankPlayer->GetSpeedY()<<" "<<m_pTankPlayer->GetSpeedX()<<endl;

//处理子弹事件
void CGameMain::AddBullet( int iDir,float fPosX,float fPosY ,int iOwner)

char* szName = CSystem::MakeSpriteName("bullet",m_iBulletNum);//创建坦克名字
CBullet* pBullet = new CBullet(szName);
if(iOwner == 1)

pBullet->SetOwner(1);//1表示我方坦克发射的子弹

else

pBullet->SetOwner(0); //0表示地方坦克发射的子弹

if(fish==0||iOwner==0)

pBullet->CloneSprite("bullet");
else
pBullet->CloneSprite("fishBullet");


pBullet->SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26, -22, 26, 22); //设置世界边界
pBullet->SetSpritePosition(fPosX,fPosY);
pBullet->SetSpriteCollisionSend(true); //设置接收碰撞
pBullet->OnMove(iDir);
m_iBulletNum++; //子弹个数加1

m_vWeapon.push_back(pBullet);

void CGameMain::LoadMap()


char* szName;
int i,j;
float x,y;
for(i=0;i<11;i++)

for(j=0;j<13;j++)

if(g_iMap[i][j]==1)

szName = CSystem::MakeSpriteName("wall",j+i*13+i);//重新起名
CWeapon* pWall = new CWeapon(szName);//新建对象
pWall->CloneSprite("wall"); //克隆墙块
pWall->SetSpriteCollisionActive(0,1); //设置为接受碰撞
pWall->SetSpriteCollisionResponse(COL_RESPONSE_CUSTOM);
x =float(-24+4*j);
y =float(-20+4*i);
pWall->SetSpritePosition(x,y);
m_vWeapon.push_back(pWall);




CWeapon* CGameMain::FindWeaponByName(const char* szName)//根据名字查找到对象

for(int i=0; i<m_vWeapon.size(); i++)

if(strcmp(szName,m_vWeapon[i]->GetName()) == 0)

return m_vWeapon[i];



void CGameMain::DeleteWeaponByName(const char* szName)//根据名字把精灵从容器中删除

for(vector<CWeapon*>::iterator it=m_vWeapon.begin();it!=m_vWeapon.end();)

CWeapon* cw =*it;
if(strcmp(szName,cw->GetName()) == 0)

m_vWeapon.erase(it);
cw->DeleteSprite();
delete cw;
break;

else

it++;



void CGameMain::AddTankEnemy(float fDeltaTime)

m_fTankEnemyTime += fDeltaTime;
if(m_fTankEnemyTime > 5)

char* szName = CSystem::MakeSpriteName("enemy",m_iTankEnemyNumber);
CTankEnemy* m_pTankEnemy = new CTankEnemy(szName);
m_pTankEnemy->CloneSprite("enemy");
m_pTankEnemy->Init();
if(changelessStatus==1)

m_pTankEnemy->SetSpeedX(0.f);
m_pTankEnemy->SetSpeedY(0.f);

m_iTankEnemyNumber++;
m_vWeapon.push_back(m_pTankEnemy); //把创建的敌方坦克插入到容器中
m_fTankEnemyTime=0.f;
m_iEnemy++;


void CGameMain::DeleteAllSprite()

int n=m_vWeapon.size();
while(m_vWeapon.size()!=0)

vector<CWeapon*>::iterator itr=m_vWeapon.begin();
CWeapon* cw = *itr;
m_vWeapon.erase(itr);
cw->DeleteSprite();
delete cw;


void CGameMain::handle(int status)

if(status==0)

transmit();
else if(status==1)

invincible();
// cout<<"当前状态是"<<invincibleStatus<<endl;
else if(status==2)

tranFi

以上是关于Funcode实现坦克大战(十个需求)的主要内容,如果未能解决你的问题,请参考以下文章

java实现经典坦克大战及源代码下载

《Java小游戏实现》:坦克大战(续三)

Unity3DTank大战

《Java小游戏实现》:坦克大战(续2)

学习 Python 之 Pygame 开发坦克大战

JAVA课程设计(坦克大战)