我对Qt很陌生,但我开始尝试制作2D游戏。我有一个非常粗糙和简单的游戏开始,但我有一个问题。每当健康状况达到0时,游戏就不会结束。我只是想知道如何结束游戏以及在进行游戏之前放置此退出命令的位置" Game Over"屏幕。我的代码在下面,从我能掌握的,我假设QApplication :: quit()进入Game.cpp文件。通过从Health.cpp和Health.h获取健康整数并将其放入Game.cpp来完成此操作。任何帮助表示赞赏。以下是我觉得答案所在的代码,如果需要更多信息,请询问。
Game.h
#ifndef GAME_H
#define GAME_H
#include <QGraphicsView>
#include <QWidget>
#include <QGraphicsScene>
#include "Player.h"
#include "Score.h"
#include "Health.h"
#include "Level.h"
#include "Main.h"
class Game: public QGraphicsView{
public:
Game(QWidget * parent=0);
QGraphicsScene * scene;
Player * player;
Score * score;
Health * health;
Level * level;
Main * close;
int end();
};
#endif // GAME_H
Game.cpp
#include "Game.h"
#include <QTimer>
#include <QGraphicsTextItem>
#include <QFont>
#include "Enemy.h"
#include <QMediaPlayer>
#include <QBrush>
#include <QImage>
#include <QApplication>
Game::Game(QWidget *parent){
// create the scene
scene = new QGraphicsScene();
scene->setSceneRect(0,0,800,600); // make the scene 800x600 instead of infinity by infinity (default)
setBackgroundBrush(QBrush(QImage(":/images/bg.png")));
// make the newly created scene the scene to visualize (since Game is a QGraphicsView Widget,
// it can be used to visualize scenes)
setScene(scene);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFixedSize(800,600);
// create the player
player = new Player();
player->setPos(400,500); // TODO generalize to always be in the middle bottom of screen
// make the player focusable and set it to be the current focus
player->setFlag(QGraphicsItem::ItemIsFocusable);
player->setFocus();
// add the player to the scene
scene->addItem(player);
// create the score/health
score = new Score();
scene->addItem(score);
health = new Health();
health->setPos(health->x(),health->y()+25);
scene->addItem(health);
level = new Level();
scene->addItem(level);Bull
level->setPos(level->x(),level->y()+50);
// spawn enemies
QTimer * timer = new QTimer();
QObject::connect(timer,SIGNAL(timeout()),player,SLOT(spawn()));
timer->start(2000);
// play background music
QMediaPlayer * music = new QMediaPlayer();
music->setMedia(QUrl("qrc:/sounds/bgsound.mp3"));
music->play();
show();
}
int Game::end(){
if (health == 0){
QApplication::quit();
}
return 0;
}
Health.h
#ifndef HEALTH_H
#define HEALTH_H
#include <QGraphicsTextItem>
class Health: public QGraphicsTextItem{
public:
Health(QGraphicsItem * parent=0);
void decrease();
int getHealth();
private:
int health;
};
#endif // HEALTH_H
Health.cpp
#include "Health.h"
#include <QFont>
#include <QApplication>
Health::Health(QGraphicsItem *parent): QGraphicsTextItem(parent){
// initialize the score to 0
health = 3;
// draw the text
setPlainText(QString("Health: ") + QString::number(health)); // Health: 3
setDefaultTextColor(Qt::red);
setFont(QFont("times",16));
}
void Health::decrease(){
health--;
setPlainText(QString("Health: ") + QString::number(health)); // Health: 2
}
int Health::getHealth(){
return health;
}
的main.cpp
#include <QApplication>
#include "Game.h"
#include "Main.h"
Game * game;
int main(int argc, char *argv[]){
QApplication a(argc, argv);
game = new Game();
game->show();
return a.exec();
}
答案 0 :(得分:2)
永远不会调用end()
函数。
实现目标的最佳方式是使用Qt's signal/slot mechanism。将事件(信号)连接到动作(插槽)很容易:
Q_OBJECT
宏添加到Health
和Game
类,并确保您的编译环境moc's两个头文件Health
signal
dead()
Health::decrease()
Game::end()
成为slot
并成为void
Health::dead()
连接到Game::end()
然后,只要Game::end()
达到零,就会调用Health
。
class Health: public QGraphicsTextItem
{
Q_OBJECT
public:
Health(QGraphicsItem * parent=0);
void decrease();
int getHealth();
signals:
void dead();
private:
int health;
};
...
class Game: public QGraphicsView{
Q_OBJECT
public:
...
public slots:
void end();
};
...
void Health::decrease(){
health--;
setPlainText(QString("Health: ") + QString::number(health));
if ( health == 0 )
emit dead();
}
...
Game::Game(QWidget *parent){
...
connect( health, SIGNAL(dead()), this, SLOT(end()) );
}
...
void Game::end(){
// no need to test health anymore, as signal is emited when health is zero
// do some extra stuff before exiting
QApplication::quit();
}
如果end()
仅调用QApplication::quit()
,您可以将其删除并将信号连接到QApplication::quit()
,如下所示:
connect( health, SIGNAL(dead()), qApp, SLOT(quit()) );
另请注意,您正在health == 0
中测试Game::end()
,但health
是一个指针,并且,查看您的代码,它永远不会是0
(您可能意思是写if ( health->getHealth() == 0 )
。
答案 1 :(得分:0)
在Health::decrease
中发出信号或将其逻辑放在“玩家被射击”区域。 但要做到这一点,你要编辑{{1} }已经是Health
或逻辑为QObject
的类,以便获取标题中的信号和插槽。QGraphicsTextItem
了。见评论。
在Health类或Player类实例化后立即将信号连接到视图的QObject
。
http://doc.qt.io/qt-5/signalsandslots.html
希望有所帮助。