import ddf.minim.*; /** * Game 41: "Circus Peanuts: Jam edition"
* Press Enter to start.
* X = sword, Z = rocks, A = bombs, arrow keys = move, P = pause, M = mute.
*
Go play more games at NMcCoy.net!
* * Creative Commons License
This work by Nathan McCoy is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. **/ // */ boolean cheat = false; boolean[] keys = new boolean[256]; boolean title; boolean paused; boolean muted; int drawing_ms_last; int physics_ms_last; int CORE_FPS = 540; int DRAWING_FPS = 60; int PHYSICS_FPS = 180; int DRAW_MS = 1000 / DRAWING_FPS; int PHYS_MS = 1000 / PHYSICS_FPS; int game_mode = -1; int PC_MAX_LIFE = 6; int pc_life; int BASIC_SPRITE_RADIUS = 20; float SMOOTH_GROUND_THRESH = 2; color SAND_COLOR = color(247, 215, 164); color[] floor_color = {color(160, 225, 120), color(120, 200, 90), color(255, 225, 174), color(235, 205, 150), color(128, 128, 128), color(108, 128, 108), color(108, 88, 88)}; color[] wall_color = {color(192, 192, 192), color(192, 192, 192),color(192, 192, 192),color(192, 192, 192),color(192, 192, 192),color(192, 192, 192),color(192, 192, 192)}; PVector pc_facing; int SWORD_TIME = 30; int SWORD_SPIN_TIME = 60; boolean has_16bit_sword; boolean has_spin_attack; boolean has_bombs; boolean has_slingshot; int carried_bombs; int carried_rocks; int max_bombs; int max_rocks; int START_BOMBS = 5; int START_ROCKS = 10; int sword_power; Minim minim; AudioSample swordSound; AudioSample bushSound; AudioSample peanutSound; AudioSample heartSound; AudioSample painSound; AudioSample killSound; AudioSample hitSound; AudioSample gotSound; AudioSample secretSound; AudioSample blonkSound; AudioSample rockSound; AudioSample bombSound; AudioSample rubbleSound; AudioSample downSound; AudioSample upSound; AudioSample chargeSound; AudioSample spinSound; AudioSample shineSound; void audioInit() { minim = new Minim(this); swordSound = minim.loadSample("sword.wav", 1024); bushSound = minim.loadSample("bush.wav", 1024); peanutSound = minim.loadSample("peanut.wav", 1024); heartSound = minim.loadSample("heart.wav", 1024); painSound = minim.loadSample("pain.wav", 1024); killSound = minim.loadSample("kill.wav", 1024); hitSound = minim.loadSample("hit.wav", 1024); gotSound = minim.loadSample("gotathing.wav", 1024); secretSound = minim.loadSample("secret.wav", 1024); blonkSound = minim.loadSample("blonk.wav", 1024); rockSound = minim.loadSample("rock.wav", 1024); bombSound = minim.loadSample("bomb.wav", 1024); rubbleSound = minim.loadSample("rubble.wav", 1024); upSound = minim.loadSample("stairsup.wav", 1024); downSound = minim.loadSample("stairsdown.wav", 1024); chargeSound = minim.loadSample("swordcharge.wav", 1024); spinSound = minim.loadSample("spin.wav", 1024); shineSound = minim.loadSample("shine.wav", 1024); } void audioClose() { minim.stop(); swordSound.close(); bushSound.close(); peanutSound.close(); heartSound.close(); painSound.close(); killSound.close(); hitSound.close(); gotSound.close(); secretSound.close(); blonkSound.close(); rockSound.close(); bombSound.close(); rubbleSound.close(); upSound.close(); downSound.close(); chargeSound.close(); spinSound.close(); shineSound.close(); } GameList stuff = new GameList(); GameList sprites = new GameList(); ArrayList blocks = new ArrayList(); ArrayList done_rooms = new ArrayList(); PlayerSprite pc; int pc_busy_timer; int room_x; int room_y; int room_z; float DANGER_XY_SCALE = 0.3; float DANGER_Z_SCALE = PI; int DUNGEON_THRESH = 3; float roomDanger(int rmx, int rmy, int rmz) { return 7 * noise(rmx * DANGER_XY_SCALE + 128, rmy * DANGER_XY_SCALE + 128, rmz * DANGER_Z_SCALE + 128); } void buildRoom() { int x = room_x; int y = room_y; int z = room_z; int room_level = (int)roomDanger(x, y, z); if(room_level >= 6 && poi(x, y, z) != 0 && !done_rooms.contains(new PVector(x, y, z))) bgmLoopPolite("nasty_critter.mp3"); else if(room_level > DUNGEON_THRESH) bgmLoopPolite("obstinate_dungeon.mp3"); else bgmLoopPolite("peanut_field.mp3"); blocks.clear(); sprites.clear(); sprites.add(pc); blocks.addAll(transitionDecorations(x, y, z)); blocks.addAll(northWall(x, y, z)); blocks.addAll(southWall(x, y, z)); blocks.addAll(eastWall(x, y, z)); blocks.addAll(westWall(x, y, z)); blocks.addAll(nwCorner(x, y, z)); blocks.addAll(neCorner(x, y, z)); blocks.addAll(swCorner(x, y, z)); blocks.addAll(seCorner(x, y, z)); if(poi(x, y, z) == 0) spawnOrdinaryStuff(); else spawnSpecialStuff(); if(hasDown(x, y, z-1) && room_z > 0) sprites.add(new StairsUp()); } int random_step; int GEOGRAPHY = 0; int CHEST = 1; int STAIRS_DOWN = 2; int BOSS = 3; int SWORD_PEDESTAL = 4; int PLAIN = 0; int ALL_ENEMIES_DEAD = 1; int SECRET_SWITCH = 2; void giveSpecial() { randomSeed(6 + room_x + 256 * room_y + 65535 * room_z); int prize_peanuts = 1 + (int)random(hereLevel() + room_z * 2) + room_z; int type = int(random(3)); if(hereLevel() == 6) type = 3; if(type == 3) { PC_MAX_LIFE += 2; pc_life = PC_MAX_LIFE; particles.add(new PrizeParticle(1, LIFE)); } else if(type == 2 && max_bombs <= START_BOMBS * room_z) { max_bombs += START_BOMBS; carried_bombs += START_BOMBS; particles.add(new PrizeParticle(START_BOMBS, BOMBS)); } else if(type == 1 && max_rocks <= START_ROCKS * room_z) { max_rocks += START_ROCKS; carried_rocks += START_ROCKS; particles.add(new PrizeParticle(START_ROCKS, ROCKS)); } else { prize_peanuts *= 10; pc_score += prize_peanuts; particles.add(new PrizeParticle(prize_peanuts, PEANUTS)); } } boolean hasDown(int x, int y, int z) { if(poi(x, y, z) >= 1 && (int)roomDanger(x, y, z + 1) > DUNGEON_THRESH/*roomDanger(x, y, z)*/ && (int)roomDanger(x, y, z) > DUNGEON_THRESH) return true; else return false; } float roomScary(int x, int y, int z) { return(roomDanger(x, y, z) + z); } void spawnSpecialStuff() { randomSeed(8 + room_x + 256 * room_y + 65535 * room_z); int special_type = 0; if(hereLevel() == 0) special_type = SWORD_PEDESTAL; if(hereLevel() == 6) special_type = BOSS; else if(hereLevel() > DUNGEON_THRESH) { if(poi(room_x, room_y, room_z) >= 1) { if(hasDown(room_x, room_y, room_z)) special_type = STAIRS_DOWN; else special_type = CHEST; } else special_type = (int)random(2); } int special_trigger = (int)random(2); if(special_type == STAIRS_DOWN) { sprites.add(new StairsDown()); spawnOrdinaryStuff(); } if(special_type == SWORD_PEDESTAL) { if(sword_power < 2) { sprites.add(new SwordPowerup(width/2, height/2)); bgmStop(); } if(sword_power < 2 || done_rooms.contains(new PVector(room_x, room_y, room_z))) { blocks.add(new Decoration(width/2, height/2 + 4, width/6 + 8, height/8 + 8, color(162, 200, 162))); blocks.add(new Decoration(width/2, height/2, width/6, height/8, color(192, 230, 192))); blocks.add(new Decoration(width/2, height/2 + BASIC_SPRITE_RADIUS + 2, BASIC_SPRITE_RADIUS+4, BASIC_SPRITE_RADIUS/2 + 4, color(162, 200, 162))); blocks.add(new Decoration(width/2, height/2 + BASIC_SPRITE_RADIUS, BASIC_SPRITE_RADIUS, BASIC_SPRITE_RADIUS/2, color(212, 250, 212))); blocks.add(new Decoration(width/2, height/2 + BASIC_SPRITE_RADIUS, BASIC_SPRITE_RADIUS/8 + 2, BASIC_SPRITE_RADIUS/16, color(162, 200, 162))); } } if(done_rooms.contains(new PVector(room_x, room_y, room_z))) { if(special_type == CHEST || special_type == BOSS) blocks.add(new EmptyChest()); } else { if(special_type == BOSS) { blocks.add(new HidingChest()); sprites.add(new MegaSlime(width/2, height/2, 4)); blocks.add(new BossWall(width/2, 0, width/2, 4)); blocks.add(new BossWall(width/2, height, width/2, 4)); blocks.add(new BossWall(0, height/2, 4, height/2)); blocks.add(new BossWall(width, height/2, 4, height/2)); } if(special_type == CHEST) { if(special_trigger == ALL_ENEMIES_DEAD) { blocks.add(new HidingChest()); spawnFoes(hereLevel()*2 + room_z * 3); } else blocks.add(new FullChest()); } } } void spawnOrdinaryStuff() { randomSeed(8 + room_x + 256 * room_y + 65535 * room_z); int room_level = (int)roomDanger(room_x, room_y, room_z); if(room_level < DUNGEON_THRESH) { for(int x = -3; x <= 3; x++) for(int y = -3; y <= 3; y++) { float what = random(1); if(what < 0.03) blocks.add(new Boulder(width/2 + x * BASIC_SPRITE_RADIUS * 3, height/2 + y * BASIC_SPRITE_RADIUS * 3)); else if(what < 0.10) blocks.add(new Bush(width/2 + x * BASIC_SPRITE_RADIUS * 3, height/2 + y * BASIC_SPRITE_RADIUS * 3)); } } spawnFoes(hereLevel() + random(hereLevel() + room_z * 3)); } void spawnFoes(float difficulty) { if(hereLevel() > DUNGEON_THRESH) //dungeon enemies { if(difficulty > 100) {} else if(difficulty > 10) { sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 9.8) { sprites.add(new MetalSlime(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 8) { sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 7) { sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 6) { sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 5) { sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Bat(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 4) { sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); } } else //field enemies { if(difficulty > 100) {} else if(difficulty > 4) { sprites.add(new Copter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Copter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Copter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Copter(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 3.8) { sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 3.5) { sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 3) { sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new WanderDude(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 2.5) { sprites.add(new Spitter(random(width/2)+width/4, random(height/2)+height/4)); } else if(difficulty > 2) { sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); sprites.add(new Slime(random(width/2)+width/4, random(height/2)+height/4)); } } } float roomRandom(float x, float y, float z) { return noise(x * 0.23, y * 0.23, z*0.23 + random_step++); } ArrayList transitionDecorations(int rmx, int rmy, int rmz) { ArrayList wall_blocks = new ArrayList(); if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx, rmy-1, rmz)) { wall_blocks.add(new Decoration(width/2, 0, width/2, height/10, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx, rmy-1, rmz)], 0.25))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx, rmy+1, rmz)) { wall_blocks.add(new Decoration(width/2, height, width/2, height/10, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx, rmy+1, rmz)], 0.25))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx-1, rmy, rmz)) { wall_blocks.add(new Decoration(0, height/2, height/10, height, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx-1, rmy, rmz)], 0.25))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx+1, rmy, rmz)) { wall_blocks.add(new Decoration(width, height/2, height/10, height, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx+1, rmy, rmz)], 0.25))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx, rmy-1, rmz)) { wall_blocks.add(new Decoration(width/2, 0, width/2, height/30, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx, rmy-1, rmz)], 0.5))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx, rmy+1, rmz)) { wall_blocks.add(new Decoration(width/2, height, width/2, height/30, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx, rmy+1, rmz)], 0.5))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx-1, rmy, rmz)) { wall_blocks.add(new Decoration(0, height/2, height/32, height, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx-1, rmy, rmz)], 0.5))); } if((int)roomDanger(rmx, rmy, rmz) != (int)roomDanger(rmx+1, rmy, rmz)) { wall_blocks.add(new Decoration(width, height/2, height/32, height, blendColors(floor_color[(int)roomDanger(rmx, rmy, rmz)], floor_color[(int)roomDanger(rmx+1, rmy, rmz)], 0.5))); } return wall_blocks; } ArrayList nwCorner(int rmx, int rmy, int rmz) { ArrayList wall_blocks = new ArrayList(); if(!northWall(rmx, rmy, rmz).isEmpty() || !westWall(rmx, rmy, rmz).isEmpty() || !northWall(rmx-1, rmy, rmz).isEmpty() || !westWall(rmx, rmy-1, rmz).isEmpty()) wall_blocks.add(new Block(0, 0, height/8, height/8, B_SOLID)); return wall_blocks; } ArrayList neCorner(int rmx, int rmy, int rmz) { ArrayList wall_blocks = nwCorner(rmx + 1, rmy, rmz);; for(Block b : wall_blocks) b.pos.x += width; return wall_blocks; } ArrayList swCorner(int rmx, int rmy, int rmz) { ArrayList wall_blocks = nwCorner(rmx, rmy+1, rmz); for(Block b : wall_blocks) b.pos.y += height; return wall_blocks; } ArrayList seCorner(int rmx, int rmy, int rmz) { ArrayList wall_blocks = nwCorner(rmx+1, rmy+1, rmz); for(Block b : wall_blocks){b.pos.x += width; b.pos.y += height;} return wall_blocks; } int poi(int x, int y, int z) { float my_d = roomDanger(x, y, z); if(my_d > roomDanger(x-1, y-1, z) && my_d > roomDanger(x, y-1, z) && my_d > roomDanger(x+1, y-1, z) && my_d > roomDanger(x-1, y, z) && my_d > roomDanger(x+1, y, z) && my_d > roomDanger(x-1, y+1, z) && my_d > roomDanger(x, y+1, z) && my_d > roomDanger(x+1, y+1, z)) return 1; if(my_d < roomDanger(x-1, y-1, z) && my_d < roomDanger(x, y-1, z) && my_d < roomDanger(x+1, y-1, z) && my_d < roomDanger(x-1, y, z) && my_d < roomDanger(x+1, y, z) && my_d < roomDanger(x-1, y+1, z) && my_d < roomDanger(x, y+1, z) && my_d < roomDanger(x+1, y+1, z)) return -1; return 0; } ArrayList northWall(int rmx, int rmy, int rmz) { ArrayList wall_blocks = new ArrayList(); if(((int)roomDanger(rmx, rmy, rmz) > DUNGEON_THRESH && (int)roomDanger(rmx, rmy-1, rmz) <= DUNGEON_THRESH)) wall_blocks.add(new Block(width/2, 0, width/2, height/8, B_SOLID)); if(((int)roomDanger(rmx, rmy-1, rmz) > DUNGEON_THRESH && (int)roomDanger(rmx, rmy, rmz) <= DUNGEON_THRESH)) { float my_d = roomDanger(rmx, rmy, rmz); if(my_d > roomDanger(rmx-1, rmy, rmz) && my_d > roomDanger(rmx+1, rmy, rmz) && rmz == 0) { // wall_blocks.add(new DoorShade(width/2, 0, width/4, height/10)); // wall_blocks.add(new DoorShade(width/2, 0, width/4, height/30)); wall_blocks.add(new Block(width/5, 0, width/5, height/8, B_SOLID)); wall_blocks.add(new Block(width*4/5, 0, width/5, height/8, B_SOLID)); } else wall_blocks.add(new Block(width/2, 0, width/2, height/8, B_SOLID)); } return wall_blocks; } ArrayList westWall(int rmx, int rmy, int rmz) { ArrayList wall_blocks = new ArrayList(); if(((int)roomDanger(rmx, rmy, rmz) > DUNGEON_THRESH && (int)roomDanger(rmx-1, rmy, rmz) <= DUNGEON_THRESH)) wall_blocks.add(new Block(0, height/2, height/8, height/2, B_SOLID)); if(((int)roomDanger(rmx-1, rmy, rmz) > DUNGEON_THRESH && (int)roomDanger(rmx, rmy, rmz) <= DUNGEON_THRESH)) { wall_blocks.add(new Block(0, height/2, height/8, height/2, B_SOLID)); } return wall_blocks; } ArrayList southWall(int rmx, int rmy, int rmz) { ArrayList wall_blocks = new ArrayList(); wall_blocks.addAll(northWall(rmx, rmy+1, rmz)); for(Block b : wall_blocks) b.pos.y += height; return wall_blocks; } ArrayList eastWall(int rmx, int rmy, int rmz) { ArrayList wall_blocks = new ArrayList(); wall_blocks.addAll(westWall(rmx+1, rmy, rmz)); for(Block b : wall_blocks) b.pos.x += width; return wall_blocks; } void setup() { size(640, 560); frameRate(600); audioInit(); info_font = loadFont("PressStartK-16.vlw"); title = true; /* stuff.add(new Mote(new PVector(width/6 * 2, height * 2 / 3), M_RED)); stuff.add(new Mote(new PVector(width/6 * 3, height * 2 / 3), M_GREEN)); stuff.add(new Mote(new PVector(width/6 * 4, height * 2 / 3), M_BLUE)); */ // stuff.add(new Mote(new PVector(width/7 * 5, height * 2 / 3), M_PURPLE)); game_mode = 1; noiseSeed(113); room_x = 0; room_y = 0; room_z = 0; //newGame(); } int pc_score; ParticleList particles; boolean gameover; void newGame() { gameover = false; stuff = new GameList(); sprites = new GameList(); particles = new ParticleList(); blocks = new ArrayList(); stuff.clear(); blocks.clear(); sprites.clear(); done_rooms.clear(); pc = new PlayerSprite(); sprites.add(pc); blocks.add(new Block(width*2/3, height/2 + 100, 50, 50, B_SOLID)); blocks.add(new Block(width/2, height, width/2, height/8, B_SOLID)); title = false; room_x = 0; room_y = 0; room_z = 0; buildRoom(); pc_facing = new PVector(0, 1); has_16bit_sword = true; has_spin_attack = false; pc_score = 0; PC_MAX_LIFE = 6; pc_life = PC_MAX_LIFE; max_rocks = 0;//START_ROCKS; max_bombs = 0;//START_BOMBS; carried_rocks = max_rocks; carried_bombs = max_bombs; sword_power = 1; } void stop() { audioClose(); super.stop(); } int ctrl_x; int ctrl_y; ArrayList spawn_queue = new ArrayList(); int phys_frame; void physicsStep() { if(!title) { ctrl_x = 0; ctrl_y = 0; if(keys[LEFT]) ctrl_x--; if(keys[RIGHT]) ctrl_x++; if(keys[UP]) ctrl_y--; if(keys[DOWN]) ctrl_y++; if(game_mode == M_RED || game_mode == M_BLUE) if(keys['Z']) ctrl_y = -1; stuff.tick(); sprites.tick(); particles.tick(); sprites.addAll(spawn_queue); spawn_queue.clear(); for(Block b : blocks) { b.ejectSprites(); } if(pc.pos.x > width) {pc.pos.x -= width; room_x++; buildRoom();} if(pc.pos.y > height) {pc.pos.y -= height; room_y++; buildRoom();} if(pc.pos.x < 0) {pc.pos.x += width; room_x--; buildRoom();} if(pc.pos.y < 0) {pc.pos.y += height; room_y--; buildRoom();} if(floor_change == 1) {room_z ++; buildRoom();} if(floor_change == -1) {room_z --; buildRoom();} floor_change = 0; if(pc_life <= 0 && pc_busy_timer <= 0 && !gameover) { sprites.remove(pc); makePoof(pc.pos); if(!muted) killSound.trigger(); gameover = true; bgmStop(); } pc_busy_timer --; phys_frame++; //jukebox stuff info_time --; } } void rockDrop(float loot, PVector pos) { if(carried_rocks < max_rocks && random(2)<1) {spawn_queue.add(new RockPickup(pos.x, pos.y, ceil(loot/2) * 5)); return;} else randomDrop(loot, pos); } void bombDrop(float loot, PVector pos) { if(carried_bombs < max_bombs && random(2)<1) {spawn_queue.add(new BombPickup(pos.x, pos.y, (int)loot * 1)); return;} else randomDrop(loot, pos); } void randomDrop(float loot, PVector pos) { randomSeed(phys_frame); if(random(loot) > 3) {spawn_queue.add(new Peanut(pos.x, pos.y, 20)); return;} if(random(loot) > 2) {spawn_queue.add(new Peanut(pos.x, pos.y, 5)); return;} if(random(1) > 0.65 && pc_life < PC_MAX_LIFE && loot > 0) {spawn_queue.add(new Heart(pos.x, pos.y)); return;} if(random(loot) > 0.9) {spawn_queue.add(new Peanut(pos.x, pos.y, 1)); return;} } void drawingStep() { background(96,32,64); //if(game_mode == M_RED) background(123, 120, 255); //if(game_mode == M_GREEN) if((int)roomDanger(room_x, room_y, room_z) > 3) background(128); else background(SAND_COLOR); //if(game_mode == M_BLUE) background(0); background(floor_color[hereLevel()]); if(title) { drawTitle(); } for(Block b : blocks) b.draw(); sprites.draw(); if(!title) { particles.draw(); textFont(info_font, 8); fill(255); textAlign(LEFT, TOP); text("("+room_x+", "+room_y+", "+room_z+")", 8, 8); drawMiniMap(5); drawHUD(); } //jukebox stuff drawSongInfo(); } void drawHUD() { textFont(info_font, 16); textAlign(LEFT, TOP); fill(255); noStroke(); text("x"+pc_score, width/2, 8); rectMode(CORNER); fill(255, 160, 70); rect(width/2 - 18, 16, 8, 8); rect(width/2 - 10, 8, 8, 8); if(max_rocks > 0) { fill(192, 128, 64); rect(width/2 - 98, 8, 16, 16); fill(255); if(carried_rocks == max_rocks) fill(255, 255, 100); noStroke(); text("x"+carried_rocks, width/2 - 80, 8); } if(max_bombs > 0) { fill(100, 120, 190); rect(width/2 - 178, 8, 16, 16); fill(255); if(carried_bombs == max_bombs) fill(255, 255, 100); noStroke(); text("x"+carried_bombs, width/2 - 160, 8); } fill(255); textAlign(RIGHT, TOP); text("LIFE: ", width - PC_MAX_LIFE/2 * 16 - 8, 8); rectMode(CORNER); for(int x = 0; x < PC_MAX_LIFE/2; x++) { fill(255, 128); rect(width - PC_MAX_LIFE/2 * 16 - 8 + x * 16, 8, 14, 14); if(x < pc_life/2) { fill(160, 0, 32); rect(width - PC_MAX_LIFE/2 * 16 - 8 + x * 16, 8, 14, 14); } else if(x < (pc_life + 1)/2) { fill(160, 0, 32); rect(width - PC_MAX_LIFE/2 * 16 - 8 + x * 16, 8, 7, 14); } } if(gameover) { textFont(info_font, 32); textAlign(CENTER, CENTER); fill(0); text("GAME OVER", width/2, height/2); } } void drawTitle() { if(game_mode == M_RED) { background(123, 120, 255); rectMode(CORNER); noStroke(); fill(0, 116, 0); rect(0, height*6/9, width/3, height*3/8); fill(122, 192, 0); rect(width*3/4, height*7/9, width/4, height*2/9); fill(162, 92, 0); rect(0, height*7/8, width, height/8); } if(game_mode == M_GREEN) { background(250, 194, 192); rectMode(CORNER); noStroke(); fill(174, 234, 190); rect(0, height * 3/4, width, height * 1/4); fill(164, 164, 164); rect(0, height*2/9, width/8, height*7/9 + 2); //fill(174, 234, 190); rect(0, height*7/10, width*3/10 + 2, height*3/10 + 2); rect(width*4/9, height*8/11, width*5/9, height*3/11 + 2); rect(width*8/9, height*3/12, width*1/9+2, height*8/10); // fill(112, 53, 0); // rect(0, height*7/8, width, height/8); } if(game_mode == M_BLUE) { background(0); rectMode(CORNER); noStroke(); fill(164); rect(width*3/4, height/2, width*1/4, height/2); rect(width*2/3, height*2/3, width*1/3+2, height*1/3+2); } stuff.draw(); textFont(info_font, 32); textAlign(CENTER, CENTER); fill(255, 160, 70); text("CIRCUS PEANUTS", width/2, height/3); noStroke(); rectMode(CORNER); rect(width/2, height/2 -32, 32, 32); rect(width/2 - 32, height/2, 32, 32); } int hereLevel() { return (int)roomDanger(room_x, room_y, room_z); } void drawMiniMap(int sense_range) { int LEFT_EDGE = 8; int TOP_EDGE = 16; int CELL_W = 12; int CELL_H = 9; rectMode(CORNER); textFont(info_font, 8); textAlign(LEFT, TOP); for(int x = -sense_range; x <= sense_range; x++) for(int y = -sense_range; y <= sense_range; y++) { if((int)roomDanger(x + room_x, y+room_y, room_z) > DUNGEON_THRESH) fill(0, 32); else fill(255, 32); if(poi(x + room_x, y + room_y, room_z) != 0); if(x == 0 && y == 0) fill(0, 255, 0, 32); strokeWeight(1); stroke(255); if(!((int)roomDanger(x + room_x, y+room_y, room_z) > DUNGEON_THRESH) && room_z > 0) {} else { rect(LEFT_EDGE + (x+sense_range)*CELL_W, TOP_EDGE + (y+sense_range)*CELL_H, CELL_W, CELL_H); if(poi(x + room_x, y + room_y, room_z) != 0 && !done_rooms.contains(new PVector(x+room_x, y+room_y, room_z))) { noFill(); rect(LEFT_EDGE + (x+sense_range)*CELL_W + CELL_W/2-1, TOP_EDGE + (y+sense_range)*CELL_H + CELL_H/2-1, 3, 3); } if(hasDown(x + room_x, y + room_y, room_z)) { fill(0, 255, 255); rect(LEFT_EDGE + (x+sense_range)*CELL_W + CELL_W/2-1, TOP_EDGE + (y+sense_range)*CELL_H + CELL_H/2-1, 3, 3); } if(hasDown(x + room_x, y + room_y, room_z-1) && room_z > 0) { fill(255, 0, 255); rect(LEFT_EDGE + (x+sense_range)*CELL_W + CELL_W/2-1, TOP_EDGE + (y+sense_range)*CELL_H + CELL_H/2-1, 3, 3); } } //text((int)roomDanger(x+room_x, y+room_y, room_z), LEFT_EDGE + (x+sense_range)*CELL_W + 2, TOP_EDGE + (y+sense_range)*CELL_H + 2); } } void draw() { while(physics_ms_last + PHYS_MS < millis()) { if(!paused) { physicsStep(); } physics_ms_last += PHYS_MS; } if(drawing_ms_last + DRAW_MS < millis()) { drawingStep(); drawing_ms_last = millis(); } } void keyPressed() { if(keyCode < 256) if(!keys[keyCode]) { keys[keyCode] = true; down(keyCode); } } void keyReleased() { if(keyCode < 256) if(keys[keyCode]) { keys[keyCode] = false; up(keyCode); } } void down(int theKey) { println(theKey + " down"); if(theKey == 'M') jbToggleMute(); if(theKey == 'P' && !title) paused = !paused; if(gameover && theKey == ENTER && !title) { title = true; sprites.clear(); blocks.clear(); particles.clear(); } else if(title && theKey == ENTER && game_mode >= 0) newGame(); if(!title && !gameover && !paused && pc_busy_timer <= 0) { if(theKey == 'X') { pc.vel.x = pc.vel.y = 0; pc_busy_timer = SWORD_TIME; sprites.add(new SwordSwipe()); if(!muted) swordSound.trigger(); pc.sword_charge = 0; } if(theKey == 'Z' && carried_rocks > 0) { carried_rocks --; pc.vel.x = pc.vel.y = 0; pc_busy_timer = SWORD_TIME; sprites.add(new Rock(pc.pos, PVector.mult(pc_facing, 4), false)); if(!muted) blonkSound.trigger(); } if(theKey == 'A' && carried_bombs > 0) { carried_bombs --; pc.vel.x = pc.vel.y = 0; pc_busy_timer = SWORD_TIME; sprites.add(new Bomb(pc.pos.x, pc.pos.y)); if(!muted) blonkSound.trigger(); } if(theKey == '1' && cheat) { room_x = 42; room_y = 17; buildRoom(); } } } void up(int theKey) { println(theKey + " up"); if(!title && !gameover && !paused && pc_busy_timer <= 0) { if(theKey == 'X' && pc.sword_charge >= pc.SWORD_FULL_CHARGE) { pc.vel.x = pc.vel.y = 0; pc_busy_timer = SWORD_SPIN_TIME; sprites.add(new SwordSpin()); if(!muted) spinSound.trigger(); pc.sword_charge = -1; } } }