QT FC坦克大战(附源码)

QT FC坦克大战

QT设计的类似FC坦克大战的程序。暂时只完成了单人模式,双人模式可以后续自行添加。

源码以及图片音频资源下载地址:上传暂时还在审核中...后续更新

目录

QT FC坦克大战

程序描述

程序基本思路

程序的基本框架

主要思路

部分算法

我方坦克移动控制

敌方坦克移动,子弹发射

子弹移动

子弹发射

我方子弹与敌方坦克的碰撞检测

 敌方坦克与敌方坦克的碰撞检测

 界面设计

程序窗口基本框架

菜单界面

实际运行效果


程序描述

关卡为26*26的方格,背景为黑色。

关卡内,场景对象包括环境:砖块,铁块,草,水,大本营;角色:我方坦克,敌方坦克;

移动:我方坦克,可以通过WASD四个按键,实现方向控制,敌方坦克,会随机移动。坦克遇到砖块,铁块与水,会无法继续前行,遇到草会隐藏在草丛下方。敌方坦克的行为规则:如果能继续前进,则坦克以0.7的概率前进,0.3的概率向其他三个方向转向。如果被挡住,四个方向各以0.25的概率转向。任何时刻,坦克都以0.3的概率向当前方向发射子弹。

发射子弹:我方坦克通过按鼠标左键,发射子弹,敌方坦克,随机发射子弹。子弹以恒定速度前行。

子弹击中砖块,会令砖块消失,同时子弹消失。击中铁块,子弹消失,铁块不变。击中水与草,会穿过。子弹碰到四周边界会消失。子弹击中对方坦克,会令对方坦克消失,并显示0.5秒钟爆炸特效。

子弹击中大本营,会判定失败。

关卡开始后,会随机在最顶行刷新20只坦克,刷新时,会显示0.5秒钟出生特效,我方坦克出生时会显示无敌特效。

敌方坦克有三种,分别为被子弹击中一次,两次,三次击杀。我方坦克被击中三次后死亡。敌方坦克彼此击中不会死亡。

当对方二十辆坦克都被击杀后,我方胜利。当我方被击杀三次,或者大本营被摧毁后,敌方胜利。

实现多关卡,主要为原任天堂游戏地图。

添加部分音效,为原游戏音效。

实现动态显示剩余坦克数、关卡数、我方坦克生命值,与原任天堂游戏相似。

实现游戏结束画面,与原任天堂游戏相似。

程序运行效果如下(GIF):

QT FC坦克大战(附源码)

程序基本思路

程序的基本框架

对程序进行板块划分,划分为地图、坦克类、我方坦克类(继承坦克类、调用子弹类)、敌方坦克类(继承坦克类、调用子弹类)、子弹类以及两个窗口(菜单窗口和游戏窗口)。

QT FC坦克大战(附源码)

地图:使用26*26的二维int数组(地图块种类:nothing 0, wall 1, steel 2, sand 3, water 4, grass 5, boss 6,boss boom 7)。地图由13*13个30*30像素的大地图块组成,每个大地图块由四个15*15像素的小地图块组成。

计时器(timer)每100ms刷新一次。

坦克类

坦克为30*30像素的图片;

成员变量:横纵坐标(x,y)、坦克方向(dir)、坦克速度(speed)、生命值(hp)、坦克等级(level)、坦克是否存活(isAlive)、坦克是否隐藏(mask)、地图数组(map);

坦克是否隐藏(mask)用于判断坦克碰撞到草地(grass)后,是否隐藏;

生命值(hp)用于判断坦克剩余受击次数,位0时,坦克爆炸;

坦克等级主要用于判断敌方坦克的类型,被子弹击中一次,两次,三次后击杀爆炸。

子弹类:

成员变量:横纵坐标(x,y)、子弹数量(count)、子弹方向(dir)、子弹速度(speed)、子弹碰撞类型(collision)、子弹是否存活(isAlive);

子弹碰撞类型用于表示子弹击中的目标类型(地图块、子弹、坦克、边界、营地五种情况),方便判断被击中目标的下一步绘制方法。

我方坦克类(继承坦克类、调用子弹类):

子弹类类对象(bullet),自定义子弹类vector容器(bullet_vector);

成员函数:void fire() 我方坦克的发射子弹函数;

成员变量:计时器(timer)、判断上下左右(up、down、left、right);

槽函数:void move()  我方坦克移动的槽函数。

敌方坦克类(继承坦克类、调用子弹类):

成员函数:void run() 敌方坦克的移动函数;

子弹类类对象(en_bullet),自定义子弹类vector容器(en_bullet_vector)。

菜单界面:

槽函数:void on_pushButton_clicked();

        void on_L_Reco_clicked();

        void on_EXIT_clicked();

分别对应开始游戏、帮助和退出游戏。

我方坦克(JPG)
QT FC坦克大战(附源码)

敌方坦克(JPG)

level1QT FC坦克大战(附源码)  level2QT FC坦克大战(附源码) level3QT FC坦克大战(附源码)

地图块(JPG)

grassQT FC坦克大战(附源码)  wallQT FC坦克大战(附源码)  iceQT FC坦克大战(附源码)  ironQT FC坦克大战(附源码)  riverQT FC坦克大战(附源码)

子弹(JPG)

QT FC坦克大战(附源码)

子弹爆炸(JPG)

QT FC坦克大战(附源码)

坦克爆炸(JPG)

QT FC坦克大战(附源码)

游戏音频(WAV)

QT FC坦克大战(附源码)

主要思路

游戏开始时播放对应音频(.wav);

首先根据地图数组进行绘制地图,然后通过我方坦克类中的定时器(timer)进行我方子弹和敌方子弹、我方子弹和敌方坦克、敌方坦克和敌方坦克、敌方子弹和我方子弹、敌方子弹和敌方子弹的碰撞检测,制造敌方坦克,营地击中检测、地图更新;

通过对我方坦克的移动控制(即W、S、A、D、鼠标左键的点击),实现我方坦克的移动和发射子弹。当碰撞到草地(grass)时,停止绘制我方坦克,但横纵坐标依然更新,直到坦克完全移出草地(grass)。当我方坦克被击中三次后,爆炸,游戏结束;

子弹射出时,压入到对应的vector中,包括子弹的速度、方向、横纵坐标等信息。子弹射出后,根据一定规则运动。当子弹发生碰撞时,通过判断碰撞的对象,从而改变子弹碰撞类型(collision)的值,根据不同的碰撞类型值在更新绘制时实现对子弹、坦克和地图块的更新,同时该子弹从vector中清除。如果子弹所属的坦克没有存活,该子弹从vector中清除;

首先创建3个敌方坦克到地图中,同时压入到自定义敌方坦克类vector容器中,且开始移动。当vector中的坦克数小于5时,在三个固定出生点随机创造一个敌方坦克,同时创建子弹压入对应vector中,以此循环,直至地图中坦克数等于5。敌方坦克的等级随机刷新。敌方坦克根据一定的规则移动和发射子弹。当碰撞到草地(grass)时,停止绘制敌方坦克,但横纵坐标依然更新,直到坦克完全移出草地(grass)。

绘制时根据地图数组依次绘制地图块,根据自定义敌方坦克类vector容器依次绘制敌方坦克,根据自定义子弹类依次绘制子弹,根据我方坦克横纵坐标绘制我方坦克;

游戏结束时绘制游戏结束画面并播放对应的音频(.wav)。

部分算法

我方坦克移动控制

通过四个bool型数据,分别代表上下左右(up、down、left、right)。如果某一数据为true,则表示向该方向移动。通过对键盘事件的响应,即mouseEvent的重写,来改变这四个bool类型的值。

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

向上的移动规则:

首先判断是否出现上移越界的情况,即纵坐标大于5。如果有,则坦克不移动;如果没有,则继续判断坦克与地图块的碰撞。

坦克与地图块的碰撞分为以下情况:地图为空、地图为草地、地图为沙地等。

地图为空:正常前进;

地图为草地:坦克隐藏,继续前进;

地图为沙地:加速前进;

其余情况:不前进;

对于具体的碰撞检测,原理是将坦克的横纵坐标转换为地图数组中的元素,再判断该元素的各个方向的地图块种类。有以四下种情况(以图示说明):

QT FC坦克大战(附源码)QT FC坦克大战(附源码)

其他方向的规则类比向上的规则;

当检测到为草地时,是否隐藏(mask)为true,否则为false;

敌方坦克移动,子弹发射

首先判断坦克是否存活(isAlive);

再通过swithc判断坦克的方向(dir):

Case 0:

If(坦克没有上移越界)

根据算法1中坦克与地图块的碰撞检测原理,判断坦克是否移动;

If 移动

随机生成一个大于0小于10的数,根据书的大小,坦克有0.3的概率转向,0.7的概率直行;

Else

随机转向;

Case 1:原理同case 0;

Case 2:原理同case 0;

Case 3:原理同case 0;

子弹移动

子弹为6*6像素大小的图片;

判断子弹存活时:

Switch(子弹方向(dir))

Case 0:

根据算法1中坦克与地图块的碰撞检测原理,判断子弹是否移动;

碰撞类型有:

空白、草地、沙地、河流:正常移动;

铁块、砖块:停止移动,并返回对应的碰撞类型值(collision),同时子弹移除;

Case 1:原理同case 0;

Case 2:原理同case 0;

Case 3:原理同case 0;

 

如果边界越界,返回对应的碰撞类型值(collision),同时子弹移除;

子弹发射

坦克向各个方向发射子弹示意图(以向上为例):

QT FC坦克大战(附源码)

子弹发射时,子弹的方向立即确定,且不被改变,即为发射时坦克的方向;

我方子弹与敌方坦克的碰撞检测

槽函数,当计时器更新时调用;

If(我方坦克存活){

For循环,遍历每一个我方坦克子弹(最多为2个)

对每一个我方坦克发射的子弹:

For循环,遍历每一个敌方坦克

If(敌方坦克存活)

根据一定的规则,判断我方子弹是否击中敌方坦克,规则如下图

}

QT FC坦克大战(附源码)

子弹击中目标后,目标和子弹移除;

 敌方坦克与敌方坦克的碰撞检测

碰撞原理如图:

QT FC坦克大战(附源码)

敌方坦克1向上与敌方坦克2向下碰撞后:坦克1、2均反向;

敌方坦克1向上与敌方坦克2向左或右碰撞后:坦克1在上则坦克2反向,反之,坦克1反向;

敌方坦克1向下与敌方坦克2向左或右碰撞后:坦克1在上则坦克1反向,反之,坦克2反向;

 界面设计

程序窗口基本框架

QT FC坦克大战(附源码)

菜单界面

去掉标题栏,设置三个按钮,分别对应开始游戏、帮助、退出游戏,通过QPalette设置背景图片。

QT FC坦克大战(附源码)

游戏界面:

去掉标题栏;

将游戏界面分为两部分,一个为游戏主体,一个为游戏信息实时显示;

游戏主题设置背景图(纯黑色);

游戏信息实时显示部分以灰色为背景图,主要分为敌方坦克数量、关卡数、我方坦克生命值的显示。敌方坦克数以2*10的排列方式显示,每减少一个敌方坦克,对应减少一个敌方坦克标志。关卡数以“旗帜”图案和数字的方式显示,每前进一关,数字加一。我方坦克数量以我方坦克标志和数字的方式显示,该数字随坦克生命值(hp)的变化为变化。

QT FC坦克大战(附源码)QT FC坦克大战(附源码)QT FC坦克大战(附源码)QT FC坦克大战(附源码)QT FC坦克大战(附源码)

       QT FC坦克大战(附源码)

实际运行效果

QT FC坦克大战(附源码)QT FC坦克大战(附源码)

 QT FC坦克大战(附源码)QT FC坦克大战(附源码)

营地被击中:

QT FC坦克大战(附源码)

 

通过草地:

QT FC坦克大战(附源码)