|
ActionControl |
|
/* * JVirus is a PacMan clone, written in Java. * * Please read "http://jvirus.sourceforge.net/jvirus_licence.txt" for copyrights. * * The sourcecode is designed and created with * Sun J2SDK 1.3 and Microsoft Visual J++ 6.0 * * JVirus homepage: http://jvirus.sourceforge.net * * autor: Slawa Weis * email: slawaweis@animatronik.net * */ package org.game.JVirus; import java.awt.event.*; import javax.swing.JFrame; /** * this class controls the movement of the avatar and the animating thread. */ public class ActionControl implements IFields, KeyListener { /** * reference to the level * * @see org.game.JVirus.Matrix */ protected Matrix level = null; /** * reference to the display * * @see org.game.JVirus.Display */ protected Display display = null; /** * reference to the JVirusFrame * * @see org.game.JVirus.JVirusFrame */ protected JFrame parent = null; /** * reference to the Avatar * * @see org.game.JVirus.Avatar */ protected Avatar avatar = null; /** * callback function */ protected ActionControl.IGameListener gameListener = null; /** * thread to for animated objects */ protected ActionControlRunner runner = null; /** * clear byte * * @see #nextMove() */ protected int set_byte = 1; /** * game running or not */ protected boolean gameStart = false; /** * game paused or not */ protected boolean gamePaused = false; /** * need to escape from stones * * @see #nextMove() */ protected long lastTimeAvatarMove = 0; /** * callback interface for game events */ public interface IGameListener { /** * constant for winning the game */ public static final int WIN = 0; /** * constant for losing the game */ public static final int LOSE = 1; /** * end of the game */ public void gameOver(int reason); /** * game score changed */ public void scoreChanged(Avatar avatar); /** * game lifes changed */ public void lifesChanged(Avatar avatar); } /** * creates the ActionControl. * * @param display reference to the Display * @param parent reference to the JVirusFrame * @param gameListener reference to the callback function */ public ActionControl(Display display, JFrame parent, ActionControl.IGameListener gameListener) { super(); this.display = display; this.parent = parent; this.gameListener = gameListener; this.avatar = new Avatar(); } /** * return the current avatar * * @see org.game.JVirus.Avatar */ public Avatar getAvatar() { return avatar; } /** * start the game * * @param level playing level */ public void startGame(Matrix level) { this.level = level; // search for start int i = 0, j = 0; boolean break_loop = false; for(i = 0; i < level.matrix.length; i++) { for(j = 0; j < level.matrix[i].length; j++) { if(level.matrix[i][j] == IFields.START) { break_loop = true; break; } } if(break_loop) break; } // reset the avatar avatar.setLevel(level, j, i); lastTimeAvatarMove = 0; // repaint the avatar display.moveAvatar(avatar); // add key listener parent.addKeyListener(this); // start animating thread runner = new ActionControlRunner(); runner.start(); gameStart = true; gamePaused = false; } /** * pause the game * * @param b pause or not */ public void pauseGame(boolean b) { if(!gameStart) return; if(b) { runner.pauseRunner(b); parent.removeKeyListener(this); gamePaused = true; } else { runner.pauseRunner(b); parent.addKeyListener(this); gamePaused = false; } } /* * * reset the game */ /* public void resetGame() { } */ /** * reset the scores and lifes of the avatar. */ public void resetAvatar() { if(!gameStart) avatar = new Avatar(); } /** * stop the game */ public void stopGame() { if(gameStart) { runner.stopRunner(); runner = null; parent.removeKeyListener(this); } gameStart = false; gamePaused = false; } /** * is the game started or not */ public boolean isRunning() { return gameStart; } /** * is the game paused or not */ public boolean isPaused() { return gamePaused; } /** * edit the avatar and call the callback funktion */ protected void gameOver(int reason) { // stop the game stopGame(); if(reason == IGameListener.WIN) { Sound.playFX(Sound.FX_WIN); // add current level scores to whole game scores avatar.gameScore += avatar.gameScoreCurrentLevel; avatar.gameLifes += avatar.gameLifesCurrentLevel; // this level solved avatar.solvedLevels[level.levelNumber] = Avatar.LEVEL_SOLVED; // unlock the next locked level for(int i = 0; i < avatar.solvedLevels.length; i++) { if(avatar.solvedLevels[i] == Avatar.LEVEL_CAN_NOT_SOLVE) { avatar.solvedLevels[i] = Avatar.LEVEL_CAN_SOLVE; break; } } } // buuuhhhh... :) if(reason == IGameListener.LOSE) { Sound.playFX(Sound.FX_LOSE); avatar.gameLifes--; } // call the callback function gameListener.gameOver(reason); } /** * get the key events */ public void keyPressed (KeyEvent e) { // the last time, the avatar ist moving lastTimeAvatarMove = System.currentTimeMillis(); // move the position on display if(e.getKeyCode() == KeyEvent.VK_LEFT) { // if(avatar.x - display.mapOnScreen.x < 1 && display.mapOnScreen.x > 0) if((avatar.x - display.mapOnScreen.x) < Display.DISPLAY_TILES_WIDTH2 && display.mapOnScreen.x > 0) { display.mapOnScreen.x--; display.repaintMatrix(); } moveAvatar(avatar.x, avatar.y, avatar.x-1, avatar.y); } else if(e.getKeyCode() == KeyEvent.VK_RIGHT) { // if((avatar.x - display.mapOnScreen.x) >= Display.DISPLAY_TILES_WIDTH-1 && // display.mapOnScreen.x+Display.DISPLAY_TILES_WIDTH < level.matrix[0].length) if((avatar.x - display.mapOnScreen.x) >= Display.DISPLAY_TILES_WIDTH2 && display.mapOnScreen.x+Display.DISPLAY_TILES_WIDTH < level.matrix[0].length) { display.mapOnScreen.x++; display.repaintMatrix(); } moveAvatar(avatar.x, avatar.y, avatar.x+1, avatar.y); } else if(e.getKeyCode() == KeyEvent.VK_UP) { // if(avatar.y - display.mapOnScreen.y < 1 && display.mapOnScreen.y > 0) if((avatar.y - display.mapOnScreen.y) < Display.DISPLAY_TILES_HEIGHT2 && display.mapOnScreen.y > 0) { display.mapOnScreen.y--; display.repaintMatrix(); } moveAvatar(avatar.x, avatar.y, avatar.x, avatar.y-1); } else if(e.getKeyCode() == KeyEvent.VK_DOWN) { // if((avatar.y - display.mapOnScreen.y) >= Display.DISPLAY_TILES_HEIGHT-1 && // display.mapOnScreen.y+Display.DISPLAY_TILES_HEIGHT < level.matrix.length) if((avatar.y - display.mapOnScreen.y) >= Display.DISPLAY_TILES_HEIGHT2 && display.mapOnScreen.y+Display.DISPLAY_TILES_HEIGHT < level.matrix.length) { display.mapOnScreen.y++; display.repaintMatrix(); } moveAvatar(avatar.x, avatar.y, avatar.x, avatar.y+1); } } /** * not used */ public void keyReleased(KeyEvent e) { } /** * not used */ public void keyTyped (KeyEvent e) { } /** * next move from thread */ protected void nextMove() { int i, j; int set = (set_byte == 1 ? 2 : 1); boolean matrix_changed = false; // search in the whole matrix for(i = 0; i < level.matrix.length; i++) for(j = 0; j < level.matrix[i].length; j++) { // if set, then this field is visited if(level.bufferMatrix1[i][j] == set) continue; // if object is a fall object if((Matrix.actionTyp[level.matrix[i][j]] & AT_FAll) == AT_FAll && (Matrix.actionTyp[level.matrix[i+1][j]] & AT_HOLD) == 0) { // if under the object is free if(level.matrix[i+1][j] == EMPTY && (avatar.x != j || avatar.y != i+1)) { matrix_changed = true; level.matrix [i+1][j] = level.matrix[i][j]; level.bufferMatrix1[i+1][j] = set; level.matrix [i][j] = EMPTY; level.bufferMatrix1[i][j] = set; // avatar die or not if((j == avatar.x) && (i+2 == avatar.y) && (System.currentTimeMillis() - lastTimeAvatarMove) > 250) gameOver(IGameListener.LOSE); } // if right under the object is free else if(level.matrix[i][j+1] == EMPTY && level.matrix[i+1][j+1] == EMPTY && (avatar.x != j+1 || avatar.y != i) && (avatar.x != j+1 || avatar.y != i+1)) { matrix_changed = true; level.matrix [i+1][j+1] = level.matrix[i][j]; level.bufferMatrix1[i+1][j+1] = set; level.matrix [i][j] = EMPTY; level.bufferMatrix1[i][j] = set; // avatar die or not if((j+1 == avatar.x) && (i+2 == avatar.y) && (System.currentTimeMillis() - lastTimeAvatarMove) > 250) gameOver(IGameListener.LOSE); } // if left under the object is free else if(level.matrix[i][j-1] == EMPTY && level.matrix[i+1][j-1] == EMPTY && (avatar.x != j-1 || avatar.y != i) && (avatar.x != j-1 || avatar.y != i+1)) { matrix_changed = true; level.matrix [i+1][j-1] = level.matrix[i][j]; level.bufferMatrix1[i+1][j-1] = set; level.matrix [i][j] = EMPTY; level.bufferMatrix1[i][j] = set; // avatar die or not if((j-1 == avatar.x) && (i+2 == avatar.y) && (System.currentTimeMillis() - lastTimeAvatarMove) > 250) gameOver(IGameListener.LOSE); } } else { // position visited level.bufferMatrix1[i][j] = set; } } set_byte = set; // if matrix changed, repaint if(matrix_changed) { Sound.playFX(Sound.FX_FALL); display.repaintMatrix(avatar); display.repaint(); } // if matrix not changed, repaint only the animated fields else { display.repaintAnimTiles(avatar); display.repaint(); } } /** * next move from user */ protected void moveAvatar(int sx, int sy, int tx, int ty) { Sound.playFX(Sound.FX_MOVE); // for the avatar image avatar.move_direction = (sx > tx); avatar.eat_sequence = !avatar.eat_sequence; if(sx != tx && tx >= 0 && tx < level.matrix[ty].length && actionAvatar(sx, sy, tx, ty)) { avatar.lx = avatar.x; avatar.ly = avatar.y; avatar.x = tx; avatar.y = ty; } if(sy != ty && ty >= 0 && ty < level.matrix.length && actionAvatar(sx, sy, tx, ty)) { avatar.lx = avatar.x; avatar.ly = avatar.y; avatar.x = tx; avatar.y = ty; } // repaint only the avatar display.moveAvatar(avatar); display.repaint(); // if avatar in the end field if(level.matrix[avatar.y][avatar.x] == END) gameOver(IGameListener.WIN); } /** * select what Action to do in this field */ protected boolean actionAvatar(int sx, int sy, int tx, int ty) { // remove field if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_EAT) == AT_EAT) { avatar.gameScoreCurrentLevel += Matrix.scoreTab[level.matrix[ty][tx]]; if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_EAT_SOUND1) == AT_EAT_SOUND1) { Sound.playFX(Sound.FX_EAT1); } else if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_EAT_SOUND2) == AT_EAT_SOUND2) { Sound.playFX(Sound.FX_EAT2); } if(level.matrix[ty][tx] == REDKEY || level.matrix[ty][tx] == GREENKEY || level.matrix[ty][tx] == BLUEKEY) { Sound.playFX(Sound.FX_GATE_OPEN); removeGate(level.matrix[ty][tx]); display.repaintMatrix(); } else if(level.matrix[ty][tx] == LIFE) { avatar.gameLifesCurrentLevel += 1; gameListener.lifesChanged(avatar); } level.matrix[ty][tx] = EMPTY; gameListener.scoreChanged(avatar); } // transport in the beam if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_BEAM) == AT_BEAM) { Sound.playFX(Sound.FX_BEAM); beamAvatar(level.matrix[ty][tx], tx, ty); display.mapOnScreen.x = avatar.x - Display.DISPLAY_TILES_WIDTH2; display.mapOnScreen.y = avatar.y - Display.DISPLAY_TILES_HEIGHT2; if(display.mapOnScreen.x < 0) display.mapOnScreen.x = 0; if(display.mapOnScreen.x + Display.DISPLAY_TILES_WIDTH >= level.matrix[0].length) display.mapOnScreen.x = level.matrix[0].length - Display.DISPLAY_TILES_WIDTH; if(display.mapOnScreen.y < 0) display.mapOnScreen.y = 0; if(display.mapOnScreen.y + Display.DISPLAY_TILES_HEIGHT >= level.matrix.length) display.mapOnScreen.y = level.matrix.length - Display.DISPLAY_TILES_HEIGHT; display.repaintMatrix(); return false; } // can moving into this field or not if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_END) == AT_END) { return true; } else if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_MOVE) == AT_MOVE) { return true; } else if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_ACTION) == AT_ACTION) { return true; } else if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_WALL) == AT_WALL) { return false; } else if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_PUSH) == AT_PUSH) { return false; } else if((Matrix.actionTyp[level.matrix[ty][tx]] & AT_ANIM) == AT_ANIM) { } return false; } /** * search for the gate that pass and remove that */ protected void removeGate(char key) { char gate = ' '; if(key == REDKEY) gate = REDGATE; else if(key == GREENKEY) gate = GREENGATE; else if(key == BLUEKEY) gate = BLUEGATE; int i, j; for(i = 0; i < level.matrix.length; i++) for(j = 0; j < level.matrix[i].length; j++) { if(level.matrix[i][j] == gate) { level.matrix[i][j] = EMPTY; break; } } } /** * search for other beam field and move the avatar */ protected void beamAvatar(char key, int x, int y) { int i, j; for(i = 0; i < level.matrix.length; i++) for(j = 0; j < level.matrix[i].length; j++) { if(level.matrix[i][j] == key && (x != j || y != i)) { avatar.x = j; avatar.y = i; break; } } } /** * Animating thread */ protected class ActionControlRunner extends Thread { protected boolean run = true; protected boolean pause = false; public void run() { while(run) { if(!pause) nextMove(); try { sleep(500); } catch(InterruptedException e) {} } } /** * pauses the while thread loop */ public void pauseRunner(boolean b) { pause = b; } /** * stop and exit from thread loop */ public void stopRunner() { System.out.println("Thread term."); run = false; } } }
|
ActionControl |
|