github链接:https://github.com/zhouyumin/FC-tank
欢迎给我star
一、环境
-
语言:C++
-
编译器:gcc version 7.3.0
-
应用程序开发框架:Qt version 5.14.1
-
集成开发环境:Qt Creator 4.11.0 (Community)
二、游戏总体介绍
1.设计规则
该游戏总共有35关,每关有20个敌方坦克,玩家每关3条命,因为是在个人电脑上玩所以仅实现了单人游戏
击败20个敌人自动进入下一关,通过35关游戏胜利,当生命数为0或大本营被击中游戏失败
玩家坦克由键盘W、S、A、D键控制移动方向,J键发射子弹,敌方坦克则自动控制
2.效果展示图
3.UML 类图
4.运行流程图
三、全局参数的设置
1.定义全局参数
我们的全局参数主要是枚举类型方向,地图数组,图像的单位尺寸,窗口长和宽
用一个config.h头文件来设置这些全局参数,并由其他类进行include
2.遇到的问题
按照上面的方式写好代码进行编译时发生了变量的重复定义报错(已经进行了宏定义防止头文件多次包含)
后来经过跟踪报错发现子弹类包含了一个map数组,而坦克类中也有map数组,两者分开是不会互相影响的,但把这两个对象放到Widget对象中就会发生冲突
3.解决方法
在config.h中指明变量为外部变量,把具体变量定义到config.cpp中
这样子弹类和坦克类所包含的同名变量都为同一个外部变量,且指向同一个地址
四、主要代码
1.初始化
游戏初始化时先加载资源文件,各定时器开始计时,创建玩家角色,和敌方坦克
我们规定地图上最多只能有四个敌方坦克,用enemyNum变量记录剩余敌人数量,用cursor来标记出生点的位置
用enemies列表来储存敌方坦克对象
void Widget::init()
{
//加载地图
loadMap();
camp.load((rootdir+"pic\\camp0.gif").c_str());
camp = resizePic(camp,SIZE,SIZE);
QSound::play((rootdir+"sound\\start.wav").c_str());
//创建敌人
cursor=0;
enemyNum = 20;
for(int i=0;i<4;i++)
{
createEnemy();
}
//创建玩家
createPlayer();
life = 3;
// 开始游戏
start = 30;
timer1->start(120);
timer2->start(150);
timer3->start(1000);
timer4->start(60);
timer5->start(33);
}
void Widget::createPlayer()
{
role1.bullet.setActive(false);
role1.setDir(direct::up);
role1.ismove=false;
role1.rect.setRect(9*BASESIZE,24*BASESIZE,SIZE,SIZE);
}
void Widget::createEnemy()
{
if(enemyNum<4)
return;
Enemy enemy;
enemy.rect.setRect(cursor*SIZE,0,SIZE,SIZE);
enemies.push_back(enemy);
cursor+=6;
cursor%=18;
}
2.图像统一大小
使用Qt中QPixmap类的scaled函数来改变图像的尺寸
QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation) const
3.地图设置
游戏界面分为26行26列由二维字符数组map保存地图内容,其设定如下所示
数据内容 | 地图类型 |
---|---|
0 | 空白 |
1 | 草地 |
2 | 冰块 |
3 | 砖块 |
4 | 海洋 |
5 | 钢铁 |
游戏初始化时从map.dat文件中读取数据,根据map来绘制游戏界面的地形
void Widget::loadMap()
{
std::ifstream file;
try
{
file.open((QCoreApplication::applicationDirPath()+"\\res\\map.dat").toStdString().c_str(),std::ios::in|std::ios::binary);
if(!file)
{
throw "无法加载地图,请确保可执行文件所在目录的res目录下有map.dat文件,并且该游戏不放在中文目录下";
}
}
catch(const char *err)
{
QMessageBox msg(QMessageBox::Icon(QMessageBox::Icon::Critical),"ERROR",err);
msg.exec();
exit(-1);
}
file.seekg(sizeof(map)*(g