Qt推箱子小游戏和飞机大战项目实战

Qt推箱子小游戏和飞机大战项目实战

首页休闲益智逻辑箱子测试版更新时间:2024-05-07
1.推箱子小游戏

项目结构

效果图

领Qt实战项目资料→

#ifndef GAMEMAP_H #define GAMEMAP_H #include <QObject> #include <QPainter> enum MapElement { Road, Wall, Box, Point, InPoint }; class GameMap : public QObject { Q_OBJECT public: explicit GameMap(QObject *parent = nullptr); ~GameMap(); bool InitByFile(QString fileName); void Clear(); void Paint(QPainter* _p,QPoint _Pos); int mRow; int mCol; int** mPArr;//用于开辟二维数组 2D地图元素 signals: public slots: }; #endif // GAMEMAP_H

#include "GameMap.h" #include <QFile> #include <QDebug> GameMap::GameMap(QObject *parent) : QObject(parent) { mRow = 0; mCol = 0; mPArr = nullptr; } GameMap::~GameMap() { Clear(); } void GameMap::Clear() { if(mPArr != nullptr) { for(int i = 0;i < mRow;i ) { delete[] mPArr[i]; } delete[] mPArr; } } bool GameMap::InitByFile(QString fileName) { QFile file(fileName);//创建文件对象 if(!file.open(QIODevice::ReadOnly)) { return false;//打开失败 } //读取所有内容 QByteArray arrAll = file.readAll(); arrAll.replace("\r\n","\n");//将 "\r\n" 替换成 “\n” QList<QByteArray> lineList = arrAll.split('\n');//以“\n” 分割子串 mRow = lineList.size();//确定行 mPArr = new int*[mRow]; for(int i = 0;i < mRow;i ) { QList<QByteArray> colList = lineList[i].split(','); mCol = colList.size();//确定列 mPArr[i] = new int[mCol];//开辟列 for(int j = 0;j < mCol;j )//遍历列 { mPArr[i][j] = colList[j].toInt(); } } } void GameMap::Paint(QPainter* _p, QPoint _Pos) { for(int i = 0;i <mRow;i ) { for(int j = 0;j < mCol;j ) { QString imgUrl; switch (mPArr[i][j]) { case Road: imgUrl = "://Image/sky.png";break; case Wall: imgUrl = "://Image/wall.png";break; case Box: imgUrl = "://Image/case.png";break; case Point: imgUrl = "://Image/end.png";break; case InPoint: imgUrl = "://Image/win.png";break; } QImage img(imgUrl); _p->drawImage(QRect(_Pos.x() j*img.width(),_Pos.y() i*img.height(),img.width(),img.height()),img); // _p->drawImage(_Pos,img); } } }

#ifndef ROLE_H #define ROLE_H #include <QObject> #include <QPoint> #include <QImage> class Role : public QObject { Q_OBJECT public: explicit Role(QObject *parent = nullptr); //对应在地图的映射行列 int mRow; int mCol; //画图位置 //人在二维数组里的x,y和显示的x,y坐标轴是反过来的 QPoint mPaintPos; //人物图片 QImage mImg; void Move(int _dRow,int _dCol);//移动函数 void Paint(QPainter* _p,QPoint _pos);//自己的绘制函数 signals: public slots: }; #endif // ROLE_H

#include "Role.h" #include <QPainter> Role::Role(QObject *parent) : QObject(parent) { mRow = 1; mCol = 1; mImg = QImage("://Image/people.png"); //显示位置 mPaintPos = QPoint(mCol,mRow) * mImg.width(); } void Role::Move(int _dRow,int _dCol) { mRow = _dRow; mCol = _dCol; mPaintPos = QPoint(mCol,mRow) * mImg.width(); } void Role::Paint(QPainter* _p,QPoint _pos) { _p->drawImage(mPaintPos _pos,mImg); }

#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "GameMap.h" #include "Role.h" namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); virtual void paintEvent(QPaintEvent* event);//绘图事件函数 virtual void keyPressEvent(QKeyEvent* event);//键盘按下事件 void Collision(int _dRow,int _dCol); ~Widget(); private: Ui::Widget *ui; GameMap* mPMap; //画家 QPainter* mMapPainter; //角色 Role* mRole; //游戏更新定时器 解决paintEvent不定时更新问题 QTimer* mTimer; }; #endif // WIDGET_H

#include "Widget.h" #include "ui_widget.h" #include <QFileDialog> #include <QPainter> #include <QMessageBox> #include <QKeyEvent> #include <QtDebug> #include <QTimer> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); //初始化地图元素 mPMap = new GameMap(this); // QString fileName =QFileDialog::getOpenFileName(this,"打开地图","./","*.txt"); if(!mPMap->InitByFile("./Map/lv1.txt")) { QMessageBox::warning(this,"警告","文件打开失败"); } mMapPainter = new QPainter(this);//创建画家 mRole = new Role(this); //定时调用更新函数 mTimer = new QTimer(this); mTimer->start(100); //定时调用更新函数 connect(mTimer,&QTimer::timeout,[this](){this->update();}); setFixedSize(1024,768);//固定窗口大小 } Widget::~Widget() { delete ui; } void Widget::paintEvent(QPaintEvent *event) { mMapPainter->begin(this);//设置画布 //画背景 QPainter bgPainter(this); bgPainter.drawImage(QRect(0,0,1024,768),QImage("://Image/ground.png")); //画地图 mPMap->Paint(mMapPainter,QPoint(10,200)); //画人物 mRole->Paint(mMapPainter,QPoint(10,200)); mMapPainter->end();//结束 } void Widget::keyPressEvent(QKeyEvent* event) { switch (event->key()) { case Qt::Key_W: case Qt::Key_Up: { //逻辑碰撞检测函数 Collision(-1,0); break; } case Qt::Key_S: case Qt::Key_Down: { //逻辑碰撞检测函数 Collision(1,0); break; } case Qt::Key_A: case Qt::Key_Left: { //逻辑碰撞检测函数 Collision(0,-1); break; } case Qt::Key_D: case Qt::Key_Right: { //逻辑碰撞检测函数 Collision(0,1); break; } } } void Widget::Collision(int _dRow,int _dCol) { //判断位置定义 int newRow = mRole->mRow _dRow; int newCol = mRole->mCol _dCol; if(mPMap->mPArr[newRow][newCol] == Wall)//判断前方是墙 { return; } else if(mPMap->mPArr[newRow][newCol] == Box)//判断前方是箱子 { //判断箱子前方 if(mPMap->mPArr[newRow _dRow][newCol _dCol] == Road) { //改变地图元素 mPMap->mPArr[newRow _dRow][newCol _dCol] = Box;//箱子前方变成箱子 mPMap->mPArr[newRow][newCol] = Road; } else if(mPMap->mPArr[newRow _dRow][newCol _dCol] == Point) { //改变地图元素 mPMap->mPArr[newRow _dRow][newCol _dCol] = InPoint;//箱子前方变成进目标点 mPMap->mPArr[newRow][newCol] = Road; } else { return;//无法推动箱子 } } else if(mPMap->mPArr[newRow][newCol] == InPoint)//前方是进目标点(箱子与目标重合) { //判断目标点前方 if(mPMap->mPArr[newRow _dRow][newCol _dCol] == Road) { //改变地图元素 mPMap->mPArr[newRow _dRow][newCol _dCol] = Box;//目标点前方变成箱子 mPMap->mPArr[newRow][newCol] = Point; } else if(mPMap->mPArr[newRow _dRow][newCol _dCol] == Point) { //改变地图元素 mPMap->mPArr[newRow _dRow][newCol _dCol] = InPoint;//箱子进点 mPMap->mPArr[newRow][newCol] = Point; } else { return;//无法推动箱子 } } //否则移动 mRole->Move(_dRow,_dCol); qDebug() << "人物绘制位置:" << mRole->mPaintPos; } 2.飞机大战项目实战2.1注意事项

添加音乐注意事项

导入资源

继承体系

2.2目录结构

2.3代码

#ifndef BULLET_H #define BULLET_H #include "gameobject.h" class Bullet : public GameObject { public: //子弹类型 enum BulletType { BT_Player,//我方 BT_Enemy//地方 }; explicit Bullet(QObject *parent = nullptr); Bullet(QPoint _pos,QPixmap _pixmap,int _type); //移动函数 void BulletMove(QPoint _dir = QPoint(0,-1)); //初始化函数 void Init(QPoint _pos,QPixmap _pixmap); ~Bullet() { qDebug() << "子弹被释放"; } protected: int mBulletType; int mSpeed; QMediaPlayer mMedia; }; #endif // BULLET_H

#include "bullet.h" Bullet::Bullet(QObject *parent) { mObjectType = GameObject::OT_BulletPlayer; } Bullet::Bullet(QPoint _pos, QPixmap _pixmap, int _type) { this->setPos(_pos); this->setPixmap(_pixmap); this->mBulletType = _type; mSpeed = 6; } void Bullet::BulletMove(QPoint _dir) { this->moveBy(_dir.x()*mSpeed,_dir.y()*mSpeed); } void Bullet::Init(QPoint _pos, QPixmap _pixmap) { this->setPos(_pos); this->setPixmap(_pixmap); //----子弹微调整 this->setScale(0.5);//缩放 this->setX(this->x() - this->scale() * pixmap().width()/2); }

#ifndef ENEMY_H #define ENEMY_H #include "plane.h" class Enemy : public Plane { public: Enemy() { mObjectType = GameObject::OT_Enemy;//标识对象 } Enemy(QPoint _pos,QPixmap _pixmap); void EnemyMove(QPoint _dir = QPoint(0,1)); void Init(QPoint _pos,QPixmap _pixmap); }; #endif // ENEMY_H

#include "enemy.h" Enemy::Enemy(QPoint _pos, QPixmap _pixmap) { this->mMoveSpeed = 3; this->mShootSpeed = 1000; this->setPos(_pos); this->setPixmap(_pixmap); } void Enemy::EnemyMove(QPoint _dir) { this->moveBy(_dir.x()*mMoveSpeed ,_dir.y()*mMoveSpeed); } void Enemy::Init(QPoint _pos, QPixmap _pixmap) { this->setPos(_pos); this->setPixmap(_pixmap); this->mMoveSpeed = 3; this->mShootSpeed = 1000; }

#ifndef ENEMYBULLET_H #define ENEMYBULLET_H #include "bullet.h" class EnemyBullet : public Bullet { public: explicit EnemyBullet(QObject *parent = nullptr); void PlaySound(); }; #endif // ENEMYBULLET_H

-enemybullet.cpp

#include "enemybullet.h" EnemyBullet::EnemyBullet(QObject *parent) { mObjectType = GameObject::OT_EnemyBullet; } void EnemyBullet::PlaySound() { mMedia.setMedia(QUrl("qrc:/sound/music/weapon_enemy.wav")); mMedia.play(); }

#ifndef GAMECONTROL_H #define GAMECONTROL_H #include "gamedefine.h" #include "widget.h" class GameControl : public QObject { //单例 GameControl(QWidget* parent = nullptr); static GameControl* instance; public: //获取单例 static GameControl* Instance() { if(instance == nullptr) { return instance = new GameControl(Widget::widget); } return instance; } //析构 ~GameControl() { qDebug() << "游戏控制释放"; } //游戏初始化 void GameInit(); void LoadStartScene();//加载开始场景 void LoadGameScene();//游戏场景加载 //游戏逻辑定时器开启 (游戏开始) void GameStart(); //游戏逻辑定时器关闭 (游戏结束) void GameOver(); //背景移动 void BGMove(); //飞机移动函数 void PlaneMove(); //我机子弹生成函数 void PlaneBulletShoot(); //敌机生成 void CreateEnemy(); //碰撞检测 void Collision(); QList<int> mKeyList;//按键组合 protected: QGraphicsView mGameView;//游戏视图 QGraphicsScene mGameScene;//游戏场景 QGraphicsScene mStartScene;//开始游戏场景 //场景元素 QGraphicsPixmapItem mBackGround1;//背景元素 QGraphicsPixmapItem mBackGround2; Player mPlane; //定时器 QTimer* mBGMoveTimer;//背景移动 QTimer* mPlaneMoveTimer;//飞机移动 QTimer* mPlaneShootTimer;//飞机发射定时器 QTimer* mBulletMoveTimer;//子弹移动定时器 QTimer* mEnemyCreateTimer;//敌机创建定时器 QTimer* mEnemyMoveTimer;//敌机创建定时器 //容器 QList<Bullet*> mBulletList;//子弹容器 QList<Enemy*> mEnemyList;//敌机容器 //背景音乐 QMediaPlayer* mMediaBG; }; #endif // GAMECONTROL_H

#include "gamecontrol.h" #include "gamedefine.h" #include "gameobjectpool.h" GameControl* GameControl::instance = nullptr; GameControl::GameControl(QWidget* parent) : QObject (parent) { // this->setParent(Widget::widget); } void GameControl::BGMove() { mBackGround2.moveBy(0,2); mBackGround1.moveBy(0,2);//moveBy 移动量 dx--x方向移动量 dy---y方向移动量 if(mBackGround1.y() >= mBackGround1.pixmap().height()) { mBackGround1.setY(-mBackGround1.pixmap().height()); } else if(mBackGround2.y() >= mBackGround2.pixmap().height()) { mBackGround2.setY(-mBackGround2.pixmap().height()); } } void GameControl::GameInit() { //对象池初始化 GameObjectPool::Instance()->Init(); //设置视图的父亲为窗口 mGameView.setParent(Widget::widget); //开始场景初始化 LoadStartScene(); //定时器初始化 mBGMoveTimer = new QTimer(Widget::widget); mPlaneMoveTimer = new QTimer(Widget::widget); mPlaneShootTimer = new QTimer(Widget::widget); mBulletMoveTimer = new QTimer(Widget::widget); mEnemyCreateTimer = new QTimer(Widget::widget); mEnemyMoveTimer = new QTimer(Widget::widget); //绑定定时器处理函数 connect(mBGMoveTimer,&QTimer::timeout,this,&GameControl::BGMove); connect(mPlaneMoveTimer,&QTimer::timeout,this,&GameControl::PlaneMove); connect(mPlaneShootTimer,&QTimer::timeout,this,&GameControl::PlaneBulletShoot); connect(mEnemyCreateTimer,&QTimer::timeout,this,&GameControl::CreateEnemy); connect(mBulletMoveTimer,&QTimer::timeout,[this](){ //子弹移动 for(auto bullet : mBulletList) { bullet->BulletMove(); //判断越界回收子弹 if(bullet->y() < -200) { //移除场景 并回收对象 bullet->GameObjectDelete(&mGameScene); //移除容器 mBulletList.removeOne(bullet); } } //碰撞检测 Collision(); }); connect(mEnemyMoveTimer,&QTimer::timeout,[this](){ for(auto enemy : mEnemyList) { enemy->EnemyMove(); if(enemy->y() > GameDefine::ScreenHeight enemy->pixmap().height()) { //移除场景 对象池回收对象 enemy->GameObjectDelete(&mGameScene); //移除容器 mEnemyList.removeOne(enemy); } } }); } void GameControl::LoadStartScene() { mStartScene.setSceneRect(QRect(0,0,512,768));//游戏开始场景大小 mStartScene.addPixmap(QPixmap(":/img/Image/img_bg_logo.jpg")); auto startBtn = new QToolButton(); startBtn->setAutoRaise(true); startBtn->setIcon(QIcon(":/img/Image/startBtn.fw.png")); startBtn->setIconSize(QSize(171,45)); startBtn->move(256-171/2,384); //开始游戏点击 connect(startBtn,&QToolButton::clicked,[this](){ //加载游戏场景 this->LoadGameScene(); //开始游戏 this->GameStart(); }); mStartScene.addWidget(startBtn); //设置当前场景为 开始场景 mGameView.setScene(&mStartScene); mGameView.show(); } void GameControl::LoadGameScene() { mGameScene.setSceneRect(QRect(0,0,512,768));//游戏进行场景大小 mBackGround1.setPixmap(QPixmap(":/img/Image/img_bg_level_2.jpg"));//于QImage用法类似 mBackGround2.setPixmap(QPixmap(":/img/Image/img_bg_level_2.jpg")); mPlane.setPixmap(QPixmap(":/img/Image/MyPlane1.fw.png")); //设置元素位置 mBackGround2.setPos(0,-mBackGround2.pixmap().height()); //图片元素添加到场景 mGameScene.addItem(&mBackGround1); mGameScene.addItem(&mBackGround2); mGameScene.addItem(&mPlane); //设置当前场景为游戏场景 mGameView.setScene(&mGameScene); mGameView.show(); //-------------播放音效 this->mMediaBG = new QMediaPlayer(Widget::widget); //注意 QUrl路径对象 字符串格式 "qrc:/ 前缀名 /路径" this->mMediaBG->setMedia(QUrl("qrc:/sound/music/starwars.mp3")); this->mMediaBG->play(); } void GameControl::GameStart() { //开启定时器 mBGMoveTimer->start(GameDefine::BackgroundUpdateTime); mPlaneMoveTimer->start(GameDefine::PlayerMoveUpdateTime); mPlaneShootTimer->start(GameDefine::PlaneShootUpdateTime); mBulletMoveTimer->start(GameDefine::BulletMoveUpdateTime); mEnemyCreateTimer->start(GameDefine::EnemyCreateTime); mEnemyMoveTimer->start(GameDefine::EnemyMoveUpdateTime); } void GameControl::GameOver() { //结束逻辑 //... } void GameControl::PlaneMove() { for(int keyCode : mKeyList) { switch (keyCode) { case Qt::Key_W: mPlane.moveBy(0,-1 * mPlane.MoveSpeed());break; case Qt::Key_S: mPlane.moveBy(0,1*mPlane.MoveSpeed());break; case Qt::Key_A: mPlane.moveBy(-1*mPlane.MoveSpeed(),0);break; case Qt::Key_D: mPlane.moveBy(1*mPlane.MoveSpeed(),0);break; } } //*******************************边界判断 if(mPlane.x() < 0) { mPlane.setX(0); } if(mPlane.y() < 0) { mPlane.setY(0); } if(mPlane.x() > GameDefine::ScreenWidth - mPlane.pixmap().width()) { mPlane.setX(GameDefine::ScreenWidth - mPlane.pixmap().width()); } if(mPlane.y() > GameDefine::ScreenHeight - mPlane.pixmap().height()) { mPlane.setY(GameDefine::ScreenHeight - mPlane.pixmap().height()); } } void GameControl::PlaneBulletShoot() { //对象池构建子弹 QPixmap bulletImg(":/img/Image/bulletPlane.fw.png"); QPoint pos(mPlane.x() mPlane.pixmap().width()/2,mPlane.y()); GameObject* obj = GameObjectPool::Instance()->GetGameObject(GameObject::OT_BulletPlayer); PlayerBullet* bullet = (PlayerBullet*)obj; bullet->Init(pos,bulletImg); bullet->PlaySound();//播放音效 //添加到场景 mGameScene.addItem(bullet); //添加到子弹管理器 mBulletList.append(bullet); } void GameControl::CreateEnemy() { // Enemy* enemy = new Enemy(QPoint(randX,-200),pixmap); //对象池获取对象 QPixmap pixmap(":/img/Image/enemy1.fw.png"); int randX = qrand()%(512-pixmap.width());// [0,32768) GameObject* obj = GameObjectPool::Instance()->GetGameObject(GameObject::OT_Enemy); Enemy* enemy = (Enemy*)obj; enemy->Init(QPoint(randX,-200),pixmap); //添加到场景 mGameScene.addItem(enemy); //添加到管理器 mEnemyList.append(enemy); } void GameControl::Collision() { //遍历子弹 for(int i = 0;i < mBulletList.size();i ) { //遍历敌机 for(int j = 0;j < mEnemyList.size();j ) { if(mBulletList[i]->collidesWithItem(mEnemyList[j]))//碰撞检测 { //移除场景 (实际的对象并没有被删除) // mGameScene.removeItem(mBulletList[i]); // mGameScene.removeItem(mEnemyList[j]); //移除场景并回收到对象池 mBulletList[i]->GameObjectDelete(&mGameScene); mEnemyList[j]->GameObjectDelete(&mGameScene); //移除管理器 mBulletList.removeOne(mBulletList[i]); mEnemyList.removeOne(mEnemyList[j]); } } } }

#ifndef GAMEDEFINE_H #define GAMEDEFINE_H #include <QtDebug> #include <QGraphicsScene> #include <QGraphicsView> #include <QTimer> #include <QList> #include <QToolButton> #include <QMediaPlayer> #include "bullet.h" #include "enemy.h" #include "player.h" #include "playerbullet.h" #include "enemybullet.h" //游戏定义类 定义游戏相关属性 class GameDefine { public: GameDefine(); static const int PlaneShootUpdateTime = 500; static const int PlayerMoveUpdateTime = 20; static const int EnemyMoveUpdateTime = 20; static const int BulletMoveUpdateTime = 10; static const int BackgroundUpdateTime = 50; static const int EnemyCreateTime = 2000; //屏幕宽高 static const int ScreenWidth = 512; static const int ScreenHeight = 768; }; #endif // GAMEDEFINE_H

#include "gamedefine.h" GameDefine::GameDefine() { }

#ifndef GAMEOBJECT_H #define GAMEOBJECT_H #include <QGraphicsPixmapItem> #include <QDebug> #include <QMediaPlayer> class GameObject : public QGraphicsPixmapItem { public: enum ObjectType { OT_BulletPlayer, OT_Enemy, OT_Player, OT_EnemyBullet }; explicit GameObject(QObject *parent = nullptr); int GetType() { return mObjectType; } //对象回收 void GameObjectDelete(QGraphicsScene* _scene); //统计对象构造 和析构 static int createCount; ~GameObject() { qDebug() << "当前释放第" QString::number(createCount--) "个对象"; } protected: int mObjectType; }; #endif // GAMEOBJECT_H

#include "gameobject.h" #include <QGraphicsScene> #include "gameobjectpool.h" #include <QDebug> int GameObject::createCount = 0; GameObject::GameObject(QObject *parent) { createCount ; qDebug() << "当前创建" QString::number(createCount) "个对象"; } void GameObject::GameObjectDelete(QGraphicsScene* _scene) { _scene->removeItem(this);//移除场景 GameObjectPool::Instance()->RecoveryGameObject(this);//回收对象 }

#ifndef GAMEOBJECTPOOL_H #define GAMEOBJECTPOOL_H #include <QObject> #include "gamedefine.h" #include "widget.h" /* * * 当对象被频繁创建 或 删除时 大量使用 new 和 delete 关键字 处理堆内存 如果该对象比较大 则对计算机的消耗就越大 很有可以在创建大量 对象时出现卡顿情况 频繁的创建和删除对计算机消耗比较大。 对象缓存池:对象缓存池 预先缓存一定数量的对象 对象需要被 使用时 直接从对象池中获取对象 能有效的解决在创建时导致的卡顿问题。在对象 需要被消耗时 不销毁对象将其回收到对象缓存池中 循环利用从而解决对计算机的 销毁。 (简单来说 就是游戏对象的循环利用) */ class GameObjectPool : public QObject { GameObjectPool(QObject *parent = nullptr); static GameObjectPool* instance; public: static GameObjectPool* Instance() { if(instance == nullptr) { return instance = new GameObjectPool(Widget::widget); } return instance; } //对象池初始化 缓存对象 void Init(); //获取对象 GameObject* GetGameObject(int _objectType); //对象回收 void RecoveryGameObject(GameObject* _object); //内存清除 void Clear(); ~GameObjectPool(); protected: //玩家子弹对象池容器 QList<PlayerBullet*> mBulletPool; //敌机对象池容器 QList<Enemy*> mEnemyPool; }; #endif // GAMEOBJECTPOOL_H

#include "gameobjectpool.h" GameObjectPool* GameObjectPool::instance = nullptr; GameObjectPool::GameObjectPool(QObject *parent) : QObject(parent) { } void GameObjectPool::Init() { //预先生产对象 for (int i = 0;i < 20; i ) { //子弹生产 PlayerBullet* bullet = new PlayerBullet(); mBulletPool.append(bullet); //敌机生产 Enemy* enemy = new Enemy(); mEnemyPool.append(enemy); } } GameObject *GameObjectPool::GetGameObject(int _objectType) { switch (_objectType) { case GameObject::OT_BulletPlayer://子弹 { PlayerBullet* bullet = mBulletPool.first(); mBulletPool.pop_front(); return bullet; } case GameObject::OT_Enemy://敌机 { Enemy* enemy = mEnemyPool.first(); mEnemyPool.pop_front(); return enemy; } } } void GameObjectPool::RecoveryGameObject(GameObject *_object) { switch (_object->GetType()) { case GameObject::OT_BulletPlayer://子弹 { mBulletPool.append((PlayerBullet*)_object); break; } case GameObject::OT_Enemy://敌机 { mEnemyPool.append((Enemy*)_object); break; } } } void GameObjectPool::Clear() { //清除子弹容器 for(auto pBullet : mBulletPool) { delete pBullet; } //清除敌机容器 for(auto pEnemy :mEnemyPool) { delete pEnemy; } } GameObjectPool::~GameObjectPool() { Clear();//内存清除 }

#ifndef PLANE_H #define PLANE_H #include "gameobject.h" class Plane : public GameObject { public: explicit Plane(QObject *parent = nullptr); float MoveSpeed() { return mMoveSpeed; } protected: float mMoveSpeed; int mShootSpeed; }; #endif // PLANE_H

#include "plane.h" Plane::Plane(QObject *parent) { mObjectType = GameObject::OT_Player; }

#ifndef MYPLANE_H #define MYPLANE_H #include "plane.h" class Player : public Plane { // Q_OBJECT QGraphicsItem的派生类 不支持 Q_OBJECT(老式 信号和槽 宏) public: Player(); }; #endif // MYPLANE_H

#include "player.h" Player::Player() { this->setPixmap(QPixmap(":/img/Image/MyPlane1.fw.png")); this->setPos(256,500); mMoveSpeed = 5; mShootSpeed = 500; }

#ifndef PLAYERBULLET_H #define PLAYERBULLET_H #include "bullet.h" class PlayerBullet : public Bullet { public: explicit PlayerBullet(QObject *parent = nullptr); //玩家子弹音效 void PlaySound(); signals: public slots: }; #endif // PLAYERBULLET_H

#include "playerbullet.h" PlayerBullet::PlayerBullet(QObject *parent) { mObjectType = GameObject::OT_BulletPlayer; mSpeed = 6; } void PlayerBullet::PlaySound() { mMedia.setMedia(QUrl("qrc:/sound/music/weapon_player.wav")); mMedia.play(); }

#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QGraphicsPixmapItem>//图形元素 #include <QGraphicsView>//视图 #include <QGraphicsScene>//场景 #include <QList>//链表 #include "enemy.h" #include "player.h" #include "bullet.h" #include <QMediaPlayer>//媒体播放器类 // 图形元素组成 ---> 场景 --> 视图 --> 窗口 namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); static Widget* widget; //按键事件 widget才能检测到这两个函数 void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); private: Ui::Widget *ui; }; #endif // WIDGET_H

#include "widget.h" #include "ui_widget.h" #include "gamecontrol.h" #include "student.h" Widget* Widget::widget = nullptr; Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); this->setFixedSize(512,768); widget = this;//拿到widget,防止使用this报错 GameControl::Instance()->setParent(this); } Widget::~Widget() { delete ui; } void Widget::keyPressEvent(QKeyEvent *event) { //添加按键到按键组合 switch (event->key()) { case Qt::Key_W: case Qt::Key_S: case Qt::Key_A: case Qt::Key_D: GameControl::Instance()->mKeyList.append(event->key()); break; } } void Widget::keyReleaseEvent(QKeyEvent *event) { //移除对应按键组合 if(GameControl::Instance()->mKeyList.contains(event->key())) { GameControl::Instance()->mKeyList.removeOne(event->key()); } }

#include <QApplication> #include "gamecontrol.h" #include "student.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); //游戏加载 GameControl::Instance()->GameInit(); return a.exec(); } 3.XMl学习3.1注意点

Config.xml

3.2目录结构

3.2代码

#ifndef HERO_H #define HERO_H #include <QObject> class Hero { public: Hero(); Hero(QString name,int atk,int def,int hp,QString des) { mName = name; mAtk =atk; mHp = hp; mDef = def; mDescript = des; } QString mName; int mAtk; int mDef; int mHp; QString mDescript; }; #endif // HERO_H

#include "Hero.h" Hero::Hero() { }

Widget.h

#ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_LoadBtn_clicked(); void on_SaveBtn_clicked(); private: Ui::Widget *ui; }; #endif // WIDGET_H

#include "Widget.h" #include "ui_widget.h" #include <QtXML> //需导入QtXML,并且执行qmake #include "Hero.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); ui->textEdit->setReadOnly(true); } Widget::~Widget() { delete ui; } void Widget::on_LoadBtn_clicked() { //构建文件对象 QFile QFile file("HeroInfo.xml"); if(!file.open(QIODevice::ReadOnly))//打开文件用于读取 return; //**************XML文件读取************* QDomDocument doc;//创建文档对象 doc.setContent(&file);//设置文档内容,将file和doc绑定起来 // doc.setContent(file.readAll());//设置文档内容 QDomElement root = doc.firstChildElement("Root");//获取第一个子标签 QDomElement hero = root.firstChildElement("Hero");//获取hero子标签 QString text; while (!hero.isNull())//判断hero标签是否存在 { text = "Name:" hero.attribute("name");//读取属性 text = " Atk:" hero.attribute("atk"); text = " Def:" hero.attribute("def"); text = " HP:" hero.attribute("hp"); //读取标签内容 text = " Des:" hero.text() "\n"; hero = hero.nextSiblingElement("Hero");//获取下一个Hero兄弟标签 } ui->textEdit->setText(text); file.close(); } void Widget::on_SaveBtn_clicked() { QVector<Hero> vec; vec.push_back(Hero("曹操",100,25,2000,"曹孟德")); vec.push_back(Hero("曹丕",100,25,2000,"曹子桓")); vec.push_back(Hero("曹植",100,25,2000,"曹子建")); vec.push_back(Hero("曹彰",100,25,2000,"曹xx")); vec.push_back(Hero("曹真",100,25,2000,"曹xx")); //创建xml文档对象 QDomDocument doc; QDomElement root = doc.createElement("Root");//创建root标签 for(int i =0;i < vec.count();i ) { QDomElement hero = doc.createElement("Hero");//创建hero标签 root.appendChild(hero); hero.setAttribute("Name",vec[i].mName);//设置属性 Name hero.setAttribute("Atk",vec[i].mAtk); hero.setAttribute("Def",vec[i].mDef); hero.setAttribute("HP",vec[i].mHp); QDomText text = doc.createTextNode(vec[i].mDescript); hero.appendChild(text); } doc.appendChild(root);//将root节点添加到文档对象 //创建文件对象 QFile file("./Config.xml"); //采用相对路径 if(!file.open(QIODevice::WriteOnly)) return; QTextStream outStream(&file);//创建文本流对象 doc.save(outStream,4); file.close(); }

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved