QT坦克小战

目录

设计思路

首先使用二维数组绘制存放地图信息,并在主界面绘制地图,然后通过主界面中的定时器进行地图刷新绘制。

初始状态下,绘制一辆己方的坦克、随机生成三辆敌方坦克。使用W、S、A、D、空格键,控制我方坦克的移动和子弹发射。检测坦克碰撞类型,并作出相应的限制和操作。

子弹发射后,创建一个子弹对象,记录子弹的方向、当前所在位置,加入容器。检测子弹碰撞类型,并做出对应的操作。

效果展示

图1
图2

使用的类

程序主要分为地图类、坦克类、子弹类以及游戏主界面
地图类:使用2626的二维int数组。基本单位是1515像素的小地图块。

计时器:每5ms刷新一次。

坦克类:坦克为30*30像素的图片,分为我方坦克和敌方坦克。

成员变量:横纵坐标、坦克方向、生命值

敌对方坦克被子弹击中一次后消失

子弹类:子弹为6*6像素的图片

成员变量:横纵坐标、子弹方向、子弹存活状况

游戏主界面:包含绘制的地图、坦克、子弹

程序概述

地图绘制

重写绘画事件(paintEvent),定义画家来绘制地图、坦克和子弹,由计时器(timer)激发绘画事件,呈现出坦克和子弹移动的动态效果。

坦克移动

我方坦克

设置四个bool型数据,分别代表上下左右。如果某一数据为true,则表示向该方向移动。重写键盘按压事件(mouseEvent),捕捉键值来改变这四个bool类型的值。

每当计时器(timer)运行一次,就对捕捉的键值进行判断。当只有这四个数据中的某一个数据为true时,我方坦克就根据在该方向上的移动规则移动。

移动判断:

首先判断坦克是否越界,即横纵坐标是否满足整个坦克在游戏界面。

坦克与地图块的碰撞分为以下情况:地图为空、地图为墙壁。

地图为空:正常前进;

地图为墙壁:不前进;

碰撞检测:将坦克横纵坐标转换成对应的地图数组坐标,判断即将前进的地图类型是否空,为空就可以前进,否则不前进。判断地图时类型时,有两种情况:1、坦克刚好在两个小地图块。2、坦克在三个小地图块中间。

敌方坦克

设置四个bool型数据,分别代表上下左右。如果某一数据为true,则表示向该方向移动。生成随机数,判断随机数的范围,进而控制敌方坦克的移动方向,30%的概率转向,70%的概率直行。

每当计时器(timer)运行一次,就对随机数范围进行判断。当只有这四个数据中的某一个数据为true时,敌方坦克就根据在该方向上的移动规则移动。

移动判断:

首先判断坦克是否越界,即横纵坐标是否满足整个坦克在游戏界面。

坦克与地图块的碰撞分为以下情况:地图为空、地图为墙壁。

地图为空:正常前进;

地图为墙壁:不前进;

碰撞检测:将坦克横纵坐标转换成对应的地图数组坐标,判断即将前进的地图类型是否空,为空就可以前进,否则不前进。判断地图时类型时,有两种情况:1、坦克刚好在两个小地图块。2、坦克在三个小地图块中间。

子弹移动

设置int类型的数据,分别表示子弹的横纵坐标、方向和存活状况。子弹的方向一旦产生,就固定不变。

每当计时器(timer)运行一次,就对子弹进行移动判断,满足条件即改变依次坐标,进行移动;不满足条件,做出相应的操作。

移动判断:

首先判断子弹是否越界,即横纵坐标是否子弹在游戏界面。

子弹与地图块的碰撞分为以下情况:地图为空、地图为墙壁。

地图为空:子弹移动;

地图为墙壁:子弹消失,土墙消失,铁墙不变;

子弹与坦克的的碰撞:敌方坦克消失、子弹消失( vector.remove() )。

碰撞检测:将子弹的横纵坐标转换成对应的地图数组坐标,判断即将前进的地图类型是否空,为空就可以前进,否则子弹和对应的地图都消失。判断地图时类型时,有两种情况:1、子弹刚好在一个小地图块。2、子弹在两个小地图块中间。

子弹发射

重写键盘按压事件(mouseEvent),捕捉键值,为空格键发射子弹。

首先定义一个子弹类型的容器(vector),每发射一颗子弹,便用子弹类创建一个对象,记录该时刻横纵坐标、方向,然后将该对象加入容器中( vector.append() )。

每当计时器(timer)运行一次,就对容器里的子弹用for循环遍历( vector.count() ),进行移动和碰撞检测。

相关代码

buttle.h

#ifndef BULET_H
#define BULET_H
#include <QPixmap>

class bulet
{
public:
    QPixmap *bulet_pic;
    bulet();
    void set_pos(int x, int y ,int dir);
    int bulet_dir;
    int bulet_x;
    int bulet_y;
    void move();
private:
    int bulet_blood = 1;
};
#endif // BULET_H

map.h

#ifndef MAP_H
#define MAP_H

#include <QWidget>
#include <QVector>
#include <QLabel>
#include <QPixmap>
#include <QPaintEvent>
#include <QPainter>
class map : public QWidget
{
    Q_OBJECT
public:
    explicit map(QWidget *parent = nullptr);
    int mapbuf[26][26]={{0,0,0,0,0,0,0,0,1,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,1,1,0,3,3,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,3,3,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,3,3,0,0,0,1,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,0,0,0,0,1,1,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,1,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,1,1,0,0,0,0,2,2,2,2,2,2,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,2,2,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,0,0,0,0,1,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                        {0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0},
                        {0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
                        {0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0}};       //26*26的数组,一小块代表15*15像素
    void display();
    void paintEvent(QPaintEvent *event);
    QPixmap *q;
signals:
public slots:
private:
};
#endif // MAP_H

tank.h

#ifndef TANK_H
#define TANK_H

#include <QWidget>
#include <QPixmap>
#include "bulet.h"
class tank : public QWidget
{
    Q_OBJECT
public:
    explicit tank(int b,QWidget *parent = nullptr);
    void way_key(int);
    bool test_blood();
    void move();
    int old_y;
    int old_x;
    int jiaodu;
    int t_dir = 0;
    QPixmap *d_tank;

    void set(int x, int y){
        old_x = x;
        old_y = y;
    }
    bool up = false;           //向前
    bool back =  false;         //向后
    bool right =  false;        //向右
    bool left = false;         //向左
    QVector<bulet *> buletlist;
signals:

public slots:
private:
    int blood;         //血量
};
#endif // TANK_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include "map.h"
#include "tank.h"
#include <QWidget>
#include <QPaintEvent>
#include <QTimerEvent>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QMatrix>
#include "bulet.h"
#include <QtGlobal>
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
    void paintEvent(QPaintEvent *event);
    void timerEvent(QTimerEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    bool move_t(int direct);
    void my_move();
    void d_move(tank *);
    void bulet_move(int i);
    bool d_move_t(int drect, tank *t);
private:
    //QPainter *p;
    int jiaodu = 0;
    int old_y;             //
    int old_x;

    QPixmap *back;
    //我方坦克的类
    tank *mytank;
    QPixmap *my;   //坦克图片
   // QPixmap *new_my;

    //地方坦克的类(20个)
    QVector<tank *> tanklist;
    int k = 999;
    //地图的类
    map *mymap;
    //计数时间
};
#endif // WIDGET_H

main.cpp


#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

buttle.cpp

#include "bulet.h"

bulet::bulet()
{
}
void bulet::set_pos(int x, int y,int dir)
{
    bulet_x = x;
    bulet_y = y;
    bulet_dir = dir;
}
void bulet::move()
{
}

map.cpp

#include "map.h"
#include <QDebug>
map::map(QWidget *parent) : QWidget(parent)
{
     qDebug() << "dasdmmmm";
}
void map::paintEvent(QPaintEvent *event)
{
}

void map::display()
{
    update();
}

tank.cpp

#include "tank.h"
#include <QDebug>
tank::tank(int b,QWidget *parent) : QWidget(parent), blood(b)
{

}

void tank::way_key(int key)
{
    qDebug() << key;
    switch (key) {
        case 65  :left = true; break;
        case 83 :back = true; break;
        case 87 :up = true; break;
        case 68  :right = true; break;
    }
}

bool tank::test_blood()
{
    if(blood == 0){    //表示死亡
        return false;
    }else{
        return true;   //表示存货
    }
}

void tank::move()
{
}

widget.cpp

#include "widget.h"
#include "QDebug"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //setFixedSize(800,800);
    //定义地图类的对象
    setFixedSize(600,390);
    mymap = new map;

    //设置地图
    mymap->q = new QPixmap(390,390);
    mymap->q->fill(Qt::black);

    //定义坦克类的对象(我方与敌方)
    mytank = new tank(3);
    my = new QPixmap;
    my->load(":/mytamke.png");
    old_x = 120;
    old_y = 360;
    startTimer(5);
}

void Widget::paintEvent(QPaintEvent *event)	//写的代码过多,此处以流程代写
{
	//绘制地图
	/*绘制我方坦克
	  坦克移动判断(包含碰撞)*/
	/*绘制敌方坦克
	  坦克移动判断(包含碰撞)*/
	/*绘制子弹
	  子弹移动判断(包含碰撞)*/
}
//我方坦克碰撞检测
bool Widget::move_t(int drect)
{
}

//敌方坦克碰撞检测
bool Widget::d_move_t(int drect, tank *t)
{
}

//我方坦克移动
void Widget::my_move()
{
}

//敌方坦克移动
void Widget::d_move(tank * t)
{
}

//重写键盘按压事件
void Widget::keyPressEvent(QKeyEvent *event)
{
}

//主界面的析构函数
Widget::~Widget()
{
}
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值