Qt编写魔塔小游戏

目录

一.游戏大致内容

        1.玩家角色

        2.怪物

        3.可触发的物品

        4.不可触发的物品

        5.地图

        6.(玩家与怪物的技能)

二.实现逻辑

三.具体实现

1.角色类声明

2.怪物类声明

3.地图类声明

4.主界面声明

5.玩家角色的构造

6.怪物的构造

7.地图的构造

8.主界面构造

9.开始按钮的槽函数与绘图事件

10.键盘事件处理

11.初始化地图界面

12.刷新地图界面

13.角色移动处理

14.运算战斗结果

15.边栏角色信息

16.主函数

四.注意事项

        1.头文件

        2.图片与音乐文件

        3.项目整体

五.游戏效果

        1.开始界面(简陋)

        2.第一层(新手大剑)

         3.第二层(开始正常游戏)

        4.后续层

        5.奖励层

        6.最后一层(暂时还没写结束结算)


最近系统学习了Qt的程序界面开发,所以用Qt尝试写了一个简单的魔塔小游戏。

下述括号内内容暂未编写

一.游戏大致内容

        1.玩家角色

                玩家角色拥有:角色名字,血量,攻击,防御,金钱,钥匙,剑,盾,(技能,经验,等级)

                通过玩家角色保存层数

        2.怪物

                怪物拥有:怪物名字,血量,攻击,防御,金钱,(技能,经验,等级)

                怪物名字不方便在代码中使用,所以给怪物添加一个“类型”变量

        3.可触发的物品

                可与玩家互动的物品

                如:血瓶,(蓝瓶),钥匙,宝石,剑,盾,门等

        4.不可触发的物品

                地面,墙等

        5.地图

                初始地图与当前地图

        6.(玩家与怪物的技能)

                (技能拥有等级,加成,蓝耗等属性)

       

二.实现逻辑

        除去暂时不想写的内容,将玩家角色写为一个类,怪物一个类,地图一个类,主界面一个类

        玩家的活动可以写在玩家类中,也可以写在主界面类中——更方便刷新主界面;玩家应有移动,战斗等事件;主界面应有初始化,刷新界面,接收键盘按键事件等功能

        使用Qt中的QLable控件装载地图的各种图标,用QPainter绘制游戏背景,用QMediaPlayer播放游戏背景音乐

        地图用三维数组存储,每一张地图都是一个二维数组,则会将地图分割成网格状,通过多个QLable控件拼接成整张地图界面

三.具体实现

        所有类的成员变量都写成了公有成员,方便在类外部通过该类对象使用这些变量

1.角色类声明

class Hero
{
public:Hero(QString);~Hero();int blood;          //血量int attack;         //攻击力int defense;        //防御力int money;          //金钱int floor;          //楼层int b_key;          //蓝钥匙int y_key;          //黄钥匙bool sword;         //持剑标志bool shield;        //持盾标志QString name;
};

2.怪物类声明

class Monster
{
public:Monster(int);~Monster();QString name;int blood;			//生命值int attack;			//攻击力int defense;		//防御力int money;          //金钱int type;			//类型    8-蓝史莱姆  9-黄史莱姆  10-蝙蝠  11-骷髅 12-法师
};

3.地图类声明

        三维数组若声明未赋值则后续不方便赋值,需使用三重for循环赋值,不方便脑补绘制地图,所以在类中声明时就为其赋值

class Map
{
public:Map();//0-墙1-地板 2-蓝门 3-黄门 4-蓝钥匙 5-黄钥匙 6-小血瓶 7-大血瓶//8-蓝史雷姆 9-黄史雷姆 10-蝙蝠 11-骷髅 12-法师 13-红宝石 14-蓝宝石//15-英雄 16-上楼 17-下楼 18-剑 19-盾
/* //空地图,用于复制{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}
*/int map[TOWER_LAYER][ONCE_WIDTH][ONCE_HEIGHT]={{{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,16,5,1,1,1,1,1,1,1,1,14,0},{0,5,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,18,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,6,1,1,1,1,1,1,1,1,1,15,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,16,1,9,8,8,1,1,1,1,1,1,0},{0,0,0,0,0,0,0,0,0,0,0,1,0},{0,5,1,1,3,1,0,1,5,1,0,1,0},{0,1,11,1,0,1,0,14,6,1,0,1,0},{0,0,3,0,0,1,0,0,0,3,0,1,0},{0,5,1,1,0,1,3,10,11,10,0,1,0},{0,1,11,1,0,1,0,0,0,0,0,1,0},{0,0,3,0,0,1,1,1,1,1,1,1,0},{0,1,1,1,0,0,3,0,0,0,3,0,0},{0,6,1,5,0,1,1,1,0,1,10,1,0},{0,6,13,5,0,17,15,1,0,9,7,8,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,5,14,0,5,7,5,0,1,0,1,6,0},{0,1,6,0,7,5,7,0,1,3,10,1,0},{0,12,1,0,5,4,5,0,1,0,0,0,0},{0,3,0,0,0,1,0,0,1,0,1,12,0},{0,1,1,10,1,1,1,9,1,1,1,1,0},{0,3,0,0,1,1,1,0,1,0,0,0,0},{0,11,1,0,0,1,0,0,1,0,1,6,0},{0,1,5,0,1,1,1,0,1,3,12,5,0},{0,6,6,0,1,1,1,0,1,0,0,0,0},{0,0,0,0,0,1,0,0,9,0,1,1,0},{0,17,15,1,1,1,1,0,1,3,1,16,0},{0,0,0,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,5,1,0,1,1,1,0,1,12,1,0},{0,6,13,4,0,1,12,1,0,5,1,7,0},{0,1,1,1,0,1,1,1,0,1,11,1,0},{0,0,3,0,0,0,2,0,0,0,3,0,0},{0,1,12,1,3,1,1,1,1,1,1,1,0},{0,1,1,1,0,0,0,0,0,0,0,0,0},{0,9,1,8,1,1,1,1,1,1,1,1,0},{0,3,0,0,3,0,0,0,3,0,0,3,0},{0,1,0,9,10,5,0,1,12,1,0,1,0},{0,1,0,5,1,5,0,9,6,9,0,15,0},{0,16,0,8,8,5,0,1,9,8,0,17,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,17,1,2,1,1,1,1,1,1,1,1,0},{0,15,1,0,1,1,12,1,12,1,1,1,0},{0,1,0,0,0,0,0,1,0,0,0,0,0},{0,1,0,5,5,0,1,1,1,0,5,12,0},{0,1,0,5,5,3,1,1,1,3,1,5,0},{0,1,0,0,0,0,1,1,1,0,0,0,0},{0,1,0,12,11,0,1,1,1,0,5,7,0},{0,1,0,1,1,3,1,1,1,3,1,5,0},{0,1,0,0,0,0,1,1,1,0,0,0,0},{0,1,0,7,7,0,1,1,1,0,12,19,0},{0,16,0,7,14,3,1,1,1,3,12,12,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,16,0,1,10,3,1,0,1,1,3,1,0},{0,1,0,1,1,0,5,0,11,12,0,2,0},{0,1,3,11,1,0,1,0,5,5,0,1,0},{0,0,0,0,3,0,10,0,5,5,0,1,0},{0,5,5,12,12,0,1,0,0,0,0,1,0},{0,5,1,1,11,0,1,12,1,1,1,1,0},{0,0,11,0,0,0,1,0,0,0,0,12,0},{0,1,12,1,1,0,10,0,1,1,1,1,0},{0,13,5,7,5,0,1,0,1,0,0,0,0},{0,0,0,0,0,0,5,0,1,0,7,14,0},{0,17,15,1,1,1,1,0,1,3,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,0,0,0},{0,17,15,7,7,7,7,7,7,7,7,7,0},{0,1,1,14,14,14,14,14,14,14,14,14,0},{0,1,1,13,13,13,13,13,13,13,13,13,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,16,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0},{0,17,15,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,12,12,12,12,12,0},{0,1,1,1,1,1,1,12,12,12,12,12,0},{0,1,1,1,1,1,1,12,12,12,12,12,0},{0,1,1,1,1,1,1,12,12,12,12,12,0},{0,1,1,1,1,1,1,12,12,12,12,12,0},{0,1,1,1,1,1,1,12,12,12,12,12,0},{0,0,0,0,0,0,0,0,0,0,0,0,0}}};
};

4.主界面声明

class Widget : public QWidget
{Q_OBJECT
public slots:void startGame();                         //开始按钮所实现的自定义槽函数
public:Widget(QWidget *parent = 0);~Widget();void keyPressEvent(QKeyEvent *event);     //键盘事件重写,上下左右与WASD键的改写void paintEvent(QPaintEvent *event);      //绘图事件重写,素材背景为白板,需要绘制背景void initMap();                           //初始化游戏地图函数void updateMap(int type,int preValue=0);  //刷新游戏地图函数void heroMove(int type,int preValue);     //角色移动判断函数void heroCombat(int preValue);            //角色战斗判断函数void showHeroInfo();                      //显示角色信息函数
private:QPushButton *start_bt;        //开始按钮bool combate_signal;          //角色战斗标志bool restart_signal;          //死亡重开标志bool start_background_signal; //更新背景图标志QMediaPlayer *bgm;            //播放背景音乐QMediaPlaylist *bgmlist;      //背景音乐列表,用于循环播放QLabel *mapLabel[13][13];     //当前地图QLabel *infoLabel;            //角色信息背景QLabel *nameLabel;            //角色名字QLabel *moneyValueLabel;      //金币QLabel *floorValueLabel;      //楼层QLabel *bloodLabel;           //生命值QLabel *attackLabel;          //攻击力QLabel *defenseLabel;         //防御力QLabel *bKeyLabel;            //蓝钥匙QLabel *yKeyLabel;            //黄钥匙Map *dynamic_map=new Map;     //当前游戏的地图Map *static_map=new Map;      //不会去更改的地图,其实也可以用Map::map来调用Hero *hero;                   //声明角色int heroX;                    //角色的模拟X坐标int heroY;                    //角色的模拟Y坐标//声明定义怪物Monster *blueSlime=new Monster(8);Monster *yellowSlime=new Monster(9);Monster *smallBat=new Monster(10);Monster *skeletonKnight=new Monster(11);Monster *exorcist=new Monster(12);
};

5.玩家角色的构造

Hero::Hero(QString name_):name(name_)
{//根据传入角色名生成指定角色if(name.compare("英雄")){blood=200;attack=20;defense=15;}else if(name.compare("勇者")){blood=100;attack=16;defense=10;}else if(name.compare("村民")){blood=60;attack=10;defense=8;}else {blood=40;attack=10;defense=5;}money=0;floor=0;b_key=0;y_key=0;
}

6.怪物的构造

Monster::Monster(int type){this->type=type;//根据传入类型生成指定小怪switch (type){case 8:blood=30;attack=12;defense=5;money=2;name="黄史莱姆";break;case 9:blood=50;attack=13;defense=5;money=3;name="蓝史莱姆";break;case 10:blood=50;attack=15;defense=8;money=5;name="蝙蝠";break;case 11:blood=100;attack=18;defense=12;money=20;name="骷髅";break;case 12:blood=200;attack=26;defense=10;money=30;name="法师";break;default:break;}
}

7.地图的构造

        因为地图数组在声明时就赋值了,所以不需要重写地图的构造函数

8.主界面构造

Widget::Widget(QWidget *parent): QWidget(parent)
{this->grabKeyboard();//设置接收键盘事件this->setFixedSize((ONCE_WIDTH+1.5)*60,ONCE_HEIGHT*60);//背景音乐bgm=new QMediaPlayer();bgmlist=new QMediaPlaylist();//用QMediaPlaylist装入背景音乐,使其能循环播放bgmlist->addMedia(QUrl("qrc:/bgm/morning.mp3"));bgmlist->setPlaybackMode(QMediaPlaylist::Loop);bgm->setPlaylist(bgmlist);bgm->setVolume(30);//设置音量大小bgm->play();//开始按钮start_bt=new QPushButton("start game");start_bt->setFixedSize(140,50);start_bt->setFont(QFont("KaiTi",16));start_bt->setStyleSheet("QPushButton{ color:rgb(255,255,255);}""QPushButton{ selection-color:rgb(181,181,181);}""QPushButton{ border-radius:18px;}""QPushButton{ background-color:rgb(0,128,255);}");start_bt->move(this->width()/2-70,this->height()/2-25);start_bt->setParent(this);//初始化各个标志restart_signal=false;combate_signal=false;start_background_signal=false;//定义角色并初始化其内容hero=new Hero("英雄");heroX=0;heroY=0;hero->sword=false;hero->shield=false;//for循环初始化地图lablefor(int i=0;i<ONCE_WIDTH;i++){for(int j=0;j<ONCE_HEIGHT;j++){mapLabel[i][j]=new QLabel(this);mapLabel[i][j]->setFixedSize(60,60);}}connect(start_bt,SIGNAL(clicked(bool)),this,SLOT(startGame()));
}

9.开始按钮的槽函数与绘图事件

//开始按钮点击后隐藏按钮,跟新地图,立即刷新绘图事件,显示角色信息
void Widget::startGame(){start_background_signal=true;start_bt->hide();repaint();initMap();showHeroInfo();
}
//绘图事件,绘制窗口背景图
void Widget::paintEvent(QPaintEvent *event){QPainter p(this);event->accept();//进入游戏后背景改为全游戏地面背景if(start_background_signal==true){for(int i=0;i<ONCE_HEIGHT;i++){for(int j=0;j<ONCE_WIDTH+1;j++){p.drawPixmap(j*60,i*60,60,60,QPixmap(":/image/1.png"));}}}//未进入游戏设置开始背景else{p.drawPixmap(0,0,60*(ONCE_WIDTH+1.5),60*ONCE_HEIGHT,QPixmap(":/image/back.jpeg"));}
}

10.键盘事件处理

void Widget::keyPressEvent(QKeyEvent *event){if(!combate_signal){int type=4;             //记录移动类型(0-上 1-下 2-左 3-右)int preValue=0;         //记录走到的位置有什么东西switch (event->key()){case Qt::Key_Up:case Qt::Key_W:type=0;preValue=dynamic_map->map[hero->floor][heroX-1][heroY];heroMove(type,preValue);break;case Qt::Key_Down:case Qt::Key_S:type=1;preValue=dynamic_map->map[hero->floor][heroX+1][heroY];heroMove(type,preValue);break;case Qt::Key_Left:case Qt::Key_A:type=2;preValue=dynamic_map->map[hero->floor][heroX][heroY-1];heroMove(type,preValue);break;case Qt::Key_Right:case Qt::Key_D:type = 3;preValue=dynamic_map->map[hero->floor][heroX][heroY+1];heroMove(type,preValue);break;default:break;}showHeroInfo();//刷新角色信息的显示}
}

11.初始化地图界面

void Widget::initMap(){if(restart_signal){//将不变的地图赋予可变地图for(int k=0;k<TOWER_LAYER;k++){for(int i=0;i<ONCE_WIDTH;i++){for(int j=0;j<ONCE_HEIGHT;j++){dynamic_map->map[k][i][j]=static_map->map[k][i][j];}}}//判断角色死亡,是否重新开始。restart_signal=false;}//绘制当前地图for(int i=0;i<ONCE_HEIGHT;i++){for(int j=0;j<ONCE_WIDTH;j++){//每次更新一层,需要刷新当前层的图片mapLabel[i][j]->clear();mapLabel[i][j]->move(j*60,i*60);mapLabel[i][j]->setPixmap(QPixmap(tr(":/image/%1.png").arg(dynamic_map->map[hero->floor][i][j])));mapLabel[i][j]->setScaledContents(true);mapLabel[i][j]->show();//检索角色位置if(dynamic_map->map[hero->floor][i][j]==15){heroX=i;heroY=j;}}}//计分板背景infoLabel=new QLabel(this);infoLabel->setFixedSize(60*1.5,ONCE_HEIGHT*60);infoLabel->setPixmap(QPixmap(tr(":/image/20.jpeg")));infoLabel->setScaledContents(true);infoLabel->move(ONCE_WIDTH*60,0);infoLabel->show();//设置字体QPalette palette;palette.setColor(QPalette::WindowText,Qt::black);QFont font;font.setPointSize(12);font.setBold(true);//角色名字nameLabel=new QLabel(this);nameLabel->setFixedSize(60*1.5,50);nameLabel->move(ONCE_WIDTH*60,0);nameLabel->setPalette(palette);nameLabel->setFont(font);nameLabel->show();//金币显示moneyValueLabel=new QLabel(this);moneyValueLabel->setFixedSize(60*1.5,50);moneyValueLabel->move(ONCE_WIDTH*60,60*1.5);moneyValueLabel->setPalette(palette);moneyValueLabel->setFont(font);moneyValueLabel->show();//楼层显示floorValueLabel=new QLabel(this);floorValueLabel->setFixedSize(60*1.5,50);floorValueLabel->move(ONCE_WIDTH*60,60*3);floorValueLabel->setPalette(palette);floorValueLabel->setFont(font);floorValueLabel->show();//生命值bloodLabel=new QLabel(this);bloodLabel->setFixedSize(60*1.5,50);bloodLabel->move(ONCE_WIDTH*60,60*4.5);bloodLabel->setPalette(palette);bloodLabel->setFont(font);bloodLabel->show();//攻击力attackLabel=new QLabel(this);attackLabel->setFixedSize(60*1.5,50);attackLabel->move(ONCE_WIDTH*60,60*6);attackLabel->setPalette(palette);attackLabel->setFont(font);attackLabel->show();//防御力defenseLabel=new QLabel(this);defenseLabel->setFixedSize(60*1.5,50);defenseLabel->move(ONCE_WIDTH*60,60*7.5);defenseLabel->setPalette(palette);defenseLabel->setFont(font);defenseLabel->show();//黄钥匙yKeyLabel=new QLabel(this);yKeyLabel->setFixedSize(60*1.5,50);yKeyLabel->move(ONCE_WIDTH*60,60*9);yKeyLabel->setPalette(palette);yKeyLabel->setFont(font);yKeyLabel->show();//蓝钥匙bKeyLabel=new QLabel(this);bKeyLabel->setFixedSize(60*1.5,50);bKeyLabel->move(ONCE_WIDTH*60,60*10.5);bKeyLabel->setPalette(palette);bKeyLabel->setFont(font);bKeyLabel->show();
}

12.刷新地图界面

void Widget::updateMap(int type,int preValue){dynamic_map->map[hero->floor][heroX][heroY]=1;//先前角色所在地置为地面mapLabel[heroX][heroY]->setPixmap(QPixmap(tr(":/image/%1.png").arg(dynamic_map->map[hero->floor][heroX][heroY])));switch(type){case 0:heroX-=1;break;case 1:heroX+=1;break;case 2:heroY-=1;break;case 3:heroY+=1;break;default:break;}//角色移动后位置显示角色dynamic_map->map[hero->floor][heroX][heroY]=15;mapLabel[heroX][heroY]->setPixmap(QPixmap(tr(":/image/15.png")));//攻击怪物,实现图像闪烁if(preValue==8||preValue==9||preValue==10||preValue==11||preValue==12){//战斗中,记录战斗状态combate_signal=true;//定时器显示怪物图片QTimer *timer1=new QTimer(this);connect(timer1,&QTimer::timeout,this,[=](){mapLabel[heroX][heroY]->setPixmap(QPixmap(tr(":/image/%1.png").arg(preValue)));});//定时器显示角色图片QTimer *timer2=new QTimer(this);connect(timer2,&QTimer::timeout,this,[=](){mapLabel[heroX][heroY]->setPixmap(QPixmap(tr(":/image/15.png")));});timer1->start(100);QThread::msleep(50);//线程实现短暂休眠timer2->start(100);//500毫秒定时器,定时器结束,闪烁结束QTimer *timer=new QTimer(this);connect(timer,&QTimer::timeout,this,[=](){timer1->stop();timer2->stop();timer->stop();combate_signal=false;//如果角色战斗失败,则显示怪物图片if(hero->blood==0){mapLabel[heroX][heroY]->setPixmap(QPixmap(tr(":/image/%1.png").arg(preValue)));}//英雄胜利,则显示角色图片else{dynamic_map->map[hero->floor][heroX][heroY]=15;mapLabel[heroX][heroY]->setPixmap(QPixmap(tr(":/image/15.png")));}});timer->start(500);}
}

13.角色移动处理

void Widget::heroMove(int type,int preValue){if(hero->sword){hero->attack+=12;hero->sword=false;}if(hero->shield){hero->defense+=8;hero->shield=false;}if(preValue==0){//墙return;}else if(preValue==1){//空地updateMap(type);}else if(preValue==3&&hero->y_key>0){//黄门updateMap(type);hero->y_key--;}else if(preValue==5){//黄钥匙updateMap(type);hero->y_key++;}else if(preValue==2&&hero->b_key>0){//蓝门updateMap(type);hero->b_key--;}else if(preValue==4){//蓝钥匙updateMap(type);hero->b_key++;}else if(preValue==6){//小血瓶updateMap(type);hero->blood+=30;}else if(preValue==7){//大血瓶updateMap(type);hero->blood+=80;}else if(preValue==13){//红宝石updateMap(type);hero->attack+=3;}else if(preValue==14){//蓝宝石updateMap(type);hero->defense+=2;}else if(preValue==16){//上楼hero->floor+=1;initMap();}else if(preValue==17){//下楼hero->floor-=1;initMap();}else if(preValue==18){//剑updateMap(type);hero->sword=true;}else if(preValue==19){//盾updateMap(type);hero->shield=true;}else if(preValue==8||preValue==9||preValue==10||preValue==11||preValue==12){//怪物heroCombat(preValue);updateMap(type,preValue);showHeroInfo();// 碰见怪物,攻击结束之后判断血量if(hero->blood==0){int select=QMessageBox::information(this,tr("游戏结束"),tr("是否重新开始"),QMessageBox::Yes|QMessageBox::No);if(select==QMessageBox::Yes){//重新开始hero=new Hero("英雄");restart_signal=true;initMap();}else{this->close();}}}
}

14.运算战斗结果

void Widget::heroCombat(int preValue){int change_blood;       //战斗后减少的血量int monster_blood;      //当前怪物血量int hero_atk_def;       //角色与怪物的攻防差int monster_atk_def;    //怪物与角色的攻防余数switch (preValue){case 8:monster_blood=blueSlime->blood;hero_atk_def=hero->attack-blueSlime->defense;monster_atk_def=blueSlime->attack-hero->defense;hero->money+=blueSlime->money;break;case 9:monster_blood=yellowSlime->blood;hero_atk_def=hero->attack-yellowSlime->defense;monster_atk_def=yellowSlime->attack-hero->defense;hero->money+=yellowSlime->money;break;case 10:monster_blood=smallBat->blood;hero_atk_def=hero->attack-smallBat->defense;monster_atk_def=smallBat->attack-hero->defense;hero->money+=smallBat->money;break;case 11:monster_blood=skeletonKnight->blood;hero_atk_def=hero->attack-skeletonKnight->defense;monster_atk_def=skeletonKnight->attack-hero->defense;hero->money+=skeletonKnight->money;break;case 12:monster_blood=exorcist->blood;hero_atk_def=hero->attack-exorcist->defense;monster_atk_def=exorcist->attack-hero->defense;hero->money+=exorcist->money;break;default:break;}//角色防御高于怪物攻击if(monster_atk_def<=1){monster_atk_def=1;}//角色防御低于怪物攻击过多else if(monster_atk_def>10){monster_atk_def=10;}//角色攻击低于怪物防御if(hero_atk_def<0){change_blood=hero->blood;}else{//角色攻击高于怪物防御过多if(hero_atk_def>monster_blood){hero_atk_def=monster_blood;}change_blood=(monster_blood/hero_atk_def)*monster_atk_def;}//将要改变的血量高于原始血量if(change_blood>hero->blood){change_blood=hero->blood;}hero->blood-=change_blood;
}

15.边栏角色信息

void Widget::showHeroInfo(){QString text;//角色名字text.append("角色名字\n");text.append(hero->name);nameLabel->setText(text);nameLabel->setAlignment(Qt::AlignCenter);//居中显示text.clear();//用完清空,方便下次使用//金币text.append("金币\n");text.append(QString::number(hero->money));moneyValueLabel->setText(text);moneyValueLabel->setAlignment(Qt::AlignCenter);text.clear();//楼层text.append("楼层\n");text.append(QString::number(hero->floor));floorValueLabel->setText(text);floorValueLabel->setAlignment(Qt::AlignCenter);text.clear();//生命值text.append("生命值\n");text.append(QString::number(hero->blood));bloodLabel->setText(text);bloodLabel->setAlignment(Qt::AlignCenter);text.clear();//攻击力text.append("攻击力\n");text.append(QString::number(hero->attack));attackLabel->setText(text);attackLabel->setAlignment(Qt::AlignCenter);text.clear();//防御力text.append("防御力\n");text.append(QString::number(hero->defense));defenseLabel->setText(text);defenseLabel->setAlignment(Qt::AlignCenter);text.clear();//蓝钥匙text.append("蓝钥匙\n");text.append(QString::number(hero->b_key));bKeyLabel->setText(text);bKeyLabel->setAlignment(Qt::AlignCenter);text.clear();//黄钥匙text.append("黄钥匙\n");text.append(QString::number(hero->y_key));yKeyLabel->setText(text);yKeyLabel->setAlignment(Qt::AlignCenter);text.clear();
}

16.主函数

        所有需要操作的都写在了主界面中,不需要更改Qt默认生成的主函数

四.注意事项

        1.头文件

                主界面所需的头文件

#include <QWidget>
#include <QMessageBox>
#include <QLabel>
#include <QKeyEvent>
#include <QTimer>
#include <QThread>
#include <QPushButton>
#include <QPainter>
#include <QPoint>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QString>#include "map.h"
#include "hero.h"
#include "monster.h"

                玩家类和怪物类只需要QString的头文件

        2.图片与音乐文件

                素材图片最好是.png格式的,背景图片任何类型都可以

                背音乐文件一般为.wav格式,若想要使用其他格式则需要安装插件

                当音乐文件放在项目.qrc文件下时,写音乐路径时必须在分号前写上"qrc"

                如:QUrl("qrc:/bgm/morning.mp3");

                当文件未放入项目中时,该路径必须是绝对路径

        3.项目整体

五.游戏效果

        1.开始界面(简陋)

        2.第一层(新手大剑)

         3.第二层(开始正常游戏)

        4.后续层

        5.奖励层

        6.最后一层(暂时还没写结束结算)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/25358.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGLM-6B 安装试用

地址&#xff1a; https://github.com/THUDM/ChatGLM-6B https://huggingface.co/THUDM/chatglm-6b git clone https://github.com/THUDM/ChatGLM-6B conda create -n chatglm python3.8 conda activate chatglm cd ChatGLM-6B/ pip install -r requirements.txt试用以下代码&…

(非华为电脑,最新版PCManager安装,支持鸿蒙、一碰传

非华为电脑&#xff0c;最新版PCManager安装&#xff0c;支持鸿蒙、一碰传 与常规安装略有不同1.下载软件和获得nfc标签但淘宝nfc标签安装教程&#xff0c;一般都是老版的没有支持升级&#xff0c;一碰传安装步骤略有不同2.修改系统时间3.打开安装工具注意1.先修改地址&#xf…

Android 录音实现方法、仿微信语音、麦克风录音、发送语音

效果图&#xff08;注&#xff01;由于使用的模拟器录制&#xff0c;所以图片中的录音时候话筒上下波动比较小&#xff0c;手机上正常&#xff01;&#xff09;&#xff1a; 使用方法&#xff1a; 录音工具类&#xff1a;AudioRecoderUtils.java&#xff0c;代码如下&#x…

chatgpt赋能python:用Python开发录音程序——为你的录音体验带来新的飞跃!

用Python开发录音程序——为你的录音体验带来新的飞跃&#xff01; 越来越多的人开始意识到录音的重要性&#xff0c;无论是进行个人录音、工作讲话记录&#xff0c;或是进行音乐创作&#xff0c;录音都是至关重要的一部分。然而&#xff0c;市场上的录音软件要么价格昂贵&…

Android开发--仿微信语音对讲录音

自微信出现以来取得了很好的成绩&#xff0c;语音对讲的实现更加方便了人与人之间的交流。今天来实践一下微信的语音对讲的录音实现&#xff0c;这个也比较容易实现。在此&#xff0c;我将该按钮封装成为一个控件&#xff0c;并通过策略模式的方式实现录音和界面的解耦合&#…

Android 录音实现方法、仿微信语音、麦克风录音、发送语音、解决5.0以上BUG

本文修改自&#xff1a;http://www.jianshu.com/p/06eca50ddda4 效果图&#xff08;注&#xff01;由于使用的模拟器录制&#xff0c;所以图片中的录音时候话筒上下波动比较小&#xff0c;手机上正常&#xff01;&#xff09;&#xff1a; 使用方法&#xff1a; 录音工具类&…

能听懂语音的ChatGPT来了:10小时录音扔进去,想问什么问什么

类 ChatGPT 模型的输入框里可以粘贴语音文档了。 大型语言模型&#xff08;LLM&#xff09;正在改变每个行业的用户期望。然而&#xff0c;建立以人类语音为中心的生成式人工智能产品仍然很困难&#xff0c;因为音频文件对大型语言模型构成了挑战。 将 LLM 应用于音频文件的一…

weui icon图标大全

转载 https://blog.csdn.net/qq_36433857/article/details/84190038

git 突然不出 绿色,红色的图标了

winr 打开后找到“HKEY_LOCAL_MACHINE–>SOFTWARE–>Microsoft–>Windows–>CurrentVersion–>Explorer–>ShellIconOverlayIdentifiers”这一项 将Tortoise相关的项都提到靠前的位置&#xff08;重命名&#xff0c;在名称之前加几个空格&#xff09; &am…

git绿色、红色图标不显示的问题(有图有真相)

今天在使用git的时候发现项目没有图标显示&#xff0c;感觉很难受&#xff0c;百度搜了好多&#xff0c;感觉这个挺好用的&#xff0c;记录一下。 图标&#xff0c;我们一般情况下就用两个图标&#xff0c;红标和绿标 顾名思义&#xff1a;绿标是指代码提交成功的&#xff0c;红…

exe文件更换图标方法

exe文件更换图标 想更换exe文件的默认图标&#xff0c;但又不想下载什么软件&#xff0c;在网上搜索后找到一种不需要下载特定软件的“欺骗法”。 注意&#xff1a;本方法并不是真的更换了exe文件的图标&#xff0c;而是为exe文件包装了一个壳子&#xff0c;使得外观上看起来更…

如何引入iconfont中的单色图标和多色图标(超简单)

网址&#xff1a;iconfont-阿里巴巴矢量图标库 超简单&#xff01;再不会引入就过分了哈! 一、单色图标引入 1、选择需要的图标 2、创建新项目、添加至该项目、下载到本地 3、将压缩包解压到自己的代码文件夹中 4、在html中link引入并回到网址上复制图标代码 5、以i标签和icon…

VC应用 -个性化你的工具栏图标

1、首先&#xff0c;提供一些最好的图标&#xff0c;大家可以省去自己绘画图标的功夫&#xff0c;可以从繁琐的绘图工作中解脱出来。 ToYcon 在线网页转换PNG-ICON http://converticon.com/ 一个非常好的ICO图标查找网站 http://www.iconfinder.net http://www.iconlet.c…

iconfont 彩色图标的使用

之前写过iconfont单色图标的应用&#xff0c;今天来介绍一下彩色图标的使用 文章目录 一、去iconfont矢量图库下载素材1、挑选自己喜欢的素材2、然后下载到本地&#xff0c;是个压缩包3、把压缩包解压到你的项目底下4、打开解压后的文件5、打开demo_index.html 二、在页面中引入…

下载iconfont图标

iconfont.js&#xff1a; const fs require(‘fs’); const https require(‘https’); // 解压工具&#xff0c;需要安装 const Admzip require(‘adm-zip’); // 项目成员在阿里图标库网站的cookie const cookie require(‘./iconfont.json’).cookie; // 阿里图标库域…

引入icon图标

最新方法:使用svg-sprite-loader引入icon 一.svg-sprite-loader的基本使用 1.在iconfont.cn下载好需要的图标后,把它添加到项目assets里并引入。 那如何引入呢&#xff1f; &#x1f50d;typescript svg cannot find module 方法:在系统文件shims-vue.d.ts里添加如下代码 sr…

Qt 更改exe图标显示

1、制作.ico格式图标。 &#xff08;网上有在线转换工具) 2、将制作好的ico图标重新命名&#xff0c;比如&#xff1a;exe._ico.ico,然后拷贝到项目工程.pro相同路径下。 3、在Qt 项目工程文件下.pro。添加一行 : RC_ICONS exe_ico.ico 4、重新构建可执行程序。

震撼来袭,GPT-4全解读

今年3月&#xff0c;OpenAI团队正式宣布&#xff1a;GPT-4 来了&#xff01; 微信搜索关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 OpenAI发布的GPT-4是深度学习方面的最新里程碑。GPT-4是一个大型的多模态模型&#xff08;可接收图像和文本输入…

chatgpt赋能python:Python发短信给手机:一种快速高效的通讯方式

Python 发短信给手机&#xff1a;一种快速高效的通讯方式 在当今数字化的时代&#xff0c;手机已成为人们日常生活不可或缺的一部分。然而&#xff0c;对于那些需要快速高效地与手机用户进行通讯的人们来说&#xff0c;传统的打电话和发送短信的方式则显得有些过于繁琐。对于这…

chatgpt赋能python:如何使用Python读取手机短信

如何使用Python读取手机短信 在现代社会&#xff0c;短信已成为人们生活中不可或缺的一部分。那么&#xff0c;如何利用Python读取手机短信呢&#xff1f;本文将介绍如何使用Python读取手机短信&#xff0c;并提出一些相关的建议。 什么是Python Python是一种高级的、开源的…