summaryrefslogtreecommitdiff
path: root/noncore/games/snake/snake.cpp
Side-by-side diff
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "snake.h"
+#include "target.h"
+#include "codes.h"
+
+#include <qpe/resource.h>
+
+#include <qregexp.h>
+
+static int Piecekey[4][4] = { {6, 0, 4, 3 }, {0, 6, 2, 1 }, { 1, 3, 5, 0 }, {2, 4, 0, 5 } };
+
+Snake::Snake(QCanvas* c)
+{
+ canvas = c;
+ score = 0;
+ snakelist.setAutoDelete(true);
+ autoMoveTimer = new QTimer(this);
+ connect( autoMoveTimer, SIGNAL(timeout()), this, SLOT(moveSnake()) );
+ createSnake();
+}
+
+void Snake::createSnake()
+{
+ snakeparts = new QCanvasPixmapArray();
+ QString s0 = Resource::findPixmap("snake/s0001");
+ s0.replace(QRegExp("0001"),"%1");
+ snakeparts->readPixmaps(s0, 15);
+
+ grow = 0;
+ last = Key_Right;
+
+ QCanvasSprite* head = new QCanvasSprite(snakeparts, canvas );
+ head->setFrame(7);
+ snakelist.insert(0, head);
+ head->show();
+ head->move(34, 16);
+
+ QCanvasSprite* body = new QCanvasSprite(snakeparts, canvas );
+ body->setFrame(6);
+ snakelist.append( body );
+ body->show();
+ body->move(18, 16);
+
+ QCanvasSprite* end = new QCanvasSprite(snakeparts, canvas );
+ end->setFrame(11);
+ snakelist.append( end );
+ end->show();
+ end->move(2, 16);
+
+ currentdir = right;
+ speed = 250;
+ autoMoveTimer->start(speed);
+ moveSnake();
+}
+
+void Snake::increaseSpeed()
+{
+ if (speed > 150)
+ speed = speed - 5;
+ autoMoveTimer->start(speed);
+}
+
+void Snake::go(int newkey)
+{
+ // check key is a direction
+ if (!( (newkey == Key_Up) || (newkey == Key_Left) ||
+ (newkey == Key_Right) || (newkey == Key_Down) ))
+ return;
+ // check move is possible
+ if ( ((currentdir == left) && ((newkey == Key_Right) || (newkey == Key_Left)) ) ||
+ ((currentdir == right) && ((newkey == Key_Left) || (newkey == Key_Right)) ) ||
+ ((currentdir == up) && ((newkey == Key_Down) || (newkey == Key_Up)) ) ||
+ ((currentdir == down) && ((newkey == Key_Up) || (newkey == Key_Down)) ) )
+ return;
+ else {
+ Snake::changeHead(newkey);
+ Snake::moveSnake();
+ }
+}
+
+void Snake::move(Direction dir)
+{
+ autoMoveTimer->start(speed);
+ int x = 0;
+ int y = 0;
+ newdir = dir;
+ switch (dir) {
+ case right: x = 16; break;
+ case left: x = -16; break;
+ case down: y = 16; break;
+ case up: y = -16; break;
+ }
+ int index = lookUpPiece(currentdir, newdir);
+ QCanvasSprite* sprite = new QCanvasSprite(snakeparts, canvas );
+ sprite->setFrame(index);
+ snakelist.insert(1, sprite);
+ sprite->move(snakelist.first()->x(), snakelist.first()->y() );
+
+ snakelist.first()->moveBy(x, y);
+ if (grow <= 0)
+ changeTail();
+ else
+ grow--;
+ sprite->show();
+
+ currentdir = dir;
+}
+
+void Snake::changeTail()
+{
+ snakelist.removeLast();
+
+ double lastx = snakelist.last()->x();
+ double prevx = snakelist.prev()->x();
+ int index = 0;
+
+ if ( prevx == lastx ) { //vertical
+ if ( snakelist.prev()->y() > snakelist.last()->y() )
+ index = 13;
+ else
+ index = 14;
+ } else { //horizontal
+ if (snakelist.prev()->x() > snakelist.last()->x() )
+ index = 11;
+ else
+ index = 12;
+ }
+
+ snakelist.last()->setFrame(index);
+}
+
+void Snake::changeHead(int lastkey)
+{
+ int index = 0;
+ last = lastkey;
+
+ switch (last)
+ {
+ case Key_Up: index = 10; break;
+ case Key_Left: index = 8; break;
+ case Key_Right: index = 7; break;
+ case Key_Down: index = 9; break;
+ }
+
+ if (index) {
+ snakelist.first()->setFrame(index);
+ }
+}
+
+// returns an integer corresponding to a particular type of snake piece
+int Snake::lookUpPiece(Direction currentdir, Direction newdir)
+{
+ return Piecekey[currentdir][newdir];
+}
+
+void Snake::extendSnake()
+{
+ grow++;
+}
+
+void Snake::moveSnake()
+{
+ switch (last)
+ {
+ case Key_Up: move(up); break;
+ case Key_Left: move(left); break;
+ case Key_Right: move(right); break;
+ case Key_Down: move(down); break;
+ }
+ detectCrash();
+}
+
+void Snake::detectCrash()
+{
+ QCanvasSprite* head = snakelist.first();
+ QCanvasItem* item;
+ QCanvasItemList l=head->collisions(FALSE);
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ item = *it;
+ // check if snake hit target
+ if ( (item->rtti()== 1500 ) && (item->collidesWith(head)) ) {
+ Target* target = (Target*) item;
+ target->done();
+ emit targethit();
+ extendSnake();
+ setScore(5);
+ return;
+ }
+ // check if snake hit obstacles
+ if ( (item->rtti()==1600) && (item->collidesWith(head)) ) {
+ emit dead();
+ autoMoveTimer->stop();
+ return;
+ }
+ }
+ //check if snake hit itself
+ for (uint i = 3; i < snakelist.count(); i++) {
+ if (head->collidesWith(snakelist.at(i)) ) {
+ emit dead();
+ autoMoveTimer->stop();
+ return;
+ }
+ }
+ //check if snake hit edge
+ if ( (head->x() > canvas->width()-5) || (head->y() > canvas->height()-10)
+ || (head->x() <2) || (head->y() <-5) ) {
+ emit dead();
+ autoMoveTimer->stop();
+ return;
+ }
+}
+
+void Snake::setScore(int amount)
+{
+ score = score + amount;
+ emit scorechanged();
+}
+
+int Snake::getScore()
+{
+ return score;
+}
+
+Snake::~Snake()
+{
+ autoMoveTimer->stop();
+}