Chris Taylor / Mbed 2 deprecated RETRO-CityRally

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Player.h Source File

Player.h

00001 #include "Constants.h"
00002 #include "RallyCar.h"
00003 #include "Flag.h"
00004 #include "Smoke.h"
00005 #include "Beeper.h"
00006 
00007 #ifndef __PLAYER_H__
00008 #define __PLAYER_H__
00009 
00010 class Player : public RallyCar
00011 {
00012 public:
00013     Player(Point startPosition) :
00014         _startPosition(startPosition),
00015         _smokeIndex(255),
00016         _lives(MAX_LIVES),
00017         _score(0)
00018     {            
00019         reset();
00020     }    
00021     
00022     virtual void reset()
00023     {
00024         setPosition(_startPosition);
00025         setDirection(Up);
00026         setDesiredDirection(Up);
00027         setState(RallyCar::Idle);
00028         setSpriteId(4);
00029         _fuel = 100;   
00030         _updateCounter = 0;     
00031         
00032         if (_flagCount == MAX_FLAGS)
00033         {
00034             _flagCount = 0;
00035         }
00036         
00037         _stateCounter = 60;
00038     }
00039     
00040     void setCars(RallyCar **cars) { _cars = cars; }
00041     void setFlags(Flag *flags) { _flags = flags; }
00042     
00043     static uint16_t lfsr_rand()
00044     {
00045         static uint16_t lfsr = 0xACE1u;
00046         lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
00047         return lfsr;
00048     }
00049  
00050     virtual void update()
00051     {                 
00052         if (_smokeIndex == 255)
00053         {
00054             for(int i = 0; i < MAX_SMOKE; ++i)
00055             {
00056                 _smoke[i].setCars(_cars);
00057                 getParent()->addGameObject(&_smoke[i]);
00058             }    
00059             _smokeIndex = 0;
00060         }
00061         
00062         if (getState() == RallyCar::Idle)
00063         {
00064             if (--_stateCounter == 0)
00065             {
00066                 setState(RallyCar::Driving);
00067             }
00068         }
00069         else if (getState() == RallyCar::Driving)
00070         {
00071             ++_updateCounter;
00072             if (_updateCounter % FUEL_COUNTER == 0) --_fuel;
00073             if (_fuel == 0) setState(RallyCar::StartCrash);
00074         
00075             Point &position = getPosition();
00076             
00077             bool allowLeftRightTurn = position.Y % 8 == 0;
00078             bool allowUpDownTurn = position.X % 8 == 0;
00079             
00080             if (GameInput::isLeftPressed()) { setDesiredDirection(Left); }
00081             if (GameInput::isRightPressed()) { setDesiredDirection(Right); }
00082             if (GameInput::isUpPressed()) { setDesiredDirection(Up); }
00083             if (GameInput::isDownPressed()) { setDesiredDirection(Down); }
00084             if (GameInput::isCirclePressed() && !_dropSmoke) {_dropSmoke = true; }
00085             
00086             bool forceTurn = false;
00087             do
00088             {
00089                 if (getDirection() != getDesiredDirection())
00090                 {            
00091                     if ((getDesiredDirection() == Left && allowLeftRightTurn && canGoLeft())
00092                     || (getDesiredDirection() == Right && allowLeftRightTurn && canGoRight())
00093                     || (getDesiredDirection() == Up && allowUpDownTurn && canGoUp())
00094                     || (getDesiredDirection() == Down && allowUpDownTurn && canGoDown()))
00095                     {
00096                          setDirection(getDesiredDirection());
00097                     }
00098                 }
00099             
00100                 switch(getDirection())
00101                 {
00102                     case Left : setSpriteId(7); forceTurn = !moveLeft(); if (_dropSmoke) smoke(Right); break;
00103                     case Right : setSpriteId(5); forceTurn = !moveRight(); if (_dropSmoke) smoke(Left); break;
00104                     case Up : setSpriteId(4); forceTurn = !moveUp(); if (_dropSmoke) smoke(Down); break;
00105                     case Down : setSpriteId(6); forceTurn = !moveDown(); if (_dropSmoke) smoke(Up); break;
00106                 }
00107                 
00108                 if (forceTurn)
00109                 {
00110                     switch (getDirection())
00111                     {
00112                         case Left:
00113                         case Right:
00114                             if (lfsr_rand() & 1) 
00115                                 setDesiredDirection(Up);
00116                             else 
00117                                 setDesiredDirection(Down);
00118                         break;
00119                         
00120                         case Up:
00121                         case Down:
00122                             if (lfsr_rand() & 1) 
00123                                 setDesiredDirection(Left);
00124                             else 
00125                                 setDesiredDirection(Right);
00126                         break;
00127                     }                
00128                 }
00129             } while (forceTurn);
00130             
00131             for(int i = 0; i < MAX_CARS; ++i)
00132             {
00133                 RallyCar *car = _cars[i];
00134                 if (car != this)
00135                 {
00136                     if (detectCollision(car))
00137                     {
00138                         setState(RallyCar::StartCrash);
00139                     }
00140                 }
00141             }
00142             
00143             for (int i = 0; i < MAX_FLAGS; ++i)
00144             {
00145                 Flag *flag = &_flags[i];
00146                 if (flag->getActive() == true && detectCollision(flag))
00147                 {
00148                     flag->setActive(false);
00149                     getParent()->removeGameObject(flag);
00150                     _score += 100;                    
00151                     ++_flagCount;
00152                     Beeper::beep(500, 3);                    
00153                     Beeper::beep(2000, 4);                    
00154                     Beeper::beep(1000, 2);                    
00155                 }
00156             }                        
00157         }
00158         else if (getState() == RallyCar::StartCrash)
00159         {
00160             _stateCounter = 30;   
00161             setState(RallyCar::Crashed);         
00162         }
00163         else if (getState() == RallyCar::Crashed)
00164         {
00165             setSpriteId(10);                        
00166             if (--_stateCounter == 0)
00167             {
00168                 --_lives;
00169                 for (int i = 0; i < MAX_CARS; ++i)
00170                 {
00171                     _cars[i]->reset();
00172                 }
00173             }
00174             Beeper::noise(2000, 2);
00175         }
00176         
00177         RallyCar::update();
00178     }
00179     
00180     inline uint8_t getLives() { return _lives; }
00181     inline uint32_t getScore() { return _score; }
00182     inline uint8_t getFuel() { return _fuel; }
00183     inline uint8_t getFlagCount() { return _flagCount; }
00184 
00185     inline void decreaseFuel() { if (_fuel > 0) --_fuel; }
00186     inline void increaseScore(int score) { _score += score; }    
00187 private:    
00188     void smoke(Direction direction)
00189     {
00190         Point &position = getPosition();
00191         TileViewer* parent = getParent();
00192         
00193         if (_fuel < 10) 
00194         {
00195             _dropSmoke = false;
00196             return;
00197         }
00198         
00199         bool onLeftRightBoundary = position.X % 16 == 0 && position.X > 16 && position.X < (parent->getMapTilesX() * 16);
00200         bool onUpDownBoundary = position.Y % 16 == 0 && position.Y > 16 && position.Y < (parent->getMapTilesY() * 16);
00201         int x = 0;
00202         int y = 0;
00203         bool drop = false;
00204         if (direction == Left && onLeftRightBoundary)
00205         {            
00206             x = position.X - 16;
00207             y = position.Y;            
00208             drop = true;
00209         }
00210         else if (direction == Right && onLeftRightBoundary)
00211         {
00212             x = position.X + 16;
00213             y = position.Y;                        
00214             drop = true;
00215         }
00216         else if (direction == Up && onUpDownBoundary)
00217         {
00218             x = position.X;
00219             y = position.Y - 16;                        
00220             drop = true;
00221         }
00222         else if (direction == Down && onUpDownBoundary)
00223         {
00224             x = position.X;
00225             y = position.Y + 16;                        
00226             drop = true;            
00227         }
00228         
00229         if (drop)
00230         {
00231             _dropSmoke = false;
00232             Smoke &smoke = _smoke[_smokeIndex];
00233             smoke.setPosition(Point(x, y));
00234             smoke.setActive(true);            
00235             _smokeIndex = (_smokeIndex + 1) % MAX_SMOKE;
00236             _fuel -= 2;
00237             
00238             Beeper::beep(500, 2);
00239             Beeper::beep(1000, 3);
00240             Beeper::beep(600, 2);
00241         }
00242     }
00243 
00244 private:
00245     Point       _startPosition;    
00246     bool        _dropSmoke;
00247     uint8_t     _smokeIndex;
00248     RallyCar   **_cars;
00249     Flag       *_flags; 
00250     Smoke       _smoke[MAX_SMOKE];
00251     uint16_t    _stateCounter;
00252         
00253     uint8_t     _lives;
00254     uint32_t    _score;
00255     uint8_t     _fuel;
00256     uint16_t    _updateCounter;
00257     uint8_t     _flagCount;
00258 };
00259 #endif //__PLAYER_H__