summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-14 13:12:12 +0200
committerEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-14 13:12:12 +0200
commitededfad305258f9f450b314d9e2d53a6905bc6d0 (patch)
tree6a3b6e4d7ec09e596c0ba2b9f81b816614089962
parentfa99a2ab12f646d73498b69fae0020da1abf9685 (diff)
Pop up message when a tank wins the game
Also fixed: Added some docs and moved the tanks a little so they don't start partly outside the scene rect.
-rw-r--r--doc/src/examples/tankgame.qdoc2
-rw-r--r--examples/statemachine/tankgame/gameovertransition.cpp39
-rw-r--r--examples/statemachine/tankgame/gameovertransition.h22
-rw-r--r--examples/statemachine/tankgame/mainwindow.cpp53
-rw-r--r--examples/statemachine/tankgame/mainwindow.h3
-rw-r--r--examples/statemachine/tankgame/tankgame.pro4
-rw-r--r--examples/statemachine/tankgame/tankitem.cpp1
-rw-r--r--examples/statemachine/tankgame/tankitem.h1
8 files changed, 113 insertions, 12 deletions
diff --git a/doc/src/examples/tankgame.qdoc b/doc/src/examples/tankgame.qdoc
index 1501a99b94..ab3e0f4886 100644
--- a/doc/src/examples/tankgame.qdoc
+++ b/doc/src/examples/tankgame.qdoc
@@ -82,6 +82,8 @@
"Add tank" menu item should be disabled. This is implemented by giving the "stopped" state two
children which define whether the map is full or not.
+ \snippet examples/statemachine/tankgame/mainwindow.cpp 5
+
To make sure that we go into the correct child state when returning from the "running" state
(if the "Stop game" menu item is selected while the game is running) we also give the "stopped"
state a history state which we make the initial state of "stopped" state.
diff --git a/examples/statemachine/tankgame/gameovertransition.cpp b/examples/statemachine/tankgame/gameovertransition.cpp
new file mode 100644
index 0000000000..21c35109f9
--- /dev/null
+++ b/examples/statemachine/tankgame/gameovertransition.cpp
@@ -0,0 +1,39 @@
+#include "gameovertransition.h"
+#include "tankitem.h"
+
+#include <QSignalEvent>
+#include <QSignalMapper>
+
+GameOverTransition::GameOverTransition(QAbstractState *targetState)
+ : QSignalTransition(new QSignalMapper(), SIGNAL(mapped(QObject*)))
+{
+ setTargetState(targetState);
+
+ QSignalMapper *mapper = qobject_cast<QSignalMapper *>(senderObject());
+ mapper->setParent(this);
+}
+
+void GameOverTransition::addTankItem(TankItem *tankItem)
+{
+ m_tankItems.append(tankItem);
+
+ QSignalMapper *mapper = qobject_cast<QSignalMapper *>(senderObject());
+ mapper->setMapping(tankItem, tankItem);
+ connect(tankItem, SIGNAL(aboutToBeDestroyed()), mapper, SLOT(map()));
+}
+
+bool GameOverTransition::eventTest(QEvent *e) const
+{
+ bool ret = QSignalTransition::eventTest(e);
+
+ if (ret) {
+ QSignalEvent *signalEvent = static_cast<QSignalEvent *>(e);
+ QObject *sender = qvariant_cast<QObject *>(signalEvent->arguments().at(0));
+ TankItem *tankItem = qobject_cast<TankItem *>(sender);
+ m_tankItems.removeAll(tankItem);
+
+ return m_tankItems.size() <= 1;
+ } else {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/examples/statemachine/tankgame/gameovertransition.h b/examples/statemachine/tankgame/gameovertransition.h
new file mode 100644
index 0000000000..53c9b863fc
--- /dev/null
+++ b/examples/statemachine/tankgame/gameovertransition.h
@@ -0,0 +1,22 @@
+#ifndef GAMEOVERTRANSITION_H
+#define GAMEOVERTRANSITION_H
+
+#include <QSignalTransition>
+
+class TankItem;
+class GameOverTransition: public QSignalTransition
+{
+ Q_OBJECT
+public:
+ GameOverTransition(QAbstractState *targetState);
+
+ void addTankItem(TankItem *tankItem);
+
+protected:
+ bool eventTest(QEvent *event) const;
+
+private:
+ mutable QList<TankItem *> m_tankItems;
+};
+
+#endif
diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp
index 870bc9c115..fcc0325b0a 100644
--- a/examples/statemachine/tankgame/mainwindow.cpp
+++ b/examples/statemachine/tankgame/mainwindow.cpp
@@ -2,6 +2,7 @@
#include "tankitem.h"
#include "rocketitem.h"
#include "plugin.h"
+#include "gameovertransition.h"
#include <QStateMachine>
#include <QGraphicsView>
@@ -53,7 +54,7 @@ void MainWindow::init()
{
TankItem *item = new TankItem(this);
- item->setPos(m_scene->sceneRect().topLeft() + QPointF(15.0, 15.0));
+ item->setPos(m_scene->sceneRect().topLeft() + QPointF(30.0, 30.0));
item->setDirection(45.0);
item->setColor(Qt::red);
@@ -63,7 +64,7 @@ void MainWindow::init()
{
TankItem *item = new TankItem(this);
- item->setPos(m_scene->sceneRect().topRight() + QPointF(-15.0, 15.0));
+ item->setPos(m_scene->sceneRect().topRight() + QPointF(-30.0, 30.0));
item->setDirection(135.0);
item->setColor(Qt::green);
@@ -73,7 +74,7 @@ void MainWindow::init()
{
TankItem *item = new TankItem(this);
- item->setPos(m_scene->sceneRect().bottomRight() + QPointF(-15.0, -15.0));
+ item->setPos(m_scene->sceneRect().bottomRight() + QPointF(-30.0, -30.0));
item->setDirection(225.0);
item->setColor(Qt::blue);
@@ -83,7 +84,7 @@ void MainWindow::init()
{
TankItem *item = new TankItem(this);
- item->setPos(m_scene->sceneRect().bottomLeft() + QPointF(15.0, -15.0));
+ item->setPos(m_scene->sceneRect().bottomLeft() + QPointF(30.0, -30.0));
item->setDirection(315.0);
item->setColor(Qt::yellow);
@@ -125,20 +126,23 @@ void MainWindow::init()
stoppedState->assignProperty(this, "started", false);
m_machine->setInitialState(stoppedState);
- QState *spawnsAvailable = new QState(stoppedState);
- spawnsAvailable->setObjectName("spawnsAvailable");
+//! [5]
+ QState *spawnsAvailable = new QState(stoppedState);
spawnsAvailable->assignProperty(addTankAction, "enabled", true);
- QState *noSpawnsAvailable = new QState(stoppedState);
- noSpawnsAvailable->setObjectName("noSpawnsAvailable");
+ QState *noSpawnsAvailable = new QState(stoppedState);
noSpawnsAvailable->assignProperty(addTankAction, "enabled", false);
+//! [5]
+ spawnsAvailable->setObjectName("spawnsAvailable");
+ noSpawnsAvailable->setObjectName("noSpawnsAvailable");
spawnsAvailable->addTransition(this, SIGNAL(mapFull()), noSpawnsAvailable);
//! [3]
- QHistoryState *hs = new QHistoryState(stoppedState);
+ QHistoryState *hs = new QHistoryState(stoppedState);
hs->setDefaultState(spawnsAvailable);
//! [3]
+ hs->setObjectName("hs");
stoppedState->setInitialState(hs);
@@ -149,10 +153,18 @@ void MainWindow::init()
m_runningState->assignProperty(addTankAction, "enabled", false);
m_runningState->assignProperty(runGameAction, "enabled", false);
m_runningState->assignProperty(stopGameAction, "enabled", true);
+
+ QState *gameOverState = new QState(m_machine->rootState());
+ gameOverState->setObjectName("gameOverState");
+ gameOverState->assignProperty(stopGameAction, "enabled", false);
+ connect(gameOverState, SIGNAL(entered()), this, SLOT(gameOver()));
stoppedState->addTransition(runGameAction, SIGNAL(triggered()), m_runningState);
m_runningState->addTransition(stopGameAction, SIGNAL(triggered()), stoppedState);
+ m_gameOverTransition = new GameOverTransition(gameOverState);
+ m_runningState->addTransition(m_gameOverTransition);
+
QTimer *timer = new QTimer(this);
timer->setInterval(100);
connect(timer, SIGNAL(timeout()), this, SLOT(runStep()));
@@ -182,6 +194,22 @@ void MainWindow::runStep()
}
}
+void MainWindow::gameOver()
+{
+ QList<QGraphicsItem *> items = m_scene->items();
+
+ TankItem *lastTankStanding = 0;
+ foreach (QGraphicsItem *item, items) {
+ if (GameItem *gameItem = qgraphicsitem_cast<GameItem *>(item)) {
+ if (lastTankStanding = qobject_cast<TankItem *>(gameItem))
+ break;
+ }
+ }
+
+ QMessageBox::information(this, "Game over!",
+ QString::fromLatin1("The tank played by '%1' has won!").arg(lastTankStanding->objectName()));
+}
+
void MainWindow::addRocket()
{
TankItem *tankItem = qobject_cast<TankItem *>(sender());
@@ -244,21 +272,26 @@ void MainWindow::addTank()
int idx = itemNames.indexOf(selectedName);
if (Plugin *plugin = idx >= 0 ? items.at(idx) : 0) {
TankItem *tankItem = m_spawns.takeLast();
+ tankItem->setObjectName(selectedName);
+ tankItem->setToolTip(selectedName);
m_scene->addItem(tankItem);
connect(tankItem, SIGNAL(cannonFired()), this, SLOT(addRocket()));
if (m_spawns.isEmpty())
emit mapFull();
+
+ m_gameOverTransition->addTankItem(tankItem);
QState *region = new QState(m_runningState);
+ region->setObjectName(QString::fromLatin1("region%1").arg(m_spawns.size()));
//! [2]
QState *pluginState = plugin->create(region, tankItem);
//! [2]
region->setInitialState(pluginState);
-
// If the plugin has an error it is disabled
//! [4]
QState *errorState = new QState(region);
+ errorState->setObjectName(QString::fromLatin1("errorState%1").arg(m_spawns.size()));
errorState->assignProperty(tankItem, "enabled", false);
pluginState->setErrorState(errorState);
//! [4]
diff --git a/examples/statemachine/tankgame/mainwindow.h b/examples/statemachine/tankgame/mainwindow.h
index 622dabe75e..40e1595b94 100644
--- a/examples/statemachine/tankgame/mainwindow.h
+++ b/examples/statemachine/tankgame/mainwindow.h
@@ -7,6 +7,7 @@
class QGraphicsScene;
class QStateMachine;
class QState;
+class GameOverTransition;
class TankItem;
class MainWindow: public QMainWindow
{
@@ -23,6 +24,7 @@ public slots:
void addTank();
void addRocket();
void runStep();
+ void gameOver();
signals:
void mapFull();
@@ -35,6 +37,7 @@ private:
QStateMachine *m_machine;
QState *m_runningState;
+ GameOverTransition *m_gameOverTransition;
QList<TankItem *> m_spawns;
QTime m_time;
diff --git a/examples/statemachine/tankgame/tankgame.pro b/examples/statemachine/tankgame/tankgame.pro
index f7b0760b29..46cfe2e3ed 100644
--- a/examples/statemachine/tankgame/tankgame.pro
+++ b/examples/statemachine/tankgame/tankgame.pro
@@ -8,6 +8,6 @@ DEPENDPATH += .
INCLUDEPATH += C:/dev/kinetic/examples/statemachine/tankgame/. .
# Input
-HEADERS += mainwindow.h plugin.h tankitem.h rocketitem.h gameitem.h
-SOURCES += main.cpp mainwindow.cpp tankitem.cpp rocketitem.cpp gameitem.cpp
+HEADERS += mainwindow.h plugin.h tankitem.h rocketitem.h gameitem.h gameovertransition.h
+SOURCES += main.cpp mainwindow.cpp tankitem.cpp rocketitem.cpp gameitem.cpp gameovertransition.cpp
CONFIG += console
diff --git a/examples/statemachine/tankgame/tankitem.cpp b/examples/statemachine/tankgame/tankitem.cpp
index 5506a7ec0b..c322d21743 100644
--- a/examples/statemachine/tankgame/tankitem.cpp
+++ b/examples/statemachine/tankgame/tankitem.cpp
@@ -113,6 +113,7 @@ void TankItem::idle(qreal elapsed)
void TankItem::hitByRocket()
{
+ emit aboutToBeDestroyed();
deleteLater();
}
diff --git a/examples/statemachine/tankgame/tankitem.h b/examples/statemachine/tankgame/tankitem.h
index 66f05aa1c4..9475397f0c 100644
--- a/examples/statemachine/tankgame/tankitem.h
+++ b/examples/statemachine/tankgame/tankitem.h
@@ -41,6 +41,7 @@ signals:
void collision(const QLineF &collidedLine);
void actionCompleted();
void cannonFired();
+ void aboutToBeDestroyed();
public slots:
void moveForwards(qreal length = 10.0);