1 /*******************************************************************
3 * Copyright 2006 Dmitry Suzdalev <dimsuz@gmail.com>
5 * This file is part of the KDE project "KLines"
7 * KLines is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * KLines is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with KLines; see the file COPYING. If not, write to
19 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
22 ********************************************************************/
26 #include <QGraphicsScene>
27 #include <KRandomSequence>
29 #include "commondefs.h"
31 static const int FIELD_SIZE
=9;
36 class QGraphicsRectItem
;
40 * Displays and drives the game
42 class KLinesScene
: public QGraphicsScene
46 explicit KLinesScene( QObject
*parent
);
51 void resizeScene( int width
, int height
);
53 * Brings in next three balls to scene
55 void nextThreeBalls();
57 * Show/Hide the preview zone
59 void setPreviewZoneVisible( bool visible
);
61 * This score points will be added as an additional bonus to
62 * every score resulted from ball erasing event.
63 * For example 1 score point is added if the game is played with
64 * hidden preview widget.
65 * By default no bonus is added.
67 void setBonusScorePoints( int points
) { m_bonusScore
= points
; }
69 * Returns colors of the 3 balls in the next turn
71 QList
<BallColor
> nextColors() const { return m_nextColors
; }
73 * Returns ballitem in field position pos or 0 if there
76 BallItem
* ballAt( const FieldPos
& pos
) { return m_field
[pos
.x
][pos
.y
]; }
78 * Overloaded above function
80 BallItem
* ballAt( int x
, int y
) { return m_field
[x
][y
]; }
82 * Field coords to pixel coords
84 inline QPointF
fieldToPix(const FieldPos
& fpos
) const
86 return QPointF( m_playFieldRect
.x() + m_playFieldBorderSize
+ fpos
.x
*m_cellSize
,
87 m_playFieldRect
.y() + m_playFieldBorderSize
+ fpos
.y
*m_cellSize
);
90 * Pixel coords to field coords
92 inline FieldPos
pixToField( const QPointF
& p
) const
94 return FieldPos(static_cast<int>(( p
.x()-m_playFieldRect
.x()-m_playFieldBorderSize
)/m_cellSize
),
95 static_cast<int>(( p
.y()-m_playFieldRect
.y()-m_playFieldBorderSize
)/m_cellSize
));
103 * Ends current and starts next turn explicitly
111 * Moves keyboard-playing focus rect to the left
113 void moveFocusLeft();
115 * Moves keyboard-playing focus rect to the right
117 void moveFocusRight();
119 * Moves keyboard-playing focus rect to the up
123 * Moves keyboard-playing focus rect to the down
125 void moveFocusDown();
127 * Takes corresponding action on cell under focus rect
131 void scoreChanged(int);
132 void stateChanged(const QString
&);
135 void moveAnimFinished();
136 void removeAnimFinished();
137 void bornAnimFinished();
140 * Creates a ball and places it in random free cell
141 * @param c color of the ball
142 * @return ball placed
144 BallItem
* randomlyPlaceBall(BallColor c
);
146 * Searches for 5 or more balls in a row and deletes them from field
148 void searchAndErase();
150 * This function takes one of two actions:
151 * If there's a ball at fpos, it will be selected.
152 * Otherwise if the cell at fpos is empty and there's
153 * a selected ball in some other cell it will be moved to fpos
154 * (if the move is possible, of course)
156 void selectOrMove( const FieldPos
& fpos
);
158 * Saves game state information to be used during undo
161 /** Does some actions upon game over. Called from various places where
162 * it is clear that game is now over. emits gameOver(int) signal
164 void gameOverHandler();
166 virtual void drawBackground( QPainter
*, const QRectF
& );
167 virtual void mousePressEvent( QGraphicsSceneMouseEvent
* );
170 * This array represents the play field.
171 * Each cell holds the pointer to BallItem
172 * or 0 if there's no ball in that cell
174 BallItem
* m_field
[FIELD_SIZE
][FIELD_SIZE
];
176 * Used to start game animations
177 * This object knows how to do some ball animations
179 KLinesAnimator
* m_animator
;
181 * We need random numbers in this game
183 KRandomSequence m_randomSeq
;
185 * Area of playfield (with border included - if any exists in theme)
187 QRect m_playFieldRect
;
189 * Size of a playfield border.
190 * Equals 0 if there's no border element in current theme
192 int m_playFieldBorderSize
;
195 * Position of selected ball (-1,-1) if none
199 * Number of free cells in the field
207 * Bonus points added to score upon ball erasing
208 * @see setBonusScorePoints()
212 * Cell size in pixels
216 * Is true if preview zone is visible
218 bool m_previewZoneVisible
;
220 * Varable which is needed for little trick (tm).
221 * Read more about it in removeAnimFinished() slot
225 * Items pending for removal after remove-anim finishes
227 QList
<BallItem
*> m_itemsToDelete
;
229 * Colors of the next turn's balls
231 QList
<BallColor
> m_nextColors
;
233 * Keyboard-playing focus indication
235 QGraphicsRectItem
*m_focusItem
;
237 * Item which displays next balls preview
239 PreviewItem
*m_previewItem
;
241 * Item to show popup messages to user
243 KGamePopupItem
*m_popupItem
;
245 * Struct for holding game state - used on undos
251 QList
<BallColor
> nextColors
;
252 BallColor fcolors
[FIELD_SIZE
][FIELD_SIZE
];
255 * Holds game state for undo.
256 * It is saved before every new turn