00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "snake.h"
00022 #include "target.h"
00023
00024 #include <opie2/oresource.h>
00025
00026 static int Piecekey[4][4] = { {6, 0, 4, 3 }, {0, 6, 2, 1 }, { 1, 3, 5, 0 }, {2, 4, 0, 5 } };
00027
00028 Snake::Snake(QCanvas* c)
00029 {
00030 canvas = c;
00031 score = 0;
00032 snakelist.setAutoDelete(true);
00033 autoMoveTimer = new QTimer(this);
00034 connect( autoMoveTimer, SIGNAL(timeout()), this, SLOT(moveSnake()) );
00035 createSnake();
00036 }
00037
00038 void Snake::createSnake()
00039 {
00040 snakeparts = new QCanvasPixmapArray();
00041 QString s0 = Opie::Core::OResource::findPixmap("snake/s0001");
00042 s0.replace(QRegExp("0001"),"%1");
00043 snakeparts->readPixmaps(s0, 15);
00044
00045 grow = 0;
00046 last = Key_Right;
00047
00048 QCanvasSprite* head = new QCanvasSprite(snakeparts, canvas );
00049 head->setFrame(7);
00050 snakelist.insert(0, head);
00051 head->show();
00052 head->move(34, 16);
00053
00054 QCanvasSprite* body = new QCanvasSprite(snakeparts, canvas );
00055 body->setFrame(6);
00056 snakelist.append( body );
00057 body->show();
00058 body->move(18, 16);
00059
00060 QCanvasSprite* end = new QCanvasSprite(snakeparts, canvas );
00061 end->setFrame(11);
00062 snakelist.append( end );
00063 end->show();
00064 end->move(2, 16);
00065
00066 currentdir = right;
00067 speed = 250;
00068 autoMoveTimer->start(speed);
00069 moveSnake();
00070 }
00071
00072 void Snake::increaseSpeed()
00073 {
00074 if (speed > 150)
00075 speed = speed - 5;
00076 autoMoveTimer->start(speed);
00077 }
00078
00079 void Snake::go(int newkey)
00080 {
00081
00082 if (!( (newkey == Key_Up) || (newkey == Key_Left) ||
00083 (newkey == Key_Right) || (newkey == Key_Down) ))
00084 return;
00085
00086 if ( ((currentdir == left) && ((newkey == Key_Right) || (newkey == Key_Left)) ) ||
00087 ((currentdir == right) && ((newkey == Key_Left) || (newkey == Key_Right)) ) ||
00088 ((currentdir == up) && ((newkey == Key_Down) || (newkey == Key_Up)) ) ||
00089 ((currentdir == down) && ((newkey == Key_Up) || (newkey == Key_Down)) ) )
00090 return;
00091 else {
00092 Snake::changeHead(newkey);
00093 Snake::moveSnake();
00094 }
00095 }
00096
00097 void Snake::move(Direction dir)
00098 {
00099 autoMoveTimer->start(speed);
00100 int x = 0;
00101 int y = 0;
00102 newdir = dir;
00103 switch (dir) {
00104 case right: x = 16; break;
00105 case left: x = -16; break;
00106 case down: y = 16; break;
00107 case up: y = -16; break;
00108 }
00109 int index = lookUpPiece(currentdir, newdir);
00110 QCanvasSprite* sprite = new QCanvasSprite(snakeparts, canvas );
00111 sprite->setFrame(index);
00112 snakelist.insert(1, sprite);
00113 sprite->move(snakelist.first()->x(), snakelist.first()->y() );
00114
00115 snakelist.first()->moveBy(x, y);
00116 if (grow <= 0)
00117 changeTail();
00118 else
00119 grow--;
00120 sprite->show();
00121
00122 currentdir = dir;
00123 }
00124
00125 void Snake::changeTail()
00126 {
00127 snakelist.removeLast();
00128
00129 double lastx = snakelist.last()->x();
00130 double prevx = snakelist.prev()->x();
00131 int index = 0;
00132
00133 if ( prevx == lastx ) {
00134 if ( snakelist.prev()->y() > snakelist.last()->y() )
00135 index = 13;
00136 else
00137 index = 14;
00138 } else {
00139 if (snakelist.prev()->x() > snakelist.last()->x() )
00140 index = 11;
00141 else
00142 index = 12;
00143 }
00144
00145 snakelist.last()->setFrame(index);
00146 }
00147
00148 void Snake::changeHead(int lastkey)
00149 {
00150 int index = 0;
00151 last = lastkey;
00152
00153 switch (last)
00154 {
00155 case Key_Up: index = 10; break;
00156 case Key_Left: index = 8; break;
00157 case Key_Right: index = 7; break;
00158 case Key_Down: index = 9; break;
00159 }
00160
00161 if (index) {
00162 snakelist.first()->setFrame(index);
00163 }
00164 }
00165
00166
00167 int Snake::lookUpPiece(Direction currentdir, Direction newdir)
00168 {
00169 return Piecekey[currentdir][newdir];
00170 }
00171
00172 void Snake::extendSnake()
00173 {
00174 grow++;
00175 }
00176
00177 void Snake::moveSnake()
00178 {
00179 switch (last)
00180 {
00181 case Key_Up: move(up); break;
00182 case Key_Left: move(left); break;
00183 case Key_Right: move(right); break;
00184 case Key_Down: move(down); break;
00185 }
00186 detectCrash();
00187 }
00188
00189 void Snake::detectCrash()
00190 {
00191 QCanvasSprite* head = snakelist.first();
00192 QCanvasItem* item;
00193 QCanvasItemList l=head->collisions(FALSE);
00194 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
00195 item = *it;
00196
00197 if ( (item->rtti()== 1500 ) && (item->collidesWith(head)) ) {
00198 Target* target = (Target*) item;
00199 target->done();
00200 emit targethit();
00201 extendSnake();
00202 setScore(5);
00203 return;
00204 }
00205
00206 if ( (item->rtti()==1600) && (item->collidesWith(head)) ) {
00207 emit dead();
00208 autoMoveTimer->stop();
00209 return;
00210 }
00211 }
00212
00213 for (uint i = 3; i < snakelist.count(); i++) {
00214 if (head->collidesWith(snakelist.at(i)) ) {
00215 emit dead();
00216 autoMoveTimer->stop();
00217 return;
00218 }
00219 }
00220
00221 if ( (head->x() > canvas->width()-5) || (head->y() > canvas->height()-10)
00222 || (head->x() <2) || (head->y() <-5) ) {
00223 emit dead();
00224 autoMoveTimer->stop();
00225 return;
00226 }
00227 }
00228
00229 void Snake::setScore(int amount)
00230 {
00231 score = score + amount;
00232 emit scorechanged();
00233 }
00234
00235 int Snake::getScore()
00236 {
00237 return score;
00238 }
00239
00240 Snake::~Snake()
00241 {
00242 autoMoveTimer->stop();
00243 }