summaryrefslogtreecommitdiff
path: root/noncore/games/snake/snake.cpp
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/games/snake/snake.cpp
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'noncore/games/snake/snake.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/snake/snake.cpp246
1 files changed, 246 insertions, 0 deletions
diff --git a/noncore/games/snake/snake.cpp b/noncore/games/snake/snake.cpp
new file mode 100644
index 0000000..9f19841
--- a/dev/null
+++ b/noncore/games/snake/snake.cpp
@@ -0,0 +1,246 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "snake.h"
22#include "target.h"
23#include "codes.h"
24
25#include <qpe/resource.h>
26
27#include <qregexp.h>
28
29static int Piecekey[4][4] = { {6, 0, 4, 3 }, {0, 6, 2, 1 }, { 1, 3, 5, 0 }, {2, 4, 0, 5 } };
30
31Snake::Snake(QCanvas* c)
32{
33 canvas = c;
34 score = 0;
35 snakelist.setAutoDelete(true);
36 autoMoveTimer = new QTimer(this);
37 connect( autoMoveTimer, SIGNAL(timeout()), this, SLOT(moveSnake()) );
38 createSnake();
39}
40
41void Snake::createSnake()
42{
43 snakeparts = new QCanvasPixmapArray();
44 QString s0 = Resource::findPixmap("snake/s0001");
45 s0.replace(QRegExp("0001"),"%1");
46 snakeparts->readPixmaps(s0, 15);
47
48 grow = 0;
49 last = Key_Right;
50
51 QCanvasSprite* head = new QCanvasSprite(snakeparts, canvas );
52 head->setFrame(7);
53 snakelist.insert(0, head);
54 head->show();
55 head->move(34, 16);
56
57 QCanvasSprite* body = new QCanvasSprite(snakeparts, canvas );
58 body->setFrame(6);
59 snakelist.append( body );
60 body->show();
61 body->move(18, 16);
62
63 QCanvasSprite* end = new QCanvasSprite(snakeparts, canvas );
64 end->setFrame(11);
65 snakelist.append( end );
66 end->show();
67 end->move(2, 16);
68
69 currentdir = right;
70 speed = 250;
71 autoMoveTimer->start(speed);
72 moveSnake();
73}
74
75void Snake::increaseSpeed()
76{
77 if (speed > 150)
78 speed = speed - 5;
79 autoMoveTimer->start(speed);
80}
81
82void Snake::go(int newkey)
83{
84 // check key is a direction
85 if (!( (newkey == Key_Up) || (newkey == Key_Left) ||
86 (newkey == Key_Right) || (newkey == Key_Down) ))
87 return;
88 // check move is possible
89 if ( ((currentdir == left) && ((newkey == Key_Right) || (newkey == Key_Left)) ) ||
90 ((currentdir == right) && ((newkey == Key_Left) || (newkey == Key_Right)) ) ||
91 ((currentdir == up) && ((newkey == Key_Down) || (newkey == Key_Up)) ) ||
92 ((currentdir == down) && ((newkey == Key_Up) || (newkey == Key_Down)) ) )
93 return;
94 else {
95 Snake::changeHead(newkey);
96 Snake::moveSnake();
97 }
98}
99
100void Snake::move(Direction dir)
101{
102 autoMoveTimer->start(speed);
103 int x = 0;
104 int y = 0;
105 newdir = dir;
106 switch (dir) {
107 case right: x = 16; break;
108 case left: x = -16; break;
109 case down: y = 16; break;
110 case up: y = -16; break;
111 }
112 int index = lookUpPiece(currentdir, newdir);
113 QCanvasSprite* sprite = new QCanvasSprite(snakeparts, canvas );
114 sprite->setFrame(index);
115 snakelist.insert(1, sprite);
116 sprite->move(snakelist.first()->x(), snakelist.first()->y() );
117
118 snakelist.first()->moveBy(x, y);
119 if (grow <= 0)
120 changeTail();
121 else
122 grow--;
123 sprite->show();
124
125 currentdir = dir;
126}
127
128void Snake::changeTail()
129{
130 snakelist.removeLast();
131
132 double lastx = snakelist.last()->x();
133 double prevx = snakelist.prev()->x();
134 int index = 0;
135
136 if ( prevx == lastx ) { //vertical
137 if ( snakelist.prev()->y() > snakelist.last()->y() )
138 index = 13;
139 else
140 index = 14;
141 } else { //horizontal
142 if (snakelist.prev()->x() > snakelist.last()->x() )
143 index = 11;
144 else
145 index = 12;
146 }
147
148 snakelist.last()->setFrame(index);
149}
150
151void Snake::changeHead(int lastkey)
152{
153 int index = 0;
154 last = lastkey;
155
156 switch (last)
157 {
158 case Key_Up: index = 10; break;
159 case Key_Left: index = 8; break;
160 case Key_Right: index = 7; break;
161 case Key_Down: index = 9; break;
162 }
163
164 if (index) {
165 snakelist.first()->setFrame(index);
166 }
167}
168
169// returns an integer corresponding to a particular type of snake piece
170int Snake::lookUpPiece(Direction currentdir, Direction newdir)
171{
172 return Piecekey[currentdir][newdir];
173}
174
175void Snake::extendSnake()
176{
177 grow++;
178}
179
180void Snake::moveSnake()
181{
182 switch (last)
183 {
184 case Key_Up: move(up); break;
185 case Key_Left: move(left); break;
186 case Key_Right: move(right); break;
187 case Key_Down: move(down); break;
188 }
189 detectCrash();
190}
191
192void Snake::detectCrash()
193{
194 QCanvasSprite* head = snakelist.first();
195 QCanvasItem* item;
196 QCanvasItemList l=head->collisions(FALSE);
197 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
198 item = *it;
199 // check if snake hit target
200 if ( (item->rtti()== 1500 ) && (item->collidesWith(head)) ) {
201 Target* target = (Target*) item;
202 target->done();
203 emit targethit();
204 extendSnake();
205 setScore(5);
206 return;
207 }
208 // check if snake hit obstacles
209 if ( (item->rtti()==1600) && (item->collidesWith(head)) ) {
210 emit dead();
211 autoMoveTimer->stop();
212 return;
213 }
214 }
215 //check if snake hit itself
216 for (uint i = 3; i < snakelist.count(); i++) {
217 if (head->collidesWith(snakelist.at(i)) ) {
218 emit dead();
219 autoMoveTimer->stop();
220 return;
221 }
222 }
223 //check if snake hit edge
224 if ( (head->x() > canvas->width()-5) || (head->y() > canvas->height()-10)
225 || (head->x() <2) || (head->y() <-5) ) {
226 emit dead();
227 autoMoveTimer->stop();
228 return;
229 }
230}
231
232void Snake::setScore(int amount)
233{
234 score = score + amount;
235 emit scorechanged();
236}
237
238int Snake::getScore()
239{
240 return score;
241}
242
243Snake::~Snake()
244{
245 autoMoveTimer->stop();
246}