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:
Mon Feb 16 03:46:57 2015 +0000
Revision:
16:f9227904afc4
Parent:
14:b4884a31069e
Added a 4th game screen

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