File indexing completed on 2024-04-21 04:02:00
0001 /* 0002 This file is part of the KDE project "KAtomic" 0003 0004 SPDX-FileCopyrightText: 2006-2007 Dmitry Suzdalev <dimsuz@gmail.com> 0005 SPDX-FileCopyrightText: 2010 Brian Croom <brian.s.croom@gmail.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #ifndef PLAYFIELD_H 0011 #define PLAYFIELD_H 0012 0013 #include "commondefs.h" 0014 0015 #include <KGameRenderer> 0016 0017 #include <QGraphicsScene> 0018 #include <QList> 0019 #include <QStack> 0020 0021 #define MIN_ELEM_SIZE 30 0022 0023 class KConfigGroup; 0024 class AtomFieldItem; 0025 class ArrowFieldItem; 0026 class MoleculePreviewItem; 0027 class QTimeLine; 0028 class KGamePopupItem; 0029 class LevelData; 0030 0031 /** 0032 * KAtomic level playfield 0033 */ 0034 class PlayField : public QGraphicsScene 0035 { 0036 Q_OBJECT 0037 public: 0038 enum Direction { Up=0, Down, Left, Right }; 0039 explicit PlayField( QObject *parent ); 0040 ~PlayField() override; 0041 /** 0042 * Resizes playfield to width,height 0043 */ 0044 void resize( int width, int height ); 0045 /** 0046 * Loads level 0047 */ 0048 void setLevelData(const LevelData* level); 0049 /** 0050 * Sets animation speed (0-slow, 1-normal, 2-fast) 0051 */ 0052 void setAnimationSpeed(int speed); 0053 /** 0054 * Animates currently selected atom movement in direction dir 0055 * @param numCells used on undos/redos 0056 */ 0057 void moveSelectedAtom( Direction dir, int numCells=0 ); 0058 /** 0059 * Saves the current game to config object 0060 */ 0061 void saveGame(KConfigGroup& config) const; 0062 /** 0063 * Loads game from config object 0064 */ 0065 void loadGame(const KConfigGroup& config); 0066 /** 0067 * Returns whether level is finished already 0068 */ 0069 bool isLevelFinished() const { return m_levelFinished; } 0070 /** 0071 * Displays a passive popup message at the bottom of the scene 0072 */ 0073 void showMessage( const QString& message ); 0074 /** 0075 * Name of the current molecule 0076 */ 0077 QString moleculeName() const; 0078 /** 0079 * The caching SVG pixmap renderer 0080 */ 0081 KGameRenderer* renderer() { return &m_renderer; } 0082 0083 public Q_SLOTS: 0084 /** 0085 * Selects next atom 0086 */ 0087 void nextAtom(); 0088 /** 0089 * Selects previous atom 0090 */ 0091 void previousAtom(); 0092 /** 0093 * Undoes one movement 0094 */ 0095 void undo(); 0096 /** 0097 * Redoes one movement 0098 */ 0099 void redo(); 0100 /** 0101 * Undoes all movements 0102 */ 0103 void undoAll(); 0104 /** 0105 * Redoes all movements 0106 */ 0107 void redoAll(); 0108 Q_SIGNALS: 0109 void gameOver(int numMoves); 0110 void updateMoves(int); 0111 void enableUndo(bool); 0112 void enableRedo(bool); 0113 private Q_SLOTS: 0114 void atomAnimFrameChanged(int frame); 0115 private: 0116 void drawForeground( QPainter*, const QRectF& ) override; 0117 void mousePressEvent( QGraphicsSceneMouseEvent* ev ) override; 0118 0119 /** 0120 * Checks if molecule is finished 0121 */ 0122 bool checkDone() const; 0123 /** 0124 * Re-renders atoms&arrows Pixmaps, updates their positions 0125 */ 0126 void updateFieldItems(); 0127 /** 0128 * Updates arrows around selected atom 0129 */ 0130 void updateArrows(bool justHide=false); 0131 /** 0132 * Set the background brush to a properly sized pixmap 0133 */ 0134 void updateBackground(); 0135 /** 0136 * Returns true if Field cell (x,y) is empty, i.e. it isn't a wall and has no atom 0137 */ 0138 bool cellIsEmpty(int x, int y) const; 0139 /** 0140 * Returns true if atom animation is running 0141 */ 0142 bool isAnimating() const; 0143 0144 inline int toPixX( int fieldX ) const { return fieldX*m_elemSize; } 0145 inline int toPixY( int fieldY ) const { return fieldY*m_elemSize; } 0146 inline int toFieldX( int pixX ) const { return pixX/m_elemSize; } 0147 inline int toFieldY( int pixY ) const { return pixY/m_elemSize; } 0148 inline int fieldCenterX() const { return toPixX(0) + m_elemSize*FIELD_SIZE/2; } 0149 inline int fieldCenterY() const { return toPixY(0) + m_elemSize*FIELD_SIZE/2; } 0150 0151 /** 0152 * Renderer object 0153 */ 0154 KGameRenderer m_renderer; 0155 /** 0156 * Number of moves made for current level 0157 */ 0158 int m_numMoves; 0159 /** 0160 * Level Data 0161 */ 0162 const LevelData* m_levelData; 0163 /** 0164 * Element (i.e. atom, wall, arrow) size 0165 */ 0166 int m_elemSize; 0167 /** 0168 * List of atom QGraphicsItems 0169 */ 0170 QList<AtomFieldItem*> m_atoms; 0171 /** 0172 * Arrow items 0173 */ 0174 ArrowFieldItem *m_upArrow, *m_leftArrow, *m_downArrow, *m_rightArrow; 0175 /** 0176 * Item used to show messages to user 0177 */ 0178 KGamePopupItem *m_messageItem; 0179 /** 0180 * Index of currently selected atom 0181 */ 0182 int m_selIdx; 0183 /** 0184 * Direction in which current atom animation moves 0185 */ 0186 Direction m_dir; 0187 /** 0188 * Animation speed. Atom will move at 1cell in m_animSpeed msec speed 0189 */ 0190 int m_animSpeed; 0191 /** 0192 * Timeline object to control atom movement animation 0193 */ 0194 QTimeLine *m_atomTimeLine; 0195 /** 0196 * True if current level is finished and thus all player input should be disabled 0197 */ 0198 bool m_levelFinished; 0199 0200 struct AtomMove 0201 { 0202 int atomIdx; // atom index in m_atoms 0203 Direction dir; 0204 int numCells; 0205 AtomMove( int idx=-1, Direction d=Up, int nc=0 ) 0206 : atomIdx(idx), dir(d), numCells(nc) { } 0207 }; 0208 QStack<AtomMove> m_undoStack; 0209 QStack<AtomMove> m_redoStack; 0210 0211 MoleculePreviewItem *m_previewItem; 0212 }; 0213 0214 #endif