Race around the city collecting the flags while avoiding those that stand in the way of your mission. Make no mistake you will need to be quick to outwit your opponents, they are smart and will try to box you in. I wrote this game to prove that writing a game with scrolling scenery is possible even with the limited 6kB of RAM available. I had to compromise sound effects for features, I wanted multiple opponents, I wanted to be able to drop smoke bombs to trap the opponents but all this required memory so the sound effects had to take a back seat.
GameScreen.h@1:1b8125937f28, 2015-02-01 (annotated)
- Committer:
- taylorza
- Date:
- Sun Feb 01 00:43:25 2015 +0000
- Revision:
- 1:1b8125937f28
- Parent:
- 0:d85c449aca6d
Minor updates
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
taylorza | 0:d85c449aca6d | 1 | #include "Constants.h" |
taylorza | 0:d85c449aca6d | 2 | #include "GameEngine.h" |
taylorza | 0:d85c449aca6d | 3 | #include "Map.h" |
taylorza | 0:d85c449aca6d | 4 | #include "Assets.h" |
taylorza | 0:d85c449aca6d | 5 | #include "Flag.h" |
taylorza | 0:d85c449aca6d | 6 | #include "Enemy.h" |
taylorza | 0:d85c449aca6d | 7 | #include "Player.h" |
taylorza | 1:1b8125937f28 | 8 | #include "Beeper.h" |
taylorza | 0:d85c449aca6d | 9 | |
taylorza | 0:d85c449aca6d | 10 | #ifndef __GAMESCREEN_H__ |
taylorza | 0:d85c449aca6d | 11 | #define __GAMESCREEN_H__ |
taylorza | 0:d85c449aca6d | 12 | |
taylorza | 0:d85c449aca6d | 13 | class GameScreen; |
taylorza | 0:d85c449aca6d | 14 | |
taylorza | 0:d85c449aca6d | 15 | class GameScreen : public TileViewer |
taylorza | 0:d85c449aca6d | 16 | { |
taylorza | 0:d85c449aca6d | 17 | public: |
taylorza | 0:d85c449aca6d | 18 | GameScreen() : TileViewer(13, 16), |
taylorza | 0:d85c449aca6d | 19 | _player(Point(184, 400)), |
taylorza | 0:d85c449aca6d | 20 | _enemy1(Point(64, 464), Point(16, -32), Point(8, 8), _player), |
taylorza | 0:d85c449aca6d | 21 | _enemy2(Point(88, 464), Point(1024, -32), Point(32, 32), _player), |
taylorza | 0:d85c449aca6d | 22 | _enemy3(Point(112, 464), Point(16, 1024), Point(-32, -32), _player), |
taylorza | 1:1b8125937f28 | 23 | _radarBitmap(46, 62), |
taylorza | 0:d85c449aca6d | 24 | _radarCanvas(&_radarBitmap), |
taylorza | 1:1b8125937f28 | 25 | _updateCounter(0), |
taylorza | 1:1b8125937f28 | 26 | _gameOver(false) |
taylorza | 0:d85c449aca6d | 27 | { |
taylorza | 0:d85c449aca6d | 28 | Game::Surface.setForegroundColor(Color565::White); |
taylorza | 0:d85c449aca6d | 29 | Game::Surface.setBackgroundColor(HUD_BACKGROUND); |
taylorza | 0:d85c449aca6d | 30 | setMap(map, 48, 64, blocks, sprites); |
taylorza | 0:d85c449aca6d | 31 | _radarCanvas.clear(); |
taylorza | 0:d85c449aca6d | 32 | |
taylorza | 0:d85c449aca6d | 33 | _cars[0] = &_player; |
taylorza | 0:d85c449aca6d | 34 | _cars[1] = &_enemy1; |
taylorza | 0:d85c449aca6d | 35 | _cars[2] = &_enemy2; |
taylorza | 0:d85c449aca6d | 36 | _cars[3] = &_enemy3; |
taylorza | 1:1b8125937f28 | 37 | |
taylorza | 1:1b8125937f28 | 38 | placeFlags(); |
taylorza | 1:1b8125937f28 | 39 | |
taylorza | 1:1b8125937f28 | 40 | _player.setPosition(Point(184, 400)); |
taylorza | 1:1b8125937f28 | 41 | _player.setCars(_cars); |
taylorza | 1:1b8125937f28 | 42 | _player.setFlags(_flags); |
taylorza | 0:d85c449aca6d | 43 | |
taylorza | 1:1b8125937f28 | 44 | addGameObject(&_enemy1); |
taylorza | 1:1b8125937f28 | 45 | addGameObject(&_enemy2); |
taylorza | 1:1b8125937f28 | 46 | addGameObject(&_enemy3); |
taylorza | 1:1b8125937f28 | 47 | addGameObject(&_player); |
taylorza | 1:1b8125937f28 | 48 | |
taylorza | 1:1b8125937f28 | 49 | track(&_player); |
taylorza | 1:1b8125937f28 | 50 | } |
taylorza | 1:1b8125937f28 | 51 | |
taylorza | 1:1b8125937f28 | 52 | void placeFlags() |
taylorza | 1:1b8125937f28 | 53 | { |
taylorza | 0:d85c449aca6d | 54 | for(int i = 0; i < MAX_FLAGS; ++i) |
taylorza | 0:d85c449aca6d | 55 | { |
taylorza | 0:d85c449aca6d | 56 | int x = 0; |
taylorza | 0:d85c449aca6d | 57 | int y = 0; |
taylorza | 0:d85c449aca6d | 58 | |
taylorza | 0:d85c449aca6d | 59 | for(;;) |
taylorza | 0:d85c449aca6d | 60 | { |
taylorza | 0:d85c449aca6d | 61 | x = rand() % getMapTilesX(); |
taylorza | 0:d85c449aca6d | 62 | y = rand() % getMapTilesY(); |
taylorza | 0:d85c449aca6d | 63 | const Block &block1 = getBlock(x * 8, y * 8); |
taylorza | 0:d85c449aca6d | 64 | if (&block1 == &blocks[0]) break; |
taylorza | 0:d85c449aca6d | 65 | } |
taylorza | 0:d85c449aca6d | 66 | |
taylorza | 1:1b8125937f28 | 67 | _flags[i].setActive(true); |
taylorza | 0:d85c449aca6d | 68 | _flags[i].setPosition(Point(x * 8, y * 8)); |
taylorza | 0:d85c449aca6d | 69 | addGameObject(&_flags[i]); |
taylorza | 1:1b8125937f28 | 70 | } |
taylorza | 0:d85c449aca6d | 71 | } |
taylorza | 1:1b8125937f28 | 72 | |
taylorza | 0:d85c449aca6d | 73 | virtual void update() |
taylorza | 0:d85c449aca6d | 74 | { |
taylorza | 0:d85c449aca6d | 75 | if (_player.getLives() > 0) |
taylorza | 0:d85c449aca6d | 76 | { |
taylorza | 1:1b8125937f28 | 77 | if (_player.getFlagCount() == MAX_FLAGS) |
taylorza | 1:1b8125937f28 | 78 | { |
taylorza | 1:1b8125937f28 | 79 | if(_player.getFuel() > 0) |
taylorza | 1:1b8125937f28 | 80 | { |
taylorza | 1:1b8125937f28 | 81 | _player.decreaseFuel(); |
taylorza | 1:1b8125937f28 | 82 | _player.increaseScore(10); |
taylorza | 1:1b8125937f28 | 83 | Beeper::beep(400 + (100 - _player.getFuel()) * 2, 5); |
taylorza | 1:1b8125937f28 | 84 | } |
taylorza | 1:1b8125937f28 | 85 | else |
taylorza | 1:1b8125937f28 | 86 | { |
taylorza | 1:1b8125937f28 | 87 | placeFlags(); |
taylorza | 1:1b8125937f28 | 88 | |
taylorza | 1:1b8125937f28 | 89 | for (int i = 0; i < MAX_CARS; ++i) |
taylorza | 1:1b8125937f28 | 90 | { |
taylorza | 1:1b8125937f28 | 91 | _cars[i]->reset(); |
taylorza | 1:1b8125937f28 | 92 | } |
taylorza | 1:1b8125937f28 | 93 | } |
taylorza | 1:1b8125937f28 | 94 | } |
taylorza | 1:1b8125937f28 | 95 | else |
taylorza | 1:1b8125937f28 | 96 | { |
taylorza | 1:1b8125937f28 | 97 | TileViewer::update(); |
taylorza | 1:1b8125937f28 | 98 | } |
taylorza | 0:d85c449aca6d | 99 | } |
taylorza | 0:d85c449aca6d | 100 | else |
taylorza | 0:d85c449aca6d | 101 | { |
taylorza | 1:1b8125937f28 | 102 | _gameOver = true; |
taylorza | 0:d85c449aca6d | 103 | } |
taylorza | 0:d85c449aca6d | 104 | } |
taylorza | 0:d85c449aca6d | 105 | |
taylorza | 0:d85c449aca6d | 106 | virtual void draw() |
taylorza | 0:d85c449aca6d | 107 | { |
taylorza | 1:1b8125937f28 | 108 | if (!_gameOver) |
taylorza | 0:d85c449aca6d | 109 | { |
taylorza | 1:1b8125937f28 | 110 | TileViewer::draw(); |
taylorza | 1:1b8125937f28 | 111 | } |
taylorza | 1:1b8125937f28 | 112 | else |
taylorza | 1:1b8125937f28 | 113 | { |
taylorza | 1:1b8125937f28 | 114 | Game::Surface.setForegroundColor(Color565::Red); |
taylorza | 1:1b8125937f28 | 115 | Game::Surface.setBackgroundColor(Color565::Black); |
taylorza | 1:1b8125937f28 | 116 | Game::Surface.drawString(font_ibm, 18, 60, "GAME OVER"); |
taylorza | 0:d85c449aca6d | 117 | } |
taylorza | 0:d85c449aca6d | 118 | |
taylorza | 1:1b8125937f28 | 119 | // Update HUD |
taylorza | 1:1b8125937f28 | 120 | if (_updateCounter++ % 8 == 0) |
taylorza | 1:1b8125937f28 | 121 | { |
taylorza | 1:1b8125937f28 | 122 | Game::Surface.drawBitmap(109, 17, getRadarBitmap(), 0, 0, 46, 62); |
taylorza | 0:d85c449aca6d | 123 | |
taylorza | 1:1b8125937f28 | 124 | char buffer[10]; |
taylorza | 1:1b8125937f28 | 125 | Game::Surface.setForegroundColor(Color565::Aqua); |
taylorza | 1:1b8125937f28 | 126 | Game::Surface.setBackgroundColor(HUD_BACKGROUND); |
taylorza | 1:1b8125937f28 | 127 | sprintf(buffer, "%d", _player.getScore()); |
taylorza | 1:1b8125937f28 | 128 | Game::Surface.drawString(font_ibm, 108, 4, buffer); |
taylorza | 1:1b8125937f28 | 129 | |
taylorza | 1:1b8125937f28 | 130 | // Render lives |
taylorza | 1:1b8125937f28 | 131 | for (int i = 0; i < _player.getLives(); ++i) |
taylorza | 1:1b8125937f28 | 132 | { |
taylorza | 1:1b8125937f28 | 133 | Game::Surface.drawBitmap(108 + i * 8, 100, spriteSheet, 56, 32, 8, 8); |
taylorza | 1:1b8125937f28 | 134 | } |
taylorza | 1:1b8125937f28 | 135 | |
taylorza | 1:1b8125937f28 | 136 | for (int i = _player.getLives(); i < MAX_LIVES; ++i) |
taylorza | 1:1b8125937f28 | 137 | { |
taylorza | 1:1b8125937f28 | 138 | Game::Surface.fillRect(108 + i * 8, 100, (108 + i * 8) + 8, 108, HUD_BACKGROUND); |
taylorza | 1:1b8125937f28 | 139 | } |
taylorza | 1:1b8125937f28 | 140 | |
taylorza | 1:1b8125937f28 | 141 | // Render fuel |
taylorza | 1:1b8125937f28 | 142 | uint8_t limit = (uint8_t)(((float)_player.getFuel() / 100) * 48); |
taylorza | 1:1b8125937f28 | 143 | |
taylorza | 1:1b8125937f28 | 144 | uint16_t fuelColor = limit < 15 ? Color565::Red : Color565::Yellow; |
taylorza | 1:1b8125937f28 | 145 | Game::Surface.fillRect(108, 84, 108 + limit, 90, fuelColor); |
taylorza | 1:1b8125937f28 | 146 | Game::Surface.fillRect(108 + limit + 1, 84, 160, 90, HUD_BACKGROUND); |
taylorza | 1:1b8125937f28 | 147 | |
taylorza | 1:1b8125937f28 | 148 | // Fuel ticks |
taylorza | 1:1b8125937f28 | 149 | Game::Surface.drawLine(108, 92, 114, 92, Color565::Red); |
taylorza | 1:1b8125937f28 | 150 | Game::Surface.drawLine(108, 92, 108, 94, Color565::Red); |
taylorza | 1:1b8125937f28 | 151 | Game::Surface.drawLine(114, 92, 114, 94, Color565::Red); |
taylorza | 1:1b8125937f28 | 152 | |
taylorza | 1:1b8125937f28 | 153 | |
taylorza | 1:1b8125937f28 | 154 | Game::Surface.drawLine(115, 92, 156, 92, Color565::Yellow); |
taylorza | 1:1b8125937f28 | 155 | for (int i = 12; i <= 48; i += 6) |
taylorza | 1:1b8125937f28 | 156 | { |
taylorza | 1:1b8125937f28 | 157 | Game::Surface.drawLine(108 + i, 92, 108 + i, 94, Color565::Yellow); |
taylorza | 1:1b8125937f28 | 158 | } |
taylorza | 1:1b8125937f28 | 159 | } |
taylorza | 0:d85c449aca6d | 160 | } |
taylorza | 0:d85c449aca6d | 161 | |
taylorza | 0:d85c449aca6d | 162 | inline RallyCar** getCars() { return _cars; } |
taylorza | 0:d85c449aca6d | 163 | |
taylorza | 1:1b8125937f28 | 164 | void drawEntity(int16_t x, int16_t y, uint16_t color) |
taylorza | 1:1b8125937f28 | 165 | { |
taylorza | 1:1b8125937f28 | 166 | _radarCanvas.setPixel(x - 1, y - 1, color); |
taylorza | 1:1b8125937f28 | 167 | _radarCanvas.setPixel(x, y - 1, color); |
taylorza | 1:1b8125937f28 | 168 | _radarCanvas.setPixel(x + 1, y - 1, color); |
taylorza | 1:1b8125937f28 | 169 | |
taylorza | 1:1b8125937f28 | 170 | _radarCanvas.setPixel(x - 1, y, color); |
taylorza | 1:1b8125937f28 | 171 | _radarCanvas.setPixel(x, y, color); |
taylorza | 1:1b8125937f28 | 172 | _radarCanvas.setPixel(x + 1, y, color); |
taylorza | 1:1b8125937f28 | 173 | |
taylorza | 1:1b8125937f28 | 174 | _radarCanvas.setPixel(x - 1, y + 1, color); |
taylorza | 1:1b8125937f28 | 175 | _radarCanvas.setPixel(x, y + 1, color); |
taylorza | 1:1b8125937f28 | 176 | _radarCanvas.setPixel(x + 1, y + 1, color); |
taylorza | 1:1b8125937f28 | 177 | } |
taylorza | 1:1b8125937f28 | 178 | |
taylorza | 0:d85c449aca6d | 179 | Bitmap2bpp& getRadarBitmap() |
taylorza | 0:d85c449aca6d | 180 | { |
taylorza | 0:d85c449aca6d | 181 | _radarCanvas.clear(); |
taylorza | 0:d85c449aca6d | 182 | |
taylorza | 0:d85c449aca6d | 183 | for (int i = 0; i < MAX_FLAGS; ++i) |
taylorza | 0:d85c449aca6d | 184 | { |
taylorza | 0:d85c449aca6d | 185 | Flag &flag = _flags[i]; |
taylorza | 0:d85c449aca6d | 186 | if (flag.getActive()) |
taylorza | 0:d85c449aca6d | 187 | { |
taylorza | 1:1b8125937f28 | 188 | drawEntity(flag.getPosition().X / 8, flag.getPosition().Y / 8, 3); |
taylorza | 0:d85c449aca6d | 189 | } |
taylorza | 0:d85c449aca6d | 190 | } |
taylorza | 0:d85c449aca6d | 191 | |
taylorza | 1:1b8125937f28 | 192 | drawEntity(_enemy1.getPosition().X / 8, _enemy1.getPosition().Y / 8, 2); |
taylorza | 1:1b8125937f28 | 193 | drawEntity(_enemy2.getPosition().X / 8, _enemy2.getPosition().Y / 8, 2); |
taylorza | 1:1b8125937f28 | 194 | drawEntity(_enemy3.getPosition().X / 8, _enemy3.getPosition().Y / 8, 2); |
taylorza | 1:1b8125937f28 | 195 | drawEntity(_player.getPosition().X / 8, _player.getPosition().Y / 8, 1); |
taylorza | 0:d85c449aca6d | 196 | |
taylorza | 0:d85c449aca6d | 197 | return _radarBitmap; |
taylorza | 0:d85c449aca6d | 198 | } |
taylorza | 0:d85c449aca6d | 199 | |
taylorza | 0:d85c449aca6d | 200 | private: |
taylorza | 0:d85c449aca6d | 201 | Player _player; |
taylorza | 0:d85c449aca6d | 202 | Enemy _enemy1; |
taylorza | 0:d85c449aca6d | 203 | Enemy _enemy2; |
taylorza | 0:d85c449aca6d | 204 | Enemy _enemy3; |
taylorza | 0:d85c449aca6d | 205 | |
taylorza | 0:d85c449aca6d | 206 | RallyCar *_cars[MAX_CARS]; |
taylorza | 0:d85c449aca6d | 207 | Flag _flags[MAX_FLAGS]; |
taylorza | 0:d85c449aca6d | 208 | |
taylorza | 0:d85c449aca6d | 209 | Bitmap2bpp _radarBitmap; |
taylorza | 0:d85c449aca6d | 210 | Canvas<Bitmap2bpp> _radarCanvas; |
taylorza | 0:d85c449aca6d | 211 | |
taylorza | 0:d85c449aca6d | 212 | uint8_t _updateCounter; |
taylorza | 1:1b8125937f28 | 213 | bool _gameOver; |
taylorza | 0:d85c449aca6d | 214 | }; |
taylorza | 0:d85c449aca6d | 215 | #endif //__GAMESCREEN_H__ |