"Lost treasure of mBedungu" 100 level puzzle game for RETRO
Dependencies: LCD_ST7735 RetroPlatform mbed
Diff: Game/GameScreen.cpp
- Revision:
- 1:dcea5500a32d
- Parent:
- 0:f5f961973d01
--- a/Game/GameScreen.cpp Sat Feb 21 06:19:29 2015 +0000 +++ b/Game/GameScreen.cpp Sun Mar 01 05:32:06 2015 +0000 @@ -1,26 +1,68 @@ +/* + * (C) Copyright 2015 Valentin Ivanov. All rights reserved. + * + * This file is part of the "Lost treasure of mBedungu" game application for Retro + * + * The "Lost treasure of mBedungu" application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + #include "GameScreen.h" #include "Retro.h" #include "Sprites.h" #include "Levels.h" +#include "Utils.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 + +const int soundfx[][8] = { + {0,24,1,1,1,4,4,9}, // gameover + {0,27,53,1,1,1,4,5}, // pickup + {0,23,60,1,1,1,4,5} // drop +}; + +void sfx(int fxno, int channel) +{ + sfx(soundfx[fxno], channel); +}; + +void sfx( const int * effect, int channel) +{ + retro.sound.command(0, effect[6], 0, channel); // set volume + retro.sound.command(1, effect[0], 0, channel); // set waveform + retro.sound.command(2, effect[5], -effect[4], channel); // set volume slide + retro.sound.command(3, effect[3], effect[2] - 58, channel); // set pitch slide + retro.sound.playNote(effect[1], effect[7], channel); // play note + +} + +Image sprites[] = { + {false, false, NULL}, + {false, false, wall}, + {false, false, barrel}, + {false, false, ladder}, + {false, false, key}, + {false, false, door}, + {false, false, left}, + {true, false, left}, + {false, false, crate}, + {false, false, totem}, + {false, true, rick}, + {false, false, rick_top}, + {false, false, rick_happy} }; GameScreen::GameScreen() @@ -30,6 +72,28 @@ _pocket[0] = 0; _pocket[1] = 0; _rickDirection = 0; + _gameOver = false; + + //for some reason writing to eeprom sometime hangs the program +// _gameData[0] = 0; +// _gameData[1] = 0; +// _gameData[2] = 0; +// _gameData[3] = 0; +// _gameData[4] = 0; +// _gameData[5] = 0; +// +// read_eeprom((char *)64, _gameData, 8); +// if( _gameData[0]=='R' && _gameData[1]=='I' && _gameData[2]=='C' && _gameData[3]=='K' ) +// { +// _level = _gameData[4]; +// _gameComplete = _gameData[5]; +// } +// +// _gameData[0]='R'; +// _gameData[1]='I'; +// _gameData[2]='C'; +// _gameData[3]='K'; + } bool GameScreen::isPocketFull() @@ -89,12 +153,12 @@ void GameScreen::moveleft() { - if( _rickDirection == 0 ) - { + if( _rickDirection == 0 ) { _rickDirection = 1; - drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); + sprites[CELL_RICK].Mirrored = true;//(_rickDirection == 1); + drawSprite(_rickX,_rickY, CELL_RICK); } - + if( _rickX == 0 ) return; @@ -103,17 +167,32 @@ if( cell == CELL_KEY || cell == CELL_BARREL ) { if( putInPocket(cell) ) { + sfx(1,0); _maze[(_rickY<<3)+_rickX-1] = CELL_EMPTY; drawSprite((_rickX-1),_rickY, CELL_EMPTY); drawPocket(); + + //Fall any crates on top of that key or barrel + int y = _rickY; + while( y >= 0 ) { + fall(_rickX-1,y--); + } + } return; } - if( cell == CELL_CRATE && (_rickX-1)>0 ) - { - if( moveto(_rickX-1,_rickY, _rickX-2,_rickY) ) + if( (cell == CELL_CRATE) && ((_rickX-1)>0) ) { + if( moveto(_rickX-1,_rickY, _rickX-2,_rickY) ) { fall(_rickX-2,_rickY); + + int y = _rickY; + while( y >= 0 ) { + fall(_rickX-1,y--); + } + + } + return; } @@ -125,12 +204,12 @@ void GameScreen::moveright() { - if( _rickDirection == 1 ) - { + if( _rickDirection == 1 ) { _rickDirection = 0; - drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); + sprites[CELL_RICK].Mirrored = false; + drawSprite(_rickX,_rickY, CELL_RICK); } - + if( _rickX == 7 ) return; @@ -138,17 +217,29 @@ if( cell == CELL_KEY || cell == CELL_BARREL ) { if( putInPocket(cell) ) { + sfx(1,0); _maze[(_rickY<<3)+_rickX+1] = CELL_EMPTY; drawSprite((_rickX+1),_rickY, CELL_EMPTY); drawPocket(); + + //Fall any crates on top of that key or barrel + int y = _rickY; + while( y >= 0 ) { + fall(_rickX+1,y--); + } } return; } - - if( cell == CELL_CRATE && (_rickX+1)<7 ) - { - if( moveto(_rickX+1,_rickY, _rickX+2,_rickY) ) + + if( (cell == CELL_CRATE) && ((_rickX+1)<7) ) { + if( moveto(_rickX+1,_rickY, _rickX+2,_rickY) ) { fall(_rickX+2,_rickY); + + int y = _rickY; + while( y >= 0 ) { + fall(_rickX+1,y--); + } + } return; } @@ -173,13 +264,14 @@ uint8_t y = _rickY; if( moveto(_rickX,_rickY,_rickX,_rickY-1) ) { if( getBarrelFromPocket() ) { + sfx(2,0); _maze[(y<<3)+x] = CELL_BARREL; drawSprite(x,y,CELL_BARREL); } else if( getKeyFromPocket() ) { + sfx(2,0); _maze[(y<<3)+x] = CELL_KEY; drawSprite(x,y,CELL_KEY); } - drawPocket(); } } @@ -187,37 +279,20 @@ void GameScreen::movedown() { - if( _rickY == 0 ) + if( _rickY == 7 ) 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( 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 ) @@ -227,11 +302,21 @@ uint8_t toCell = _maze[((toY)<<3)+toX]; if( isRick ) { - if( toCell == CELL_EMPTY || toCell == CELL_LADDER || toCell == CELL_TOTEM ) { + if( toCell == CELL_EMPTY || toCell == CELL_LADDER ) { drawSprite(fromX,fromY, fromCell); _rickX = toX; _rickY = toY; - drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); + drawSprite(_rickX,_rickY, CELL_RICK); + return true; + } + if( toCell == CELL_TOTEM ) + { + sfx(0,0); + _gameOver = true; + drawSprite(fromX,fromY, fromCell); + _rickX = toX; + _rickY = toY; + drawSprite(_rickX,_rickY, CELL_RICK); return true; } if( toCell == CELL_DOOR ) { @@ -240,16 +325,22 @@ _maze[((toY)<<3)+toX] = CELL_EMPTY; _rickX = toX; _rickY = toY; - drawSprite(_rickX,_rickY, CELL_RICK, _rickDirection == 1); + drawSprite(_rickX,_rickY, CELL_RICK); drawPocket(); return true; } } - }else if( fromCell == CELL_CRATE && toCell == CELL_EMPTY ) - { + if( (toCell == CELL_RIGHT && fromX < toX) || (toCell == CELL_LEFT && fromX > toX)) { + drawSprite(fromX,fromY, fromCell); + _rickX = toX; + _rickY = toY; + drawSprite(_rickX,_rickY, CELL_RICK); + 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; @@ -321,28 +412,21 @@ break; } } + + _state = 0; + _pocket[0] = 0; + _pocket[1] = 0; + _rickDirection = 0; + _gameOver = false; + + sprites[CELL_RICK].Mirrored = false; + + frame = 0; } 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() @@ -350,12 +434,12 @@ if( _pocket[0] == 0 ) retro.display.fillRect(136,80,151,95,0); else - retro.display.drawBitmapIndexed(136,80, 16,16,sprites[_pocket[0]], palette); + retro.display.drawBitmapIndexed(136,80, 16,16,sprites[_pocket[0]].Sprite, 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); + retro.display.drawBitmapIndexed(136,96, 16,16,sprites[_pocket[1]].Sprite, palette); } @@ -368,7 +452,7 @@ } //Put Rick on the map - drawSprite(_rickX, _rickY, CELL_RICK, _rickDirection == 1); + drawSprite(_rickX, _rickY, CELL_RICK); //Draw the statistics and "pocket" area for( int y = 0; y < 8; y++ ) { @@ -378,38 +462,94 @@ 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); + drawLevelNumber(136,32,_level); drawPocket(); } + Screen GameScreen::Update() { + frame++; + if( _state == 0 ) { drawLevel(); _state = 1; } + + if( _gameOver ) + { + if( (frame % 3) == 0 ) + { + sprites[12].Mirrored = !sprites[12].Mirrored; + drawSprite(_rickX,_rickY,12); + } + } - if(retro.buttons.pressed(BTN_LEFT)) { - moveleft(); + if(retro.pressed(BTN_LEFT)) { + //sfx(0,0); + if( !_gameOver ) + moveleft(); } - if(retro.buttons.pressed(BTN_RIGHT)) { + if(retro.pressed(BTN_RIGHT)) { + //sfx(1,0); + if( !_gameOver ) moveright(); } - if(retro.buttons.pressed(BTN_UP)) { - moveup(); + if(retro.pressed(BTN_UP)) { + //sfx(2,0); + if( !_gameOver ) + moveup(); } - if(retro.buttons.pressed(BTN_DOWN)) { + if(retro.pressed(BTN_DOWN)) { + //sfx(3,0); + if( !_gameOver ) movedown(); } - if(retro.buttons.pressed(BTN_ROBOT)) { + if(retro.pressed(BTN_ROBOT)) { _state = 0; return Menu; } + + if(retro.pressed(BTN_SHIP)) { + if( _gameOver ) + { + if( _level < 99 ) + { + _level++; + resetLevel(); + +//for some reason writing to eeprom sometime hangs the program +// _gameData[4]= _level; +// _gameData[5] = _gameComplete; +// +// write_eeprom(_gameData, (char *)64, 8 ); + } + } + } return Game; +} + + +void drawSprite(int x, int y, int sprite) +{ + 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].Sprite, palette, sprites[sprite].Mirrored); + } +} + +void drawLevelNumber(int x, int y, int level) +{ + char buf[3]; + if( (level/10) > 0 ) + sprintf(buf,"%d",level); + else + sprintf(buf,"@%d",level); + drawString(x,y,buf, palette_orange); } \ No newline at end of file