Great game by Aurelién Rodot for Gamebuin. Ported by Jonne
Dependencies: PokittoLib
Fork of Asterocks by
Crabator.cpp
00001 //#include <SPI.h> 00002 #include <Pokitto.h> 00003 #include "Crabator.h" 00004 Pokitto::Core gb; 00005 //#include <EEPROM.h> 00006 //#include <avr/pgmspace.h> 00007 00008 uint16_t hazepalette[16]; 00009 00010 extern const byte font3x5[]; 00011 extern const byte font5x7[]; 00012 00013 #define WORLD_W 16 00014 #define WORLD_H 12 00015 uint8_t byteWidth = (WORLD_H + 7) / 8; 00016 00017 //declare all the sprites which are in the "sprites" tab 00018 extern const byte PROGMEM logo[]; 00019 extern const byte PROGMEM world[]; 00020 extern const byte PROGMEM tiles[]; 00021 extern const byte PROGMEM mobSprite[]; 00022 extern const byte PROGMEM bossSprite[]; 00023 extern const byte PROGMEM playerSprite[]; 00024 extern const byte PROGMEM splashSprite[]; 00025 extern const byte PROGMEM crateSprite[]; 00026 extern const byte PROGMEM fullHeart[]; 00027 extern const byte PROGMEM halfHeart[]; 00028 extern const byte PROGMEM emptyHeart[]; 00029 00030 #define playerW 6 00031 #define playerH 6 00032 byte playerSpeed; 00033 int playerX; 00034 int playerY; 00035 int playerLife; 00036 #define playerLifeMax 6 00037 byte playerDir; 00038 int cameraX; 00039 int cameraY; 00040 byte shake_magnitude; 00041 byte shake_timeLeft; 00042 const PROGMEM uint16_t player_damage_sound[] = {0x0045,0x564,0x0000}; 00043 00044 ///////////////////////////////////// MOBS 00045 #define NUMMOBS 16 00046 #define INITNUMMOBS 4 00047 #define MOBSRATE 6 //how often is the mob number increased (every X kills) 00048 #define BOSSFREQ 16//one boss every X kills (initially) 00049 #define BOSSRATE 1 //every boss killed, the next one will spawn X kills earlier 00050 byte boss_nextSpawn; 00051 byte boss_freq; 00052 byte activeMobs; 00053 int mobs_x[NUMMOBS]; 00054 int mobs_y[NUMMOBS]; 00055 byte mobs_dir[NUMMOBS]; 00056 int8_t mobs_life[NUMMOBS]; // was char - Jonne 00057 byte mobs_size[NUMMOBS]; 00058 byte mob_maxLife = 10; 00059 byte boss_maxLife = 100; 00060 #define boss_size 6 00061 #define mob_size 4 00062 //const PROGMEM uint16_t mob_damage_sound[] = {0x5C1F, 0x0000}; 00063 const PROGMEM uint16_t mob_death_sound[] = {0x0045,0x184,0x0000}; 00064 00065 #define NUMSPLASH 16 00066 boolean splash_active[NUMSPLASH]; 00067 int splash_x[NUMSPLASH]; 00068 int splash_y[NUMSPLASH]; 00069 int splash_dir[NUMSPLASH]; 00070 00071 ///////////////////////////////////// WEAPONS 00072 #define NUMBULLETS 10 00073 int bullets_x[NUMBULLETS]; 00074 int bullets_y[NUMBULLETS]; 00075 byte bullets_dir[NUMBULLETS]; 00076 boolean bullets_active[NUMBULLETS]; 00077 byte bullets_weapon[NUMBULLETS]; 00078 00079 int blast_x; 00080 int blast_y; 00081 byte blast_lifespan; 00082 byte blast_bullet; 00083 00084 #define NUMWEAPONS 5 00085 byte currentWeapon; 00086 byte nextShot; 00087 00088 const char str357[] PROGMEM = ".357"; 00089 const char strP90[] PROGMEM = "P90"; 00090 const char strAK47[] PROGMEM = "AK47"; 00091 const char strRPG[] PROGMEM = "RPG"; 00092 const char strMG42[] PROGMEM = "MG42"; 00093 const char* const weapon_name[NUMWEAPONS] PROGMEM = { 00094 str357,strP90, strAK47, strRPG, strMG42}; 00095 const byte weapon_size[NUMWEAPONS] = { 00096 2, 1, 2, 3, 2}; 00097 const byte weapon_damage[NUMWEAPONS] = { 00098 10, 2, 3, 5, 4}; 00099 const byte weapon_rate[NUMWEAPONS] = { 00100 30, 1, 2, 30, 1}; 00101 const byte weapon_speed[NUMWEAPONS] = { 00102 4, 5, 3, 2, 5}; 00103 const byte weapon_spread[NUMWEAPONS] = { 00104 1, 2, 1, 0, 2}; 00105 const byte weapon_ennemyRecoil[NUMWEAPONS] = { 00106 3, 2, 3, 0, 3}; 00107 const byte weapon_playerRecoil[NUMWEAPONS] = { 00108 0, 0, 1, 3, 3}; 00109 const unsigned int weapon_ammo[NUMWEAPONS] = { 00110 9999, 500, 300, 20, 150}; 00111 unsigned int ammo; 00112 00113 const uint16_t magnum_sound[] PROGMEM = {0x0045,0x7049,0x17C,0x784D,0x42C,0x0000}; 00114 const uint16_t p90_sound[] PROGMEM = {0x0045, 0x0154, 0x0000}; 00115 const uint16_t p90_alternative_sound[] PROGMEM = {0x0045, 0x014C, 0x0000}; 00116 const uint16_t ak47_sound[] PROGMEM = {0x0045, 0x012C, 0x0000}; 00117 const uint16_t mg42_sound[] PROGMEM = {0x0045,0x140,0x8141,0x7849,0x788D,0x52C,0x0000}; 00118 const uint16_t rpg_sound[] PROGMEM = {0x0045,0x8101,0x7F30,0x0000}; 00119 00120 const uint16_t* const weapons_sounds[NUMWEAPONS] PROGMEM= { 00121 magnum_sound, p90_sound, ak47_sound, rpg_sound, mg42_sound}; 00122 const uint16_t blast_sound[] PROGMEM = {0x0045,0x7849,0x784D,0xA28,0x0000}; 00123 int crate_x, crate_y; 00124 const uint16_t power_up[] PROGMEM = {0x0005,0x140,0x150,0x15C,0x170,0x180,0x16C,0x154,0x160,0x174,0x184,0x14C,0x15C,0x168,0x17C,0x18C,0x0000}; 00125 00126 ///////////////////////////////////// SCORE 00127 #define RANKMAX 5 //number of high scores to save 00128 int score = 0; 00129 //int lastScore = 0; 00130 int kills = 0; 00131 int highscore[RANKMAX]; 00132 //byte scoreDisplayTimeLeft; 00133 #define NAMELENGTH 10 00134 char name[RANKMAX][NAMELENGTH+1]; 00135 00136 // predefinitions 00137 00138 void loadHighscore(); 00139 void initGame(); 00140 boolean collideWorld(int16_t, int16_t, uint8_t, uint8_t); 00141 void damageMob(byte,byte); 00142 boolean checkMobCollisions(byte); 00143 boolean collideOtherMobs(byte); 00144 void pausem(); 00145 void play(); 00146 void displayHighScores(); 00147 void saveHighscore(); 00148 void shakeScreen(); 00149 void drawWorld(int16_t, int16_t); 00150 void displayScore(); 00151 00152 /*int16_t random (int lo,int hi) { 00153 return rand() % hi + lo; 00154 }*/ 00155 00156 ///////////////////////////////////// SETUP 00157 void setup() { 00158 00159 /** Set colors for this game **/ 00160 00161 /** TO ADD COLORS TO YOUR GAMEBUINO GAME, SIMPLY USE VALUES ABOVE 1 !!!! */ 00162 00163 gb.display.palette[1] = COLOR_WHITE; 00164 gb.display.palette[2] = COLOR_CYAN; 00165 gb.display.palette[3] = COLOR_MAGENTA; 00166 gb.display.palette[4] = COLOR_RED; 00167 gb.display.palette[8] = gb.display.RGBto565(0xff,0xfc,0); // small mob 00168 gb.display.palette[7] = gb.display.RGBto565(0x18,0x9a,0x61); // shrub shadow 00169 gb.display.palette[5] = gb.display.RGBto565(0x2c,0xff,0x0b); //world (shrubs) 00170 gb.display.palette[6] = gb.display.RGBto565(0xf7,0xb2,0);// crate 00171 gb.display.palette[9] = gb.display.RGBto565(0xfc,0x14,4);// big mob fc1404 00172 gb.display.palette[10] = gb.display.RGBto565(0,0x53,0xae); // blue shadow 00173 gb.display.palette[15] = gb.display.RGBto565(0xff,0xfd,0xbf); // bright sunlight 00174 00175 /** YOU HAVE 16 COLORS FREELY SELECTABLE FROM 256000 COLORS !!! **/ 00176 00177 /** NOW LETS REBUILD! **/ 00178 00179 00180 00181 for (uint16_t k =0 ; k<16; k++) hazepalette[k] = gb.display.interpolateColor(gb.display.palette[k],gb.display.palette[15],0); 00182 gb.display.paletteptr = hazepalette; 00183 gb.begin(); 00184 //while(1) gb.update(); 00185 gb.display.setFont(font5x7); 00186 gb.titleScreen(logo); 00187 00188 gb.pickRandomSeed(); 00189 loadHighscore(); 00190 initGame(); 00191 } 00192 00193 ///////////////////////////////////// LOOP 00194 void loop() { 00195 play(); 00196 if (!gb.isRunning()) return; 00197 pausem(); 00198 if (!gb.isRunning()) return; 00199 gb.titleScreen(logo); 00200 } 00201 00202 ///////////////////////////////////// SCREEN COORD 00203 boolean screenCoord(int absoluteX, int absoluteY, int &x, int &y){ 00204 x = absoluteX - cameraX + 8; 00205 x = (x >= 0) ? x%(WORLD_W*8) : WORLD_W*8 + x%(WORLD_W*8); 00206 x -= 8; 00207 y = absoluteY - cameraY + 8; 00208 y = (y >= 0) ? y%(WORLD_H*8) : WORLD_H*8 + y%(WORLD_H*8); 00209 y -= 8; 00210 if((x > LCDWIDTH) || (y > LCDHEIGHT)) 00211 return false; 00212 return true; 00213 } 00214 00215 #define wrap(i, imax) ((imax+i)%(imax)) 00216 00217 ///////////////////////////////////// MOVE XYDS 00218 void moveXYDS(int &x, int &y, byte &dir, int8_t speed){ 00219 switch(dir){ //switch case depending on the mob's movement direction 00220 case 0: //going upward 00221 y -= speed; 00222 break; 00223 case 1: //left 00224 x -= speed; 00225 break; 00226 case 2: //downward 00227 y += speed; 00228 break; 00229 case 3: //right 00230 x += speed; 00231 break; 00232 } 00233 x = wrap(x, WORLD_W*8); 00234 y = wrap(y, WORLD_H*8); 00235 } 00236 00237 ///////////////////////////////////// DISTANCE BETWEEN 00238 byte distanceBetween(int pos1, int pos2, int worldSize){ 00239 byte dist = abs(pos1 - pos2); 00240 dist = (dist < worldSize/2) ? dist : worldSize - dist; 00241 return dist; 00242 } 00243 00244 ///////////////////////////////////// ASSIGN ARRAY 00245 void assignArray(char *array1, char *array2, byte length){ 00246 for(byte i=0; i<length; i++) 00247 array1[i] = array2[i]; 00248 } 00249 00250 ///////////////////////////////////// SHOOT 00251 #define min(a,b) (((a)<(b))?(a):(b)) 00252 #define max(a,b) (((a)>(b))?(a):(b)) 00253 00254 00255 void shoot(){ 00256 if(ammo){ 00257 if(nextShot == 0){ 00258 for(byte thisBullet = 0; thisBullet < NUMBULLETS; thisBullet++){ 00259 if(!bullets_active[thisBullet]){ //look for the first inactive bullet 00260 bullets_active[thisBullet] = true; //set it to active as it's fired 00261 bullets_weapon[thisBullet] = currentWeapon; 00262 00263 nextShot = weapon_rate[currentWeapon]; 00264 ammo--; 00265 //spawn a bullet with some spreading 00266 int8_t spreadMax = weapon_spread[currentWeapon]; // this was char, jonne 00267 int8_t spreadMin = (weapon_size[currentWeapon]%2==0) ? -spreadMax : -spreadMax-1; 00268 bullets_x[thisBullet] = playerX + playerW/2 + random(spreadMin,spreadMax+1) - weapon_size[currentWeapon]/2; 00269 bullets_y[thisBullet] = playerY + playerH/2 + random(spreadMin,spreadMax+1) - weapon_size[currentWeapon]/2; 00270 00271 bullets_dir[thisBullet] = playerDir; 00272 blast_bullet = thisBullet; 00273 if(((currentWeapon == 1)||(currentWeapon==4))&&(gb.frameCount%2)) 00274 { 00275 } 00276 else{ 00277 gb.sound.playPattern((uint16_t*)pgm_read_word(&(weapons_sounds[currentWeapon])), 0); 00278 } 00279 if(currentWeapon == 1){//with P90 cancel every two sounds to avoid continuous beep 00280 if(rand()%2) 00281 gb.sound.playPattern(p90_alternative_sound, 0); 00282 } 00283 //player recoil 00284 byte recoil = weapon_playerRecoil[currentWeapon]; 00285 moveXYDS(playerX, playerY, playerDir, -recoil); 00286 for(byte i = 0; i<recoil; i++){ 00287 if(collideWorld(playerX, playerY, playerW, playerH)) 00288 moveXYDS(playerX, playerY, playerDir, 1); 00289 else 00290 break; 00291 } 00292 if(currentWeapon == 4){ //MG42 00293 shake_magnitude = 1; 00294 shake_timeLeft = 2; 00295 } 00296 break; 00297 } 00298 } 00299 } 00300 } 00301 else{ 00302 currentWeapon = max(0, currentWeapon-1); //cut... no, magnum finally 00303 ammo = weapon_ammo[currentWeapon]; 00304 nextShot = 20; 00305 gb.popup(("Out of ammo!"), 30); 00306 } 00307 } 00308 00309 ///////////////////////////////////// MOVE BULLETS 00310 void moveBullets(){ 00311 for(byte thisBullet = 0; thisBullet < NUMBULLETS; thisBullet++){ 00312 if(bullets_active[thisBullet]){ 00313 byte s = weapon_size[bullets_weapon[thisBullet]]; 00314 moveXYDS(bullets_x[thisBullet], bullets_y[thisBullet], bullets_dir[thisBullet], weapon_speed[bullets_weapon[thisBullet]]); 00315 00316 //collide world 00317 if(collideWorld(bullets_x[thisBullet], bullets_y[thisBullet], s, s)){ 00318 bullets_active[thisBullet] = false; 00319 if(bullets_weapon[thisBullet] == 3){ //RPG 00320 blast_x = bullets_x[thisBullet]; 00321 blast_y = bullets_y[thisBullet]; 00322 blast_lifespan = 8; 00323 gb.sound.playPattern(blast_sound, 0); 00324 } 00325 else{ 00326 } 00327 continue; 00328 } 00329 00330 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ //for each mob 00331 00332 if(gb.collideRectRect(bullets_x[thisBullet], bullets_y[thisBullet], s, s, 00333 mobs_x[thisMob], mobs_y[thisMob], mobs_size[thisMob], mobs_size[thisMob])){ 00334 00335 if(bullets_weapon[thisBullet] == 3){ //RPG 00336 blast_x = bullets_x[thisBullet]; 00337 blast_y = bullets_y[thisBullet]; 00338 blast_lifespan = 8; 00339 gb.sound.playPattern(blast_sound, 0); 00340 } 00341 else { 00342 damageMob(thisMob, thisBullet); 00343 } 00344 bullets_active[thisBullet] = false; 00345 break; 00346 } 00347 } 00348 00349 } 00350 } 00351 } 00352 00353 ///////////////////////////////////// EXPLODE 00354 void explode(){ 00355 if(blast_lifespan){ 00356 blast_lifespan--; 00357 //gb.buzz(50+random(0,100),40); 00358 shake_magnitude = 4; 00359 shake_timeLeft = 2; 00360 //pick a random blast 00361 byte s = 10 + random (0,6); 00362 int x = blast_x + random(-4,4) -s/2; 00363 int y = blast_y + random(-4,4) -s/2; 00364 //damages 00365 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ 00366 if(gb.collideRectRect(mobs_x[thisMob], mobs_y[thisMob], mobs_size[thisMob], mobs_size[thisMob], 00367 x,y,s,s)) 00368 damageMob(thisMob,blast_bullet); 00369 } 00370 //display 00371 int x_screen, y_screen; 00372 if(screenCoord(x, y, x_screen, y_screen)) 00373 gb.display.fillRect(x_screen, y_screen, s, s); 00374 } 00375 } 00376 00377 ///////////////////////////////////// DRAW BULLETS 00378 void drawBullets(){ 00379 gb.display.setColor(1); 00380 for(byte thisBullet = 0; thisBullet < NUMBULLETS; thisBullet++){ 00381 if(bullets_active[thisBullet]){ 00382 int x, y; 00383 if(screenCoord(bullets_x[thisBullet], bullets_y[thisBullet], x, y)){ 00384 byte s = weapon_size[bullets_weapon[thisBullet]]; 00385 if(s==1) 00386 gb.display.drawPixel(x, y); 00387 else 00388 gb.display.fillRect(x, y, s, s); 00389 } 00390 } 00391 } 00392 } 00393 00394 ///////////////////////////////////// DRAW AMMO OVERLAY 00395 void drawAmmoOverlay(){ 00396 if(ammo){ 00397 // text shadow 00398 /* 00399 gb.display.setColor(10); 00400 gb.display.cursorX = -1; 00401 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight-1; 00402 gb.display.print((const __FlashStringHelper*)pgm_read_word(weapon_name+currentWeapon)); //some crazy casts 00403 gb.display.cursorX = -1; 00404 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight+1; 00405 gb.display.print((const __FlashStringHelper*)pgm_read_word(weapon_name+currentWeapon)); //some crazy casts 00406 gb.display.cursorX = 1; 00407 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight-1; 00408 gb.display.print((const __FlashStringHelper*)pgm_read_word(weapon_name+currentWeapon)); //some crazy casts 00409 gb.display.cursorX = +1; 00410 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight+1; 00411 gb.display.print((const __FlashStringHelper*)pgm_read_word(weapon_name+currentWeapon)); //some crazy casts 00412 */ 00413 // white on top 00414 gb.display.setColor(2); 00415 gb.display.cursorX = 0; 00416 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight; 00417 gb.display.print((char*)(weapon_name[currentWeapon])); //some crazy casts 00418 00419 if(nextShot>2) 00420 gb.display.fillRect(-2,LCDHEIGHT-2,nextShot,2); 00421 if(currentWeapon > 0){ //don't display the ammo of the cut 00422 byte xOffset = 0; 00423 if (ammo < 100) 00424 xOffset += gb.display.fontWidth; 00425 if (ammo < 10) 00426 xOffset += gb.display.fontWidth; 00427 gb.display.cursorX = LCDWIDTH-3*gb.display.fontWidth+xOffset; 00428 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight; 00429 gb.display.print(ammo); 00430 } 00431 else { 00432 gb.display.cursorX = LCDWIDTH-3*gb.display.fontWidth; 00433 gb.display.cursorY = LCDHEIGHT-gb.display.fontHeight; 00434 gb.display.print(("inf")); 00435 } 00436 } 00437 } 00438 00439 ///////////////////////////////////// SET SPLASH 00440 void setSplash(int x, int y){ 00441 for(byte thisSplash = 0; thisSplash < NUMSPLASH; thisSplash++){ 00442 if(!splash_active[thisSplash]){ //look for the first inactive splash 00443 splash_active[thisSplash] = true; //set it to active 00444 splash_x[thisSplash] = x; 00445 splash_y[thisSplash] = y; 00446 splash_dir[thisSplash] = random(0,5); 00447 break; 00448 } 00449 } 00450 } 00451 00452 ///////////////////////////////////// DRAW SPLASHES 00453 void drawSplashes(){ 00454 for(byte thisSplash = 0; thisSplash < NUMSPLASH; thisSplash++){ 00455 if(splash_active[thisSplash]){ 00456 int x, y; 00457 if(screenCoord(splash_x[thisSplash], splash_y[thisSplash], x, y)){ //if the splash is in the screen 00458 //draw it 00459 gb.display.drawBitmap(x-2, y-2, splashSprite, splash_dir[thisSplash], NOFLIP); 00460 } 00461 else{ //erase it if it is out of the screen 00462 splash_active[thisSplash] = false; 00463 } 00464 } 00465 } 00466 } 00467 00468 00469 ///////////////////////////////////// SPAWN CRATE 00470 void spawnCrate(){ 00471 boolean okay = false; 00472 while (okay == false){ 00473 //pick a random location 00474 crate_x = random(0, WORLD_W) * 8; 00475 crate_y = random(0, WORLD_H) * 8; 00476 okay = true; 00477 //is that in a wall ? 00478 if(collideWorld(crate_x, crate_y, 8, 8)){ 00479 okay = false; 00480 } 00481 //is that in the screen ? 00482 int x, y; 00483 if(screenCoord(crate_x, crate_y, x, y)){ 00484 okay = false; 00485 } 00486 } 00487 } 00488 00489 ///////////////////////////////////// COLLIDE CRATE 00490 void collideCrate(){ 00491 if(gb.collideRectRect(crate_x+2, crate_y+2, 4, 4, playerX, playerY, playerW, playerH)){ 00492 if (score <5){ 00493 gb.popup(("Earn $5 first"), 30); 00494 return; 00495 } 00496 if(currentWeapon<(NUMWEAPONS-1)){ 00497 gb.popup(("Upgraded !"), 30); 00498 gb.sound.playPattern(power_up,0); 00499 } 00500 else{ 00501 gb.popup(("Refilled !"), 30); 00502 } 00503 score -= 5; 00504 spawnCrate(); 00505 currentWeapon = min(NUMWEAPONS-1, currentWeapon+1); //upgrade to the next weapon 00506 ammo = weapon_ammo[currentWeapon]; 00507 //gb.popup(weapon_name[currentWeapon], 30); 00508 //if(random(0,score/10)==0) //the higher is your score, the less life you will find in crates 00509 playerLife = min(playerLife+1, playerLifeMax); 00510 int hazefactor = (255-42*playerLife)*2/3; 00511 for (uint16_t k =0 ; k<16; k++) hazepalette[k] = gb.display.interpolateColor(gb.display.palette[k],gb.display.palette[4],hazefactor); 00512 //gb.buzz(2000,40); 00513 } 00514 } 00515 00516 ///////////////////////////////////// DRAW CRATE 00517 void drawCrate(){ 00518 int x, y; 00519 if(screenCoord(crate_x, crate_y, x, y)){ 00520 gb.display.setColor(8); 00521 gb.display.drawBitmap(x, y, crateSprite); 00522 //gb.display.setColor(6); 00523 //gb.display.drawBitmap(x-1, y, crateSprite); 00524 } 00525 } 00526 00527 00528 00529 ///////////////////////////////////// SPAWN ONE MOB 00530 boolean spawnMob(byte thisMob){ 00531 boolean okay = false; 00532 byte timout = 0; 00533 mobs_size[thisMob] = mob_size; 00534 mobs_life[thisMob] = mob_maxLife; 00535 if(!boss_nextSpawn){ //spawn big mobs every 20 kills starting from 15 00536 boss_freq = max(boss_freq - BOSSRATE, 1); 00537 boss_nextSpawn = boss_freq; 00538 mobs_size[thisMob] = boss_size; 00539 mobs_life[thisMob] = boss_maxLife; 00540 //gb.popup("Boss spawned !", 30); 00541 } 00542 while(okay == false){ //do the following until it's okay 00543 //pick a random location 00544 mobs_x[thisMob] = random(0, WORLD_W*2) * 4; 00545 mobs_y[thisMob] = random(0, WORLD_H*2) * 4; 00546 //and check if that position is okay 00547 okay = true; 00548 00549 if(checkMobCollisions(thisMob)){ 00550 okay = false; 00551 continue; 00552 } 00553 //spawn the mobs out of the player's view 00554 if(wrap(mobs_x[thisMob] - cameraX, WORLD_W*8) < LCDWIDTH){ 00555 okay = false; 00556 continue; 00557 } 00558 if(wrap(mobs_y[thisMob] - cameraY, WORLD_H*8) < LCDHEIGHT){ 00559 okay = false; 00560 continue; 00561 } 00562 } 00563 mobs_dir[thisMob] = rand() % 4; //then pick a random direction 00564 return true; 00565 } 00566 00567 ///////////////////////////////////// SPAWN ALL MOBS 00568 boolean spawnMobs(){ 00569 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ //put mobs far away 00570 mobs_x[thisMob] = 9999; 00571 mobs_y[thisMob] = 9999; 00572 } 00573 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ 00574 if(!spawnMob(thisMob)) //try to spawn a mob 00575 return false; //return false if an error occur 00576 } 00577 return true; 00578 } 00579 00580 ///////////////////////////////////// MOVE MOBS 00581 void moveMobs(){ 00582 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ //for each mob 00583 int x = wrap(mobs_x[thisMob] - cameraX, WORLD_W*8); 00584 int y = wrap(mobs_y[thisMob] - cameraY, WORLD_H*8); 00585 //if the mob is close to the screen 00586 if( (distanceBetween(mobs_x[thisMob], playerX, WORLD_W*8) < (LCDWIDTH+32)) && (distanceBetween(mobs_y[thisMob], playerY, WORLD_H*8) < (LCDHEIGHT+32))){ 00587 moveXYDS(mobs_x[thisMob], mobs_y[thisMob], mobs_dir[thisMob], 1); //go forward 00588 00589 //if there is a collision, move a step backward and pick a new random direction 00590 if(checkMobCollisions(thisMob)){ 00591 moveXYDS(mobs_x[thisMob], mobs_y[thisMob], mobs_dir[thisMob], -1); 00592 mobs_dir[thisMob] = rand()%4; 00593 continue; 00594 } 00595 00596 //go in a random direction 00597 if(random(0,32)==0){ 00598 mobs_dir[thisMob] = rand()%4; 00599 continue; 00600 } 00601 00602 //go in the direction on the player (randomly choose between X and Y axis) 00603 if(random(0,16)==0){ 00604 if(random(0,2)){ 00605 //get closer to the player on the X axis 00606 if((LCDWIDTH/2 - x) > 0){ //go to the left if the player is on the left 00607 mobs_dir[thisMob] = 3; 00608 } 00609 else{ // or go to the right if the player is on the right 00610 mobs_dir[thisMob] = 1; 00611 } 00612 } 00613 //if the distance between the player and the mob is larger on the Y axis 00614 else { 00615 //get closer to the player on the Y axis 00616 if((LCDHEIGHT/2 - y) > 0){ //go downward 00617 mobs_dir[thisMob] = 2; 00618 } 00619 else{ //go upward 00620 mobs_dir[thisMob] = 0; 00621 } 00622 } 00623 } 00624 } 00625 } 00626 } 00627 00628 ///////////////////////////////////// CHECK MOB COLLISIONS 00629 boolean checkMobCollisions(byte thisMob){ 00630 //check collision with the world 00631 if(collideWorld(mobs_x[thisMob], mobs_y[thisMob], mobs_size[thisMob], mobs_size[thisMob])) 00632 return true; 00633 //check collision with other mobs 00634 if(collideOtherMobs(thisMob)) 00635 return true; 00636 return false; 00637 } 00638 00639 00640 ///////////////////////////////////// CHECK IF A MOB COLLIDE ANOTHER ONE 00641 boolean collideOtherMobs(byte thisMob){ 00642 for(byte otherMob=0; otherMob<activeMobs; otherMob++){ 00643 if(thisMob == otherMob) //don't check collision with iself >_<' 00644 continue; 00645 if(gb.collideRectRect(mobs_x[thisMob], mobs_y[thisMob], mobs_size[thisMob], mobs_size[thisMob], 00646 mobs_x[otherMob], mobs_y[otherMob], mobs_size[otherMob], mobs_size[otherMob])){ 00647 return true; 00648 } 00649 } 00650 return false; 00651 } 00652 00653 ///////////////////////////////////// DRAW MOBS 00654 void drawMobs(){ 00655 gb.display.setColor(1); //8 00656 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ 00657 //int x = wrap(mobs_x[thisMob] - cameraX + playerW/2, WORLD_W*8); 00658 //int y = wrap(mobs_y[thisMob] - cameraY + playerH/2, WORLD_H*8); 00659 int x, y; 00660 if(screenCoord(mobs_x[thisMob], mobs_y[thisMob], x, y)){ 00661 if(mobs_size[thisMob] != boss_size) 00662 { 00663 gb.display.setColor(8); 00664 gb.display.drawBitmap(x-2, y-2, mobSprite, mobs_dir[thisMob], NOFLIP); 00665 } else 00666 { gb.display.setColor(9); 00667 gb.display.drawBitmap(x-1, y-1, bossSprite, mobs_dir[thisMob], NOFLIP); 00668 } 00669 //gb.fillRect(x, y, mobs_size[thisMob], mobs_size[thisMob], BLACK); 00670 } 00671 } 00672 } 00673 00674 ///////////////////////////////////// DAMAGE MOB 00675 void damageMob(byte thisMob, byte thisBullet){ 00676 mobs_life[thisMob] -= weapon_damage[bullets_weapon[thisBullet]]; 00677 //recoil 00678 byte recoil = weapon_ennemyRecoil[bullets_weapon[thisBullet]]; 00679 if(mobs_size[thisMob] == boss_size) 00680 recoil /= 4; 00681 moveXYDS(mobs_x[thisMob], mobs_y[thisMob], bullets_dir[thisBullet], recoil); 00682 if(checkMobCollisions(thisMob)) 00683 moveXYDS(mobs_x[thisMob], mobs_y[thisMob], bullets_dir[thisBullet], -recoil); 00684 mobs_dir[thisMob] = (bullets_dir[thisBullet] + 2) % 4; 00685 //gb.buzz(1200,10); 00686 if(mobs_life[thisMob] <= 0){ //the mob dies 00687 score++; 00688 kills++; 00689 boss_nextSpawn--; 00690 if(bullets_weapon[thisBullet]!=3){ //if it's no the RPG 00691 gb.sound.playPattern(mob_death_sound,0); 00692 } 00693 if(mobs_size[thisMob] == boss_size) 00694 score += 4; 00695 setSplash(mobs_x[thisMob], mobs_y[thisMob]); 00696 int x, y; 00697 if(screenCoord(mobs_x[thisMob], mobs_y[thisMob], x, y)){ 00698 gb.display.fillRect(x-1, y-1, mobs_size[thisMob]+1, mobs_size[thisMob]+1); 00699 } 00700 //gb.buzz(1400,20); 00701 spawnMob(thisMob); 00702 if(activeMobs < NUMMOBS){ //if the max isn't reached 00703 if(activeMobs < (kills/MOBSRATE)+INITNUMMOBS){ //every 8 mobs killed 00704 activeMobs++; //add a mob 00705 spawnMob(activeMobs-1); //spawn the mob added 00706 } 00707 } 00708 } 00709 else { //the mob survives 00710 } 00711 } 00712 00713 00714 00715 #define PAUSEMENULENGTH 5 00716 const char strPlay[] PROGMEM = "Play"; 00717 const char strRestart[] PROGMEM = "Restart"; 00718 const char strHighScores[] PROGMEM = "High scores"; 00719 const char strSystemInfo[] PROGMEM = "System Info"; 00720 const char strMainMenu[] PROGMEM = "Main Menu"; 00721 00722 00723 const char* const pauseMenu[PAUSEMENULENGTH] PROGMEM = { 00724 strPlay, 00725 strRestart, 00726 strHighScores, 00727 strSystemInfo, 00728 strMainMenu 00729 }; 00730 00731 ///////////////////////////////////// PAUSE 00732 void pausem(){ 00733 while(gb.isRunning()){ 00734 if(gb.update()){ 00735 switch(gb.menu(pauseMenu, PAUSEMENULENGTH)){ 00736 case 0: //resume 00737 gb.wait(100); 00738 gb.display.setFont(font3x5); 00739 play(); 00740 gb.display.setFont(font5x7); 00741 gb.battery.show = true; 00742 break; 00743 case 1: //restart 00744 initGame(); 00745 gb.display.setFont(font3x5); 00746 play(); 00747 gb.display.setFont(font5x7); 00748 gb.battery.show = true; 00749 return; 00750 case 2: //high scores 00751 displayHighScores(); 00752 break; 00753 case 3: //System info 00754 gb.display.setFont(font3x5); 00755 while (1) { 00756 if (gb.update()) { 00757 if (gb.buttons.pressed(BTN_C)) { 00758 gb.display.setFont(font5x7); 00759 gb.sound.playCancel(); 00760 break; 00761 } 00762 //gb.display.setCursor(0, 0); 00763 gb.display.print(("Bat:")); 00764 gb.display.print(gb.battery.voltage); 00765 gb.display.println(("mV")); 00766 00767 gb.display.print(("Bat lvl:")); 00768 gb.display.print(gb.battery.level); 00769 gb.display.println(("/4")); 00770 00771 gb.display.print(("Light:")); 00772 gb.display.println(gb.backlight.ambientLight); 00773 00774 gb.display.print(("Backlight:")); 00775 gb.display.println(gb.backlight.backlightValue); 00776 00777 gb.display.print(("Volume:")); 00778 gb.display.print(gb.sound.getVolume()); 00779 //gb.display.print(F("/")); 00780 //gb.display.println(gb.sound.volumeMax); 00781 00782 gb.display.print("Mobs:"); 00783 gb.display.print(activeMobs); 00784 gb.display.print("/"); 00785 gb.display.println(NUMMOBS); 00786 00787 gb.display.print("Killed:"); 00788 gb.display.println(kills); 00789 } 00790 } 00791 break; 00792 case 4: //change game 00793 //gb.changeGame(); 00794 gb.titleScreen(logo); 00795 break; 00796 default: 00797 return; 00798 } 00799 } 00800 } 00801 } 00802 00803 ///////////////////////////////////// DISPLAY HIGHSCORES 00804 void displayHighScores(){ 00805 while(true){ 00806 if(gb.update()){ 00807 gb.display.cursorX = 9+random(0,2); 00808 gb.display.cursorY = 0+random(0,2); 00809 gb.display.println(("HIGH SCORES")); 00810 gb.display.textWrap = false; 00811 gb.display.cursorX = 0; 00812 gb.display.cursorY = gb.display.fontHeight; 00813 for(byte thisScore=0; thisScore<RANKMAX; thisScore++){ 00814 if(highscore[thisScore]==0) 00815 gb.display.print('-'); 00816 else 00817 gb.display.print(name[thisScore]); 00818 gb.display.cursorX = LCDWIDTH-3*gb.display.fontWidth; 00819 gb.display.cursorY = gb.display.fontHeight+gb.display.fontHeight*thisScore; 00820 gb.display.println(highscore[thisScore]); 00821 } 00822 if(gb.buttons.pressed(BTN_A) || gb.buttons.pressed(BTN_B) || gb.buttons.pressed(BTN_C)){ 00823 gb.sound.playOK(); 00824 break; 00825 } 00826 } 00827 } 00828 } 00829 00830 00831 00832 00833 ///////////////////////////////////// INIT GAME 00834 void initGame(){ 00835 //lastScore = score; 00836 if(score > highscore[RANKMAX-1]){ //if the score is better than the worse high score 00837 saveHighscore(); 00838 } 00839 //scoreDisplayTimeLeft = 64; 00840 score = 0; 00841 kills = 0; 00842 currentWeapon = 0; //magnum 00843 ammo = 9999; 00844 nextShot = 0; 00845 shake_timeLeft = 0; 00846 playerLife = playerLifeMax; 00847 boss_freq = BOSSFREQ; 00848 boss_nextSpawn = boss_freq; 00849 activeMobs = INITNUMMOBS; //6 initial mobs 00850 do{ 00851 do{ 00852 playerX = random(0, WORLD_W) * 8; 00853 playerY = random(0, WORLD_H) * 8; 00854 } 00855 while(collideWorld(playerX, playerY, playerW, playerH)); 00856 cameraX = playerX - LCDWIDTH/2 + playerW/2; 00857 cameraY = playerY - LCDHEIGHT/2 + playerW/2; 00858 } 00859 while(!spawnMobs()); //do that until mobs are spawned without error 00860 //spawn crate 00861 spawnCrate(); 00862 //reset bullets 00863 for(byte thisBullet = 0; thisBullet < NUMBULLETS; thisBullet++){ 00864 bullets_active[thisBullet] = false; 00865 } 00866 //reset splashes 00867 for(byte thisSplash = 0; thisSplash < NUMSPLASH; thisSplash++){ 00868 splash_active[thisSplash] = false; 00869 } 00870 blast_lifespan = 0; //reset explosion 00871 } 00872 00873 ///////////////////////////////////// PLAY 00874 void play(){ 00875 gb.battery.show = false; 00876 byte i = 0; 00877 while(i < 10 && gb.isRunning()){ 00878 if(gb.update()){ 00879 gb.display.fontSize = 2; 00880 gb.display.cursorX = 6; 00881 gb.display.cursorY = 16; 00882 gb.display.print(("LET'S GO!")); 00883 i++; 00884 } 00885 } 00886 gb.display.fontSize = 1; 00887 gb.popup(("\x15:shoot \x16:run"), 60); 00888 00889 while(gb.isRunning()){ 00890 if(gb.update()){ 00891 if(gb.buttons.pressed(BTN_C)){ 00892 gb.sound.playCancel(); 00893 return; 00894 //gb.battery.show = true; 00895 //pause(); 00896 //gb.battery.show = false; 00897 } 00898 boolean moved = false; 00899 if(gb.buttons.repeat(BTN_RIGHT, 1)){ 00900 playerDir = 3; 00901 moved = true; 00902 } 00903 else{ 00904 if(gb.buttons.repeat(BTN_LEFT, 1)){ 00905 playerDir = 1; 00906 moved = true; 00907 } 00908 } 00909 if(gb.buttons.repeat(BTN_DOWN, 1)){ 00910 playerDir = 2; 00911 moved = true; 00912 } 00913 else{ 00914 if(gb.buttons.repeat(BTN_UP, 1)){ 00915 playerDir = 0; 00916 moved = true; 00917 } 00918 } 00919 if(moved){ 00920 moveXYDS(playerX, playerY, playerDir, playerSpeed); 00921 if(collideWorld(playerX, playerY, playerW, playerH)) 00922 moveXYDS(playerX, playerY, playerDir, -playerSpeed); 00923 } 00924 cameraX = playerX + playerW/2 - LCDWIDTH/2; 00925 cameraY = playerY + playerH/2 - LCDHEIGHT/2; 00926 shakeScreen(); 00927 /* 00928 gb.display.setColor(7); // shrub shadow 00929 drawWorld(cameraX-3, cameraY-3); 00930 gb.display.setColor(5); // shrubs 00931 drawWorld(cameraX, cameraY); 00932 */ 00933 int x, y; 00934 screenCoord(playerX, playerY, x, y); 00935 //gb.display.setColor(10); //shadow 00936 int8_t ox=0,oy=0; 00937 ox--; 00938 //gb.display.drawBitmap(x+ox, y+oy, playerSprite, playerDir, NOFLIP); 00939 gb.display.setColor(3); //magenta 00940 gb.display.drawBitmap(x, y, playerSprite, playerDir, NOFLIP); 00941 byte thisSprite = 0; 00942 moveMobs(); 00943 drawMobs(); 00944 if(nextShot) 00945 nextShot--; 00946 if(gb.buttons.repeat(BTN_A, 1) && !gb.buttons.repeat(BTN_B, 1)){ 00947 shoot(); 00948 } 00949 if (gb.buttons.repeat(BTN_B, 1)){ 00950 playerSpeed = 2; 00951 } 00952 else { 00953 playerSpeed = 1; 00954 } 00955 moveBullets(); 00956 drawBullets(); 00957 explode(); 00958 gb.display.setColor(4); 00959 drawSplashes(); 00960 collideCrate(); 00961 drawCrate(); 00962 /** DRAW WORLD**/ 00963 //gb.display.setColor(7); // shrub shadow 00964 //drawWorld(cameraX-2, cameraY-2); 00965 gb.display.setColor(5); // shrubs 00966 drawWorld(cameraX, cameraY); 00967 //life remaining 00968 for(byte i=0; i<=playerLifeMax/2; i+=1){ 00969 if((i*2)<=playerLife){ 00970 gb.display.setColor(4); 00971 gb.display.drawBitmap(LCDWIDTH-i*9+2, 0, fullHeart); 00972 } 00973 else{ 00974 gb.display.setColor(0,0); 00975 gb.display.drawBitmap(LCDWIDTH-i*9+2, 0, fullHeart); 00976 gb.display.setColor(4,0); 00977 gb.display.drawBitmap(LCDWIDTH-i*9+2, 0, emptyHeart); 00978 } 00979 } 00980 if(!playerLife){ 00981 if((gb.frameCount%2)==0){ 00982 shake_magnitude = 2; 00983 shake_timeLeft = 1; 00984 } 00985 } 00986 else{ 00987 if(playerLife == 1){ 00988 shake_magnitude = 1; 00989 shake_timeLeft = 1; 00990 } 00991 } 00992 00993 if(playerLife%2){ //odd number 00994 gb.display.setColor(4,0); 00995 gb.display.drawBitmap(LCDWIDTH-(playerLife/2+1)*9+2, 0, halfHeart); 00996 } 00997 00998 drawAmmoOverlay(); 00999 01000 displayScore(); 01001 for(byte thisMob=0; thisMob<activeMobs; thisMob++){ 01002 if(gb.collideRectRect(mobs_x[thisMob],mobs_y[thisMob], mobs_size[thisMob], mobs_size[thisMob], 01003 playerX, playerY, playerW, playerH)){ 01004 playerLife--; 01005 //pokConsoleAddMessage(MSG_PRINT,V_INT16,playerLife); 01006 shake_magnitude = 2; 01007 shake_timeLeft = 4; 01008 if(mobs_size[thisMob] == boss_size){ 01009 playerLife--; 01010 shake_magnitude = 3; 01011 shake_timeLeft = 4; 01012 } 01013 //int hazefactor = (255-42*playerLife)*2/3; 01014 //for (uint16_t k =0 ; k<16; k++) hazepalette[k] = pokInterpolateColor(palette[k],palette[4],hazefactor); 01015 gb.sound.playPattern(player_damage_sound, 0); 01016 spawnMob(thisMob); 01017 if(playerLife < 0){ 01018 byte timer=0; 01019 while(1){ 01020 if(gb.update()){ 01021 //gb.display.setColor(1); 01022 drawMobs(); 01023 drawBullets(); 01024 drawSplashes(); 01025 drawCrate(); 01026 drawAmmoOverlay(); 01027 displayScore(); 01028 drawWorld(cameraX, cameraY); 01029 gb.display.drawBitmap(x-1, y-1, playerSprite, playerDir, NOFLIP); 01030 gb.display.setColor(WHITE); 01031 gb.display.fillRect(0,0,timer*2,LCDHEIGHT); 01032 gb.display.fillRect(LCDWIDTH-timer*2,0,timer*2,LCDHEIGHT); 01033 gb.display.setColor(BLACK, WHITE); 01034 gb.display.cursorX = 12; 01035 gb.display.cursorY = 1; 01036 gb.display.print(("GAME OVER!")); 01037 timer++; 01038 if(timer==((LCDWIDTH/4)+10)) 01039 break; 01040 } 01041 //int hazefactor = 0; 01042 //for (uint16_t k =0 ; k<16; k++) hazepalette[k] = pokInterpolateColor(palette[k],palette[4],hazefactor); 01043 } 01044 while(1){ 01045 if(gb.update()){ 01046 if(score > highscore[RANKMAX-1]){ //if the score is better than the worse high score 01047 gb.display.cursorX = 2+rand()%2; 01048 gb.display.cursorY = 0+rand()%2; 01049 gb.display.print(("NEW HIGHSCORE")); 01050 } 01051 else{ 01052 gb.display.cursorX = 12; 01053 gb.display.cursorY = 1; 01054 gb.display.print(("GAME OVER!")); 01055 } 01056 gb.display.cursorX = 0; 01057 gb.display.cursorY = 12; 01058 gb.display.print(("You made $")); 01059 gb.display.print(score); 01060 gb.display.print(("\nby killing\n")); 01061 gb.display.print(kills); 01062 gb.display.print((" crabs.")); 01063 gb.display.cursorX = 0; 01064 gb.display.cursorY = 40; 01065 gb.display.print(("\x15:accept")); 01066 if(gb.buttons.pressed(BTN_A)){ 01067 gb.sound.playOK(); 01068 break; 01069 } 01070 } 01071 } 01072 initGame(); 01073 break; 01074 } 01075 } 01076 } 01077 01078 } 01079 } 01080 } 01081 01082 ///////////////////////////////////// DISPLAY SCORE 01083 void displayScore(){ 01084 // blue on bottom 01085 /* gb.display.setColor(10); 01086 gb.display.cursorX = -1; 01087 gb.display.cursorY = -1; 01088 gb.display.print('$'); 01089 gb.display.println(score); 01090 gb.display.cursorX = 0; 01091 gb.display.cursorY = -1; 01092 gb.display.print('$'); 01093 gb.display.println(score); 01094 gb.display.cursorX = 1; 01095 gb.display.cursorY = -1; 01096 gb.display.print('$'); 01097 gb.display.println(score); 01098 gb.display.cursorX = -1; 01099 gb.display.cursorY = 0; 01100 gb.display.print('$'); 01101 gb.display.println(score); 01102 gb.display.cursorX = 0; 01103 gb.display.cursorY = 1; 01104 gb.display.print('$'); 01105 gb.display.println(score); 01106 gb.display.cursorX = -1; 01107 gb.display.cursorY = 1; 01108 gb.display.print('$'); 01109 gb.display.println(score); 01110 gb.display.cursorX = 0; 01111 gb.display.cursorY = 1; 01112 gb.display.print('$'); 01113 gb.display.println(score); 01114 gb.display.cursorX = 1; 01115 gb.display.cursorY = 1; 01116 gb.display.print('$'); 01117 gb.display.println(score); 01118 gb.display.cursorX = 1; 01119 gb.display.cursorY = 0; 01120 gb.display.print('$'); 01121 gb.display.println(score);*/ 01122 // white on top 01123 gb.display.setColor(8); 01124 gb.display.cursorX = 0; 01125 gb.display.cursorY = 0; 01126 gb.display.print('$'); 01127 gb.display.println(score); 01128 } 01129 01130 ///////////////////////////////////// SHAKE SCREEN 01131 void shakeScreen(){ 01132 if(shake_timeLeft){ 01133 shake_timeLeft--; 01134 cameraX += random(-shake_magnitude,shake_magnitude+1); 01135 cameraY += random(-shake_magnitude,shake_magnitude+1); 01136 byte backlightStep = gb.backlight.backlightMax / 4; 01137 gb.backlight.set(gb.backlight.backlightValue-random(0,backlightStep*shake_magnitude)); 01138 } 01139 } 01140 01141 ///////////////////////////////////// LOAD HIGHSCORE 01142 void loadHighscore(){ 01143 /* 01144 for(byte thisScore = 0; thisScore < RANKMAX; thisScore++){ 01145 for(byte i=0; i<NAMELENGTH; i++){ 01146 name[thisScore][i] = EEPROM.read(i + thisScore*(NAMELENGTH+2)); 01147 } 01148 highscore[thisScore] = EEPROM.read(NAMELENGTH + thisScore*(NAMELENGTH+2)) & 0x00FF; //LSB 01149 highscore[thisScore] += (EEPROM.read(NAMELENGTH+1 + thisScore*(NAMELENGTH+2)) << 8) & 0xFF00; //MSB 01150 highscore[thisScore] = (highscore[thisScore]==0xFFFF) ? 0 : highscore[thisScore]; 01151 }*/ //jonnehw 01152 } 01153 01154 ///////////////////////////////////// SAVE HIGHSCORE 01155 void saveHighscore(){ 01156 //gb.getDefaultName(name[RANKMAX-1]); 01157 gb.display.setFont(font5x7); 01158 gb.keyboard(name[RANKMAX-1], NAMELENGTH+1); 01159 highscore[RANKMAX-1] = score; 01160 for(byte i=RANKMAX-1; i>0; i--){ //bubble sorting FTW 01161 if(highscore[i-1] < highscore[i]){ 01162 char tempName[NAMELENGTH]; 01163 strcpy(tempName, name[i-1]); 01164 strcpy(name[i-1], name[i]); 01165 strcpy(name[i], tempName); 01166 unsigned int tempScore; 01167 tempScore = highscore[i-1]; 01168 highscore[i-1] = highscore[i]; 01169 highscore[i] = tempScore; 01170 } 01171 else{ 01172 break; 01173 } 01174 } 01175 /* 01176 for(byte thisScore = 0; thisScore < RANKMAX; thisScore++){ 01177 for(byte i=0; i<NAMELENGTH; i++){ 01178 EEPROM.write(i + thisScore*(NAMELENGTH+2), name[thisScore][i]); 01179 } 01180 EEPROM.write(NAMELENGTH + thisScore*(NAMELENGTH+2), highscore[thisScore] & 0x00FF); //LSB 01181 EEPROM.write(NAMELENGTH+1 + thisScore*(NAMELENGTH+2), (highscore[thisScore] >> 8) & 0x00FF); //MSB 01182 }*/// jonnehw 01183 displayHighScores(); 01184 } 01185 01186 01187 01188 const byte PROGMEM logo[] = 01189 { 01190 64,36, //width and height 01191 B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, 01192 B10000000, B00000000, B00000000, B00000000, B00000000, B00000001, B01000001, B01000001, 01193 B10000000, B00000000, B00000001, B10000000, B00000110, B00000100, B00010100, B00010001, 01194 B10000000, B00000000, B00000001, B10000000, B00000110, B00000000, B10000000, B10000001, 01195 B10000000, B00000000, B00000001, B10000000, B00000110, B00000000, B00000000, B01000001, 01196 B10001111, B00111111, B01111001, B10111001, B11101111, B10011110, B01111110, B00010001, 01197 B10011001, B10111011, B11001101, B11111011, B00110110, B00110011, B01110110, B00100001, 01198 B10011001, B10110011, B00001101, B10011000, B00110110, B00110011, B01100110, B01000101, 01199 01200 B10011000, B00110000, B01111101, B10011001, B11110110, B00110011, B01100000, B00000011, 01201 B10011000, B00110000, B11001101, B10011011, B00110110, B00110011, B01100001, B01000001, 01202 B10011000, B00110000, B11001101, B10011011, B00110110, B00110011, B01100100, B00010101, 01203 B10011001, B10110000, B11011101, B10011011, B01110110, B00110011, B01100000, B10001001, 01204 B11001111, B00110000, B11111101, B11110011, B11110011, B10011110, B01100000, B01000001, 01205 B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000101, B00010101, 01206 B10100000, B00000000, B00000000, B00000000, B00000000, B00100000, B10000000, B10100001, 01207 B11000000, B00000000, B00011000, B00001100, B00000000, B00000000, B00001111, B11110101, 01208 01209 B10010000, B00000000, B00100100, B01010010, B10000000, B11110000, B00001000, B00010011, 01210 B11010000, B00000010, B10101100, B01010110, B10000001, B11111000, B00001111, B11110001, 01211 B10011001, B01000011, B00110100, B11011010, B11100001, B11111000, B00001010, B00110101, 01212 B10010101, B01000010, B00100101, B01010010, B10000001, B11111000, B00001100, B01011001, 01213 B11011101, B11000010, B00011001, B11001100, B01100001, B01101000, B00001111, B11110001, 01214 B10000000, B01000000, B00000000, B00000000, B00000000, B11110000, B00001000, B00010101, 01215 B10000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00001111, B11110001, 01216 B11000000, B00000000, B00000000, B00000000, B00000110, B00000000, B00000000, B00000101, 01217 01218 B10000000, B00000000, B00000000, B00000000, B00001111, B00000000, B00000000, B00000011, 01219 B11000000, B00000000, B00000000, B00000000, B00000110, B00000000, B00000000, B00000001, 01220 B10010000, B00000000, B00000000, B00000000, B00001001, B00000000, B00000000, B00000101, 01221 B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00001001, 01222 B11000001, B01000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001, 01223 B10010011, B11010000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000101, 01224 B10100011, B11100000, B00000000, B00000000, B00000000, B00000110, B00000000, B00000001, 01225 B10000011, B11100000, B00000101, B01000101, B01000000, B00001111, B00000101, B01000101, 01226 01227 B10000011, B11010000, B00000010, B00000010, B00000000, B00000110, B00000010, B00000011, 01228 B10000001, B01000000, B00000001, B01000001, B01000000, B00001001, B00000001, B01000001, 01229 B10000000, B00000000, B00000100, B00010100, B00010000, B00000000, B00000100, B00010101, 01230 B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, 01231 }; 01232 01233 const byte PROGMEM world[]= 01234 { 01235 B11001111,B11001111, 01236 B10000000,B01000000, 01237 B00000001,B11111100, 01238 B00111001,B11100000, 01239 B00001100,B00000110, 01240 B10000111,B00011111, 01241 B11000011,B11000001, 01242 B10000001,B00000001, 01243 B00111100,B00110011, 01244 B00000111,B11100000, 01245 B10000100,B00001001, 01246 B11000001,B11001111, 01247 }; 01248 const byte PROGMEM tiles[]= 01249 { 01250 8,8, 01251 B01010100, 01252 B00100000, 01253 B00010100, 01254 B01000001, 01255 B10001000, 01256 B00000100, 01257 B01010001, 01258 B00001010, 01259 }; 01260 const byte PROGMEM mobSprite[]= 01261 { 01262 8,8, 01263 B00000000, 01264 B00000000, 01265 B00011000, 01266 B00111100, 01267 B00011000, 01268 B00100100, 01269 B00000000, 01270 B00000000, 01271 }; 01272 const byte PROGMEM bossSprite[]= 01273 { 01274 8,8, 01275 B00000000, 01276 B00100100, 01277 B00011000, 01278 B01111110, 01279 B00111100, 01280 B01111110, 01281 B00111100, 01282 B00000000, 01283 }; 01284 const byte PROGMEM playerSprite[]= 01285 { 01286 8,8, 01287 B00000000, 01288 B00111100, 01289 B01011010, 01290 B01111110, 01291 B01111110, 01292 B01111110, 01293 B00111100, 01294 B00000000, 01295 }; 01296 const byte PROGMEM splashSprite[]= 01297 { 01298 8,8, 01299 B00000000, 01300 B00001000, 01301 B00000000, 01302 B00011000, 01303 B00111000, 01304 B10110100, 01305 B00000000, 01306 B00010000, 01307 }; 01308 const byte PROGMEM crateSprite[]= 01309 { 01310 8,8, 01311 B11111111, 01312 B10000001, 01313 B11111111, 01314 B10100011, 01315 B11000101, 01316 B11111111, 01317 B10000001, 01318 B11111111, 01319 }; 01320 const byte PROGMEM fullHeart[]= 01321 { 01322 8,8, 01323 B01101100, 01324 B11111110, 01325 B11111110, 01326 B01111100, 01327 B00111000, 01328 B00010000, 01329 B00000000, 01330 B00000000, 01331 }; 01332 const byte PROGMEM halfHeart[]= 01333 { 01334 8,8, 01335 B00000000, 01336 B00001100, 01337 B00011100, 01338 B00011000, 01339 B00010000, 01340 B00000000, 01341 B00000000, 01342 B00000000, 01343 }; 01344 const byte PROGMEM emptyHeart[]= 01345 { 01346 8,8, 01347 B01101100, 01348 B10010010, 01349 B10000010, 01350 B01000100, 01351 B00101000, 01352 B00010000, 01353 B00000000, 01354 B00000000, 01355 }; 01356 01357 01358 01359 ///////////////////////////////////// GET TILE 01360 boolean getTile(uint8_t i, uint8_t j){ 01361 01362 uint8_t test; 01363 test = (pgm_read_byte(world + (j%WORLD_H)*byteWidth + (i%WORLD_W)/8) & (B10000000 >> (i % 8))); 01364 if(test) 01365 return true; 01366 else 01367 return false; 01368 } 01369 01370 ///////////////////////////////////// DRAW WORLD 01371 void drawWorld(int16_t x, int16_t y){ 01372 int8_t i, j, 01373 w = WORLD_W, 01374 h = WORLD_H; 01375 x = wrap(x,w*8); 01376 y = wrap(y,h*8); 01377 for(j=y/8; j < (LCDHEIGHT/8 + y/8 + 1); j++) { 01378 for(i=x/8; i < (LCDWIDTH/8 + x/8 + 1); i++ ) { 01379 if(getTile(i, j)) { 01380 gb.display.drawBitmap(i*8 - x, j*8 - y, tiles); 01381 } 01382 } 01383 } 01384 } 01385 01386 ///////////////////////////////////// COLLIDE WORLD 01387 boolean collideWorld(int16_t x, int16_t y, uint8_t w, uint8_t h){ 01388 if(getTile(x/8, y/8)) 01389 return true; 01390 if(getTile((x+w-1)/8, y/8)) 01391 return true; 01392 if(getTile((x+w-1)/8, (y+h-1)/8)) 01393 return true; 01394 if(getTile(x/8, (y+h-1)/8)) 01395 return true; 01396 return false; 01397 } 01398
Generated on Wed Jul 13 2022 19:58:18 by 1.7.2