Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

snake.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
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    // check key is a direction
00082    if (!( (newkey == Key_Up) || (newkey == Key_Left) || 
00083           (newkey == Key_Right) || (newkey == Key_Down) ))
00084         return;
00085    // check move is possible   
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 ) {  //vertical
00134          if ( snakelist.prev()->y() > snakelist.last()->y() )
00135               index = 13;
00136          else
00137               index = 14;
00138      } else {  //horizontal
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 // returns an integer corresponding to a particular type of snake piece
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        // check if snake hit target
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        // check if snake hit obstacles
00206        if ( (item->rtti()==1600) && (item->collidesWith(head)) ) {
00207              emit dead();
00208              autoMoveTimer->stop();
00209              return;
00210        }
00211     }
00212     //check if snake hit itself
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    //check if snake hit edge
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 }

Generated on Sat Nov 5 16:17:25 2005 for OPIE by  doxygen 1.4.2