BImage tilesImg, characterImg, bgImg, logoImg, panelImg, levelCompleteImg; String levels[], bhlevels[], bhpractice[]; Level level; boolean onMenu = true; void setup() { size(320,200); framerate(20); tilesImg = loadImage("tiles.gif"); characterImg = loadImage("character.gif"); bgImg = loadImage("bg.gif"); logoImg = loadImage("logo.gif"); panelImg = loadImage("panel.gif"); levelCompleteImg = loadImage("levelcomplete.gif"); levels = bhlevels = loadStrings("bhlevels.txt"); bhpractice = loadStrings("bhpractice.txt"); hint (DISABLE_TEXT_SMOOTH); textFont( loadFont("verdana.vlw"), 16); loadLevel(-1); } void loadLevel(int di) { if (di<0) leveli=0; else leveli += di; int i=leveli*2; i++; level = new Level(levels[i], levels[i+1]); } float logoy=0,logody=0; int demoStep = 0; int demoPosition = 0; int leveli = 0; void loop() { if (onMenu && demoStep--<=0) { demoStep = 5; switch (levels[0].charAt(demoPosition++)) { case 'N': level.input(UP); break; case 'S': level.input(DOWN); break; case 'W': level.input(LEFT); break; case 'E': level.input(RIGHT); break; } if (level.foundExit) loadLevel(+1); if (demoPosition>=levels[0].length()) { demoPosition = 0; loadLevel(-1); } } level.update(); translate(20,20); level.draw(); translate(-20,-20); if (onMenu) { logody+=0.4; logoy+=logody; if (logoy>=150) { logoy=150; logody *= -0.5; } fill(255,255,255,128); noStroke(); rect(20,20,200,160); image (logoImg, 20, logoy-120); textMode(ALIGN_CENTER); fill(0); text("Click to start", 120,140); text("Keys: Arrows move/pickup", 120,150); text("R restarts level", 120,160); } for (int x=0;x<12;x++) { image(bgImg,x*20,0); image(bgImg,x*20,180); } for (int y=0;y<10;y++) { image(bgImg,0,y*20); image(bgImg,220,y*20); } image(panelImg, 240, 0); } void mousePressed() { if (onMenu) { onMenu = false; loadLevel(-1); } } public void keyPressed(KeyEvent e) { super.keyPressed(e); int code = e.getKeyCode(); if (onMenu) { onMenu = false; loadLevel(-1); } else level.input(code); } final static byte EMPTY = 0; final static byte EMPTY2 = 1; final static byte WALL = 2; final static byte DECAL = 3; final static byte WATER = 4; final static byte WATERTOP = 5; final static byte ITEM = 6; final static byte EXIT = 6; final static byte BOX = 7; final static byte BOX2 = 8; final static byte CLOCK = 9; final static byte PLAYER = 10; class Level { String name; int tileset = 0; int width, height; byte tiles[] = new byte[99*99]; byte items[] = new byte[99*99]; int viewx=0, viewy=0; Level(String info, String data) { tileset = info.charAt(0)-'0'; name = info.substring(4); int i = 0; int x = 0; int y = 0; while (iwidth) width = x; x=0; y++; height++; continue; case 'S': playerx=x; playery=y; x++; continue; case ' ': fill = EMPTY; break; case '.': fill = DECAL; break; case '#': fill = WALL; break; case 'W': fill = WATER; break; case 'w': fill = WATERTOP; break; case 'B': fill = BOX; break; case 'C': fill = CLOCK; break; case 'F': fill = EXIT; setView(x,y); break; } if (isNum(a)) { String count = ""+a; i++; if (isNum(b)) { count+=b; i++; } try { int length = Integer.parseInt(count,10); while (length-->0) { if (fill>=ITEM) setItem(x++,y,fill); else setTile(x++,y,fill); } } catch (Exception e) {} } else { if (fill>=ITEM) setItem(x++,y,fill); else setTile(x++,y,fill); } } } void setView(int x, int y) { viewx=x-5; viewy=y-4; if (viewx<0) viewx=0; if (viewx>width-11) viewx=width-11; if (viewy<0) viewy=0; if (viewy>height-8) viewy=height-8; } void slideView(int x, int y) { int vx = viewx+5; int vy = viewy+4; if (xvx) vx++; if (yvy) vy++; setView(vx,vy); } void setTile(int x, int y, byte type) { tiles[x+y*99] = type; } byte getTile(int x, int y) { if (x<0||y<0||x>=width||y>=height) return WALL; return tiles[x+y*99]; } void setItem(int x, int y, byte type) { items[x+y*99] = type; } byte getItem(int x, int y) { if (x<0||y<0||x>=width||y>=height) return 0; return items[x+y*99]; } boolean isNum(char c) { return c>='0' && c<='9'; } boolean isObstacle(int x, int y) { return getTile(x,y)==WALL || getItem(x,y)==BOX || getItem(x,y)==BOX2; } boolean isBlockObstacle(int x, int y) { return isObstacle(x,y) || getTile(x,y)==WATER; } boolean canPickup(int x, int y) { return (getItem(x,y)==BOX || getItem(x,y)==BOX2) && !isObstacle(x,y-1); } boolean facingRight = true; boolean holdingBox = false; int step = 0; int playerx = 0, playery = 0; boolean box2 = false; boolean foundExit = false; void update() { if (step>0) step--; slideView(playerx,playery); } void input(int key) { if (foundExit) { if (key==KeyEvent.VK_ENTER) loadLevel(+1); return; } int x; switch (key) { case UP: if (holdingBox) break; x = playerx + (facingRight?1:-1); if (canPickup(x,playery)) { box2 = getItem(x,playery)==BOX; setItem(x,playery,EMPTY); holdingBox = true; } break; case DOWN: if (!holdingBox) break; x = playerx + (facingRight?1:-1); if (!isBlockObstacle(x,playery-1)) { int y = isBlockObstacle(x,playery) ? playery-1 : playery; while (!isBlockObstacle(x,y+1)) y++; setItem(x,y,box2?BOX:BOX2); holdingBox = false; } break; case LEFT: step= step > 0 ? -3 : 3; if (!isObstacle(playerx-1,playery) && (!holdingBox || !isObstacle(playerx-1,playery-1))) playerx--; else if (!facingRight && !isObstacle(playerx-1,playery-1) && (!holdingBox || !isObstacle(playerx-1,playery-2))) { playerx--; playery--; } facingRight = false; break; case RIGHT: step= step > 0 ? -3 : 3; if (!isObstacle(playerx+1,playery) && (!holdingBox || !isObstacle(playerx+1,playery-1))) playerx++; else if (facingRight && !isObstacle(playerx+1,playery-1) && (!holdingBox || !isObstacle(playerx+1,playery-2))) { playerx++; playery--; } facingRight = true; break; case KeyEvent.VK_R: loadLevel(0); break; } while (!isObstacle(playerx,playery+1)) { checkPlayer(); playery++; } checkPlayer(); } void checkPlayer() { if (getItem(playerx,playery)==EXIT) foundExit = true; if (getItem(playerx,playery)==CLOCK) { setItem(playerx,playery,EMPTY); } } void drawTile(int x, int y, int tile) { image(tilesImg, 20*x, 20*y, 20, 20, tile*20, tileset*20, (tile+1)*20, (tileset+1)*20); } void drawCharacter(int x, int y, int tile) { image(characterImg, 20*x, 20*y, 20, 20, tile*20, tileset*20, (tile+1)*20, (tileset+1)*20); } void draw() { translate(-viewx*20,-viewy*20); for (int y=viewy; y0) frame++; if (!foundExit && holdingBox) { drawTile(playerx,playery-1,box2?BOX2:BOX); frame+=2; } drawCharacter(playerx,playery, frame); translate(viewx*20,viewy*20); if (foundExit) { fill(255,255,255,128); noStroke(); rect(0,0,200,160); image(levelCompleteImg, 0,0); fill(0); text("Press Enter to continue...", 100,130); } } }