1 /* 2 This file is part of the KDE project "KAtomic" 3 4 SPDX-FileCopyrightText: 2006-2007 Dmitry Suzdalev <dimsuz@gmail.com> 5 SPDX-FileCopyrightText: 2010 Brian Croom <brian.s.croom@gmail.com> 6 7 SPDX-License-Identifier: GPL-2.0-or-later 8 */ 9 10 #ifndef PLAYFIELD_H 11 #define PLAYFIELD_H 12 13 #include "commondefs.h" 14 15 #include <KGameRenderer> 16 17 #include <QGraphicsScene> 18 #include <QList> 19 #include <QStack> 20 21 #define MIN_ELEM_SIZE 30 22 23 class KConfigGroup; 24 class AtomFieldItem; 25 class ArrowFieldItem; 26 class MoleculePreviewItem; 27 class QTimeLine; 28 class KGamePopupItem; 29 class LevelData; 30 31 /** 32 * KAtomic level playfield 33 */ 34 class PlayField : public QGraphicsScene 35 { 36 Q_OBJECT 37 public: 38 enum Direction { Up=0, Down, Left, Right }; 39 explicit PlayField( QObject *parent ); 40 ~PlayField() override; 41 /** 42 * Resizes playfield to width,height 43 */ 44 void resize( int width, int height ); 45 /** 46 * Loads level 47 */ 48 void setLevelData(const LevelData* level); 49 /** 50 * Sets animation speed (0-slow, 1-normal, 2-fast) 51 */ 52 void setAnimationSpeed(int speed); 53 /** 54 * Animates currently selected atom movement in direction dir 55 * @param numCells used on undos/redos 56 */ 57 void moveSelectedAtom( Direction dir, int numCells=0 ); 58 /** 59 * Saves the current game to config object 60 */ 61 void saveGame(KConfigGroup& config) const; 62 /** 63 * Loads game from config object 64 */ 65 void loadGame(const KConfigGroup& config); 66 /** 67 * Returns whether level is finished already 68 */ isLevelFinished()69 bool isLevelFinished() const { return m_levelFinished; } 70 /** 71 * Displays a passive popup message at the bottom of the scene 72 */ 73 void showMessage( const QString& message ); 74 /** 75 * Name of the current molecule 76 */ 77 QString moleculeName() const; 78 /** 79 * The caching SVG pixmap renderer 80 */ renderer()81 KGameRenderer* renderer() { return &m_renderer; } 82 83 public Q_SLOTS: 84 /** 85 * Selects next atom 86 */ 87 void nextAtom(); 88 /** 89 * Selects previous atom 90 */ 91 void previousAtom(); 92 /** 93 * Undoes one movement 94 */ 95 void undo(); 96 /** 97 * Redoes one movement 98 */ 99 void redo(); 100 /** 101 * Undoes all movements 102 */ 103 void undoAll(); 104 /** 105 * Redoes all movements 106 */ 107 void redoAll(); 108 Q_SIGNALS: 109 void gameOver(int numMoves); 110 void updateMoves(int); 111 void enableUndo(bool); 112 void enableRedo(bool); 113 private Q_SLOTS: 114 void atomAnimFrameChanged(int frame); 115 private: 116 void drawForeground( QPainter*, const QRectF& ) override; 117 void mousePressEvent( QGraphicsSceneMouseEvent* ev ) override; 118 119 /** 120 * Checks if molecule is finished 121 */ 122 bool checkDone() const; 123 /** 124 * Re-renders atoms&arrows Pixmaps, updates their positions 125 */ 126 void updateFieldItems(); 127 /** 128 * Updates arrows around selected atom 129 */ 130 void updateArrows(bool justHide=false); 131 /** 132 * Set the background brush to a properly sized pixmap 133 */ 134 void updateBackground(); 135 /** 136 * Returns true if Field cell (x,y) is empty, i.e. it isn't a wall and has no atom 137 */ 138 bool cellIsEmpty(int x, int y) const; 139 /** 140 * Returns true if atom animation is running 141 */ 142 bool isAnimating() const; 143 toPixX(int fieldX)144 inline int toPixX( int fieldX ) const { return fieldX*m_elemSize; } toPixY(int fieldY)145 inline int toPixY( int fieldY ) const { return fieldY*m_elemSize; } toFieldX(int pixX)146 inline int toFieldX( int pixX ) const { return pixX/m_elemSize; } toFieldY(int pixY)147 inline int toFieldY( int pixY ) const { return pixY/m_elemSize; } fieldCenterX()148 inline int fieldCenterX() const { return toPixX(0) + m_elemSize*FIELD_SIZE/2; } fieldCenterY()149 inline int fieldCenterY() const { return toPixY(0) + m_elemSize*FIELD_SIZE/2; } 150 151 /** 152 * Renderer object 153 */ 154 KGameRenderer m_renderer; 155 /** 156 * Number of moves made for current level 157 */ 158 int m_numMoves; 159 /** 160 * Level Data 161 */ 162 const LevelData* m_levelData; 163 /** 164 * Element (i.e. atom, wall, arrow) size 165 */ 166 int m_elemSize; 167 /** 168 * List of atom QGraphicsItems 169 */ 170 QList<AtomFieldItem*> m_atoms; 171 /** 172 * Arrow items 173 */ 174 ArrowFieldItem *m_upArrow, *m_leftArrow, *m_downArrow, *m_rightArrow; 175 /** 176 * Item used to show messages to user 177 */ 178 KGamePopupItem *m_messageItem; 179 /** 180 * Index of currently selected atom 181 */ 182 int m_selIdx; 183 /** 184 * Direction in which current atom animation moves 185 */ 186 Direction m_dir; 187 /** 188 * Animation speed. Atom will move at 1cell in m_animSpeed msec speed 189 */ 190 int m_animSpeed; 191 /** 192 * Timeline object to control atom movement animation 193 */ 194 QTimeLine *m_atomTimeLine; 195 /** 196 * True if current level is finished and thus all player input should be disabled 197 */ 198 bool m_levelFinished; 199 200 struct AtomMove 201 { 202 int atomIdx; // atom index in m_atoms 203 Direction dir; 204 int numCells; 205 AtomMove( int idx=-1, Direction d=Up, int nc=0 ) atomIdxAtomMove206 : atomIdx(idx), dir(d), numCells(nc) { } 207 }; 208 QStack<AtomMove> m_undoStack; 209 QStack<AtomMove> m_redoStack; 210 211 MoleculePreviewItem *m_previewItem; 212 }; 213 214 #endif 215