"Lost treasure of mBedungu" 100 level puzzle game for RETRO
Dependencies: LCD_ST7735 RetroPlatform mbed
Game/GameScreen.cpp
- Committer:
- Architect
- Date:
- 2015-02-21
- Revision:
- 0:f5f961973d01
- Child:
- 1:dcea5500a32d
File content as of revision 0:f5f961973d01:
#include "GameScreen.h" #include "Retro.h" #include "Sprites.h" #include "Levels.h" extern Retro retro; #ifdef FULL_COLOR const uint16_t * sprites[] = { #else const uint8_t * sprites[] = { #endif NULL, wall, barrel, ladder, key, door, left, right, crate, totem, rick }; GameScreen::GameScreen() { _level = 0; _state = 0; _pocket[0] = 0; _pocket[1] = 0; _rickDirection = 0; } bool GameScreen::isPocketFull() { return (_pocket[0] != 0 && _pocket[1] != 0); } bool GameScreen::isPocketEmpty() { return (_pocket[0] == 0 && _pocket[1] == 0); } bool GameScreen::putInPocket( int item ) { if( item != CELL_BARREL && item != CELL_KEY ) return false; bool bRet = true; if( _pocket[0] == 0 ) _pocket[0] = item; else if( _pocket[1] == 0 ) _pocket[1] = item; else bRet = false; return bRet; } bool GameScreen::getKeyFromPocket() { bool bRet = true; if( _pocket[0] == CELL_KEY ) _pocket[0] = 0; else if( _pocket[1] == CELL_KEY ) _pocket[1] = 0; else bRet = false; return bRet; } bool GameScreen::getBarrelFromPocket() { bool bRet = true; if( _pocket[0] == CELL_BARREL ) _pocket[0] = 0; else if( _pocket[1] == CELL_BARREL ) _pocket[1] = 0; else bRet = false; return bRet; } void GameScreen::moveleft() { if( _rickDirection == 0 ) { _rickDirection = 1; drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); } if( _rickX == 0 ) return; uint8_t cell = _maze[(_rickY<<3)+_rickX-1]; if( cell == CELL_KEY || cell == CELL_BARREL ) { if( putInPocket(cell) ) { _maze[(_rickY<<3)+_rickX-1] = CELL_EMPTY; drawSprite((_rickX-1),_rickY, CELL_EMPTY); drawPocket(); } return; } if( cell == CELL_CRATE && (_rickX-1)>0 ) { if( moveto(_rickX-1,_rickY, _rickX-2,_rickY) ) fall(_rickX-2,_rickY); return; } if( moveto(_rickX,_rickY,_rickX-1,_rickY) ) fall(_rickX,_rickY); } void GameScreen::moveright() { if( _rickDirection == 1 ) { _rickDirection = 0; drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); } if( _rickX == 7 ) return; uint8_t cell = _maze[(_rickY<<3)+_rickX+1]; if( cell == CELL_KEY || cell == CELL_BARREL ) { if( putInPocket(cell) ) { _maze[(_rickY<<3)+_rickX+1] = CELL_EMPTY; drawSprite((_rickX+1),_rickY, CELL_EMPTY); drawPocket(); } return; } if( cell == CELL_CRATE && (_rickX+1)<7 ) { if( moveto(_rickX+1,_rickY, _rickX+2,_rickY) ) fall(_rickX+2,_rickY); return; } if( moveto(_rickX,_rickY,_rickX+1,_rickY) ) fall(_rickX,_rickY); } void GameScreen::moveup() { if( _rickY == 0 ) return; uint8_t currentCell = _maze[((_rickY)<<3)+_rickX]; uint8_t aboveCell = _maze[((_rickY-1)<<3)+_rickX]; //if already on ladder if( currentCell == CELL_LADDER ) moveto(_rickX,_rickY,_rickX,_rickY-1); else if( currentCell == CELL_EMPTY && !isPocketEmpty()) { uint8_t x = _rickX; uint8_t y = _rickY; if( moveto(_rickX,_rickY,_rickX,_rickY-1) ) { if( getBarrelFromPocket() ) { _maze[(y<<3)+x] = CELL_BARREL; drawSprite(x,y,CELL_BARREL); } else if( getKeyFromPocket() ) { _maze[(y<<3)+x] = CELL_KEY; drawSprite(x,y,CELL_KEY); } drawPocket(); } } } void GameScreen::movedown() { if( _rickY == 0 ) return; // uint8_t currentCell = _maze[((_rickY)<<3)+_rickX]; // uint8_t belowCell = _maze[((_rickY+1)<<3)+_rickX]; if( moveto(_rickX,_rickY,_rickX,_rickY+1) ) { fall(_rickX,_rickY); } // if( _rickY > 0 ) { // uint8_t cellAbove = _maze[((_rickY-1)<<3)+_rickX]; // if(cellAbove == CELL_EMPTY && !isPocketEmpty()) { // if( getKeyFromPocket() ) { // _maze[(_rickY<<3)+_rickX] = CELL_KEY; // } else if( getBarrelFromPocket() ) // _maze[(_rickY<<3)+_rickX] = CELL_BARREL; // // _rickY--; // drawSprite(_rickX,_rickY+1, _maze[((_rickY+1)<<3)+_rickX]); // drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); // drawPocket(); // } // } } bool GameScreen::moveto(uint8_t fromX, uint8_t fromY, uint8_t toX, uint8_t toY) { bool isRick = false; if( fromX == _rickX && fromY == _rickY ) isRick = true; uint8_t fromCell = _maze[((fromY)<<3)+fromX]; uint8_t toCell = _maze[((toY)<<3)+toX]; if( isRick ) { if( toCell == CELL_EMPTY || toCell == CELL_LADDER || toCell == CELL_TOTEM ) { drawSprite(fromX,fromY, fromCell); _rickX = toX; _rickY = toY; drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); return true; } if( toCell == CELL_DOOR ) { if( getKeyFromPocket() ) { drawSprite(fromX,fromY, fromCell); _maze[((toY)<<3)+toX] = CELL_EMPTY; _rickX = toX; _rickY = toY; drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); drawPocket(); return true; } } }else if( fromCell == CELL_CRATE && toCell == CELL_EMPTY ) { _maze[((toY)<<3)+toX] = CELL_CRATE; _maze[((fromY)<<3)+fromX] = CELL_EMPTY; drawSprite(fromX,fromY, toCell); drawSprite(toX,toY, fromCell); return true; } return false; } bool GameScreen::fall(uint8_t fromX, uint8_t fromY) { if( fromY == 7 ) return false; uint8_t curCell = _maze[(fromY<<3)+fromX]; if( curCell == CELL_LADDER ) return false; uint8_t cell = _maze[((fromY+1)<<3)+fromX]; while( cell == CELL_EMPTY || cell == CELL_TOTEM ) { if( moveto(fromX,fromY,fromX,fromY+1) ) { fromY++; if( fromY == 7 ) break; cell = _maze[((fromY+1)<<3)+fromX]; } else { break; } } return true; } void GameScreen::unpackLevel( int level ) { if( level < 0 || level > 99 ) level = 0; _level = level; const uint32_t * pLevel = &levels[level*8]; for( int y = 0; y < 8; y++ ) for( int x = 0; x < 8; x++ ) { _maze[(y<<3) + x] = (pLevel[y]>>(28-(x<<2))) & 0x0F; switch( _maze[(y<<3) + x] ) { case CELL_RICK: //The level data has specialy marked cell for Rick //During the game Rick position is tracked separately //This allows us to put Rick on none EMPTY cells _maze[(y<<3) + x] = CELL_EMPTY; _rickX = x; _rickY = y; break; case CELL_TOTEM: _totemX = x; _totemY = y; break; default: break; } } } void GameScreen::resetLevel() { unpackLevel(_level); _state = 0; _pocket[0] = 0; _pocket[1] = 0; _rickDirection = 0; } void GameScreen::drawSprite(int x, int y, int sprite, bool mirrored) { int screenx = x<<4; int screeny = y<<4; if( sprite == 0 ) retro.display.fillRect(screenx,screeny, screenx+15,screeny+15,0); else { retro.display.drawBitmapIndexed(screenx,screeny, 16,16,sprites[sprite],palette, mirrored); } } void GameScreen::drawPocket() { if( _pocket[0] == 0 ) retro.display.fillRect(136,80,151,95,0); else retro.display.drawBitmapIndexed(136,80, 16,16,sprites[_pocket[0]], palette); if( _pocket[1] == 0 ) retro.display.fillRect(136,96,151,111,0); else retro.display.drawBitmapIndexed(136,96, 16,16,sprites[_pocket[1]], palette); } void GameScreen::drawLevel() { //Draw the maze for( int y = 0; y < 8; y++ ) for( int x = 0; x < 8; x++ ) { drawSprite(x, y, _maze[(y<<3)+x]); } //Put Rick on the map drawSprite(_rickX, _rickY, CELL_RICK, _rickDirection == 1); //Draw the statistics and "pocket" area for( int y = 0; y < 8; y++ ) { retro.display.drawBitmapIndexed(128,y<<4, 16,16,wall, palette); retro.display.drawBitmapIndexed(144,y<<4, 16,16, wall, palette); } retro.display.drawBitmapIndexed(136,16, 16,16,totem,palette); retro.display.fillRect(132,32,155,39,0); char buff[4]; sprintf(buff,"%d",_level); drawString(132,32,buff); drawPocket(); } Screen GameScreen::Update() { if( _state == 0 ) { drawLevel(); _state = 1; } if(retro.buttons.pressed(BTN_LEFT)) { moveleft(); } if(retro.buttons.pressed(BTN_RIGHT)) { moveright(); } if(retro.buttons.pressed(BTN_UP)) { moveup(); } if(retro.buttons.pressed(BTN_DOWN)) { movedown(); } if(retro.buttons.pressed(BTN_ROBOT)) { _state = 0; return Menu; } return Game; }