IntroItem, improved movement rules and move counting.
authortimoph <timop.harkonen@gmail.com>
Sat, 2 Jan 2010 08:09:53 +0000 (08:09 +0000)
committertimoph <timop.harkonen@gmail.com>
Sat, 2 Jan 2010 08:09:53 +0000 (08:09 +0000)
git-svn-id: file:///svnroot/impuzzle/trunk@2 e6bec12f-0854-4cc4-ad26-6875f1509f77

src/defines.h
src/gameview.cpp
src/gameview.h
src/introitem.cpp [new file with mode: 0644]
src/introitem.h [new file with mode: 0644]
src/puzzleitem.cpp
src/puzzleitem.h
src/src.pro

index 573bef0..8584b5e 100644 (file)
@@ -23,4 +23,6 @@
 
 #define IMAGE_HEIGHT 400
 
+#define GAME_VERSION = "0.1"
+
 #endif // DEFINES_H
index f660dc1..5b0a689 100644 (file)
@@ -19,6 +19,7 @@
 #include "gameview.h"
 #include "puzzleitem.h"
 #include "defines.h"
+#include "introitem.h"
 
 #include <QGraphicsScene>
 #include <QDateTime>
@@ -26,6 +27,7 @@
 #include <QPropertyAnimation>
 #include <QParallelAnimationGroup>
 #include <QFont>
+#include <QMessageBox>
 
 #include <QDebug>
 
@@ -38,6 +40,13 @@ GameView::GameView(QWidget *parent) :
     hiddenIndex_ = -1;
     setScene(scene_);
 
+    introItem_ = new IntroItem;
+    introItem_->setText("Select new game from menu to play");
+    scene_->addItem(introItem_);
+
+    verticalStep_ = 0;
+    horizontalStep_ = 0;
+
     qsrand(QDateTime::currentDateTime().toTime_t());
 }
 
@@ -87,8 +96,8 @@ void GameView::setPieces(const QList<PuzzleItem *> pieces)
     }
 
     int verticalCount = pieces_.count() / horizontalCount;
-    int horizontalStep = IMAGE_WIDTH / horizontalCount + 5;
-    int verticalStep = IMAGE_HEIGHT / verticalCount + 5;
+    horizontalStep_ = IMAGE_WIDTH / horizontalCount + 5;
+    verticalStep_ = IMAGE_HEIGHT / verticalCount + 5;
 
     int pieceNumber = 0;
 
@@ -96,7 +105,7 @@ void GameView::setPieces(const QList<PuzzleItem *> pieces)
     for(int i = 0; i < verticalCount; ++i) {
         for(int j = 0; j < horizontalCount; ++j) {
             scene_->addItem(pieces_.at(pieceNumber));
-            QPointF point(j * horizontalStep, i * verticalStep);
+            QPointF point(j * horizontalStep_, i * verticalStep_);
             pieces_.at(pieceNumber)->setPos(point);
             pieces_.at(pieceNumber)->setCorrectPlace(point);
             pieces_.at(pieceNumber)->setCurrentPlace(point);
@@ -105,7 +114,7 @@ void GameView::setPieces(const QList<PuzzleItem *> pieces)
     }
 
     // Wait a second
-    QTimer::singleShot(1000, this, SLOT(shufflePieces()));
+    QTimer::singleShot(750, this, SLOT(shufflePieces()));
 }
 
 void GameView::shufflePieces()
@@ -115,8 +124,8 @@ void GameView::shufflePieces()
         return;
     }
 
-    // TODO Give pieces ramdom locations
-    int rounds = 5;
+    // Give pieces ramdom locations
+    int rounds = 5; //TODO
     for(int j = 0; j < rounds; ++j) {
         for(int i = 0; i < pieces_.count(); ++i) {
             QPointF tmp;
@@ -162,19 +171,64 @@ void GameView::setEmptyPlace(const QPointF &place)
 bool GameView::areAllPiecesOk() const
 {
     for(int i = 0; i < pieces_.count(); ++i) {
+        // Skip hidden piece
         if(i == hiddenIndex_) {
             continue;
         }
+        // Id piece is not in it's place
         else if(pieces_.at(i)->correctPlace() != pieces_.at(i)->currentPlace()) {
             return false;
         }
     }
+    // Show hidden piece and move it to it's place
     pieces_.at(hiddenIndex_)->show();
     pieces_.at(hiddenIndex_)->moveMeTo(emptyPlace_);
 
+    // Set all pieces not movable
     for(int i = 0; i < pieces_.count(); ++i) {
         pieces_.at(i)->setMovable(false);
     }
 
+    // Show dialog with move count
+    QMessageBox::about(const_cast<GameView *>(this), tr("You won"), QString("Puzzle completed with %1 moves").arg(PuzzleItem::moveCount()));
+
     return true;
 }
+
+void GameView::setMovingPieces()
+{
+    if(pieces_.isEmpty()) {
+        qDebug() << "Empty list @ GameView::setMovingPieces";
+        return;
+    }
+
+    QPointF point = QPointF();
+    for(int i = 0; i < pieces_.count(); ++i) {
+        point = pieces_.at(i)->currentPlace();
+
+        // Is piece on the left side of the empty space
+        if(emptyPlace_.y() == point.y() && point.x() + horizontalStep_ == emptyPlace_.x()) {
+            pieces_.at(i)->setMovable(true);
+        }
+
+        // Is piece on the right side of the empty space
+        else if(emptyPlace_.y() == point.y() && point.x() - horizontalStep_ == emptyPlace_.x()) {
+            pieces_.at(i)->setMovable(true);
+        }
+
+        // Is piece below the empty space
+        else if(emptyPlace_.x() == point.x() && point.y() - verticalStep_ == emptyPlace_.y()) {
+            pieces_.at(i)->setMovable(true);
+        }
+
+        // Is piece on top of the empty space
+        else if(emptyPlace_.x() == point.x() && point.y() + verticalStep_ == emptyPlace_.y()) {
+            pieces_.at(i)->setMovable(true);
+        }
+
+        // The piece is somewhere else
+        else {
+            pieces_.at(i)->setMovable(false);
+        }
+    }
+}
index f213fe3..60af555 100644 (file)
@@ -23,6 +23,7 @@
 
 class GraphicsScene;
 class PuzzleItem;
+class IntroItem;
 
 class GameView : public QGraphicsView
 {
@@ -34,6 +35,7 @@ public:
     QPointF emptyPlace();
     void setEmptyPlace(const QPointF &place);
     bool areAllPiecesOk() const;
+    void setMovingPieces();
 
 public slots:
     void setPieces(const QList<PuzzleItem *> pieces);
@@ -47,5 +49,9 @@ private:
     QList<PuzzleItem *> pieces_;
     QPointF emptyPlace_;
     int hiddenIndex_;
+    IntroItem *introItem_;
+
+    int verticalStep_;
+    int horizontalStep_;
 };
 #endif
diff --git a/src/introitem.cpp b/src/introitem.cpp
new file mode 100644 (file)
index 0000000..87f0b56
--- /dev/null
@@ -0,0 +1,54 @@
+#include "introitem.h"
+#include "defines.h"
+
+#include <QPainter>
+#include <QFontMetricsF>
+
+IntroItem::IntroItem(QGraphicsItem *parent) :
+        QGraphicsItem(parent)
+{
+    text_ = "";
+}
+
+QRectF IntroItem::boundingRect() const
+{
+    return QRectF(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+}
+
+void IntroItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option)
+    Q_UNUSED(widget)
+
+    painter->save();
+
+    painter->setBrush(Qt::NoBrush);
+    painter->setPen(Qt::white);
+
+    // Get font metrics
+    QFontMetricsF fontMetricsF(painter->font());
+    QRectF textRectF = fontMetricsF.boundingRect(text_);
+    int horizontalIntend = (IMAGE_WIDTH - textRectF.width()) / 2;
+    int verticalIntend = (IMAGE_HEIGHT - textRectF.height()) / 2;
+
+    // Draw text aligned to the center of boundingRect
+    painter->drawText(boundingRect()
+                      .adjusted(horizontalIntend, verticalIntend,-horizontalIntend, -verticalIntend),
+                      text_);
+
+    painter->restore();
+}
+
+QString IntroItem::text() const
+{
+    return text_;
+}
+
+void IntroItem::setText(const QString &txt)
+{
+    text_ = txt;
+
+    if(isVisible()) {
+        update();
+    }
+}
diff --git a/src/introitem.h b/src/introitem.h
new file mode 100644 (file)
index 0000000..40a8ccd
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef INTROITEM_H
+#define INTROITEM_H
+
+#include <QGraphicsItem>
+
+class IntroItem : public QGraphicsItem
+{
+public:
+    IntroItem(QGraphicsItem *parent = 0);
+    QRectF boundingRect() const;
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    QString text() const;
+    void setText(const QString &txt);
+
+private:
+    QString text_;
+};
+#endif
index 1be8e9e..500b475 100644 (file)
@@ -22,6 +22,8 @@
 #include <QGraphicsSceneMouseEvent>
 #include <QPropertyAnimation>
 
+int PuzzleItem::moveCount_ = 0;
+
 PuzzleItem::PuzzleItem(QGraphicsItem *parent) :
         QGraphicsPixmapItem(parent)
 {
@@ -75,9 +77,17 @@ void PuzzleItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
         GameView::instance()->setEmptyPlace(tmp);
         event->accept();
 
+        moveCount_++;
+
         // If piece is in its place check if we won the game
+        bool won = false;
         if(currentPlace() == correctPlace()) {
-            GameView::instance()->areAllPiecesOk();
+            won = GameView::instance()->areAllPiecesOk();
+        }
+
+        // if we didn't win set pieces that can be moved
+        if(!won) {
+            GameView::instance()->setMovingPieces();
         }
     }
     else {
@@ -89,3 +99,13 @@ void PuzzleItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
     event->ignore();
 }
+
+int PuzzleItem::moveCount()
+{
+    return moveCount_;
+}
+
+void PuzzleItem::resetMoveCount()
+{
+    moveCount_ = 0;
+}
index 0fb5827..8cf4819 100644 (file)
@@ -38,6 +38,8 @@ public:
     bool movable() const;
     void setMovable(bool canMove);
     void moveMeTo(const QPointF &location);
+    static int moveCount();
+    static void resetMoveCount();
 
 protected:
     void mousePressEvent(QGraphicsSceneMouseEvent *event);
@@ -48,5 +50,6 @@ private:
     QPointF currentPlace_;
     bool movable_;
     QPropertyAnimation *moveAnimation_;
+    static int moveCount_;
 };
 #endif
index a8781bb..14d00c1 100644 (file)
@@ -10,11 +10,15 @@ HEADERS += gameview.h \
     imageimporter.h \
     puzzleitem.h \
     newgamedialog.h \
-    defines.h
+    defines.h \
+    introitem.h
+
 SOURCES += gameview.cpp \
     main.cpp \
     mainwindow.cpp \
     imageimporter.cpp \
     puzzleitem.cpp \
-    newgamedialog.cpp
+    newgamedialog.cpp \
+    introitem.cpp
+
 RESOURCES += resources.qrc