C++(qt)游戏实战项目:坦克大战(五)

2017年06月19日 21:26:06

发射子弹
单独的子弹类根据坦克属性生成相应的子弹对象。

//file bullet.h
#ifndef BULLET_H
#define BULLET_H

#include"wanwu.h"
#include"tank.h"
class Bullet : public Wanwu
{
public:
    Bullet(const Tank &tank);
    // 绘图
  void Display(QPainter &paint) ;

    // 移动
    void Move() ;
    //
    protected:
    void CalculateSphere();
private:
    int style;
    int group;//子弹所在组

};

#endif // BULLET_H
//file bullet.cpp
#include "bullet.h"
#include"status.h"
Bullet::Bullet(const Tank &tank)
{
    m_dir=tank.m_dir;
    m_pos=tank.m_pos;
    style=tank.style/2;
    m_step=tank.m_step+10;
    wuli=tank.wuli;
    fashu-tank.fashu;
    group=tank.group;
    m_bDisappear=false;
CalculateSphere();
}

void Bullet::Display(QPainter &paint){
   if(m_bDisappear==true)return;
    switch(m_dir){
        case UP:

           paint.drawImage(m_rectSphere,*glo.bulletimage,QRect(2*PICBULLETWIDTH,style*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//身体
           //paint.drawImage(xm_rectSphere,*glo.bulletimage,QRect(2*PICBULLETWIDTH,(style*2+1)*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//炮塔
            break;
        case DOWN:
            paint.drawImage(m_rectSphere,*glo.bulletimage,QRect(0*PICBULLETWIDTH,style*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//身体
            //paint.drawImage(xm_rectSphere,*glo.bulletimage,QRect(0*PICBULLETWIDTH,(style*2+1)*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//炮塔
            break;
        case LEFT:
            paint.drawImage(m_rectSphere,*glo.bulletimage,QRect(1*PICBULLETWIDTH,style*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//身体
            //paint.drawImage(xm_rectSphere,*glo.bulletimage,QRect(1*PICBULLETWIDTH,(style*2+1)*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//炮塔
            break;
        case RIGHT:
            paint.drawImage(m_rectSphere,*glo.bulletimage,QRect(3*PICBULLETWIDTH,style*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//身体
            //paint.drawImage(xm_rectSphere,*glo.bulletimage,QRect(3*PICBULLETWIDTH,(style*2+1)*PICBULLETHEIGHT,PICBULLETWIDTH,PICBULLETHEIGHT));//炮塔
            break;
      }



}




void Bullet::Move(){


     switch(m_dir){
         case UP:
             m_pos.setY(m_pos.y()-m_step);
             break;
         case DOWN:
             m_pos.setY(m_pos.y()+m_step);
             break;
         case LEFT:
             m_pos.setX(m_pos.x()-m_step);
             break;
         case RIGHT:
             m_pos.setX(m_pos.x()+m_step);
             break;
       }
     CalculateSphere();

//子弹是否与地图块碰撞
     for(int i=0;i<INUM;i++)
         for(int j=0;j<JNUM;j++)
          if(glo.gamemap->getcell(i,j))
           if(!glo.gamemap->getcell(i,j)->ischuantou1())
          if(IsBoom(*glo.gamemap->getcell(i,j)))
          {glo.gamemap->getcell(i,j)->downlife(wuli,0);m_bDisappear=true;
          *glo.status=Status(*glo.gamemap->getcell(i,j));

          }

//子弹是否击中敌对坦克
     for(int i=0;i<glo.badtanks.count();i++)
     if(glo.badtanks.at(i)&&glo.badtanks.at(i)->group!=this->group&&IsBoom(*glo.badtanks.at(i)))
     {

        m_bDisappear=true;//子弹消失
        glo.badtanks.at(i)->downlife(wuli);
        *glo.status=Status(*glo.badtanks.at(i));//将打中的对象的血量显示出来

     }

     if(glo.player->group!=this->group&&IsBoom(*glo.player))
     {

         m_bDisappear=true;//子弹消失
         glo.player->downlife(wuli);
         *glo.status=Status(*glo.player);//将打中的对象的血量显示出来

     }


//子弹出界
     if(m_pos.x()<0||m_pos.x()>WIDTH||m_pos.y()>HEIGHT||m_pos.y()<0)
         m_bDisappear=true;//子弹消失


}




void Bullet::CalculateSphere(){


this->m_rectSphere.setRect(m_pos.x()-BULLETWIDTH/2,m_pos.y()-BULLETHEIGHT/2,BULLETWIDTH,BULLETHEIGHT);

}

坦克拥有子弹,我们可以用包含关系来管理子弹,坦克发射子弹就是新建一个子弹对象插入到子弹链表中
坦克类更改如下

#ifndef TANK_H
#define TANK_H
#include"wanwu.h"
#include"main.h"
#include"gamemap.h"
#include"bullet.h"
class Tank : public Wanwu
{
protected:
    QList<Bullet*> bullets;
     static int steps[8];
     static float lifes[8];
     static float wulis[8];
     static float fashus[8];
     static float hujias[8];
     static float mokangs[8];
     static int gongjijianges[8];
   int  group;//坦克所在组
   // 计算势力范围
   virtual void CalculateSphere();
public:
   friend class Bullet;
    Tank();
    Tank(int iIndex,int jIndex,Dir dir=UP,int style=0,int group=1);


    // 绘图
    void Display(QPainter &paint);

    // 移动
    void Move();
    //
    void Move1();//fangzhi si xun huan
    //设置移动状态为开
    void startmove(){ismove=true;}
    //设置移动状态为关
    void stopmove(){ismove=false;}
    //
    void fire();
    void startfire();
    void stopfire();
    //设置方向
    void setdir(Dir dir){m_dir=dir;}
    //坦克下一步 是否和地图块碰撞
   bool nextsiboom();


private:
    int style;
    bool ismove;
    bool isfire;
    int gongjijiange;

};

#endif // TANK_H

#include "tank.h"
int Tank::steps[8]={4,8,8,16,16,32,32,64};
float Tank::lifes[8]={200,400,600,800,900,1100,1300,1500};
float Tank::wulis[8]={20,40,80,160,160,320,320,640};
float Tank::fashus[8]={20,40,80,160,160,320,320,640};
float Tank::hujias[8]={50,70,90,110,130,150,170,190};
float Tank::mokangs[8]={50,70,90,110,130,150,170,190};
int Tank::gongjijianges[8]={8,7,6,5,4,3,2,2};
Tank::Tank()
{
    this->m_pos.setX(10*CELLWIDTH+CELLWIDTH/2);
    this->m_pos.setY(8*CELLHEIGHT+CELLHEIGHT/2);
    this->wuli=200;
    this->group=0;//0玩家组,1敌人组
    m_step=16;
    gongjijiange=3;
    this->style=0;
    ismove=false;
    m_dir=UP;
    isfire=false;
    m_bDisappear=false;
    life=1000;
    CalculateSphere();
}


Tank::Tank(int iIndex,int jIndex,Dir dir,int style,int group){
    this->m_pos.setX(jIndex*CELLWIDTH+CELLWIDTH/2);
    this->m_pos.setY(iIndex*CELLHEIGHT+CELLHEIGHT/2);
    this->m_dir=dir;
    this->style=style;
    this->group=group;
    isfire=false;
    wuli=wulis[style];
    fashu=fashus[style];
    hujia=hujias[style];
    mokang=mokangs[style];
    m_step=steps[style];
    gongjijiange=gongjijianges[style];
    m_bDisappear=false;
    life=lifes[style];
    CalculateSphere();
}




void Tank::Display(QPainter &paint){
    for(int i=0;i<bullets.count();i++)
        if(bullets.at(i)&&!bullets.at(i)->IsDisappear())
    bullets.at(i)->Display(paint);
        else if(bullets.at(i)){
            delete bullets.at(i);//回收new出来的对象空间
            bullets.removeAt(i);//将对象指针从链表删除
            i--;
        }

    QRect xm_rectSphere=m_rectSphere;
    if(m_bDisappear)return;
    switch(m_dir){
        case UP:

           paint.drawImage(m_rectSphere,*glo.tankimage,QRect(2*PICTANKWIDTH,style*2*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//身体
           paint.drawImage(xm_rectSphere,*glo.tankimage,QRect(2*PICTANKWIDTH,(style*2+1)*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//炮塔
            break;
        case DOWN:
            paint.drawImage(m_rectSphere,*glo.tankimage,QRect(0*PICTANKWIDTH,style*2*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//身体
            paint.drawImage(xm_rectSphere,*glo.tankimage,QRect(0*PICTANKWIDTH,(style*2+1)*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//炮塔
            break;
        case LEFT:
            paint.drawImage(m_rectSphere,*glo.tankimage,QRect(1*PICTANKWIDTH,style*2*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//身体
            paint.drawImage(xm_rectSphere,*glo.tankimage,QRect(1*PICTANKWIDTH,(style*2+1)*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//炮塔
            break;
        case RIGHT:
            paint.drawImage(m_rectSphere,*glo.tankimage,QRect(3*PICTANKWIDTH,style*2*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//身体
            paint.drawImage(xm_rectSphere,*glo.tankimage,QRect(3*PICTANKWIDTH,(style*2+1)*PICTANKHEIGHT,PICTANKWIDTH,PICTANKHEIGHT));//炮塔
            break;
      }

}
void Tank::Move()
{
    for(int i=0;i<bullets.count();i++)
    bullets.at(i)->Move();
   if(m_bDisappear)return ;
   if(nextsiboom())return;
   if(ismove==true){
    switch(m_dir){
        case UP:
            m_pos.setY(m_pos.y()-m_step);
            break;
        case DOWN:
            m_pos.setY(m_pos.y()+m_step);
            break;
        case LEFT:
            m_pos.setX(m_pos.x()-m_step);
            break;
        case RIGHT:
            m_pos.setX(m_pos.x()+m_step);
            break;
      }
    CalculateSphere();
    qDebug("move on");
 }
qDebug("move off");
}

void Tank::Move1()//和move一样,为了避免死循环
{
   if(ismove==true){
    switch(m_dir){
        case UP:
            m_pos.setY(m_pos.y()-m_step);
            break;
        case DOWN:
            m_pos.setY(m_pos.y()+m_step);
            break;
        case LEFT:
            m_pos.setX(m_pos.x()-m_step);
            break;
        case RIGHT:
            m_pos.setX(m_pos.x()+m_step);
            break;
      }
    CalculateSphere();
    qDebug("yuce ");
 }
qDebug("move off");
}


bool Tank::nextsiboom(){
 Tank tmp=*this;
 tmp.Move1();
 //qDebug("%d",tmp.m_rectSphere.right());
 //qDebug("%d",glo.gamemap->getcell(1,4)->m_rectSphere.left());
 //是否与地图块碰撞
 for(int i=0;i<INUM;i++)
     for(int j=0;j<JNUM;j++)
         if(glo.gamemap->getcell(i,j)&&!glo.gamemap->getcell(i,j)->ischuantou()&&tmp.IsBoom(*glo.gamemap->getcell(i,j))){
            qDebug("-----------boom-------"); return true;
         }
 qDebug("---------------");
 //是否与地图边界碰撞
 if(tmp.m_rectSphere.left()<0||tmp.m_rectSphere.right()>WIDTH||tmp.m_rectSphere.bottom()>HEIGHT||tmp.m_rectSphere.top()<0)
 return true;//

 return false;
}


void Tank::fire(){
    if(m_bDisappear)return;
if(isfire==true&&glo.framei%gongjijiange==0){
Bullet *newbullet=new Bullet(*this);
bullets.append(newbullet);
}

}


void Tank::startfire(){

    isfire=true;

}

void Tank::stopfire(){



    isfire=false;
}



void Tank::CalculateSphere(){

this->m_rectSphere.setRect(m_pos.x()-TANKWIDTH/2,m_pos.y()-TANKHEIGHT/2,TANKWIDTH,TANKHEIGHT);

}

地图块类有些能被子弹穿透,有些能被坦克穿透,因此增加两个属性。外加其他方面更改

#ifndef MAPCELL_H
#define MAPCELL_H

#include"wanwu.h"
#include"main.h"
#include<fstream>
class Mapcell : public Wanwu
{
public:
        enum {BLOCKSNUM=13};
        static float lifes[BLOCKSNUM];
        static float hujias[BLOCKSNUM];
        static float mokangs[BLOCKSNUM];
        static bool chuantous[BLOCKSNUM];
        static bool chuantous1[BLOCKSNUM];
    Mapcell();
    Mapcell(int iIndex, int jIndex, int style=0);//护甲魔抗物理攻击魔法攻击攻击速度移动速度暂时用不到
    // 绘图
    void Display(QPainter &paint);

    // 移动
   void Move();
   //得到方块样式
   int getstyle(){return style;}
   //切换样式
   int switchstyle(){style++;style=style%BLOCKSNUM; this->life=lifes[this->style];
                     this->hujia=hujias[this->style];
                     this->mokang=mokangs[this->style];
                     this->chuantou=chuantous[this->style];
                     this->chuantou1=chuantous1[this->style];return style;}
   //设置样式
   void setstyle(int style){this->style=style%BLOCKSNUM; this->life=lifes[this->style];
                            this->hujia=hujias[this->style];
                            this->mokang=mokangs[this->style];
                            this->chuantou=chuantous[this->style];
                            this->chuantou1=chuantous1[this->style];}
   //
   bool ischuantou(){return chuantou;}
   //
   bool ischuantou1(){return chuantou1;}
private:
//static QImage blockimage;
   int style;//方块样式,从图片上依次编号0 ,1,2 ,3,4,5.。。。。
   //
   void cal(int style,int &i,int &j){//将一维编号变成一行有4列的二维编号i行j列
     i=style/4;
    j=style%4;
   }
void CalculateSphere(){
    this->m_rectSphere.setRect(m_pos.x()-CELLWIDTH/2,m_pos.y()-CELLHEIGHT/2,CELLWIDTH,CELLHEIGHT);

}

bool chuantou;//坦克能否穿透方块
bool chuantou1;//子弹能否穿透方块

};

#endif // MAPCELL_H
#include "mapcell.h"
//QImage Mapcell::blockimage=QImage(":/images/map_block.png"); linux
float Mapcell::lifes[BLOCKSNUM]={30000,3000,2000,1000,800,700,600,20000,0,0,0,0,0};
float Mapcell::hujias[BLOCKSNUM]={1000,500,400,300,200,100,50,800,0,0,0,0,0};
float Mapcell::mokangs[BLOCKSNUM]={1000,500,400,300,200,100,50,800,0,0,0,0,0};
bool Mapcell::chuantous[BLOCKSNUM]={false,false,false,false,false,false,false,false,true,true,true,true,true};
bool Mapcell::chuantous1[BLOCKSNUM]={false,false,false,false,false,false,false,false,true,true,true,true,true};
Mapcell::Mapcell()
{
    this->m_pos.setX(8*CELLWIDTH+CELLWIDTH/2);
    this->m_pos.setY(8*CELLHEIGHT+CELLHEIGHT/2);
    this->CalculateSphere();
    this->m_bDisappear=false;
    this->style=0;//map_block.png总共有28小块
    this->life=lifes[this->style];
    this->hujia=hujias[this->style];
    this->mokang=mokangs[this->style];
    this->chuantou=chuantous[this->style];
    this->chuantou1=chuantous1[this->style];

}

Mapcell::Mapcell(int iIndex,int jIndex,int style){//护甲魔抗物理攻击魔法攻击攻击速度移动速度暂时用不到
    this->m_pos.setX(jIndex*CELLWIDTH+CELLWIDTH/2);
    this->m_pos.setY(iIndex*CELLHEIGHT+CELLHEIGHT/2);
    this->CalculateSphere();
    this->m_bDisappear=false;
    this->style=style%BLOCKSNUM;//map_block.png总共有28小块
    this->life=lifes[this->style];
    this->hujia=hujias[this->style];
    this->mokang=mokangs[this->style];
    this->chuantou=chuantous[this->style];
    this->chuantou1=chuantous1[this->style];
}


void Mapcell::Display(QPainter &paint){
int i,j;
cal(style,i,j);
if(!this->IsDisappear())
paint.drawImage(m_rectSphere,*glo.blockimage,QRect(j*PICWIDTH,i*PICHEIGHT,PICWIDTH,PICHEIGHT));//优化代码,速度飞一般
//paint.drawImage(m_rectSphere,QImage(":/images/map_block.png"),QRect(j*PICWIDTH,i*PICHEIGHT,PICWIDTH,PICHEIGHT));


}
void Mapcell::Move(){



}

增加一个状态类。为了实时记录被子弹打种物体的血量

#ifndef STATUS_H
#define STATUS_H

#include"wanwu.h"
class Status
{
public:
    float life;
    Status(){life=0;}
    Status(const Wanwu &wanwu);
    void Display(QPainter &paint);
};

#endif // STATUS_H
#include "status.h"
#include<QColor>
Status::Status(const Wanwu &wanwu)
{
life=wanwu.life;
}

void Status::Display(QPainter &paint){

    paint.drawText(500,180,QString("life:")+QString::number(life));

}

void MainWindow::keyPressEvent(QKeyEvent *event)函数中加入

else if(event->key()==Qt::Key_J){

                 glo.player->startfire();

          }

Glo结构体加入

Status *status;

MainWindow::MainWindow(QWidget *parent)里加入

glo.status=new Status();

MainWindow::paintEvent(QPaintEvent *event)函数加入

glo.status->Display(paint);

这样就完成了坦克发射子弹和血量的显示

本文章为作者原创
转载请标明本系列文章地址:http://blog.csdn.net/qq_26046771/article/details/72643740

C++实战项目:坦克大战(一)

对坦克大战情有独钟是因为大学时候第一次参加程序设计比赛就做的这个游戏。当时用的语言是Java,那个比赛让我悟出了面向对象的强大之处,我也是从那时开始接触设计模式的。对我而言,坦克大战有着非同寻常的意义...
  • qq_26046771
  • qq_26046771
  • 2017年03月26日 08:54
  • 8725

c++坦克大战

这是做的第一个小游戏,虽然小但也同样花了很多时间,对它有了自己的情感,我希望能一直保存下去,所以放到博客上也是不错的选择?就从这里开始一步步向游戏开发靠近。(游戏需要引入外部资源,博客上放不上去,光复...
  • s759012193
  • s759012193
  • 2016年09月01日 21:54
  • 2846

c++ 大作业 实现坦克大战

  • 2016年06月24日 22:20
  • 16KB
  • 下载

C++坦克大战游戏源码

  • 2016年06月29日 15:05
  • 1.36MB
  • 下载

C++版的坦克大战(1)---实现基本设计和j简单思想

最近在学习c++,发现好难学,还在还学会一点。那么,就学以致用一下,打算写个c++简单版的坦克游戏。只所以选择做这个,因为比较简单。         相信很多人都玩过这个游戏,如果没有玩过的话,可以去...
  • oBuYiSeng
  • oBuYiSeng
  • 2015年09月01日 17:53
  • 2441

C/C++坦克大战源代码

  • 2015年09月19日 15:45
  • 137KB
  • 下载

坦克大战游戏源代码(C++源代码)

  • 2011年02月27日 12:44
  • 62KB
  • 下载

用Qt写的一个坦克大战游戏

学习C++有一段时间了,于是想做点项目练练手,苦于MFC学起来比较困难,就用Qt写了一个简单的坦克大战游戏,没有用复杂的算法,而是用的Qt库提供的库函数实现碰撞检测,这里的主要实现方法依靠getRec...
  • u010101067
  • u010101067
  • 2014年10月14日 16:45
  • 2513

坦克大战C++源代码

  • 2011年01月11日 15:45
  • 2.61MB
  • 下载

QT下实现的简单坦克大战

  • 2014年07月29日 22:15
  • 8.07MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++(qt)游戏实战项目:坦克大战(五)
举报原因:
原因补充:

(最多只允许输入30个字)