advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement

Boulderdash


Java Source:

/*================================

          BOULDERDASH
         -------------
          Dave Koelle
          August 2000

http://www.ultranet.com/~dkoelle

Sound has been disabled for this
version to make the applet load
faster.  To bring back sound,
uncomment parts of redrawAndSound(),
redrawCoords(), init(), and three
instances of moveSound[].play()
=================================*/

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import java.lang.Thread;
import java.io.*;
import java.util.StringTokenizer;
import java.util.Vector;

class Coord {
    int x,y;

    public Coord() {
        x = 0;
        y = 0;
    }

    public Coord(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class BotPosition {
    int x,y;
    int heading,direction;

    public BotPosition() {
        x = 0;
        y = 0;
        heading = 1;
        direction = 0;
    }

    public BotPosition(int x, int y, int heading, int direction) {
        this.x = x;
        this.y = y;
        this.heading = heading;
        this.direction = direction;
    }
}

public class Boulderdash extends Applet implements Runnable {

  private static final String VERSION = "1.0";
  private static final String ID = "200009131200";

  Vector redraw = new Vector();
  Vector sounds = new Vector();
  Graphics g;
  Thread botThread;
  boolean paused;
  private static final int SLEEP_DELAY = 2750;
  int maxtimer=1,timer,level;
  int score,accumulatedScore,scorePerDiamond=5,scorePerExtraDiamond=10;
  public static final int UP     = 0;
  public static final int RIGHT  = 1;
  public static final int DOWN   = 2;
  public static final int LEFT   = 3;


  // Control buttons
  private Button buttonPrev     = new Button("< Prev");
  private Button buttonRestart  = new Button("Restart");
  private Button buttonNext     = new Button("Next >");

  // Game variables
  Coord coordPlayer,coordExit;
  int numNeededDiamonds,numFulfilledDiamonds;
  boolean levelDone,playerAlmostDead,playerDead;

  // Arrays to handle input from APPLET tag
  int[] arrNumNeededDiamonds,arrScorePerDiamond,arrScorePerExtraDiamond,arrMaxtimer;
  String[] arrLevelTitle,arrLevelAuthor,arrImageFilename;

  // Image and icon data
  private Image[] img;
  private static final int NUM_IMAGES = 15;
  private static final String imgRep = ".:#WMPO+*BFA][R";
  private String imageFilename = "images.gif";
  private static int[][] imgCoord =
    {{  0, 0,20,20},   // Space
     { 20, 0,20,20},   // Dirt
     { 40, 0,20,20},   // Titanium Wall
     {  0,20,20,20},   // Brick Wall
     { 20,20,20,20},   // Magic Wall
     { 40,20,20,20},   // Player
     {  0,40,20,20},   // Rock
     { 20,40,20,20},   // Diamond
     { 40,40,20,20},   // Explosion
     {  0,60,20,20},   // Butterfly
     { 20,60,20,20},   // Firefly
     { 40,60,20,20},   // Amoeba
     {  0,80,20,20},   // Closed Exit
     { 20,80,20,20},   // Open Exit
     { 40,80,20,20}};  // Robot (not programmed)

  // Sound data
  private static final int NUM_SOUNDS = 13;
  private static final int MOVE_MAGICWALL_SOUND        = 0;
  private static final int MOVE_ROCK_SOUND             = 1;
  private static final int MOVE_DIAMOND_SOUND          = 2;
  private static final int MOVE_OPENEXIT_SOUND         = 3;
  private static final int MOVE_AMOEBA_SOUND           = 4;
  private static final int MOVE_SMASH_SOUND            = 5;
  private static final int MOVE_NULL_SOUND             = 6;
  private static final int MOVE_DIRT_SOUND             = 7;
  private static final int MOVE_PLAYERSMASH_SOUND      = 8;
  private static final int MOVE_DIED_SOUND             = 9;
  private static final int MOVE_CONGRATULATIONS_SOUND  = 10;
  private static final int MOVE_COMPLETE_SOUND         = 11;
  private static final int MOVE_ROCK2_SOUND            = 12;

  private static String[] soundFilename =
    {"magicwall.wav", "rock.wav", "diamond.au", "openexit.wav", "amoeba.au", "smash.au",
     "null.au", "dirt.au", "playersmash.au", "died.wav", "congrats.wav", "complete.wav", "rock2.wav"};
  private AudioClip[] moveSound;

  // Map and level data
  private static final int X_DIMEN = 20;
  private static final int Y_DIMEN = 20;
  private static final int SQUARE_DIMEN = 20;
  private static final int CON_DIMEN = 40;
  private static final int VER_DIMEN = 12;
  private static final int SIG_DIMEN = 24;
  private char[][] levelMap;
  private int NUM_LEVELS;
  private String levelTitle,levelAuthor;
  private String[][] levelData;
  Vector bots = new Vector();

  public void init() {
    if (g == null) {
      g = getGraphics();
    }
    this.requestFocus();    // Ask for keyboard focus so we get key events

    // Get parameters from the HTML file
    String numlevels = getParameter("levels");
    if (numlevels == null) return;
    NUM_LEVELS = Integer.parseInt(numlevels);

    levelData = new String[NUM_LEVELS][Y_DIMEN];
    arrNumNeededDiamonds = new int[NUM_LEVELS];
    arrScorePerDiamond = new int[NUM_LEVELS];
    arrScorePerExtraDiamond = new int[NUM_LEVELS];
    arrMaxtimer = new int[NUM_LEVELS];
    arrLevelTitle = new String[NUM_LEVELS];
    arrLevelAuthor = new String[NUM_LEVELS];
    arrImageFilename = new String[NUM_LEVELS];

    for (int i=0; i<NUM_LEVELS; i++) {
        for (int u=0; u<Y_DIMEN; u++) {
            levelData[i][u] = getParameter("LEVEL_DATA_"+(i+1)+"_"+(u+1));
        }
        arrNumNeededDiamonds[i] = Integer.parseInt(getParameter("NEEDED_DIAMONDS_"+(i+1)));
        arrScorePerDiamond[i] = Integer.parseInt(getParameter("POINTS_PER_DIAMOND_"+(i+1)));
        arrScorePerExtraDiamond[i] = Integer.parseInt(getParameter("POINTS_PER_EXTRA_DIAMOND_"+(i+1)));
//        arrMaxtimer[i] = Integer.parseInt(getParameter("MAX_TIMER_"+(i+1)));
        arrLevelTitle[i] = getParameter("LEVEL_TITLE_"+(i+1));
        if (arrLevelTitle[i] == null) arrLevelTitle[i] = "Unnamed";
        arrLevelAuthor[i] = getParameter("LEVEL_AUTHOR_"+(i+1));
        if (arrLevelAuthor[i] == null) arrLevelAuthor[i] = "Anonymous";
        arrImageFilename[i] = getParameter("IMAGEFILE_"+(i+1));
        if (arrImageFilename[i] == null) arrImageFilename[i] = "images.gif";
    }


    // Load up all of the sounds
/*  CURRENTLY DISABLED
    moveSound = new AudioClip[NUM_SOUNDS];
    for (int i=0; i<NUM_SOUNDS; i++) {
        moveSound[i] = getAudioClip(getCodeBase(), soundFilename[i]);
    }
*/

    // Set up player variables
    coordPlayer = new Coord();
    coordExit = new Coord();

    // Just in case someone forgets to define these, let's make them exist
    coordPlayer.x = 2; coordPlayer.y = 2;
    coordExit.x = 1; coordExit.y = 1;

    // Set up the map
    levelMap = new char[X_DIMEN][];
    for (int i=0; i<X_DIMEN; i++) {
        levelMap[i] = new char[Y_DIMEN];
    }

    setLayout(new BorderLayout());
    Panel p = new Panel();
    p.add(buttonPrev);
    p.add(buttonRestart);
    p.add(buttonNext);
    add("South", p);

    level = 1;
    setupLevel(level);
  }

  private void loadImages()
  {
    // Break up source image into individual images
    // First, load the large image
    Image sourceImage;
    MediaTracker tracker = new MediaTracker(this);
    sourceImage = getImage(getCodeBase(), imageFilename);
    tracker.addImage(sourceImage,0);

    // Now break it up into pieces
    img = new Image[NUM_IMAGES];
    for (int i=0; i<NUM_IMAGES; i++) {
      img[i] = splitSourceImage(sourceImage,imgCoord[i]);
      tracker.addImage(img[i], i+1);
    }

    // Wait for all of the image pieces to get into memory
    try {
      tracker.waitForAll();
    } catch (InterruptedException e) {
      System.out.println("Boulderdash.init() caught "+e);
      e.printStackTrace();
    }
  }

  private Image splitSourceImage(Image sourceImage, int[] dimen)
  {
    ImageFilter filter;
    ImageProducer producer;

    filter = new CropImageFilter(dimen[0],dimen[1],dimen[2],dimen[3]);
    producer = new FilteredImageSource(sourceImage.getSource(), filter);
    return (createImage(producer));
  }

  private void setupLevel(int level) {
    g.setColor(Color.black);
    g.fillRect(0,0,X_DIMEN*SQUARE_DIMEN,Y_DIMEN*SQUARE_DIMEN);

    levelTitle = new String(arrLevelTitle[level-1]);
    levelAuthor = new String(arrLevelAuthor[level-1]);
    numNeededDiamonds = arrNumNeededDiamonds[level-1];
    scorePerDiamond = arrScorePerDiamond[level-1];
    scorePerExtraDiamond = arrScorePerExtraDiamond[level-1];
//    maxtimer = arrMaxtimer[level-1];
    imageFilename = new String(arrImageFilename[level-1]);

    /* Get the images*/
    loadImages();

    /* Set up the level */
    levelDone = false;
    playerAlmostDead = false;
    playerDead = false;
    bots = new Vector();
    numFulfilledDiamonds = 0;
    for (int y=0; y<Y_DIMEN; y++) {
      for (int x=0; x<X_DIMEN; x++) {
        levelMap[x][y] = levelData[level-1][y].charAt(x);
        drawCoord(x,y);
        if ((levelMap[x][y] == '[') || (levelMap[x][y] == ']')) {
          coordExit.x = x;
          coordExit.y = y;
        } else
        if (levelMap[x][y] == 'P') {
          coordPlayer.x = x;
          coordPlayer.y = y;
        } else
        if ((levelMap[x][y] == 'B') || (levelMap[x][y] == 'F')) {
            int dir = (levelMap[x][y] == 'F')?0:1;
            BotPosition botpos = new BotPosition(x,y,1,dir);
            bots.addElement(botpos);
        }
      }
    }

    updateStatus();
  }

  public void start() {
    if ((botThread == null) && (paused == false)) {
      botThread = new Thread(this);
      botThread.start();
    }
  }

  public void run() {
    // This will take care of animation
    if (paused) {
        return;
    }

    boolean botSmash,rockSmash,amoebaSmash,explosionsQuenched=false;
    Coord smashCoord = new Coord();
    char me = '.';

    while (true) {
      if (playerAlmostDead && explosionsQuenched) {
        for (int y=Y_DIMEN-2; (y>=0) && (explosionsQuenched); y--) {
          for (int x=0; (x<X_DIMEN) && (explosionsQuenched); x++) {
            if (levelMap[x][y] == '*') {
              explosionsQuenched = false;
            }
          }
        }
        if (explosionsQuenched) {
          playerAlmostDead = false;
          playerDead = true;
        }
      }

      explosionsQuenched = false;
      for (int y=Y_DIMEN-2; y>=0; y--) {
        for (int x=0; x<X_DIMEN; x++) {
          botSmash = false;
          rockSmash = false;
          amoebaSmash = false;

          // Is this item smashed by amoeba?
          if (((y-1 > 0) && (levelMap[x][y-1] == 'A')) ||
              ((x+1 < X_DIMEN) && (levelMap[x+1][y] == 'A')) ||
              ((y+1 < Y_DIMEN) && (levelMap[x][y+1] == 'A')) ||
              ((x-1 > 0) && (levelMap[x-1][y] == 'A')) &&
              ((levelMap[x][y] == 'B') || (levelMap[x][y] == 'F'))) {
            amoebaSmash = true;
            smashCoord = new Coord(x,y);
          }

          // Quench all explosions
          if (levelMap[x][y] == '*') {
            levelMap[x][y] = '.';
            redrawAndSound(new Coord(x,y),MOVE_NULL_SOUND);
            explosionsQuenched = true;
          } else

          // If, for any reason, the player is dead, restart the level
          // Do this AFTER the explosions take place
          if (playerDead) {
//            paused = true;
            // All done with the level!  Give a little pause...
            niceBanner("Oh no, you've died!");
/*            moveSound[MOVE_DIED_SOUND].play();*/

            try {
              Thread.sleep(SLEEP_DELAY);
            } catch (Exception e) {
              e.printStackTrace();
            }

            score = accumulatedScore;
            setupLevel(level);
            paused = false;
          }

          // Is the player standing next to a bot?
          if (levelMap[x][y] == 'P') {
              if (((y-1 > 0) && ((levelMap[x][y-1] == 'B') || (levelMap[x][y-1] == 'F'))) ||
                  ((x+1 < X_DIMEN) && ((levelMap[x+1][y] == 'B') || (levelMap[x+1][y] == 'F'))) ||
                  ((y+1 < Y_DIMEN) && ((levelMap[x][y+1] == 'B') || (levelMap[x][y+1] == 'F'))) ||
                  ((x-1 > 0) && ((levelMap[x-1][y] == 'B') || (levelMap[x-1][y] == 'F')))) {
                  botSmash = true;
                  smashCoord = new Coord(x,y);
                  playerAlmostDead = true;
              }
          } else

          // Work with rocks and diamonds
          if ((levelMap[x][y] == 'O') || (levelMap[x][y] == '+') || (amoebaSmash || botSmash)) {
            if (levelMap[x][y] == 'O') {
                me = 'O';
            } else
            if (levelMap[x][y] == '+') {
                me = '+';
            } else {
                me = '?';
            }

            // Gravity first...
            if ((me != '?') && (levelMap[x][y+1] == '.')) {
              levelMap[x][y+1] = me;
              levelMap[x][y] = '.';
              redrawAndSound(new Coord(x,y),MOVE_ROCK_SOUND);
              redrawAndSound(new Coord(x,y+1),MOVE_ROCK2_SOUND);
              if ((y+2 < Y_DIMEN) && ((levelMap[x][y+2] == 'B') || (levelMap[x][y+2] == 'F') || (levelMap[x][y+2] == 'P'))) {
                rockSmash = true;
                smashCoord = new Coord(x,y+2);
              }
            } else

            // ... then handle stack collapsing
            if ((me != '?') && ((levelMap[x][y+1] == 'O') || (levelMap[x][y+1] == '+'))) {
                if ((levelMap[x+1][y+1] == '.') && (levelMap[x+1][y] == '.')) {
                    levelMap[x+1][y+1] = me;
                    levelMap[x][y] = '.';
                    redrawAndSound(new Coord(x,y),MOVE_ROCK2_SOUND);
                    redrawAndSound(new Coord(x+1,y+1),MOVE_ROCK_SOUND);
                    if ((y+2 < Y_DIMEN) && ((levelMap[x+1][y+2] == 'B') && (levelMap[x+1][y+2] == 'F') || (levelMap[x+1][y+2] == 'P'))) {
                      rockSmash = true;
                      smashCoord = new Coord(x+1,y+2);
                    }
                } else
                if ((levelMap[x-1][y+1] == '.') && (levelMap[x-1][y] == '.')) {
                    levelMap[x-1][y+1] = me;
                    levelMap[x][y] = '.';
                    redrawAndSound(new Coord(x,y),MOVE_ROCK2_SOUND);
                    redrawAndSound(new Coord(x-1,y+1),MOVE_ROCK2_SOUND);
                    if ((y+2 < Y_DIMEN) && ((levelMap[x-1][y+2] == 'B') && (levelMap[x-1][y+2] == 'F') || (levelMap[x-1][y+2] == 'P'))) {
                      rockSmash = true;
                      smashCoord = new Coord(x-1,y+2);
                    }
                }
            }
          }

            // Smash a butterfly, fly, or player
label1:     if ((botSmash || amoebaSmash || rockSmash) && ((levelMap[smashCoord.x][smashCoord.y] == 'B') || (levelMap[smashCoord.x][smashCoord.y] == 'F') || (levelMap[smashCoord.x][smashCoord.y] == 'P'))) {
              boolean diamond = (levelMap[smashCoord.x][smashCoord.y] == 'B')?true:false;
              if (levelMap[smashCoord.x][smashCoord.y] == 'P') {
			if (botSmash || rockSmash) {
	              playerAlmostDead = true;
                  } else break label1;
              }
              for (int i=smashCoord.x-1;i<=smashCoord.x+1;i++) {
                for (int u=smashCoord.y-1;u<=smashCoord.y+1;u++) {
                    if ((levelMap[i][u] == '.') || (levelMap[i][u] == ':') || (levelMap[i][u] == 'W') || (levelMap[i][u] == 'M') || (levelMap[i][u] == '+') || (levelMap[i][u] == 'A')
                        || ((i==smashCoord.x) && (u==smashCoord.y-1)) || ((i==smashCoord.x) && (u==smashCoord.y)) && (i > 0) && (i < X_DIMEN) && (u > 0) && (u < Y_DIMEN)) {
                        if (diamond) {
                            levelMap[i][u]='+';
                        } else {
                            levelMap[i][u]='*';
                        }
                        redrawAndSound(new Coord(i,u),MOVE_SMASH_SOUND);
                        for (int b=0; b<bots.size(); b++) {
                            BotPosition bot = (BotPosition)bots.elementAt(b);
                            if ((bot.x == smashCoord.x) && (bot.y == smashCoord.y)) {
                                bots.removeElementAt(b);
                            }
                        }
                    }
                }
              }
            }

            // Go into a magic wall
            if ((levelMap[x][y] == 'M') && (y > 1) && ((levelMap[x][y-1] == 'O') || (levelMap[x][y-1] == '+'))) {
              if (levelMap[x][y+1] == '.') {
                if (levelMap[x][y-1] == 'O') {
                  levelMap[x][y+1] = '+';
                  redrawAndSound(new Coord(x,y+1),MOVE_MAGICWALL_SOUND);
                } else {
                  levelMap[x][y+1] = 'O';
                  redrawAndSound(new Coord(x,y+1),MOVE_MAGICWALL_SOUND);
                }
              }
              levelMap[x][y-1] = '.';
              redrawAndSound(new Coord(x,y-1),MOVE_NULL_SOUND);
            }


          // Grow the amoeba
          if (levelMap[x][y] == 'A') {
             if (timer >= maxtimer) {
                if (Math.random() < 0.10) {
                    int dx=0,dy=0;
                    if (Math.random() < 0.5) {
                        dx = (int)((Math.round(Math.random()*2))-1);
                        dy = 0;
                    } else {
                        dy = (int)((Math.round(Math.random()*2))-1);
                        dx = 0;
                    }
                    // Spread it only to places that are empty or have dirt
                    if ((x+dx < X_DIMEN) && (x+dx > 0) && (y+dy < Y_DIMEN) && (y+dy > 0)) {
                        if ((levelMap[x+dx][y+dy] == '.') || (levelMap[x+dx][y+dy] == ':')) {
                            levelMap[x+dx][y+dy] = 'A';
                            redrawAndSound(new Coord(x+dx,y+dy),MOVE_AMOEBA_SOUND);
                        }
                    }
                }
             }
          }
        } // for
      } // for

      // Move any Fireflies clockwise, and Butterflies counterclockwise
      if (timer >= maxtimer) {
        for (int b = 0; b < bots.size(); b++) {
          BotPosition bot = (BotPosition)bots.elementAt(b);
          Coord c = new Coord(bot.x,bot.y);

          if (bot.heading == UP) {
            if ((bot.direction == UP) && (levelMap[bot.x+1][bot.y] == '.')) {
                bot.x++;
                bot.heading = RIGHT;
            } else
            if ((bot.direction == RIGHT) && (levelMap[bot.x-1][bot.y] == '.')) {
                bot.x--;
                bot.heading = LEFT;
            } else
            if (levelMap[bot.x][bot.y-1] == '.') {
              bot.y--;
            } else {
              bot.heading = DOWN;
            }
          }

          if (bot.heading == RIGHT) {
            if ((bot.direction == UP) && (levelMap[bot.x][bot.y+1] == '.')) {
                bot.y++;
                bot.heading = DOWN;
            } else
            if ((bot.direction == RIGHT) && (levelMap[bot.x][bot.y-1] == '.')) {
                bot.y--;
                bot.heading = UP;
            } else
            if (levelMap[bot.x+1][bot.y] == '.') {
              bot.x++;
            } else {
              bot.heading = LEFT;
            }
          }

          if (bot.heading == DOWN) {
            if ((bot.direction == UP) && (levelMap[bot.x-1][bot.y] == '.')) {
                bot.x--;
                bot.heading = LEFT;
            } else
            if ((bot.direction == RIGHT) && (levelMap[bot.x+1][bot.y] == '.')) {
                bot.x++;
                bot.heading = RIGHT;
            } else
            if (levelMap[bot.x][bot.y+1] == '.') {
              bot.y++;
            } else {
              bot.heading = UP;
            }
          }

          if (bot.heading == LEFT) {
            if ((bot.direction == UP) && (levelMap[bot.x][bot.y-1] == '.')) {
                bot.y--;
                bot.heading = UP;
            } else
            if ((bot.direction == RIGHT) && (levelMap[bot.x][bot.y+1] == '.')) {
                bot.y++;
                bot.heading = DOWN;
            } else
            if (levelMap[bot.x-1][bot.y] == '.') {
              bot.x--;
            } else {
              bot.heading = RIGHT;
            }
          }


          bots.setElementAt(bot,b);
          if ((bot.x != c.x) || (bot.y != c.y)) {
            levelMap[c.x][c.y] = '.';
            levelMap[bot.x][bot.y] = (bot.direction==0)?'F':'B';
            redrawAndSound(new Coord(c.x,c.y),MOVE_NULL_SOUND);
            redrawAndSound(new Coord(bot.x,bot.y),MOVE_NULL_SOUND);
          }
        }

      } // timer


      // Check if amoeba is suffocated
      boolean amoebaSuffocated = true;
      for (int i=1; i<X_DIMEN-1 && amoebaSuffocated; i++) {
        for (int u=1; u<Y_DIMEN-1 && amoebaSuffocated; u++) {
            if (levelMap[i][u] == 'A') {
                if ((levelMap[i][u-1] == '.') || (levelMap[i][u-1] == ':') ||
                    (levelMap[i-1][u] == '.') || (levelMap[i-1][u] == ':') ||
                    (levelMap[i][u+1] == '.') || (levelMap[i][u+1] == ':') ||
                    (levelMap[i+1][u] == '.') || (levelMap[i+1][u] == ':')) {
                    amoebaSuffocated = false;
                }
            }
        }
      }

      // If the amoeba is suffocated, convert all amoeba into diamonds
      if (amoebaSuffocated) {
          for (int i=1; i<X_DIMEN-1; i++) {
            for (int u=1; u<Y_DIMEN-1; u++) {
                if (levelMap[i][u] == 'A') {
                    levelMap[i][u] = '+';
                    redrawAndSound(new Coord(i,u),MOVE_NULL_SOUND);
                }
            }
          }
      }


      redrawCoords();

      if (timer >= maxtimer) {
        timer = 0;
      }
      timer++;
      try {
        Thread.sleep(150);
      } catch (InterruptedException e) {
        System.out.println("Interrupted");
      }
     } // while
  } // run


  public boolean action(Event evt, Object o) {
    if ((evt.target == buttonPrev) && (level-1 > 0)) {
        score = accumulatedScore;
        setupLevel(--level);
    } else
    if (evt.target == buttonRestart) {
        score = accumulatedScore;
        setupLevel(level);
    } else
    if ((evt.target == buttonNext) && (level+1 < NUM_LEVELS+1)) {
        score = accumulatedScore;
        setupLevel(++level);
    }
    return true;
  }

  public boolean mouseDown(Event evt, int x, int y) {
    if ((x > 0) && (x < X_DIMEN*SQUARE_DIMEN) && (y > Y_DIMEN*SQUARE_DIMEN+CON_DIMEN) && (y < Y_DIMEN*SQUARE_DIMEN+CON_DIMEN+SIG_DIMEN)) {
        g.setFont(new Font("Helvetica",Font.BOLD|Font.ITALIC,14));
        for (int i=0; i<3; i++) {
            g.setColor(Color.magenta);
            g.fillRect(0,Y_DIMEN*SQUARE_DIMEN+CON_DIMEN,X_DIMEN*SQUARE_DIMEN,SIG_DIMEN);
            try { Thread.sleep(150); } catch (InterruptedException e) { e.printStackTrace(); }
            g.setColor(Color.blue);
            g.fillRect(0,Y_DIMEN*SQUARE_DIMEN+CON_DIMEN,X_DIMEN*SQUARE_DIMEN,SIG_DIMEN);
            g.setColor(Color.yellow);
            g.drawString("Click here to visit this applet's homepage!",45,(Y_DIMEN*SQUARE_DIMEN)+CON_DIMEN+16);
            try { Thread.sleep(150); } catch (InterruptedException e) { e.printStackTrace(); }
        }
        try {
            AppletContext ac = getAppletContext();

            // PLEASE DO NOT CHANGE WHERE THIS URL POINTS!
            ac.showDocument(new URL("http://www.ultranet.com/~dkoelle/Boulderdash"));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return true;
  }

  public boolean keyDown(Event evt, int keyCode) {
    if (paused) {
      return false;
    }

    Coord delta = new Coord();
    Coord delta2 = new Coord();
    Coord move  = new Coord();
    Coord move2  = new Coord();
    boolean validMove = false;

    // Interpret the keycode
    if (keyCode == Event.UP) {
      delta.x = 0;   delta.y = -1;
    } else
    if (keyCode == Event.RIGHT) {
      delta.x = 1;   delta.y = 0;
    } else
    if (keyCode == Event.DOWN) {
      delta.x = 0;   delta.y = 1;
    } else
    if (keyCode == Event.LEFT) {
      delta.x = -1;  delta.y = 0;
    } else
    if (keyCode == Event.ESCAPE) {
      playerAlmostDead = true;
      levelMap[coordPlayer.x][coordPlayer.y] = '*';
      redrawAndSound(coordPlayer,MOVE_PLAYERSMASH_SOUND);
    }

    // Make move relative to player
    move.x = coordPlayer.x + delta.x;
    move.y = coordPlayer.y + delta.y;

    // Range checking on the move
    if (move.x < 0) { move.x = 0; } else
    if (move.x > X_DIMEN) { move.x = X_DIMEN; }
    if (move.y < 0) { move.y = 0; } else
    if (move.y > Y_DIMEN) { move.y = Y_DIMEN; }

    // Create a "look-ahead" position
    delta2.x = delta.x*2;
    delta2.y = delta.y*2;
    move2.x = coordPlayer.x + delta2.x;
    move2.y = coordPlayer.y + delta2.y;

    // Moving into an empty space?  "I'll allow it!" -- Mills Lane
    if ((levelMap[move.x][move.y] == '.') || (levelMap[move.x][move.y] == ':')) {
      if (levelMap[move.x][move.y] == '.') {
        redrawAndSound(move,MOVE_NULL_SOUND); // SPACE sound
      } else {
        redrawAndSound(move,MOVE_NULL_SOUND); // DIRT sound
      }
      validMove = true;
    } else

    // Pushing a rock?
    if ((levelMap[move.x][move.y] == 'O') && (move2.y != move.y-1)) {
      if (((move2.x >= 0) && (move2.x <= X_DIMEN)) &&
          ((move2.y >= 0) && (move2.y <= Y_DIMEN))) {
        if (levelMap[move2.x][move2.y] == '.') {
          // "look-ahead" is an empty space.  Move the rock.
          levelMap[move2.x][move2.y] = levelMap[move.x][move.y];
          redrawAndSound(move2,MOVE_ROCK_SOUND);
          redrawAndSound(move,MOVE_NULL_SOUND);
          validMove = true;
        }
      }
    } else

    // Grabbing a Diamond?
    // Add one to the Number of Fulfilled Diamonds,
    // and see if the exit should be opened
    if (levelMap[move.x][move.y] == '+') {
       numFulfilledDiamonds++;
       score += (numFulfilledDiamonds<numNeededDiamonds ? scorePerDiamond : scorePerExtraDiamond);
       updateScore();
       redrawAndSound(move,MOVE_DIAMOND_SOUND);
       if (numFulfilledDiamonds == numNeededDiamonds) {
         levelMap[coordExit.x][coordExit.y] = '[';
         redrawAndSound(coordExit,MOVE_OPENEXIT_SOUND);
       }
       validMove = true;
    } else

    // If moving into an exit, make sure it's open!
    if (levelMap[move.x][move.y] == '[') {
      redrawAndSound(move,MOVE_NULL_SOUND);
      validMove = true;
    }

    // If the player is holding the shift key, don't move the character
    if (evt.shiftDown() && validMove) {
        levelMap[move.x][move.y] = '.';
        validMove = false;
    }

    if (validMove) {
      levelMap[move.x][move.y] = 'P';
      levelMap[coordPlayer.x][coordPlayer.y] = '.';
      drawCoord(coordPlayer.x,coordPlayer.y);
      coordPlayer.x = move.x;
      coordPlayer.y = move.y;
    }

    // Redraw coordinates that need to be redrawn
    redrawCoords();

    // Is the level over?
    if ((coordPlayer.x == coordExit.x) &&
        (coordPlayer.y == coordExit.y)) {
      paused = true;
      levelDone = true;
      if (level == NUM_LEVELS) {
        niceBanner("All levels complete!");
/*        moveSound[MOVE_COMPLETE_SOUND].play();*/
      } else {
        niceBanner("Congratulations!");
/*        moveSound[MOVE_CONGRATULATIONS_SOUND].play();*/
      }

      // All done with the level!  Give a little pause...
      try {
        Thread.sleep(SLEEP_DELAY);
      } catch (Exception e) {
        e.printStackTrace();
      }

      accumulatedScore = score;
      paused = false;
      if (level+1 < NUM_LEVELS+1) {
        level++;
      } else {
        level = 1;
      }
      setupLevel(level);
    }

    return true;
  }

  public void paint(Graphics g) {
    for (int x=0; x<X_DIMEN; x++) {
      for (int y=0; y<Y_DIMEN; y++) {
        drawCoord(x,y);
      }
    }

    updateStatus();
  }

  public void updateStatus() {
    g.setColor(Color.lightGray);
    g.fillRect(0,Y_DIMEN*SQUARE_DIMEN,X_DIMEN*SQUARE_DIMEN,CON_DIMEN);

    // Game info
    g.setColor(Color.black);
    g.setFont(new Font("Helvetica",Font.BOLD,14));
    g.drawString(levelTitle,12,(Y_DIMEN*SQUARE_DIMEN)+12);
    g.setFont(new Font("Helvetica",Font.ITALIC,12));
    g.drawString("by "+levelAuthor,12,(Y_DIMEN*SQUARE_DIMEN)+26);
    g.setFont(new Font("Helvetica",Font.BOLD,10));
    g.drawString("Level "+level+" / "+NUM_LEVELS,12,(Y_DIMEN*SQUARE_DIMEN)+38);

    // Second column of Game info
    g.setFont(new Font("Helvetica",Font.PLAIN,12));
    g.drawString("Score: "+score,200,(Y_DIMEN*SQUARE_DIMEN)+12);
    g.drawString("Diamonds: "+numFulfilledDiamonds+" / "+(numFulfilledDiamonds<numNeededDiamonds ? numNeededDiamonds : 0),200,(Y_DIMEN*SQUARE_DIMEN)+24);
    g.drawString("Diamond Points: "+(numFulfilledDiamonds<numNeededDiamonds ? scorePerDiamond : scorePerExtraDiamond),200,(Y_DIMEN*SQUARE_DIMEN)+36);

    // "Click here for the applet homepage" (SIG)
    g.setColor(Color.blue);
    g.fillRect(0,Y_DIMEN*SQUARE_DIMEN+CON_DIMEN,X_DIMEN*SQUARE_DIMEN,SIG_DIMEN);
    g.setColor(Color.yellow);
    g.setFont(new Font("Helvetica",Font.BOLD + Font.ITALIC,14));
    g.drawString("Click here to visit this applet's homepage!",45,(Y_DIMEN*SQUARE_DIMEN)+CON_DIMEN+16);

    // Version info
    g.setColor(Color.black);
    g.fillRect(0,Y_DIMEN*SQUARE_DIMEN+CON_DIMEN+SIG_DIMEN,X_DIMEN*SQUARE_DIMEN,VER_DIMEN);
    g.setColor(Color.white);
    g.setFont(new Font("Helvetica",Font.BOLD,10));
    g.drawString("Java Boulderdash  -  Version "+VERSION+"  -  ID "+ID,55,(Y_DIMEN*SQUARE_DIMEN)+CON_DIMEN+SIG_DIMEN+10);
  }

  public void updateScore() {
    g.setColor(Color.lightGray);
    g.fillRect(200,Y_DIMEN*SQUARE_DIMEN,X_DIMEN*SQUARE_DIMEN,CON_DIMEN);

    g.setColor(Color.black);
    g.setFont(new Font("Helvetica",Font.PLAIN,12));
    g.drawString("Score: "+score,200,(Y_DIMEN*SQUARE_DIMEN)+12);
    g.drawString("Diamonds: "+numFulfilledDiamonds+" / "+(numFulfilledDiamonds<numNeededDiamonds ? numNeededDiamonds : 0),200,(Y_DIMEN*SQUARE_DIMEN)+24);
    g.drawString("Diamond Points: "+(numFulfilledDiamonds<numNeededDiamonds ? scorePerDiamond : scorePerExtraDiamond),200,(Y_DIMEN*SQUARE_DIMEN)+36);
  }



  public void drawCoord(int x, int y)
  {
    int index;
    for (index=0; index<imgRep.length(); index++) {
        if (imgRep.charAt(index) == levelMap[x][y]) {
            g.drawImage(img[index],x*SQUARE_DIMEN,y*SQUARE_DIMEN,null);
        }
    }
  }

  public void redrawCoords() {
    // Redraw any coordinates that should be redrawn
    try {
        for (int i=0; i<redraw.size(); i++) {
            Coord display = (Coord)redraw.elementAt(i);
            drawCoord(display.x,display.y);
/*
            if (i<sounds.size()) {
                ((AudioClip)sounds.elementAt(i)).play();
            }
*/

        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    redraw.removeAllElements();
    sounds.removeAllElements();
  }

  public void redrawAndSound(Coord coord, int sound) {
    redraw.addElement(coord);
/*
    sounds.addElement(moveSound[sound]);
*/
  }

  public void niceBanner(String msg) {
    g.setColor(Color.darkGray);
    g.fillRect(SQUARE_DIMEN*2,SQUARE_DIMEN*4,SQUARE_DIMEN*16,SQUARE_DIMEN*5);
    g.setColor(Color.blue);
    g.fillRect(SQUARE_DIMEN*3,SQUARE_DIMEN*5,SQUARE_DIMEN*14,SQUARE_DIMEN*3);
    g.setColor(Color.yellow);
    g.setFont(new Font("Helvetica",Font.BOLD|Font.ITALIC,20));
    g.drawString(msg,SQUARE_DIMEN*6-10,SQUARE_DIMEN*7-5);
  }

  public String getAppletInfo() {
    return("Boulderdash Applet, (C) 2000 by David Koelle\nInspired by the game, \"Super Boulderdash\"\n\n" +
           "Please visit http://www.ultranet.com/~dkoelle/Boulderdash to find out\nhow to use and modify this applet!");
  }

  public String[][] getParameterInfo() {
    return(new String[][] {{"LEVELS","int","Number of levels included in this .html file"},
            {"LEVEL_NAME_x","String","Name of Level x"},
            {"LEVEL_AUTHOR_x","String","Author of Level x"},
            {"LEVEL_DATA_x_r","String","Map for Level x. 'r' is 1 - 20, representing a row of the map"},
            {"NEEDED_DIAMONDS_x","int","Number of diamonds needed to open the exit for Level x"},
            {"POINTS_PER_DIAMOND_x","int","Number of points awarded for getting a diamond for Level x"},
            {"POINTS_PER_EXTRA_DIAMOND_x","int","Number of points awarded for getting a diamond after all needed diamonds have been obtained for Level x"},
//            {"MAXTIMER","int","Cycle timer for monsters"},
            {"IMAGEFILE_x","String","Filename of the image file to use for Level x"}});
  }

} // Boulderdash


Back to Boulderdash

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

 Microsoft RIA Development Center
 IBM Rational Resource Center
 Destination .NET
XML error: not well-formed (invalid token) at line 33
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

Free VMware Server 2.0 Now Release Candidate
Linux Player Xandros Grabs Storied Rival Linspire
Hey Enterprise: Here Comes the 3G iPhone
MySpace Opens Profile Portability API
Microsoft Jumps Into Virtualization Fray
Eclipse Ganymede Makes It Easier for Devs
Open Source Nokia a Threat to Microsoft, Google?
Salesforce, Google Head for 2nd on Apps
HP Open Sources Unix File System for Linux
Red Hat Opens Its Network to Space

Build a Generic Histogram Generator for SQL Server
Beyond XML and JSON: YAML for Java Developers
Mastering the Windows Mobile Emulators
Avaya AE Services Provide Rapid Telephony Integration with Facebook
Featured Algorithm: Intel Threading Building Blocks: parallel_reduce
Getting Started with Windows Live Admin Center
Eight Key Practices for ASP.NET Deployment
Java ME User Interfaces: Do It with LWUIT!
Talking VPro: Transcript
Bringing Semantic Technology to the Enterprise

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
IBM eBook: Planning a Service Oriented Architecture
IBM eBook: Choosing the Right Architecture--What It Means for You and Your Business
Microsoft Article: Will Hyper-V Make VMware This Decade's Netscape?
Avaya Article: Using Intelligent Presence to Create Smarter Business Applications
Intel Go Parallel Article: Getting Started with TBB on Windows
Microsoft Article: 7.0, Microsoft's Lucky Version?
Avaya Article: How to Feed Data into the Avaya Event Processor
IBM Article: Developing a Software Policy for Your Organization
Microsoft Article: Managing Virtual Machines with Microsoft System Center
Intel Go Parallel Article: Intel Threading Tools and OpenMP
HP eBook: Storage Networking , Part 1
Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
HP Video: StorageWorks EVA4400 and Oracle
HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Red Gate Download: SQL Toolbelt and free High-Performance SQL Code eBook
Iron Speed Designer Application Generator
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
Silverlight 2 App and Walkthrough: Leverage Silverlight 2 with SQL Server and XML
IBM Article: Enterprise Search--Do You Know What's Out There?
HP Demo: StorageWorks EVA4400
Microsoft Article: The Progress and Promise of Deep Zoom
Microsoft How-to Article: Get Going with Silverlight and Windows Live
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES