Platform game written for the GHI/OutrageousCircuits RETRO game device. Navigate the caves collecting all the pickups and avoiding the creatures and haunted mine carts that patrol the caves. Oh and remember to watch out for the poisonous plants... This game demonstrates the ability to have multiple animated sprites where the sprites can overlap the background environment. See how the player moves past the fence and climbs the wall in the 3rd screen.

Dependencies:   mbed

Committer:
taylorza
Date:
Sun Jan 11 02:53:03 2015 +0000
Revision:
9:34008d8b1cdf
Child:
11:9ae9a88a1da8
Final version before optimizations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 9:34008d8b1cdf 1 #include "mbed.h"
taylorza 9:34008d8b1cdf 2 #include "GameEngine.h"
taylorza 9:34008d8b1cdf 3 #include "GameObject.h"
taylorza 9:34008d8b1cdf 4
taylorza 9:34008d8b1cdf 5 GameObject::GameObject() :
taylorza 9:34008d8b1cdf 6 _spriteId(0),
taylorza 9:34008d8b1cdf 7 _position(0,0),
taylorza 9:34008d8b1cdf 8 _dx(0),
taylorza 9:34008d8b1cdf 9 _dy(0),
taylorza 9:34008d8b1cdf 10 _lastdx(0),
taylorza 9:34008d8b1cdf 11 _lastdy(0),
taylorza 9:34008d8b1cdf 12 _speed(2),
taylorza 9:34008d8b1cdf 13 _animationCounter(0),
taylorza 9:34008d8b1cdf 14 _collisionRect(0, 0, 16, 16),
taylorza 9:34008d8b1cdf 15 _flipSprite(false)
taylorza 9:34008d8b1cdf 16 {
taylorza 9:34008d8b1cdf 17
taylorza 9:34008d8b1cdf 18 }
taylorza 9:34008d8b1cdf 19
taylorza 9:34008d8b1cdf 20 void GameObject::setStartPosition(Point position)
taylorza 9:34008d8b1cdf 21 {
taylorza 9:34008d8b1cdf 22 _position = position;
taylorza 9:34008d8b1cdf 23 }
taylorza 9:34008d8b1cdf 24
taylorza 9:34008d8b1cdf 25 void GameObject::setSpriteId(uint8_t spriteId)
taylorza 9:34008d8b1cdf 26 {
taylorza 9:34008d8b1cdf 27 _spriteId = spriteId;
taylorza 9:34008d8b1cdf 28 }
taylorza 9:34008d8b1cdf 29
taylorza 9:34008d8b1cdf 30 void GameObject::setSpeed(uint8_t speed)
taylorza 9:34008d8b1cdf 31 {
taylorza 9:34008d8b1cdf 32 _speed = speed;
taylorza 9:34008d8b1cdf 33 }
taylorza 9:34008d8b1cdf 34
taylorza 9:34008d8b1cdf 35 void GameObject::setCollisionRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
taylorza 9:34008d8b1cdf 36 {
taylorza 9:34008d8b1cdf 37 _collisionRect = Rect(x, y, w, h);
taylorza 9:34008d8b1cdf 38 }
taylorza 9:34008d8b1cdf 39
taylorza 9:34008d8b1cdf 40 void GameObject::animate()
taylorza 9:34008d8b1cdf 41 {
taylorza 9:34008d8b1cdf 42 if (_animationCounter++ % 2)
taylorza 9:34008d8b1cdf 43 {
taylorza 9:34008d8b1cdf 44 _pScene->animate(_spriteId);
taylorza 9:34008d8b1cdf 45 }
taylorza 9:34008d8b1cdf 46 }
taylorza 9:34008d8b1cdf 47
taylorza 9:34008d8b1cdf 48 bool GameObject::moveLeft()
taylorza 9:34008d8b1cdf 49 {
taylorza 9:34008d8b1cdf 50 if ((abs(_dx) == _speed) || !canGoLeft(_position.X, _position.Y)) return false;
taylorza 9:34008d8b1cdf 51 _dx -= _speed;
taylorza 9:34008d8b1cdf 52 _position.X -= _speed;
taylorza 9:34008d8b1cdf 53 _flipSprite = false;
taylorza 9:34008d8b1cdf 54 return true;
taylorza 9:34008d8b1cdf 55 }
taylorza 9:34008d8b1cdf 56
taylorza 9:34008d8b1cdf 57 bool GameObject::moveRight()
taylorza 9:34008d8b1cdf 58 {
taylorza 9:34008d8b1cdf 59 if ((abs(_dx) == _speed) || !canGoRight(_position.X, _position.Y)) return false;
taylorza 9:34008d8b1cdf 60 _dx += _speed;
taylorza 9:34008d8b1cdf 61 _position.X += _speed;
taylorza 9:34008d8b1cdf 62 _flipSprite = true;
taylorza 9:34008d8b1cdf 63 return true;
taylorza 9:34008d8b1cdf 64 }
taylorza 9:34008d8b1cdf 65
taylorza 9:34008d8b1cdf 66 bool GameObject::moveUp()
taylorza 9:34008d8b1cdf 67 {
taylorza 9:34008d8b1cdf 68 if ((abs(_dy) == _speed) || !canGoUp(_position.X, _position.Y)) return false;
taylorza 9:34008d8b1cdf 69 _dy -= _speed;
taylorza 9:34008d8b1cdf 70 _position.Y -= _speed;
taylorza 9:34008d8b1cdf 71 return true;
taylorza 9:34008d8b1cdf 72 }
taylorza 9:34008d8b1cdf 73
taylorza 9:34008d8b1cdf 74 bool GameObject::moveDown()
taylorza 9:34008d8b1cdf 75 {
taylorza 9:34008d8b1cdf 76 if ((abs(_dy) == _speed) || !canGoDown(_position.X, _position.Y, 0)) return false;
taylorza 9:34008d8b1cdf 77 _dy += _speed;
taylorza 9:34008d8b1cdf 78 _position.Y += _speed;
taylorza 9:34008d8b1cdf 79 return true;
taylorza 9:34008d8b1cdf 80 }
taylorza 9:34008d8b1cdf 81
taylorza 9:34008d8b1cdf 82 bool GameObject::fall()
taylorza 9:34008d8b1cdf 83 {
taylorza 9:34008d8b1cdf 84 if ((abs(_dy) == _speed) || !canGoDown(_position.X, _position.Y, 4)) return false;
taylorza 9:34008d8b1cdf 85
taylorza 9:34008d8b1cdf 86 const Block& left = _pScene->getBlock(_position.X + 4, _position.Y + 16);
taylorza 9:34008d8b1cdf 87 const Block& right = _pScene->getBlock(_position.X + 12, _position.Y + 16);
taylorza 9:34008d8b1cdf 88 if (left.getType() == Block::Ladder || right.getType() == Block::Ladder) return false;
taylorza 9:34008d8b1cdf 89
taylorza 9:34008d8b1cdf 90 _dy += _speed;
taylorza 9:34008d8b1cdf 91 _position.Y += _speed;
taylorza 9:34008d8b1cdf 92
taylorza 9:34008d8b1cdf 93 return true;
taylorza 9:34008d8b1cdf 94 }
taylorza 9:34008d8b1cdf 95
taylorza 9:34008d8b1cdf 96 const GameObject* GameObject::detectCollision()
taylorza 9:34008d8b1cdf 97 {
taylorza 9:34008d8b1cdf 98 return _pScene->detectCollision(this);
taylorza 9:34008d8b1cdf 99 }
taylorza 9:34008d8b1cdf 100
taylorza 9:34008d8b1cdf 101 const Block* GameObject::detectBlock()
taylorza 9:34008d8b1cdf 102 {
taylorza 9:34008d8b1cdf 103 return _pScene->detectBlock(this);
taylorza 9:34008d8b1cdf 104 }
taylorza 9:34008d8b1cdf 105
taylorza 9:34008d8b1cdf 106 Rect GameObject::getCollisionRect()
taylorza 9:34008d8b1cdf 107 {
taylorza 9:34008d8b1cdf 108 return Rect(_position.X + _collisionRect.left, _position.Y + _collisionRect.top, _collisionRect.getWidth(), _collisionRect.getHeight());
taylorza 9:34008d8b1cdf 109 }
taylorza 9:34008d8b1cdf 110
taylorza 9:34008d8b1cdf 111 bool GameObject::pickupObject()
taylorza 9:34008d8b1cdf 112 {
taylorza 9:34008d8b1cdf 113 uint8_t cellX = _position.X / 8;
taylorza 9:34008d8b1cdf 114 uint8_t cellY = _position.Y / 8;
taylorza 9:34008d8b1cdf 115 for (uint8_t cx = 0; cx < 2; ++cx)
taylorza 9:34008d8b1cdf 116 {
taylorza 9:34008d8b1cdf 117 for (uint8_t cy = 0; cy < 2; ++cy)
taylorza 9:34008d8b1cdf 118 {
taylorza 9:34008d8b1cdf 119 if (_pScene->pickupObject(cellX + cx, cellY + cy)) return true;
taylorza 9:34008d8b1cdf 120 }
taylorza 9:34008d8b1cdf 121 }
taylorza 9:34008d8b1cdf 122
taylorza 9:34008d8b1cdf 123 return false;
taylorza 9:34008d8b1cdf 124 }
taylorza 9:34008d8b1cdf 125
taylorza 9:34008d8b1cdf 126 bool GameObject::canGoLeft(uint8_t x, uint8_t y)
taylorza 9:34008d8b1cdf 127 {
taylorza 9:34008d8b1cdf 128 int16_t tx = x - _speed;
taylorza 9:34008d8b1cdf 129 if (tx < 0) return false;
taylorza 9:34008d8b1cdf 130
taylorza 9:34008d8b1cdf 131 if (!_pScene->canEnter(tx, y + 0)) return false;
taylorza 9:34008d8b1cdf 132 if (!_pScene->canEnter(tx, y + 7)) return false;
taylorza 9:34008d8b1cdf 133 if (!_pScene->canEnter(tx, y + 8)) return false;
taylorza 9:34008d8b1cdf 134 if (!_pScene->canEnter(tx, y + 15)) return false;
taylorza 9:34008d8b1cdf 135
taylorza 9:34008d8b1cdf 136 return true;
taylorza 9:34008d8b1cdf 137 }
taylorza 9:34008d8b1cdf 138
taylorza 9:34008d8b1cdf 139 bool GameObject::canGoRight(uint8_t x, uint8_t y)
taylorza 9:34008d8b1cdf 140 {
taylorza 9:34008d8b1cdf 141 int tx = x + 15 + _speed;
taylorza 9:34008d8b1cdf 142
taylorza 9:34008d8b1cdf 143 if ((tx / 8) == _pScene->getMapXCells()) return false;
taylorza 9:34008d8b1cdf 144
taylorza 9:34008d8b1cdf 145 if (!_pScene->canEnter(tx, y + 0)) return false;
taylorza 9:34008d8b1cdf 146 if (!_pScene->canEnter(tx, y + 7)) return false;
taylorza 9:34008d8b1cdf 147 if (!_pScene->canEnter(tx, y + 8)) return false;
taylorza 9:34008d8b1cdf 148 if (!_pScene->canEnter(tx, y + 15)) return false;
taylorza 9:34008d8b1cdf 149
taylorza 9:34008d8b1cdf 150 return true;
taylorza 9:34008d8b1cdf 151 }
taylorza 9:34008d8b1cdf 152
taylorza 9:34008d8b1cdf 153 bool GameObject::canGoUp(uint8_t x, uint8_t y)
taylorza 9:34008d8b1cdf 154 {
taylorza 9:34008d8b1cdf 155 int16_t ty = y - _speed;
taylorza 9:34008d8b1cdf 156 if (ty < 0) return false;
taylorza 9:34008d8b1cdf 157
taylorza 9:34008d8b1cdf 158 if (!_pScene->canEnter(x + 4, ty)) return false;
taylorza 9:34008d8b1cdf 159 if (!_pScene->canEnter(x + 7, ty)) return false;
taylorza 9:34008d8b1cdf 160 if (!_pScene->canEnter(x + 8, ty)) return false;
taylorza 9:34008d8b1cdf 161 if (!_pScene->canEnter(x + 11, ty)) return false;
taylorza 9:34008d8b1cdf 162
taylorza 9:34008d8b1cdf 163 return true;
taylorza 9:34008d8b1cdf 164 }
taylorza 9:34008d8b1cdf 165
taylorza 9:34008d8b1cdf 166 bool GameObject::canGoDown(uint8_t x, uint8_t y, uint8_t collisionBorder)
taylorza 9:34008d8b1cdf 167 {
taylorza 9:34008d8b1cdf 168 uint8_t by = y + 15;
taylorza 9:34008d8b1cdf 169 uint8_t ty = by + _speed;
taylorza 9:34008d8b1cdf 170
taylorza 9:34008d8b1cdf 171 // If not moving to a new cell then no need to test
taylorza 9:34008d8b1cdf 172 if ((by / 8) == (ty / 8)) return true;
taylorza 9:34008d8b1cdf 173
taylorza 9:34008d8b1cdf 174 if ((ty / 8) >= (_pScene->getMapYCells() - 1)) return false;
taylorza 9:34008d8b1cdf 175
taylorza 9:34008d8b1cdf 176 if (!_pScene->canEnterFromTop(x + collisionBorder, ty)) return false;
taylorza 9:34008d8b1cdf 177 if (!_pScene->canEnterFromTop(x + 7, ty)) return false;
taylorza 9:34008d8b1cdf 178 if (!_pScene->canEnterFromTop(x + 8, ty)) return false;
taylorza 9:34008d8b1cdf 179 if (!_pScene->canEnterFromTop(x + 15 - collisionBorder, ty)) return false;
taylorza 9:34008d8b1cdf 180
taylorza 9:34008d8b1cdf 181 return true;
taylorza 9:34008d8b1cdf 182 }
taylorza 9:34008d8b1cdf 183
taylorza 9:34008d8b1cdf 184 bool GameObject::isOpenBelow()
taylorza 9:34008d8b1cdf 185 {
taylorza 9:34008d8b1cdf 186 return isOpenBelow(4) && isOpenBelow(12);
taylorza 9:34008d8b1cdf 187 }
taylorza 9:34008d8b1cdf 188
taylorza 9:34008d8b1cdf 189 bool GameObject::isOpenBelow(int8_t dx)
taylorza 9:34008d8b1cdf 190 {
taylorza 9:34008d8b1cdf 191 return _pScene->canEnterFromTop(_position.X + dx, _position.Y + 20);
taylorza 9:34008d8b1cdf 192 }
taylorza 9:34008d8b1cdf 193
taylorza 9:34008d8b1cdf 194 bool GameObject::isOverLadder()
taylorza 9:34008d8b1cdf 195 {
taylorza 9:34008d8b1cdf 196 const Block& left = _pScene->getBlock(_position.X + 4, _position.Y + 12);
taylorza 9:34008d8b1cdf 197 const Block& right = _pScene->getBlock(_position.X + 12, _position.Y + 15);
taylorza 9:34008d8b1cdf 198 return left.getType() == Block::Ladder || right.getType() == Block::Ladder;
taylorza 9:34008d8b1cdf 199 }
taylorza 9:34008d8b1cdf 200
taylorza 9:34008d8b1cdf 201 bool GameObject::isLadderAbove()
taylorza 9:34008d8b1cdf 202 {
taylorza 9:34008d8b1cdf 203 const Block& left = _pScene->getBlock(_position.X + 4, _position.Y + 2);
taylorza 9:34008d8b1cdf 204 const Block& right = _pScene->getBlock(_position.X + 12, _position.Y + 2);
taylorza 9:34008d8b1cdf 205 return left.getType() == Block::Ladder && right.getType() == Block::Ladder;
taylorza 9:34008d8b1cdf 206 }
taylorza 9:34008d8b1cdf 207
taylorza 9:34008d8b1cdf 208 bool GameObject::isLadderBelow()
taylorza 9:34008d8b1cdf 209 {
taylorza 9:34008d8b1cdf 210 const Block& left = _pScene->getBlock(_position.X + 4, _position.Y + 16);
taylorza 9:34008d8b1cdf 211 const Block& right = _pScene->getBlock(_position.X + 12, _position.Y + 16);
taylorza 9:34008d8b1cdf 212 return left.getType() == Block::Ladder && right.getType() == Block::Ladder;
taylorza 9:34008d8b1cdf 213 }
taylorza 9:34008d8b1cdf 214
taylorza 9:34008d8b1cdf 215 bool GameObject::isLadderLeft()
taylorza 9:34008d8b1cdf 216 {
taylorza 9:34008d8b1cdf 217 const Block& left = _pScene->getBlock(_position.X - 4, _position.Y + 2);
taylorza 9:34008d8b1cdf 218 return left.getType() == Block::Ladder;
taylorza 9:34008d8b1cdf 219 }
taylorza 9:34008d8b1cdf 220
taylorza 9:34008d8b1cdf 221 bool GameObject::isLadderRight()
taylorza 9:34008d8b1cdf 222 {
taylorza 9:34008d8b1cdf 223 const Block& right = _pScene->getBlock(_position.X + 20, _position.Y + 2);
taylorza 9:34008d8b1cdf 224 return right.getType() == Block::Ladder;
taylorza 9:34008d8b1cdf 225 }
taylorza 9:34008d8b1cdf 226
taylorza 9:34008d8b1cdf 227 const Block& GameObject::getBlockAbove()
taylorza 9:34008d8b1cdf 228 {
taylorza 9:34008d8b1cdf 229 return _pScene->getBlock(_position.X + 8, _position.Y - 4);
taylorza 9:34008d8b1cdf 230 }
taylorza 9:34008d8b1cdf 231
taylorza 9:34008d8b1cdf 232 const Block& GameObject::getBlockBelow()
taylorza 9:34008d8b1cdf 233 {
taylorza 9:34008d8b1cdf 234 return _pScene->getBlock(_position.X + 8, _position.Y + 16);
taylorza 9:34008d8b1cdf 235 }
taylorza 9:34008d8b1cdf 236
taylorza 9:34008d8b1cdf 237 void GameObject::update()
taylorza 9:34008d8b1cdf 238 {
taylorza 9:34008d8b1cdf 239 }
taylorza 9:34008d8b1cdf 240
taylorza 9:34008d8b1cdf 241 void GameObject::draw()
taylorza 9:34008d8b1cdf 242 {
taylorza 9:34008d8b1cdf 243 _pScene->drawSprite(_spriteId, _position.X, _position.Y, _dx, _dy, _flipSprite);
taylorza 9:34008d8b1cdf 244 _lastdx = _dx;
taylorza 9:34008d8b1cdf 245 _lastdy = _dy;
taylorza 9:34008d8b1cdf 246 _dx = 0;
taylorza 9:34008d8b1cdf 247 _dy = 0;
taylorza 9:34008d8b1cdf 248 }