您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页坦克大战代码

坦克大战代码

来源:爱go旅游网
坦克大战代码

// 1、TTank.cpp: implementation of the TTank class.坦克类

//

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\"

#include \"TankWar.h\" #include \"TTank.h\" #include \"TWorld.h\" #include \"TExplode.h\" #include \"TBonus.h\" #include \"TBullet.h\"

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////// // TEnemyTank

/////////////////////////////////////////////////////////////////// EPG TEnemyTank::m_epg[3];

//////////////////////////////////////////////// //敌军坦克移动

void TEnemyTank::Move() {

if(!IsMyTime()) return ;

//防护小于0,还不死吗 if(m_nShield < 0) { Dead(); //玩家增加经验值 g_world.Player(0)->m_nExper += 10 + m_nType * 10; //加点爆炸效果 g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY,EXPLODE_TANK)); }

/////////////////////////////////////////////////////

//疯子要行动了,怎么动呢?用随机数来决定吧

//玩家没进入范围,什么也不做

if(ABS(m_nX-g_world.Player(0)->GetX())>500 || ABS(m_nY-g_world.Player(0)->GetY())>500) return ;

//产生0到100之间的随机数状态 int status=Rand(0,100);

//保存现在的位置坐标 int x=m_nX,y=m_nY;

//根据产生的状态行动 if(status<2){ //状态小于2,改变一下方向(概率是... 计算一下好像是: 2/100即0.02) m_dir =(DIRECTION) Rand(0,4); }else if(status <3) { //状态小于3,开火(概率是... 计算一下好像是: (3-2)/100即0.01) switch(m_nType) { case FIRE_TANK: //火弹:射程100,威力20 g_world.BulletLink().Add(NEW TBullet(m_nX,m_nY,m_dir,FIRE,20,100)); break; case DOUBLE_MISSILE_TANK: //火弹:射程250,威力15 g_world.BulletLink().Add(NEW TBullet(m_nX,m_nY,m_dir,DMISSILE,15,250)); break; case SINGLE_MISSILE_TANK: //火弹:射程250,威力10 g_world.BulletLink().Add(NEW TBullet(m_nX,m_nY,m_dir,SMISSILE,10,250)); break; } }else { //其它的状态值就表示运行吧(概率是... 计算一下好像是: 100-3/100即0.97) //生命在于运动嘛:) m_nX+=g_nDirXY[m_dir][0]; m_nY+=g_nDirXY[m_dir][1]; }

///////////////////////////////////////////////////// //计算一下上面的移动是否有效

//先假设移动有效

BOOL canMove=TRUE;

//取得自己的边框 RECT rc; GetRect(rc);

////////////////////////////////////////////////////

//根据方向来计算是否与障碍地图上的障碍物碰撞 if(m_dir==DIR_UP){ //方向向上,只检查左上角及右上角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = FALSE; else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = FALSE; }else if(m_dir==DIR_DOWN){ //方向向下,只检查左下角及右下角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove = FALSE; else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove = FALSE; }else if(m_dir==DIR_RIGHT){ //方向向右,只检查右下角及右上角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = FALSE; else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove = FALSE; }else if(m_dir==DIR_LEFT){ //方向向左,只检查左上角及左上角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = FALSE; else

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT))

canMove = FALSE; }

//总不能移到世界范围以外吧

if(m_nY>g_world.GetHeight()-OBSTACLE_HEIGHT || m_nX>g_world.GetWidth()-OBSTACLE_WIDTH || m_nX<0 || m_nY<0) canMove = FALSE;

//有没有碰到其它的NC坦克?不过要记住排除与自己相撞的情况 //疯子也不会疯到这种程度吧

if(g_world.EnemyTankLink().HitTestAll(this)) //停下来,打个招呼 canMove = FALSE;

//撞到了其它障碍物(木箱、邪恶之源)了吗? if(g_world.ObstacleLink().HitTestAll(this)) canMove = FALSE;

//碰到玩家坦克了吗?

if(g_world.Player(0)->HitTest(this)) //当然不能动了 canMove = FALSE;

//移动无效,恢复原值 if(canMove==FALSE) m_nX = x,m_nY=y;

////////////////////////// //计算当前动画帧

m_nCurrentFrame=m_dir; }

////////////////////////////////////////////////// //画坦克

void TEnemyTank::Draw() {

POINT p; p.x = m_nX; p.y = m_nY;

g_world.LPToDP(p);

WGE_Surface.Blt(m_epg[m_nType], m_nCurrentFrame, p.x,p.y ); }

///////////////////////////////////////// //取边框

void TEnemyTank::GetRect(RECT& rc) {

rc.left = m_nX - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyX; rc.top = m_nY - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyY; rc.bottom = rc.top + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwHeight ; rc.right = rc.left + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwWidth ; }

/////////////////////////////////////////////// //

TEnemyTank::TEnemyTank(int x, int y, int nType)

:TSprite(x,y,100,0,CLASS_TENEMYTANK),m_nType(nType) {

switch(nType) {

case FIRE_TANK: //防护力100,速度1/(50/1000) m_nShield = 100; SetDelayTimer(50); break;

case DOUBLE_MISSILE_TANK: //防护力150,速度1/(70/1000) m_nShield = 150; SetDelayTimer(70); break;

case SINGLE_MISSILE_TANK: //防护力100,速度1/(30/1000) m_nShield = 200; SetDelayTimer(30); break; } }

///////////////////////////////////////////////////////// //碰撞是否有效

BOOL TEnemyTank::HitBy(TObject * pObj) {

//////////////////////////////////////////// //与参数对象碰撞 if(HitTest(pObj)) { ////////////////////////////////////////// //参数对象是一个子弹 if(pObj->ClassType()==CLASS_TBULLET) { //转变为子弹对象 TBullet * pBullet = (TBullet*)pObj;

if(pBullet->m_nType == LIGHT) { //是光弹,防护减去光弹的力量 m_nShield -= pBullet->m_nShield ; return TRUE; } } }

return FALSE; }

///////////////////////////////////////////////////////////////////////

// TPlayerTank玩家

///////////////////////////////////////////////////////////////////

EPG TPlayerTank::m_epg[3];

TPlayerTank::TPlayerTank(int x, int y, int nType)

:TSprite(x,y,100,0,CLASS_TPLAYERTANK),m_nType(nType), m_nExper(0),m_nMoney(0),m_nMaxShield(100) {

SetDelayTimer(1); //参考值40,这里是1 }

///////////////////////////////////////////////// //碰撞是否有效

BOOL TPlayerTank::HitBy(TObject * pObj) {

/////////////////////////////////////////// //是否与参数对象碰撞 if(HitTest(pObj)) { if(pObj->ClassType()==CLASS_TBULLET) { //参数对象炮弹 TBullet * pBullet = (TBullet*)pObj; if(pBullet->m_nType == FIRE||pBullet->m_nType DMISSILE||pBullet->m_nType == SMISSILE) { //被火弹,双导弹,单导弹(都是敌方的炮弹)击中,减防护力 // m_nShield -= pBullet->m_nShield ; m_nShield += pBullet->m_nShield ; return TRUE; } }else if(pObj->ClassType()==CLASS_TBONUS) { //参数对象是奖励 TBonus * pBonus = (TBonus*)pObj;

==

switch(pBonus->m_nBonusType) { case BONUS_RECOVER: //恢复物品 m_nShield += 20; //恢复20点 m_nShield = MIN(m_nShield+20,m_nMaxShield); break; case BONUS_EXPER: //经验物品 //m_nExper += 10; //经验值加10 m_nType = MIN((m_nExper/1000),2); //第1000点升一级 m_nMaxShield = 100 + m_nExper/100; m_dwDelayTimer -= m_dwDelayTimer*10/100; break; case BONUS_MONEY: m_nMoney += 100; //得到100元 } return TRUE; } }

return FALSE; }

///////////////////////////////////////////////////// //玩家坦克移动

void TPlayerTank::Move() {

if(!IsMyTime()) return ; /*

if(m_nShield<0) { Dead(); g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY,EXPLODE_PLAYER)); return;

} */

/////////////////////////////////////////////////// //响应键盘事件,移动坦克

//保存原坐标

int x=m_nX,y=m_nY;

//处理按键

if(WGE_Input.Key()[DIK_UP]){ if(m_nY>0) m_nY -- ;

//调整最大防护 //速度提高10% m_dir = DIR_UP; }else

if(WGE_Input.Key()[DIK_DOWN]){ if(m_nYif(WGE_Input.Key()[DIK_LEFT]){ if(m_nX>0) m_nX -= 1; m_dir = DIR_LEFT; }else

if(WGE_Input.Key()[DIK_RIGHT]){ if(m_nX///////////////////////////////////////////////////////// //计算上面的移动是否有效

BOOL canMove=TRUE; //假设有效先

RECT rc; GetRect(rc);

//是否碰撞地形障碍?方法和敌人坦克一样

if(m_dir==DIR_UP){

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = TRUE; else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = TRUE; }else

if(m_dir==DIR_DOWN){

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove =TRUE; else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove = TRUE; }else

if(m_dir==DIR_RIGHT){

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEI

GHT)) canMove = TRUE; else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove = TRUE; }else

if(m_dir==DIR_LEFT){

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) canMove = TRUE; else

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) canMove = TRUE; }

//碰到了敌人的坦克没有?

if(g_world.EnemyTankLink().HitTestAll(this)) canMove = FALSE;

//是否碰到了障碍物(木箱或邪恶源)

if(g_world.ObstacleLink().HitTestAll(this)) canMove = FALSE;

//移动无效,恢复原坐标 if(canMove==FALSE) m_nX = x,m_nY=y;

//计算当前动画帧 m_nCurrentFrame=m_dir;

//按左CTRL键开火,不过每100ms才能开一次,加弹总要花点时间吧:) static DWORD dwFireTick=GetTickCount();

if(GetTickCount()-dwFireTick>10) //参考值100ms,这里是10ms {

if(WGE_Input.Key()[DIK_LCONTROL]||WGE_Input.Key()[DIK_RCONTROL]){ g_world.BulletLink().Add(NEW

TBullet(m_nX,m_nY,m_dir,LIGHT,10+m_nMoney/300,100+m_nType*25)); } dwFireTick=GetTickCount(); }

//让玩家坦克处于可视区的中央 g_world.GetViewportRect(rc);

int height= rc.bottom - rc.top - OBSTACLE_HEIGHT; int width= rc.right - rc.left - OBSTACLE_WIDTH; g_world.SetViewport(m_nX-width/2,m_nY-height/2); }

////////////////////////////////////////////////////// //画玩家坦克

void TPlayerTank::Draw() {

POINT p; p.x = m_nX; p.y = m_nY;

g_world.LPToDP(p);

WGE_Surface.Blt(m_epg[m_nType], m_nCurrentFrame, p.x,p.y ); }

/////////////////////////////////////////////// //返回坦克的边框

void TPlayerTank::GetRect(RECT& rc) {

rc.left = m_nX - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyX; rc.top = m_nY - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyY; rc.bottom = rc.top + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwHeight ; rc.right = rc.left + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwWidth ; }

//2、TBonus.cpp: implementation of the TBonus class.奖励类 //

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TBonus.h\" #include \"TWorld.h\"

EPG TBonus::m_epg_bonus[3]; ESound TBonus::m_sound[1];

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

TBonus::~TBonus() { }

TBonus::TBonus(int x, int y, BONUS nBonusType) :TObject(x,y,CLASS_TBONUS) {

m_nBonusType = nBonusType ; m_nCurrentFrame = 0; m_dwDelayTimer= 100; }

void TBonus::Draw() {

POINT p; p.x = m_nX; p.y = m_nY;

g_world.LPToDP(p);

WGE_Surface.Blt(m_epg_bonus[m_nBonusType], m_nCurrentFrame, p.x,p.y ); }

void TBonus::GetRect(RECT &rc) {

rc.left = m_nX

m_epg_bonus[m_nBonusType].GetFrame(m_nCurrentFrame)->m_nKeyX; rc.top = m_nY

m_epg_bonus[m_nBonusType].GetFrame(m_nCurrentFrame)->m_nKeyY; rc.bottom = rc.top

m_epg_bonus[m_nBonusType].GetFrame(m_nCurrentFrame)->m_dwHeight ; rc.right = rc.left

m_epg_bonus[m_nBonusType].GetFrame(m_nCurrentFrame)->m_dwWidth ; }

void TBonus::Move() {

if(!IsMyTime()) return ;

if(g_world.Player(0)->HitBy(this)) { Dead();

- - + +

}

m_sound[0].Play(); }

++m_nCurrentFrame%=m_epg_bonus[m_nBonusType].GetFrameCount();

//3、TBullet.cpp: implementation of the TBullet class.子弹类 //

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TBullet.h\" #include \"TExplode.h\" #include \"Tworld.h\"

ESound TBullet::m_sound[4]; EPG TBullet::m_epg[4];

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

TBullet::TBullet(int x,int y,DIRECTION dir,BULLET_TYPE nType,int nShield,int nFireRange)

:TSprite(x,y,nShield,0,CLASS_TBULLET),m_nType(nType) {

SetDelayTimer(50); m_dir = dir;

m_nFireRange = nFireRange;

////////////////////////////////////////// //计算音效的音量及均衡

int valume,pan; //音量和均衡 int w,h;

//声源与玩家的距离

w = x - g_world.Player(0)->GetX(); h = y - g_world.Player(0)->GetY();

//计算音效的音量及均衡

valume = MAX(ABS(w),ABS(h)) * (-10000/800);

pan = w * (10000/400);

///////////////////////////////////////////////// //跟据类型设置速度

switch(nType) {

case LIGHT: //玩家的子弹,总会听到声音的 m_nSpeed = 15; //if(valume>-10000) //小于最小音量,没必要播放 m_sound[2].Play(-1000,pan); break; case FIRE: m_nSpeed = 10; if(valume>-10000) m_sound[1].Play(valume,pan); break;

case DMISSILE: m_nSpeed = 0; //导弹开始速度为0,然后利用加速度加速 if(valume>-10000) m_sound[0].Play(valume,pan); break;

case SMISSILE: m_nSpeed = 0; if(valume>-10000) m_sound[0].Play(valume,pan); break; } }

TBullet::~TBullet() { }

void TBullet::Move() {

if(!IsMyTime()) return ;

TLinkNode * pNode; switch(m_nType) {

case FIRE: //火弹,由火坦克发射的炮弹 //计算出当前动画帧 m_nCurrentFrame = m_dir*3+(m_nCurrentFrame+1)%3;

//超出射程范围,发出死亡信息 if(m_nFireRange<0) { Dead(); } //击中玩家了吗?(即使死了也不让你好过) if(g_world.Player(0)->HitBy(this)) { //击中目标,任务完成 Dead(); } //已经死亡,来个爆炸效果 if(IsDead()) g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY,EXPLODE_FIRE)); break;

case DMISSILE: //双导弹,敌军的导弹 m_nSpeed +=1; //以加速为1的速度运动 m_nCurrentFrame = m_dir; //计算当前动画的帧 //超出射程范围,发出死亡信息 if(m_nFireRange<0) Dead(); //击中玩家? if(g_world.Player(0)->HitBy(this)) Dead(); //死了 if(IsDead()) { ///////////////////////////////////////////////////// //双导弹当然是两个爆炸效果 if(m_dir==DIR_RIGHT||m_dir==DIR_LEFT) { g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY+6,EXPLODE_MISSILE)); g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY-6,EXPLODE_MISSILE)); }else { g_world.ExplodeLink().Add(NEW TExplode(m_nX+6,m_nY,EXPLODE_MISSILE));

g_world.ExplodeLink().Add(NEW TExplode(m_nX-6,m_nY,EXPLODE_MISSILE)); } } break;

case SMISSILE: //单导弹,不用注释了吧 m_nSpeed ++; m_nCurrentFrame = m_dir; if(m_nFireRange<0) Dead(); if(g_world.Player(0)->HitBy(this)) Dead(); if(IsDead()) g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY,EXPLODE_MISSILE)); break;

case LIGHT: //我们的武器:) m_nCurrentFrame = 0; //////////////////////////////////////////////////// //计算是否打中在链表中的敌军坦克 //取得链表中的第一辆坦克 pNode=g_world.EnemyTankLink().m_pHeader; while(pNode) //还不到链尾 { //打中了吗? if(pNode->m_pObject->HitBy(this)) //Ok,Mission completed Dead(); //取得下一辆坦克 pNode = pNode->m_pNext; } //////////////////////////////////////////////////// //计算是否打中障碍物 pNode = g_world.ObstacleLink().m_pHeader ; while(pNode) { if(pNode->m_pObject->HitBy(this)) Dead(); pNode = pNode->m_pNext; }

if(m_nFireRange<0) { //太远了,没办法 Dead(); } //???,为什么没有爆炸效果? break; default: TRACE(0,\"Invalid bullet id\"); break; }

//填加的代码

//取得自己的边框 RECT rc; GetRect(rc);

if(m_nType==LIGHT||m_nType==FIRE||m_nType==SMISSILE||m_nType==DMISSILE) { if(m_dir==DIR_UP){ //方向向上,只检查左上角及右上角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) Dead(); //子弹消失 else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) Dead(); }else if(m_dir==DIR_DOWN){ //方向向下,只检查左下角及右下角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) Dead(); else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) Dead(); }else if(m_dir==DIR_RIGHT){ //方向向右,只检查右下角及右上角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) Dead();

else

if(g_world.ObstacleMap(rc.right/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) Dead(); }else if(m_dir==DIR_LEFT){ //方向向左,只检查左上角及左上角坐标是否碰到障碍

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.top/OBSTACLE_HEIGHT)) Dead(); else

if(g_world.ObstacleMap(rc.left/OBSTACLE_WIDTH,rc.bottom/OBSTACLE_HEIGHT)) Dead(); } }

//是不是死了? if(!IsDead()) { //没死,那么继续移动 //速度太快了! if(m_nSpeed>24) m_nSpeed = 24; //向前,向前,向前... m_nX+=g_nDirXY[m_dir][0]*m_nSpeed; m_nY+=g_nDirXY[m_dir][1]*m_nSpeed; //改变射程 m_nFireRange -= m_nSpeed; } }

////////////////////////////////////////////// //画子弹

void TBullet::Draw() {

POINT p; p.x = m_nX; p.y = m_nY;

g_world.LPToDP(p); //把世界逻辑坐标转换到设备坐标 WGE_Surface.Blt(m_epg[m_nType], m_nCurrentFrame, p.x,p.y );

}

/////////////////////////////////////////////// //取得碰撞矩形

void TBullet::GetRect(RECT& rc) {

rc.left = m_nX - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyX; rc.top = m_nY - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyY; rc.bottom = rc.top + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwHeight ; rc.right = rc.left + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwWidth ; }

// TExplode.cpp: implementation of the TExplode class. //

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TExplode.h\" #include \"TWorld.h\"

EPG TExplode::m_epg[4];

ESound TExplode::m_sound[3];

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

TExplode::TExplode(int x,int y,EXPLODE nType)

:TObject(x,y,CLASS_TEXPLODE),m_nType(nType),m_nCurrentFrame(0) {

SetDelayTimer(100); switch(nType) {

case EXPLODE_TANK: case EXPLODE_BOX: m_sound[0].Play(); break;

case EXPLODE_PLAYER: //玩家爆炸动画慢一点,与声音配合 SetDelayTimer(200); m_sound[0].Play(); break;

} }

TExplode::~TExplode() { }

/////////////////////////////////////////////// //移动

void TExplode::Move() {

if(!IsMyTime()) return ;

/////////////////////////////////////////// //计算

if(m_nType==EXPLODE_PLAYER) { //玩家爆炸应该壮烈一点 if(m_nCurrentFrame>=m_epg[3].GetFrameCount()-1) { //先来一个小爆炸 m_sound[1].Play(); //然后变成大爆炸 m_nType = EXPLODE_TANK; m_nCurrentFrame = 0; return ; } }else{ //一般爆炸就可以了 if(m_nCurrentFrame>=m_epg[m_nType].GetFrameCount()-1) { //爆炸消失 Dead(); return ; } }

m_nCurrentFrame ++; }

/////////////////////////////////////////////// //画出爆炸

void TExplode::Draw() {

POINT p; p.x = m_nX; p.y = m_nY;

g_world.LPToDP(p);

if(m_nType==EXPLODE_PLAYER) { WGE_Surface.Blt(m_epg[3],m_nCurrentFrame, p.x,p.y); }else WGE_Surface.Blt(m_epg[m_nType], m_nCurrentFrame, p.x,p.y ); }

//////////////////////////////////////////// //取得动画边框

void TExplode::GetRect(RECT& rc) {

int i;

if(m_nType==EXPLODE_PLAYER) i = 3; else i = m_nType;

rc.left = m_nX - m_epg[i].GetFrame(m_nCurrentFrame)->m_nKeyX; rc.top = m_nY - m_epg[i].GetFrame(m_nCurrentFrame)->m_nKeyY;

rc.bottom = rc.top + m_epg[i].GetFrame(m_nCurrentFrame)->m_dwHeight ; rc.right = rc.left + m_epg[i].GetFrame(m_nCurrentFrame)->m_dwWidth ; }

// 4、TLink.cpp: implementation of the TLink class.连接类 //

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TLink.h\"

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

TLink::TLink() {

m_pHeader = NULL; }

TLink::~TLink() {

DeleteAll(); }

void TLink::AddHeader(TObject * pObject) {

ASSERT(pObject);

TLinkNode * pAddNode = NEW TLinkNode(pObject); pAddNode->m_pNext = m_pHeader; m_pHeader = pAddNode; }

void TLink::AddTail(TObject * pObject) {

ASSERT(pObject);

TLinkNode * pAddNode = NEW TLinkNode(pObject); if(m_pHeader==NULL) { m_pHeader = pAddNode ; m_pHeader->m_pNext = NULL; }else { TLinkNode * pNode = m_pHeader ; while(pNode->m_pNext) { ASSERT(pObject!=pNode->m_pObject); pNode = pNode->m_pNext ; } pNode->m_pNext = pAddNode ; pAddNode->m_pNext = NULL; } }

void TLink::Add(TObject * pObject) {

AddHeader(pObject); }

void TLink::DeleteAll() {

TLinkNode * pNode = m_pHeader; while(pNode) { m_pHeader = pNode->m_pNext ; delete pNode ;

pNode = m_pHeader; } }

void TLink::Delete(TObject * pObject) {

TLinkNode * pPreNode = m_pHeader ;

if(m_pHeader->m_pObject == pObject) { m_pHeader = m_pHeader->m_pNext ; delete pPreNode ; return ; }

TLinkNode * pNode = pPreNode->m_pNext ; while(pNode) { if(pNode->m_pObject == pObject) { pPreNode->m_pNext = pNode->m_pNext ; delete pNode; return ; } pPreNode = pNode ; pNode = pNode->m_pNext ; } }

/////////////////////////////// //画出链表中所有的对象 void TLink::DrawAll() {

TLinkNode * pNode = m_pHeader; while(pNode) { pNode->m_pObject->Draw(); pNode = pNode->m_pNext ; } }

//////////////////////////////////////////// //移动链表中所有的对象 void TLink::MoveAll() {

//取得第一个结点

TLinkNode * pNode = m_pHeader;

//循环整个链表 while(pNode)

{ if(pNode->m_pObject->IsDead()) { //该对象已经被击毁,从链表中删除 TObject * pDeleteObj = pNode->m_pObject; pNode = pNode->m_pNext ; Delete(pDeleteObj); } else { //调用该对象的Move()函数 pNode->m_pObject->Move(); pNode = pNode->m_pNext ; } } }

BOOL TLink::HitTestAll(TObject * pObj) {

TLinkNode * pNode = m_pHeader; BOOL bHit = FALSE;

while(pNode && bHit==FALSE) { if(pNode->m_pObject != pObj) bHit=pNode->m_pObject->HitTest(pObj); pNode = pNode->m_pNext ; }

return bHit; }

//5、TObject.cpp: implementation of the TObject class.物体类 //

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TObject.h\"

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

TObject::TObject(int x,int y,CLASS_TYPE nClassType)

:m_nX(x),m_nY(y),m_dwLastTickCount(0),m_dwDelayTimer(0), m_nClassType(nClassType),m_bIsDead(FALSE) {

}

TObject::~TObject() { }

///////////////////////////////////////////// //该对象是否与另它对象碰撞

BOOL TObject::HitTest(TObject* object) {

RECT rc1,rc2,temp; GetRect(rc1);

object->GetRect(rc2);

return IntersectRect(&temp,&rc1,&rc2); }

////////////////////////////////////////////// //是否该我动了?

BOOL TObject::IsMyTime() {

if(GetTickCount()-m_dwLastTickCount>=m_dwDelayTimer) { m_dwLastTickCount = GetTickCount(); return TRUE; }

return FALSE; }

//6、TObstacle.cpp: implementation TObstacle class.障碍物类 //

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TObstacle.h\" #include \"TBonus.h\" #include \"TBullet.h\" #include \"TExplode.h\" #include \"TWorld.h\"

EPG TObstacle::m_epg[2];

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

of the

TObstacle::TObstacle(int x,int y,OBSTACLE nType)

:TObject(x,y,CLASS_TOBSTACLE),m_nType(nType),m_nCurrentFrame(0) {

SetDelayTimer(100); switch(m_nType) {

case OBSTACLE_BOX: //木箱 //硬度100 m_nHardiness = 100; break;

case OBSTACLE_END: //邪恶源 //硬度1000! ,非常硬 m_nHardiness = 1000; break; } }

TObstacle::~TObstacle() { }

void TObstacle::Destroy() {

m_epg[0].Destroy(); m_epg[1].Destroy(); }

///////////////////////////////////////////// //击中测试

BOOL TObstacle::HitBy(TObject * pObj) {

if(HitTest(pObj)) { ////////////////////////////////////// //只能被光弹击中 if(pObj->ClassType()==CLASS_TBULLET) { TBullet * pBullet = (TBullet*)pObj; if(pBullet->m_nType == LIGHT) { m_nHardiness -= pBullet->m_nShield ; return TRUE; } } }

return FALSE; }

////////////////////////////////////////// //移动

void TObstacle::Move() {

if(!IsMyTime()) return ;

//计算当前帧

++m_nCurrentFrame%=m_epg[m_nType].GetFrameCount();

if(m_nHardiness<0){ //消失 Dead(); if(m_nType == OBSTACLE_END) { //邪恶源被击毁,过关 //强烈爆炸 g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY, EXPLODE_PLAYER)); //经验值+1000 g_world.Player(0)->m_nExper += 1000; //进入下一关 g_game_status = GAME_STAGECLEAR; }else if(m_nType == OBSTACLE_BOX) { //产生一个随机物品 g_world.BonusLink().Add(NEW TBonus(m_nX,m_nY, (BONUS)Rand(0,3))); //然后爆炸 g_world.ExplodeLink().Add(NEW TExplode(m_nX,m_nY, EXPLODE_BOX)); } } }

/////////////////////////////////////////// //画出来

void TObstacle::Draw() {

POINT p;

p.x = m_nX; p.y = m_nY;

g_world.LPToDP(p);

WGE_Surface.Blt(m_epg[m_nType], m_nCurrentFrame, p.x,p.y ); }

///////////////////////////////////////////////////// //碰撞边框

void TObstacle::GetRect(RECT& rc) {

rc.left = m_nX - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyX; rc.top = m_nY - m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_nKeyY; rc.bottom = rc.top + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwHeight ; rc.right = rc.left + m_epg[m_nType].GetFrame(m_nCurrentFrame)->m_dwWidth ; }

// TSprite.cpp: implementation of the TSprite class. 精灵类//

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TSprite.h\"

int g_nDirXY[4][2] = {

{1,0} , {0,1},{-1,0},{0,-1} };

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

TSprite::TSprite(int x,int y,int nShield,int nStatus,CLASS_TYPE nClassType)

:TObject(x,y,nClassType),m_nShield(nShield),m_nStatus(nStatus),m_dir(DIR_LEFT),m_nCurrentFrame(0) { }

TSprite::~TSprite() { }

// TWorld.cpp: implementation of the TWorld class. 世界类//

//////////////////////////////////////////////////////////////////////

#include \"stdafx.h\" #include \"TankWar.h\" #include \"TWorld.h\" #include \"TBonus.h\" #include \"TObstacle.h\"

TWorld g_world; //全局唯一的世界对象

////////////////////////////////////////////////////////////////////// // Construction/Destruction

//////////////////////////////////////////////////////////////////////

EGroupPic TWorld::m_grp_terrain; EPG TWorld::m_epg_icon[3];

TWorld::TWorld()

:m_pTerrainMap(NULL),m_pObstacleMap(NULL) { }

TWorld::~TWorld() {

DestroyWorld(); }

//////////////////////////////////////////////// //加载地形图像

BOOL TWorld::LoadTerrainPicture(LPCSTR szGrpFile,EDataFile* pDat) {

if(m_grp_terrain.Load(szGrpFile,pDat)==FALSE){ MessageBox(NULL,szGrpFile,\"加载错误\ return FALSE; }

return TRUE;

}

//////////////////////////////////////////////////// //加载图标图像

BOOL TWorld::LoadIconPicture(LPCSTR szFile,int nIndex,EDataFile* pDat) {

ASSERT(nIndex<3);

if(m_epg_icon[nIndex].Load(szFile,pDat)==FALSE) { MessageBox(NULL,szFile,\"加载错误\ TRACE(0,\"Load %s error\ return FALSE; }

return TRUE; }

/////////////////////////////////////////// //删除世界的资源

void TWorld::DestroyResource() {

m_grp_terrain.Destroy(); m_epg_icon[0].Destroy(); m_epg_icon[1].Destroy(); m_epg_icon[2].Destroy(); }

/////////////////////////////////////////// //加载新的地图然后开始这一关

BOOL TWorld::LoadStage(int nStage,EDataFile * pDat) {

if(nStage == 0) { //已经打完三关,重新开始 m_nStage = 1; } else { m_nStage = nStage; }

//删除各对象链表数据

m_EnemyTankLink.DeleteAll(); m_BonusLink.DeleteAll(); m_ObstacleLink.DeleteAll(); m_BulletLink.DeleteAll(); m_ExplodeLink.DeleteAll();

char buf[255];

sprintf(buf,MEDIA(\"第%d关.map\"),m_nStage);

EPackFile map;

//打开地图文件

if(map.Open(buf,pDat)==FALSE) { MessageBox(NULL,buf,\"加载错误\ TRACE(0,\"加载地图文件错误:%s\ return FALSE; }

//读取地图ID DWORD dwID;

map.Read(&dwID,sizeof(dwID)); if(dwID!=MAP_ID) { MessageBox(NULL,buf,\"加载错误\ TRACE(0,\"非法的地图文件:%s\ return FALSE; }

//读取地图高度和宽度 INT32 nWidth,nHeight;

map.Read(&nWidth,sizeof(nWidth)); map.Read(&nHeight,sizeof(nHeight));

//为地形地图分配内存 if(m_pTerrainMap) MemFree(m_pTerrainMap);

m_pTerrainMap = (TERRAIN_INDEX*)MemAlloc(nWidth * nHeight sizeof(TERRAIN_INDEX)); if(m_pTerrainMap==NULL) return FALSE;

//为障碍地图分配内存 if(m_pObstacleMap) MemFree(m_pObstacleMap); m_pObstacleMap (OBSTACLE_ID*)MemAlloc(4*nWidth*nHeight*sizeof(OBSTACLE_ID)); if(m_pObstacleMap==NULL) return FALSE;

//读取地形数据

map.Read(m_pTerrainMap,nWidth * nHeight * sizeof(TERRAIN_INDEX));

m_nMaxVertTerrain = nHeight; m_nMaxHorzTerrain = nWidth;

* =

//计算出游戏世界的大小

m_nWorldHeight = nHeight * TERRAIN_HEIGHT; m_nWorldWidth = nWidth * TERRAIN_WIDTH;

//设置可视区

SetupViewport(0,0,WGE_Surface.m_pBmp->w,WGE_Surface.m_pBmp->h);

//读取障碍物数据和物体数据

//障碍地图高度与宽度分别是地形地图的高度与宽度的两倍 nWidth *= 2; nHeight *= 2;

for(int h=0;hTBonus(w*OBSTACLE_WIDTH,h*OBSTACLE_HEIGHT, BONUS_EXPER) ); break; case 6: //钱 //加入奖励链表 g_world.BonusLink().Add( NEW

TBonus(w*OBSTACLE_WIDTH,h*OBSTACLE_HEIGHT, BONUS_MONEY) ); break; case 7: //恢复物品 //加入奖励链表 g_world.BonusLink().Add( NEW

TBonus(w*OBSTACLE_WIDTH,h*OBSTACLE_HEIGHT, BONUS_RECOVER)

); break; case 4: //木箱 //加入障碍链表 g_world.ObstacleLink().Add( NEW

TObstacle(w*OBSTACLE_WIDTH,h*OBSTACLE_HEIGHT, OBSTACLE_BOX) ); //m_pObstacleMap[w+h*nWidth] = obstacle_id; break; case 9: //邪恶之源 //加入障碍链表,这可是最大的障碍 g_world.ObstacleLink().Add( NEW

TObstacle(w*OBSTACLE_WIDTH,h*OBSTACLE_HEIGHT, OBSTACLE_END) ); //m_pObstacleMap[w+h*nWidth] = obstacle_id; break; case 8: //玩家起始位置

m_pPlayer[0]->SetXY(w*OBSTACLE_WIDTH,h*OBSTACLE_HEIGHT); break; case 1: //双弹坦克 //加入NC坦克链表 g_world.EnemyTankLink().Add( NEW TEnemyTank(w*OBSTACLE_WIDTH, h*OBSTACLE_HEIGHT, DOUBLE_MISSILE_TANK) ); break; case 2: //单弹坦克 //加入NC坦克链表 g_world.EnemyTankLink().Add( NEW TEnemyTank(w*OBSTACLE_WIDTH, h*OBSTACLE_HEIGHT, SINGLE_MISSILE_TANK) ); break; case 3: //火坦克 //加入NC坦克链表 g_world.EnemyTankLink().Add( NEW TEnemyTank(w*OBSTACLE_WIDTH, h*OBSTACLE_HEIGHT, FIRE_TANK) ); break;

case 0x81: //石头高地障碍 //在障碍地图中设置该位置为障碍 m_pObstacleMap[w+h*nWidth] = obstacle_id; break; default: //无障碍 m_pObstacleMap[w+h*nWidth] = 0; } } }

//关闭地图文件 map.Close();

//移动可视区到玩家坦克处 RECT rc;

g_world.GetViewportRect(rc);

int height= rc.bottom - rc.top - OBSTACLE_HEIGHT; int width= rc.right - rc.left - OBSTACLE_WIDTH;

g_world.SetViewport(Player(0)->GetX()-width/2,Player(0)->GetY()-height/2);

//画出场景,显示Ready DrawWorld();

sprintf(buf,\"Stage %d Ready\

WGE_Surface.OutTextXY((400-strlen(buf)*8)/2,140,buf); WGE_pScreen->Update();

//加载背景音乐

sprintf(buf,MEDIA(\"stage%d.mid\"),m_nStage); VERIFY(g_back_music.LoadMidi(buf,pDat)); g_back_music.SetRepeats(99999); g_back_music.Play();

//等待3秒

DWORD dwTimer = GetTickCount(); while(GetTickCount()-dwTimer < 3000);

//开始游戏

g_game_status = GAME_PLAY;

return TRUE; }

/////////////////////////////////////////////// //创建一个新世界

BOOL TWorld::CreateWorld(EDataFile *pDat) {

//删除旧游戏世界 DestroyWorld();

//创建一个新玩家

m_pPlayer[0] = NEW TPlayerTank(0,0,GREEN_TANK);

//加载第1关地图

return LoadStage(1,pDat); }

//////////////////////////////////////////////// //删除旧的世界

void TWorld::DestroyWorld() {

//删除地形地图 if(m_pTerrainMap){ MemFree(m_pTerrainMap); m_pTerrainMap = NULL; }

//删除障碍地图

if(m_pObstacleMap){ MemFree(m_pObstacleMap); m_pObstacleMap = NULL; }

m_nViewportHeight = m_nViewportWidth = 0; m_nViewportTop = m_nViewportLeft = 0;

//删除当前的玩家 if( m_pPlayer[0]){ delete m_pPlayer[0]; m_pPlayer[0]=NULL; }

//删除所有对象

m_EnemyTankLink.DeleteAll(); m_BonusLink.DeleteAll(); m_ObstacleLink.DeleteAll(); m_BulletLink.DeleteAll(); m_ExplodeLink.DeleteAll(); }

//////////////////////////////////////////

//设置可视区相对设备坐标的位置及大小

void TWorld::SetupViewport(int origin_x,int origin_y,int width, int height) {

m_nViewportOriginX = origin_x; m_nViewportOriginY = origin_y;

//调整可视区的高度及宽度不能超过世界的大小和屏幕的大小 int minHeight,minWidth;

minWidth = WGE_Surface.m_pBmp->ww:m_nWorldWidth;

minHeight = WGE_Surface.m_pBmp->hw:m_nWorldHeight;

if(origin_x+width>minWidth) width -= origin_x + width - minWidth; if(origin_y+height>minHeight) height -= origin_y + height - minHeight;

m_nViewportHeight = height; m_nViewportWidth = width; }

///////////////////////////////////////////////// //滚动可视区域

void TWorld::ScrollViewport(int dx, int dy) {

SetViewport(m_nViewportLeft + dx,m_nViewportTop + dy); }

///////////////////////////////////////////////// //设置可视区在游戏世界中的坐标 void TWorld::SetViewport(int x, int y) {

//设置可视区的坐标 m_nViewportTop = y; m_nViewportLeft = x;

//调整可视区坐标

if(m_nViewportTop<0) m_nViewportTop = 0;

if(m_nViewportTop + m_nViewportHeight >= m_nWorldHeight) m_nViewportTop = m_nWorldHeight - m_nViewportHeight -1;

if(m_nViewportLeft < 0) m_nViewportLeft = 0;

if(m_nViewportLeft + m_nViewportWidth >= m_nWorldWidth) m_nViewportLeft = m_nWorldWidth - m_nViewportWidth -1; }

/////////////////////////////////////////// //画出整个世界

void TWorld::DrawWorld() {

//保存屏幕缓冲面的剪载框

1, 1);

RECT rcClip;

rcClip.left = WGE_Surface.m_pBmp->clip->left; rcClip.right =WGE_Surface.m_pBmp->clip->right; rcClip.top = WGE_Surface.m_pBmp->clip->top;

rcClip.bottom =WGE_Surface.m_pBmp->clip->bottom; //取得可视区矩形 RECT rcViewport;

GetViewportRect(rcViewport); //然后转换为设备坐标 LPToDP(rcViewport);

//把可视区作为屏幕缓冲面的裁剪框

WGE_Surface.SetClip((short)rcViewport.left,(short)rcViewport.top, (short)rcViewport.right,(short)rcViewport.bottom);

//计算在可视区中显示的地形坐标范围

int top = m_nViewportTop /TERRAIN_WIDTH;

int bottom = (m_nViewportTop + m_nViewportHeight) /TERRAIN_HEIGHT; int left = m_nViewportLeft/TERRAIN_HEIGHT;

int right = (m_nViewportLeft + m_nViewportWidth) / TERRAIN_WIDTH; //画地形

for(int h=top;h<=bottom ;h++) for(int w=left;w<=right;w++) { WGE_Surface.Blt(m_grp_terrain, m_pTerrainMap[h*m_nMaxHorzTerrain+w], w*TERRAIN_WIDTH - m_nViewportLeft+m_nViewportOriginX -

}

h*TERRAIN_HEIGHT- m_nViewportTop+m_nViewportOriginY -

//画障碍物

m_ObstacleLink.DrawAll(); //画玩家

if(!m_pPlayer[0]->IsDead()) m_pPlayer[0]->Draw(); //画所有的敌军坦克

m_EnemyTankLink.DrawAll(); //画奖励物品

m_BonusLink.DrawAll(); //画子弹

m_BulletLink.DrawAll();

//画爆炸效果

m_ExplodeLink.DrawAll();

//恢复裁剪框

WGE_Surface.SetClip((short)rcClip.left,(short)rcClip.top, (short)rcClip.right,(short)rcClip.bottom);

//======================================================= //画分数条

//------------------------------------------------------- char msg[80];

//设置字符色为绿色

WGE_Surface.SetDrawColor(0,255,0);

//计算出分数条的位置 int x,y;

x = WGE_Surface.m_pBmp->w-160; y = 2;

//准备分数条字符串

sprintf(msg,\" %05d %05d %3d/%3d\ Player(0)->m_nExper, Player(0)->m_nMoney, Player(0)->m_nShield, Player(0)->m_nMaxShield);

//画分数条上的图标

WGE_Surface.Blt(m_epg_icon[0],Player(0)->m_nType,x,y); WGE_Surface.Blt(m_epg_icon[1],0,x+46,y); WGE_Surface.Blt(m_epg_icon[2],0,x+94,y);

//画分数条字符

WGE_Surface.OutTextXY(x,y,msg); }

///////////////////////////////////////////////

//取得可视区在世界坐标中的矩形框

void TWorld::GetViewportRect(RECT& rect) {

rect.left = m_nViewportLeft ; rect.top = m_nViewportTop ;

rect.right = m_nViewportLeft + m_nViewportWidth ; rect.bottom = m_nViewportTop + m_nViewportHeight ; }

//////////////////////////////////////////////////////////

//逻辑坐标转换到设备坐标(即把游戏坐标转换到屏幕坐标) void TWorld::LPToDP(RECT &rc) {

rc.top -= m_nViewportTop - m_nViewportOriginY; rc.left -= m_nViewportLeft - m_nViewportOriginX; rc.bottom -= m_nViewportTop - m_nViewportOriginY; rc.right -= m_nViewportLeft - m_nViewportOriginX; }

//////////////////////////////////////////////////////////

//逻辑坐标转换到设备坐标(即把游戏坐标转换到屏幕坐标) void TWorld::LPToDP(POINT &pt) {

pt.x -= m_nViewportLeft - m_nViewportOriginX; pt.y -= m_nViewportTop - m_nViewportOriginY; }

////////////////////////////////////////////////// //让精灵移动

BOOL TWorld::Move() {

if(!m_pPlayer[0]->IsDead()) //没死,Move m_pPlayer[0]->Move(); else { //死了,GAME OVER g_game_status = GAME_OVER; }

//处理其它对象的行动 m_BonusLink.MoveAll(); m_ObstacleLink.MoveAll(); m_EnemyTankLink.MoveAll(); m_BulletLink.MoveAll(); m_ExplodeLink.MoveAll();

return TRUE; }

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务