发射子弹
单独的子弹类根据坦克属性生成相应的子弹对象。
//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 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;iif(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;iMove();
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;ifor(int j=0;jif(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
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