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.

Dependencies:   mbed

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?

UserRevisionLine numberNew contents of line
taylorza 0:d85c449aca6d 1 #include "mbed.h"
taylorza 0:d85c449aca6d 2 #include "TileViewer.h"
taylorza 0:d85c449aca6d 3 #include "GameEngine.h"
taylorza 0:d85c449aca6d 4
taylorza 0:d85c449aca6d 5 #define max(a, b) ((a < b) ? b : a)
taylorza 0:d85c449aca6d 6 #define min(a, b) ((a > b) ? b : a)
taylorza 0:d85c449aca6d 7
taylorza 0:d85c449aca6d 8
taylorza 0:d85c449aca6d 9 TileViewer::TileViewer(uint8_t viewTilesX, uint8_t viewTilesY) :
taylorza 0:d85c449aca6d 10 _bitmap(viewTilesX * 8, viewTilesY * 8),
taylorza 0:d85c449aca6d 11 _canvas(&_bitmap),
taylorza 0:d85c449aca6d 12 _viewTilesX(viewTilesX),
taylorza 0:d85c449aca6d 13 _viewTilesY(viewTilesY),
taylorza 0:d85c449aca6d 14 _map(NULL),
taylorza 0:d85c449aca6d 15 _mapTilesX(0),
taylorza 0:d85c449aca6d 16 _mapTilesY(0),
taylorza 0:d85c449aca6d 17 _offsetX(0),
taylorza 0:d85c449aca6d 18 _offsetY(0),
taylorza 0:d85c449aca6d 19 _blocks(NULL),
taylorza 0:d85c449aca6d 20 _sprites(NULL),
taylorza 0:d85c449aca6d 21 _pTrackedGameObject(NULL)
taylorza 0:d85c449aca6d 22 {
taylorza 0:d85c449aca6d 23 }
taylorza 0:d85c449aca6d 24
taylorza 0:d85c449aca6d 25 void TileViewer::setMap(const uint8_t *map, uint8_t mapTilesX, uint8_t mapTilesY, const Block *blocks, Sprite *sprites)
taylorza 0:d85c449aca6d 26 {
taylorza 0:d85c449aca6d 27 _map = map;
taylorza 0:d85c449aca6d 28 _mapTilesX = mapTilesX;
taylorza 0:d85c449aca6d 29 _mapTilesY = mapTilesY;
taylorza 0:d85c449aca6d 30 _blocks = blocks;
taylorza 0:d85c449aca6d 31 _sprites = sprites;
taylorza 0:d85c449aca6d 32 }
taylorza 0:d85c449aca6d 33
taylorza 0:d85c449aca6d 34 void TileViewer::addGameObject(GameObject *gameObject)
taylorza 0:d85c449aca6d 35 {
taylorza 0:d85c449aca6d 36 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 0:d85c449aca6d 37 {
taylorza 0:d85c449aca6d 38 if (_gameObjects[i] == NULL)
taylorza 0:d85c449aca6d 39 {
taylorza 0:d85c449aca6d 40 _gameObjects[i] = gameObject;
taylorza 0:d85c449aca6d 41 gameObject->setParent(this);
taylorza 0:d85c449aca6d 42 break;
taylorza 0:d85c449aca6d 43 }
taylorza 0:d85c449aca6d 44 }
taylorza 0:d85c449aca6d 45 }
taylorza 0:d85c449aca6d 46
taylorza 0:d85c449aca6d 47 void TileViewer::removeGameObject(GameObject *gameObject)
taylorza 0:d85c449aca6d 48 {
taylorza 0:d85c449aca6d 49 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 0:d85c449aca6d 50 {
taylorza 0:d85c449aca6d 51 if (_gameObjects[i] == gameObject)
taylorza 0:d85c449aca6d 52 {
taylorza 0:d85c449aca6d 53 gameObject->setParent(NULL);
taylorza 0:d85c449aca6d 54 _gameObjects[i] = NULL;
taylorza 0:d85c449aca6d 55 break;
taylorza 0:d85c449aca6d 56 }
taylorza 0:d85c449aca6d 57 }
taylorza 0:d85c449aca6d 58 }
taylorza 0:d85c449aca6d 59
taylorza 0:d85c449aca6d 60 void TileViewer::track(GameObject *pGameObject)
taylorza 0:d85c449aca6d 61 {
taylorza 0:d85c449aca6d 62 _pTrackedGameObject = pGameObject;
taylorza 0:d85c449aca6d 63 }
taylorza 0:d85c449aca6d 64
taylorza 0:d85c449aca6d 65 const GameObject* TileViewer::detectCollision(GameObject *primary)
taylorza 0:d85c449aca6d 66 {
taylorza 0:d85c449aca6d 67 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 0:d85c449aca6d 68 {
taylorza 0:d85c449aca6d 69 GameObject *other = _gameObjects[i];
taylorza 0:d85c449aca6d 70 if (other != NULL && other != primary)
taylorza 0:d85c449aca6d 71 {
taylorza 0:d85c449aca6d 72 if (detectCollision(primary, other))
taylorza 0:d85c449aca6d 73 {
taylorza 0:d85c449aca6d 74 return other;
taylorza 0:d85c449aca6d 75 }
taylorza 0:d85c449aca6d 76 }
taylorza 0:d85c449aca6d 77 }
taylorza 0:d85c449aca6d 78 return NULL;
taylorza 0:d85c449aca6d 79 }
taylorza 0:d85c449aca6d 80
taylorza 0:d85c449aca6d 81 bool TileViewer::detectCollision(GameObject *o1, GameObject *o2)
taylorza 0:d85c449aca6d 82 {
taylorza 0:d85c449aca6d 83 Rect r1 = o1->getCollisionRect();
taylorza 0:d85c449aca6d 84 Rect r2 = o2->getCollisionRect();
taylorza 0:d85c449aca6d 85
taylorza 0:d85c449aca6d 86 return r1.left < r2.right &&
taylorza 0:d85c449aca6d 87 r2.left < r1.right &&
taylorza 0:d85c449aca6d 88 r1.top < r2.bottom &&
taylorza 0:d85c449aca6d 89 r2.top < r1.bottom;
taylorza 0:d85c449aca6d 90 }
taylorza 0:d85c449aca6d 91
taylorza 0:d85c449aca6d 92 const Block* TileViewer::detectBlock(GameObject *primary)
taylorza 0:d85c449aca6d 93 {
taylorza 0:d85c449aca6d 94 return NULL;
taylorza 0:d85c449aca6d 95 }
taylorza 0:d85c449aca6d 96
taylorza 0:d85c449aca6d 97 void TileViewer::centerAt(int16_t x, int16_t y)
taylorza 0:d85c449aca6d 98 {
taylorza 0:d85c449aca6d 99 _offsetX = x - (_viewTilesX / 2) * 8;
taylorza 0:d85c449aca6d 100 _offsetY = y - (_viewTilesY / 2) * 8;
taylorza 0:d85c449aca6d 101
taylorza 0:d85c449aca6d 102 int maxOffsetX = (_mapTilesX - _viewTilesX) * 8;
taylorza 0:d85c449aca6d 103 int maxOffsetY = (_mapTilesY - _viewTilesY) * 8;
taylorza 0:d85c449aca6d 104
taylorza 0:d85c449aca6d 105 if (_offsetX < 0) _offsetX = 0;
taylorza 0:d85c449aca6d 106 if (_offsetX > maxOffsetX) _offsetX = maxOffsetX;
taylorza 0:d85c449aca6d 107
taylorza 0:d85c449aca6d 108 if (_offsetY < 0) _offsetY = 0;
taylorza 0:d85c449aca6d 109 if (_offsetY > maxOffsetY) _offsetY = maxOffsetY;
taylorza 0:d85c449aca6d 110 }
taylorza 0:d85c449aca6d 111
taylorza 0:d85c449aca6d 112 bool TileViewer::canEnter(uint16_t x, uint16_t y)
taylorza 0:d85c449aca6d 113 {
taylorza 0:d85c449aca6d 114 const Block &block = getBlock(x, y);
taylorza 0:d85c449aca6d 115 Block::Type type = block.getType();
taylorza 0:d85c449aca6d 116
taylorza 0:d85c449aca6d 117 switch(type)
taylorza 0:d85c449aca6d 118 {
taylorza 0:d85c449aca6d 119 case Block::Background : return true;
taylorza 0:d85c449aca6d 120 case Block::Solid : return false;
taylorza 0:d85c449aca6d 121 }
taylorza 0:d85c449aca6d 122
taylorza 0:d85c449aca6d 123 return true;
taylorza 0:d85c449aca6d 124 }
taylorza 0:d85c449aca6d 125
taylorza 0:d85c449aca6d 126 const Block& TileViewer::getBlock(uint16_t x, uint16_t y)
taylorza 0:d85c449aca6d 127 {
taylorza 0:d85c449aca6d 128 uint8_t tileX = x / 8;
taylorza 0:d85c449aca6d 129 uint8_t tileY = y / 8;
taylorza 0:d85c449aca6d 130 uint8_t blockId = _map[(tileY * _mapTilesX) + tileX];
taylorza 0:d85c449aca6d 131 return _blocks[blockId];
taylorza 0:d85c449aca6d 132 }
taylorza 0:d85c449aca6d 133
taylorza 0:d85c449aca6d 134 void TileViewer::animate(uint8_t spriteId)
taylorza 0:d85c449aca6d 135 {
taylorza 0:d85c449aca6d 136 Sprite &sprite = _sprites[spriteId];
taylorza 0:d85c449aca6d 137 sprite.animate();
taylorza 0:d85c449aca6d 138 }
taylorza 0:d85c449aca6d 139
taylorza 0:d85c449aca6d 140 bool TileViewer::pickupObject(uint8_t tileX, uint8_t tileY)
taylorza 0:d85c449aca6d 141 {
taylorza 0:d85c449aca6d 142 return false;
taylorza 0:d85c449aca6d 143 }
taylorza 0:d85c449aca6d 144
taylorza 0:d85c449aca6d 145 void TileViewer::drawSprite(uint8_t spriteId, int16_t x, int16_t y)
taylorza 0:d85c449aca6d 146 {
taylorza 0:d85c449aca6d 147 const Sprite &sprite = _sprites[spriteId];
taylorza 0:d85c449aca6d 148 const ImageFrame &frame = sprite.getFrame();
taylorza 0:d85c449aca6d 149
taylorza 0:d85c449aca6d 150 _canvas.drawBitmap(x, y, (Bitmap2bpp&)frame.getBitmap(), frame.getX(), frame.getY(), frame.getWidth(), frame.getHeight(), true);
taylorza 0:d85c449aca6d 151 }
taylorza 0:d85c449aca6d 152
taylorza 0:d85c449aca6d 153 void TileViewer::update()
taylorza 0:d85c449aca6d 154 {
taylorza 0:d85c449aca6d 155 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 0:d85c449aca6d 156 {
taylorza 0:d85c449aca6d 157 GameObject *p = _gameObjects[i];
taylorza 0:d85c449aca6d 158 if (p != NULL)
taylorza 0:d85c449aca6d 159 {
taylorza 0:d85c449aca6d 160 p->update();
taylorza 0:d85c449aca6d 161 }
taylorza 0:d85c449aca6d 162 }
taylorza 0:d85c449aca6d 163
taylorza 0:d85c449aca6d 164 if (_pTrackedGameObject != NULL)
taylorza 0:d85c449aca6d 165 {
taylorza 0:d85c449aca6d 166 Point &position = _pTrackedGameObject->getPosition();
taylorza 0:d85c449aca6d 167 centerAt(position.X + 8, position.Y + 8);
taylorza 0:d85c449aca6d 168 }
taylorza 0:d85c449aca6d 169 }
taylorza 0:d85c449aca6d 170
taylorza 0:d85c449aca6d 171 void TileViewer::draw()
taylorza 0:d85c449aca6d 172 {
taylorza 0:d85c449aca6d 173 _canvas.clear();
taylorza 0:d85c449aca6d 174
taylorza 0:d85c449aca6d 175 int firstTileX = max(0, _offsetX / 8);
taylorza 0:d85c449aca6d 176 int firstTileY = max(0, _offsetY / 8);
taylorza 0:d85c449aca6d 177 int lastTileX = min(_mapTilesX, firstTileX + _viewTilesX + 1);
taylorza 0:d85c449aca6d 178 int lastTileY = min(_mapTilesY, firstTileY + _viewTilesY + 1);
taylorza 0:d85c449aca6d 179
taylorza 0:d85c449aca6d 180 int adjustX = _offsetX % 8;
taylorza 0:d85c449aca6d 181 int adjustY = _offsetY % 8;
taylorza 0:d85c449aca6d 182
taylorza 0:d85c449aca6d 183 for (int y = -adjustY, yTile = firstTileY; yTile < lastTileY; ++yTile, y += 8)
taylorza 0:d85c449aca6d 184 {
taylorza 0:d85c449aca6d 185 int offset = yTile * _mapTilesX;
taylorza 0:d85c449aca6d 186 for (int x = -adjustX, xTile = firstTileX; xTile < lastTileX; ++xTile, x += 8)
taylorza 0:d85c449aca6d 187 {
taylorza 0:d85c449aca6d 188 uint8_t blockId = _map[offset + xTile];
taylorza 0:d85c449aca6d 189 if (blockId == 0) continue;
taylorza 0:d85c449aca6d 190
taylorza 0:d85c449aca6d 191 const Block &block = _blocks[blockId];
taylorza 0:d85c449aca6d 192 const ImageFrame &frame = block.getFrame();
taylorza 0:d85c449aca6d 193
taylorza 0:d85c449aca6d 194 _canvas.drawBitmap(x, y, (Bitmap2bpp&)frame.getBitmap(),
taylorza 0:d85c449aca6d 195 frame.getX(), frame.getY(),
taylorza 0:d85c449aca6d 196 frame.getWidth(), frame.getHeight(), false);
taylorza 0:d85c449aca6d 197 }
taylorza 0:d85c449aca6d 198 }
taylorza 0:d85c449aca6d 199
taylorza 0:d85c449aca6d 200 for (int i = 0; i < MAX_GAMEOBJECTS; ++i)
taylorza 0:d85c449aca6d 201 {
taylorza 0:d85c449aca6d 202 GameObject *p = _gameObjects[i];
taylorza 0:d85c449aca6d 203 if (p != NULL)
taylorza 0:d85c449aca6d 204 {
taylorza 0:d85c449aca6d 205 p->draw();
taylorza 0:d85c449aca6d 206 }
taylorza 0:d85c449aca6d 207 }
taylorza 0:d85c449aca6d 208 Game::Surface.drawBitmap(0, 0, _bitmap, 0, 0, _bitmap.getWidth(), _bitmap.getHeight());
taylorza 0:d85c449aca6d 209 }