Java/Game/Game Swing

Материал из Java эксперт
Перейти к: навигация, поиск

Game-Swing:MenuTest

   <source lang="java">
      /*

DEVELOPING GAME IN JAVA Caracteristiques Editeur : NEW RIDERS Auteur : BRACKEEN Parution : 09 2003 Pages : 972 Isbn : 1-59273-005-1 Reliure : Paperback Disponibilite : Disponible a la librairie

  • /

import java.awt.AWTException; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.ruponent; import java.awt.ruposite; import java.awt.Container; import java.awt.Cursor; import java.awt.DisplayMode; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Point; import java.awt.Robot; import java.awt.Toolkit; import java.awt.Transparency; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.RepaintManager; import javax.swing.SwingUtilities; /**

* Extends the InputManagerTest demo and adds Swing buttons for pause, config
* and quit.
*/

public class MenuTest extends InputManagerTest implements ActionListener {

 public static void main(String[] args) {
   new MenuTest().run();
 }
 protected GameAction configAction;
 private JButton playButton;
 private JButton configButton;
 private JButton quitButton;
 private JButton pauseButton;
 private JPanel playButtonSpace;
 public void init() {
   super.init();
   // make sure Swing components don"t paint themselves
   NullRepaintManager.install();
   // create an addtional GameAction for "config"
   configAction = new GameAction("config");
   // create buttons
   quitButton = createButton("quit", "Quit");
   playButton = createButton("play", "Continue");
   pauseButton = createButton("pause", "Pause");
   configButton = createButton("config", "Change Settings");
   // create the space where the play/pause buttons go.
   playButtonSpace = new JPanel();
   playButtonSpace.setOpaque(false);
   playButtonSpace.add(pauseButton);
   JFrame frame = super.screen.getFullScreenWindow();
   Container contentPane = frame.getContentPane();
   // make sure the content pane is transparent
   if (contentPane instanceof JComponent) {
     ((JComponent) contentPane).setOpaque(false);
   }
   // add components to the screen"s content pane
   contentPane.setLayout(new FlowLayout(FlowLayout.LEFT));
   contentPane.add(playButtonSpace);
   contentPane.add(configButton);
   contentPane.add(quitButton);
   // explicitly layout components (needed on some systems)
   frame.validate();
 }
 /**
  * Extends InputManagerTest"s functionality to draw all Swing components.
  */
 public void draw(Graphics2D g) {
   super.draw(g);
   JFrame frame = super.screen.getFullScreenWindow();
   // the layered pane contains things like popups (tooltips,
   // popup menus) and the content pane.
   frame.getLayeredPane().paintComponents(g);
 }
 /**
  * Changes the pause/play button whenever the pause state changes.
  */
 public void setPaused(boolean p) {
   super.setPaused(p);
   playButtonSpace.removeAll();
   if (isPaused()) {
     playButtonSpace.add(playButton);
   } else {
     playButtonSpace.add(pauseButton);
   }
 }
 /**
  * Called by the AWT event dispatch thread when a button is pressed.
  */
 public void actionPerformed(ActionEvent e) {
   Object src = e.getSource();
   if (src == quitButton) {
     // fire the "exit" gameAction
     super.exit.tap();
   } else if (src == configButton) {
     // doesn"t do anything (for now)
     configAction.tap();
   } else if (src == playButton || src == pauseButton) {
     // fire the "pause" gameAction
     super.pause.tap();
   }
 }
 /**
  * Creates a Swing JButton. The image used for the button is located at
  * "../images/menu/" + name + ".png". The image is modified to create a
  * "default" look (translucent) and a "pressed" look (moved down and to the
  * right).
*

* The button doesn"t use Swing"s look-and-feel and instead just uses the * image. */ public JButton createButton(String name, String toolTip) { // load the image String imagePath = "../images/menu/" + name + ".png"; ImageIcon iconRollover = new ImageIcon(imagePath); int w = iconRollover.getIconWidth(); int h = iconRollover.getIconHeight(); // get the cursor for this button Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); // make translucent default image Image image = screen.createCompatibleImage(w, h, Transparency.TRANSLUCENT); Graphics2D g = (Graphics2D) image.getGraphics(); Composite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f); g.setComposite(alpha); g.drawImage(iconRollover.getImage(), 0, 0, null); g.dispose(); ImageIcon iconDefault = new ImageIcon(image); // make a pressed iamge image = screen.createCompatibleImage(w, h, Transparency.TRANSLUCENT); g = (Graphics2D) image.getGraphics(); g.drawImage(iconRollover.getImage(), 2, 2, null); g.dispose(); ImageIcon iconPressed = new ImageIcon(image); // create the button JButton button = new JButton(); button.addActionListener(this); button.setIgnoreRepaint(true); button.setFocusable(false); button.setToolTipText(toolTip); button.setBorder(null); button.setContentAreaFilled(false); button.setCursor(cursor); button.setIcon(iconDefault); button.setRolloverIcon(iconRollover); button.setPressedIcon(iconPressed); return button; } } /** * InputManagerTest tests the InputManager with a simple run-and-jump mechanism. * The player moves and jumps using the arrow keys and the space bar. * <p> * Also, InputManagerTest demonstrates pausing a game by not updating the game * elements if the game is paused. */ class InputManagerTest extends GameCore { public static void main(String[] args) { new InputManagerTest().run(); } protected GameAction jump; protected GameAction exit; protected GameAction moveLeft; protected GameAction moveRight; protected GameAction pause; protected InputManager inputManager; private Player player; private Image bgImage; private boolean paused; public void init() { super.init(); Window window = screen.getFullScreenWindow(); inputManager = new InputManager(window); // use these lines for relative mouse mode //inputManager.setRelativeMouseMode(true); //inputManager.setCursor(InputManager.INVISIBLE_CURSOR); createGameActions(); createSprite(); paused = false; } /** * Tests whether the game is paused or not. */ public boolean isPaused() { return paused; } /** * Sets the paused state. */ public void setPaused(boolean p) { if (paused != p) { this.paused = p; inputManager.resetAllGameActions(); } } public void update(long elapsedTime) { // check input that can happen whether paused or not checkSystemInput(); if (!isPaused()) { // check game input checkGameInput(); // update sprite player.update(elapsedTime); } } /** * Checks input from GameActions that can be pressed regardless of whether * the game is paused or not. */ public void checkSystemInput() { if (pause.isPressed()) { setPaused(!isPaused()); } if (exit.isPressed()) { stop(); } } /** * Checks input from GameActions that can be pressed only when the game is * not paused. */ public void checkGameInput() { float velocityX = 0; if (moveLeft.isPressed()) { velocityX -= Player.SPEED; } if (moveRight.isPressed()) { velocityX += Player.SPEED; } player.setVelocityX(velocityX); if (jump.isPressed() && player.getState() != Player.STATE_JUMPING) { player.jump(); } } public void draw(Graphics2D g) { // draw background g.drawImage(bgImage, 0, 0, null); // draw sprite g.drawImage(player.getImage(), Math.round(player.getX()), Math .round(player.getY()), null); } /** * Creates GameActions and maps them to keys. */ public void createGameActions() { jump = new GameAction("jump", GameAction.DETECT_INITAL_PRESS_ONLY); exit = new GameAction("exit", GameAction.DETECT_INITAL_PRESS_ONLY); moveLeft = new GameAction("moveLeft"); moveRight = new GameAction("moveRight"); pause = new GameAction("pause", GameAction.DETECT_INITAL_PRESS_ONLY); inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE); inputManager.mapToKey(pause, KeyEvent.VK_P); // jump with spacebar or mouse button inputManager.mapToKey(jump, KeyEvent.VK_SPACE); inputManager.mapToMouse(jump, InputManager.MOUSE_BUTTON_1); // move with the arrow keys... inputManager.mapToKey(moveLeft, KeyEvent.VK_LEFT); inputManager.mapToKey(moveRight, KeyEvent.VK_RIGHT); // ... or with A and D. inputManager.mapToKey(moveLeft, KeyEvent.VK_A); inputManager.mapToKey(moveRight, KeyEvent.VK_D); // use these lines to map player movement to the mouse //inputManager.mapToMouse(moveLeft, // InputManager.MOUSE_MOVE_LEFT); //inputManager.mapToMouse(moveRight, // InputManager.MOUSE_MOVE_RIGHT); } /** * Load images and creates the Player sprite. */ private void createSprite() { // load images bgImage = loadImage("../images/background.jpg"); Image player1 = loadImage("../images/player1.png"); Image player2 = loadImage("../images/player2.png"); Image player3 = loadImage("../images/player3.png"); // create animation Animation anim = new Animation(); anim.addFrame(player1, 250); anim.addFrame(player2, 150); anim.addFrame(player1, 150); anim.addFrame(player2, 150); anim.addFrame(player3, 200); anim.addFrame(player2, 150); player = new Player(anim); player.setFloorY(screen.getHeight() - player.getHeight()); } } /** * The Player extends the Sprite class to add states (STATE_NORMAL or * STATE_JUMPING) and gravity. */ class Player extends Sprite { public static final int STATE_NORMAL = 0; public static final int STATE_JUMPING = 1; public static final float SPEED = .3f; public static final float GRAVITY = .002f; private int floorY; private int state; public Player(Animation anim) { super(anim); state = STATE_NORMAL; } /** * Gets the state of the Player (either STATE_NORMAL or STATE_JUMPING); */ public int getState() { return state; } /** * Sets the state of the Player (either STATE_NORMAL or STATE_JUMPING); */ public void setState(int state) { this.state = state; } /** * Sets the location of "floor", where the Player starts and lands after * jumping. */ public void setFloorY(int floorY) { this.floorY = floorY; setY(floorY); } /** * Causes the Player to jump */ public void jump() { setVelocityY(-1); state = STATE_JUMPING; } /** * Updates the player"s positon and animation. Also, sets the Player"s state * to NORMAL if a jumping Player landed on the floor. */ public void update(long elapsedTime) { // set vertical velocity (gravity effect) if (getState() == STATE_JUMPING) { setVelocityY(getVelocityY() + GRAVITY * elapsedTime); } // move player super.update(elapsedTime); // check if player landed on floor if (getState() == STATE_JUMPING && getY() >= floorY) { setVelocityY(0); setY(floorY); setState(STATE_NORMAL); } } } /** * The GameAction class is an abstract to a user-initiated action, like jumping * or moving. GameActions can be mapped to keys or the mouse with the * InputManager. */ class GameAction { /** * Normal behavior. The isPressed() method returns true as long as the key * is held down. */ public static final int NORMAL = 0; /** * Initial press behavior. The isPressed() method returns true only after * the key is first pressed, and not again until the key is released and * pressed again. */ public static final int DETECT_INITAL_PRESS_ONLY = 1; private static final int STATE_RELEASED = 0; private static final int STATE_PRESSED = 1; private static final int STATE_WAITING_FOR_RELEASE = 2; private String name; private int behavior; private int amount; private int state; /** * Create a new GameAction with the NORMAL behavior. */ public GameAction(String name) { this(name, NORMAL); } /** * Create a new GameAction with the specified behavior. */ public GameAction(String name, int behavior) { this.name = name; this.behavior = behavior; reset(); } /** * Gets the name of this GameAction. */ public String getName() { return name; } /** * Resets this GameAction so that it appears like it hasn"t been pressed. */ public void reset() { state = STATE_RELEASED; amount = 0; } /** * Taps this GameAction. Same as calling press() followed by release(). */ public synchronized void tap() { press(); release(); } /** * Signals that the key was pressed. */ public synchronized void press() { press(1); } /** * Signals that the key was pressed a specified number of times, or that the * mouse move a spcified distance. */ public synchronized void press(int amount) { if (state != STATE_WAITING_FOR_RELEASE) { this.amount += amount; state = STATE_PRESSED; } } /** * Signals that the key was released */ public synchronized void release() { state = STATE_RELEASED; } /** * Returns whether the key was pressed or not since last checked. */ public synchronized boolean isPressed() { return (getAmount() != 0); } /** * For keys, this is the number of times the key was pressed since it was * last checked. For mouse movement, this is the distance moved. */ public synchronized int getAmount() { int retVal = amount; if (retVal != 0) { if (state == STATE_RELEASED) { amount = 0; } else if (behavior == DETECT_INITAL_PRESS_ONLY) { state = STATE_WAITING_FOR_RELEASE; amount = 0; } } return retVal; } } /** * Simple abstract class used for testing. Subclasses should implement the * draw() method. */ abstract class GameCore { protected static final int FONT_SIZE = 24; private static final DisplayMode POSSIBLE_MODES[] = { new DisplayMode(800, 600, 32, 0), new DisplayMode(800, 600, 24, 0), new DisplayMode(800, 600, 16, 0), new DisplayMode(640, 480, 32, 0), new DisplayMode(640, 480, 24, 0), new DisplayMode(640, 480, 16, 0) }; private boolean isRunning; protected ScreenManager screen; /** * Signals the game loop that it"s time to quit */ public void stop() { isRunning = false; } /** * Calls init() and gameLoop() */ public void run() { try { init(); gameLoop(); } finally { screen.restoreScreen(); } } /** * Sets full screen mode and initiates and objects. */ public void init() { screen = new ScreenManager(); DisplayMode displayMode = screen .findFirstCompatibleMode(POSSIBLE_MODES); screen.setFullScreen(displayMode); Window window = screen.getFullScreenWindow(); window.setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE)); window.setBackground(Color.blue); window.setForeground(Color.white); isRunning = true; } public Image loadImage(String fileName) { return new ImageIcon(fileName).getImage(); } /** * Runs through the game loop until stop() is called. */ public void gameLoop() { long startTime = System.currentTimeMillis(); long currTime = startTime; while (isRunning) { long elapsedTime = System.currentTimeMillis() - currTime; currTime += elapsedTime; // update update(elapsedTime); // draw the screen Graphics2D g = screen.getGraphics(); draw(g); g.dispose(); screen.update(); // take a nap try { Thread.sleep(20); } catch (InterruptedException ex) { } } } /** * Updates the state of the game/animation based on the amount of elapsed * time that has passed. */ public void update(long elapsedTime) { // do nothing } /** * Draws to the screen. Subclasses must override this method. */ public abstract void draw(Graphics2D g); } /** * The ScreenManager class manages initializing and displaying full screen * graphics modes. */ class ScreenManager { private GraphicsDevice device; /** * Creates a new ScreenManager object. */ public ScreenManager() { GraphicsEnvironment environment = GraphicsEnvironment .getLocalGraphicsEnvironment(); device = environment.getDefaultScreenDevice(); } /** * Returns a list of compatible display modes for the default device on the * system. */ public DisplayMode[] getCompatibleDisplayModes() { return device.getDisplayModes(); } /** * Returns the first compatible mode in a list of modes. Returns null if no * modes are compatible. */ public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) { DisplayMode goodModes[] = device.getDisplayModes(); for (int i = 0; i < modes.length; i++) { for (int j = 0; j < goodModes.length; j++) { if (displayModesMatch(modes[i], goodModes[j])) { return modes[i]; } } } return null; } /** * Returns the current display mode. */ public DisplayMode getCurrentDisplayMode() { return device.getDisplayMode(); } /** * Determines if two display modes "match". Two display modes match if they * have the same resolution, bit depth, and refresh rate. The bit depth is * ignored if one of the modes has a bit depth of * DisplayMode.BIT_DEPTH_MULTI. Likewise, the refresh rate is ignored if one * of the modes has a refresh rate of DisplayMode.REFRESH_RATE_UNKNOWN. */ public boolean displayModesMatch(DisplayMode mode1, DisplayMode mode2) { if (mode1.getWidth() != mode2.getWidth() || mode1.getHeight() != mode2.getHeight()) { return false; } if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && mode1.getBitDepth() != mode2.getBitDepth()) { return false; } if (mode1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && mode2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && mode1.getRefreshRate() != mode2.getRefreshRate()) { return false; } return true; } /** * Enters full screen mode and changes the display mode. If the specified * display mode is null or not compatible with this device, or if the * display mode cannot be changed on this system, the current display mode * is used. * <p> * The display uses a BufferStrategy with 2 buffers. */ public void setFullScreen(DisplayMode displayMode) { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setUndecorated(true); frame.setIgnoreRepaint(true); frame.setResizable(false); device.setFullScreenWindow(frame); if (displayMode != null && device.isDisplayChangeSupported()) { try { device.setDisplayMode(displayMode); } catch (IllegalArgumentException ex) { } // fix for mac os x frame.setSize(displayMode.getWidth(), displayMode.getHeight()); } // avoid potential deadlock in 1.4.1_02 try { EventQueue.invokeAndWait(new Runnable() { public void run() { frame.createBufferStrategy(2); } }); } catch (InterruptedException ex) { // ignore } catch (InvocationTargetException ex) { // ignore } } /** * Gets the graphics context for the display. The ScreenManager uses double * buffering, so applications must call update() to show any graphics drawn. * <p> * The application must dispose of the graphics object. */ public Graphics2D getGraphics() { Window window = device.getFullScreenWindow(); if (window != null) { BufferStrategy strategy = window.getBufferStrategy(); return (Graphics2D) strategy.getDrawGraphics(); } else { return null; } } /** * Updates the display. */ public void update() { Window window = device.getFullScreenWindow(); if (window != null) { BufferStrategy strategy = window.getBufferStrategy(); if (!strategy.contentsLost()) { strategy.show(); } } // Sync the display on some systems. // (on Linux, this fixes event queue problems) Toolkit.getDefaultToolkit().sync(); } /** * Returns the window currently used in full screen mode. Returns null if * the device is not in full screen mode. */ public JFrame getFullScreenWindow() { return (JFrame) device.getFullScreenWindow(); } /** * Returns the width of the window currently used in full screen mode. * Returns 0 if the device is not in full screen mode. */ public int getWidth() { Window window = device.getFullScreenWindow(); if (window != null) { return window.getWidth(); } else { return 0; } } /** * Returns the height of the window currently used in full screen mode. * Returns 0 if the device is not in full screen mode. */ public int getHeight() { Window window = device.getFullScreenWindow(); if (window != null) { return window.getHeight(); } else { return 0; } } /** * Restores the screen"s display mode. */ public void restoreScreen() { Window window = device.getFullScreenWindow(); if (window != null) { window.dispose(); } device.setFullScreenWindow(null); } /** * Creates an image compatible with the current display. */ public BufferedImage createCompatibleImage(int w, int h, int transparancy) { Window window = device.getFullScreenWindow(); if (window != null) { GraphicsConfiguration gc = window.getGraphicsConfiguration(); return gc.createCompatibleImage(w, h, transparancy); } return null; } } /** * The InputManager manages input of key and mouse events. Events are mapped to * GameActions. */ class InputManager implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener { /** * An invisible cursor. */ public static final Cursor INVISIBLE_CURSOR = Toolkit.getDefaultToolkit() .createCustomCursor(Toolkit.getDefaultToolkit().getImage(""), new Point(0, 0), "invisible"); // mouse codes public static final int MOUSE_MOVE_LEFT = 0; public static final int MOUSE_MOVE_RIGHT = 1; public static final int MOUSE_MOVE_UP = 2; public static final int MOUSE_MOVE_DOWN = 3; public static final int MOUSE_WHEEL_UP = 4; public static final int MOUSE_WHEEL_DOWN = 5; public static final int MOUSE_BUTTON_1 = 6; public static final int MOUSE_BUTTON_2 = 7; public static final int MOUSE_BUTTON_3 = 8; private static final int NUM_MOUSE_CODES = 9; // key codes are defined in java.awt.KeyEvent. // most of the codes (except for some rare ones like // "alt graph") are less than 600. private static final int NUM_KEY_CODES = 600; private GameAction[] keyActions = new GameAction[NUM_KEY_CODES]; private GameAction[] mouseActions = new GameAction[NUM_MOUSE_CODES]; private Point mouseLocation; private Point centerLocation; private Component comp; private Robot robot; private boolean isRecentering; /** * Creates a new InputManager that listens to input from the specified * component. */ public InputManager(Component comp) { this.rup = comp; mouseLocation = new Point(); centerLocation = new Point(); // register key and mouse listeners comp.addKeyListener(this); comp.addMouseListener(this); comp.addMouseMotionListener(this); comp.addMouseWheelListener(this); // allow input of the TAB key and other keys normally // used for focus traversal comp.setFocusTraversalKeysEnabled(false); } /** * Sets the cursor on this InputManager"s input component. */ public void setCursor(Cursor cursor) { comp.setCursor(cursor); } /** * Sets whether realtive mouse mode is on or not. For relative mouse mode, * the mouse is "locked" in the center of the screen, and only the changed * in mouse movement is measured. In normal mode, the mouse is free to move * about the screen. */ public void setRelativeMouseMode(boolean mode) { if (mode == isRelativeMouseMode()) { return; } if (mode) { try { robot = new Robot(); recenterMouse(); } catch (AWTException ex) { // couldn"t create robot! robot = null; } } else { robot = null; } } /** * Returns whether or not relative mouse mode is on. */ public boolean isRelativeMouseMode() { return (robot != null); } /** * Maps a GameAction to a specific key. The key codes are defined in * java.awt.KeyEvent. If the key already has a GameAction mapped to it, the * new GameAction overwrites it. */ public void mapToKey(GameAction gameAction, int keyCode) { keyActions[keyCode] = gameAction; } /** * Maps a GameAction to a specific mouse action. The mouse codes are defined * herer in InputManager (MOUSE_MOVE_LEFT, MOUSE_BUTTON_1, etc). If the * mouse action already has a GameAction mapped to it, the new GameAction * overwrites it. */ public void mapToMouse(GameAction gameAction, int mouseCode) { mouseActions[mouseCode] = gameAction; } /** * Clears all mapped keys and mouse actions to this GameAction. */ public void clearMap(GameAction gameAction) { for (int i = 0; i < keyActions.length; i++) { if (keyActions[i] == gameAction) { keyActions[i] = null; } } for (int i = 0; i < mouseActions.length; i++) { if (mouseActions[i] == gameAction) { mouseActions[i] = null; } } gameAction.reset(); } /** * Gets a List of names of the keys and mouse actions mapped to this * GameAction. Each entry in the List is a String. */ public List getMaps(GameAction gameCode) { ArrayList list = new ArrayList(); for (int i = 0; i < keyActions.length; i++) { if (keyActions[i] == gameCode) { list.add(getKeyName(i)); } } for (int i = 0; i < mouseActions.length; i++) { if (mouseActions[i] == gameCode) { list.add(getMouseName(i)); } } return list; } /** * Resets all GameActions so they appear like they haven"t been pressed. */ public void resetAllGameActions() { for (int i = 0; i < keyActions.length; i++) { if (keyActions[i] != null) { keyActions[i].reset(); } } for (int i = 0; i < mouseActions.length; i++) { if (mouseActions[i] != null) { mouseActions[i].reset(); } } } /** * Gets the name of a key code. */ public static String getKeyName(int keyCode) { return KeyEvent.getKeyText(keyCode); } /** * Gets the name of a mouse code. */ public static String getMouseName(int mouseCode) { switch (mouseCode) { case MOUSE_MOVE_LEFT: return "Mouse Left"; case MOUSE_MOVE_RIGHT: return "Mouse Right"; case MOUSE_MOVE_UP: return "Mouse Up"; case MOUSE_MOVE_DOWN: return "Mouse Down"; case MOUSE_WHEEL_UP: return "Mouse Wheel Up"; case MOUSE_WHEEL_DOWN: return "Mouse Wheel Down"; case MOUSE_BUTTON_1: return "Mouse Button 1"; case MOUSE_BUTTON_2: return "Mouse Button 2"; case MOUSE_BUTTON_3: return "Mouse Button 3"; default: return "Unknown mouse code " + mouseCode; } } /** * Gets the x position of the mouse. */ public int getMouseX() { return mouseLocation.x; } /** * Gets the y position of the mouse. */ public int getMouseY() { return mouseLocation.y; } /** * Uses the Robot class to try to postion the mouse in the center of the * screen. * <p> * Note that use of the Robot class may not be available on all platforms. */ private synchronized void recenterMouse() { if (robot != null && comp.isShowing()) { centerLocation.x = comp.getWidth() / 2; centerLocation.y = comp.getHeight() / 2; SwingUtilities.convertPointToScreen(centerLocation, comp); isRecentering = true; robot.mouseMove(centerLocation.x, centerLocation.y); } } private GameAction getKeyAction(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode < keyActions.length) { return keyActions[keyCode]; } else { return null; } } /** * Gets the mouse code for the button specified in this MouseEvent. */ public static int getMouseButtonCode(MouseEvent e) { switch (e.getButton()) { case MouseEvent.BUTTON1: return MOUSE_BUTTON_1; case MouseEvent.BUTTON2: return MOUSE_BUTTON_2; case MouseEvent.BUTTON3: return MOUSE_BUTTON_3; default: return -1; } } private GameAction getMouseButtonAction(MouseEvent e) { int mouseCode = getMouseButtonCode(e); if (mouseCode != -1) { return mouseActions[mouseCode]; } else { return null; } } // from the KeyListener interface public void keyPressed(KeyEvent e) { GameAction gameAction = getKeyAction(e); if (gameAction != null) { gameAction.press(); } // make sure the key isn"t processed for anything else e.consume(); } // from the KeyListener interface public void keyReleased(KeyEvent e) { GameAction gameAction = getKeyAction(e); if (gameAction != null) { gameAction.release(); } // make sure the key isn"t processed for anything else e.consume(); } // from the KeyListener interface public void keyTyped(KeyEvent e) { // make sure the key isn"t processed for anything else e.consume(); } // from the MouseListener interface public void mousePressed(MouseEvent e) { GameAction gameAction = getMouseButtonAction(e); if (gameAction != null) { gameAction.press(); } } // from the MouseListener interface public void mouseReleased(MouseEvent e) { GameAction gameAction = getMouseButtonAction(e); if (gameAction != null) { gameAction.release(); } } // from the MouseListener interface public void mouseClicked(MouseEvent e) { // do nothing } // from the MouseListener interface public void mouseEntered(MouseEvent e) { mouseMoved(e); } // from the MouseListener interface public void mouseExited(MouseEvent e) { mouseMoved(e); } // from the MouseMotionListener interface public void mouseDragged(MouseEvent e) { mouseMoved(e); } // from the MouseMotionListener interface public synchronized void mouseMoved(MouseEvent e) { // this event is from re-centering the mouse - ignore it if (isRecentering && centerLocation.x == e.getX() && centerLocation.y == e.getY()) { isRecentering = false; } else { int dx = e.getX() - mouseLocation.x; int dy = e.getY() - mouseLocation.y; mouseHelper(MOUSE_MOVE_LEFT, MOUSE_MOVE_RIGHT, dx); mouseHelper(MOUSE_MOVE_UP, MOUSE_MOVE_DOWN, dy); if (isRelativeMouseMode()) { recenterMouse(); } } mouseLocation.x = e.getX(); mouseLocation.y = e.getY(); } // from the MouseWheelListener interface public void mouseWheelMoved(MouseWheelEvent e) { mouseHelper(MOUSE_WHEEL_UP, MOUSE_WHEEL_DOWN, e.getWheelRotation()); } private void mouseHelper(int codeNeg, int codePos, int amount) { GameAction gameAction; if (amount < 0) { gameAction = mouseActions[codeNeg]; } else { gameAction = mouseActions[codePos]; } if (gameAction != null) { gameAction.press(Math.abs(amount)); gameAction.release(); } } } class Sprite { private Animation anim; // position (pixels) private float x; private float y; // velocity (pixels per millisecond) private float dx; private float dy; /** * Creates a new Sprite object with the specified Animation. */ public Sprite(Animation anim) { this.anim = anim; } /** * Updates this Sprite"s Animation and its position based on the velocity. */ public void update(long elapsedTime) { x += dx * elapsedTime; y += dy * elapsedTime; anim.update(elapsedTime); } /** * Gets this Sprite"s current x position. */ public float getX() { return x; } /** * Gets this Sprite"s current y position. */ public float getY() { return y; } /** * Sets this Sprite"s current x position. */ public void setX(float x) { this.x = x; } /** * Sets this Sprite"s current y position. */ public void setY(float y) { this.y = y; } /** * Gets this Sprite"s width, based on the size of the current image. */ public int getWidth() { return anim.getImage().getWidth(null); } /** * Gets this Sprite"s height, based on the size of the current image. */ public int getHeight() { return anim.getImage().getHeight(null); } /** * Gets the horizontal velocity of this Sprite in pixels per millisecond. */ public float getVelocityX() { return dx; } /** * Gets the vertical velocity of this Sprite in pixels per millisecond. */ public float getVelocityY() { return dy; } /** * Sets the horizontal velocity of this Sprite in pixels per millisecond. */ public void setVelocityX(float dx) { this.dx = dx; } /** * Sets the vertical velocity of this Sprite in pixels per millisecond. */ public void setVelocityY(float dy) { this.dy = dy; } /** * Gets this Sprite"s current image. */ public Image getImage() { return anim.getImage(); } } /** * The Animation class manages a series of images (frames) and the amount of * time to display each frame. */ class Animation { private ArrayList frames; private int currFrameIndex; private long animTime; private long totalDuration; /** * Creates a new, empty Animation. */ public Animation() { frames = new ArrayList(); totalDuration = 0; start(); } /** * Adds an image to the animation with the specified duration (time to * display the image). */ public synchronized void addFrame(Image image, long duration) { totalDuration += duration; frames.add(new AnimFrame(image, totalDuration)); } /** * Starts this animation over from the beginning. */ public synchronized void start() { animTime = 0; currFrameIndex = 0; } /** * Updates this animation"s current image (frame), if neccesary. */ public synchronized void update(long elapsedTime) { if (frames.size() > 1) { animTime += elapsedTime; if (animTime >= totalDuration) { animTime = animTime % totalDuration; currFrameIndex = 0; } while (animTime > getFrame(currFrameIndex).endTime) { currFrameIndex++; } } } /** * Gets this Animation"s current image. Returns null if this animation has * no images. */ public synchronized Image getImage() { if (frames.size() == 0) { return null; } else { return getFrame(currFrameIndex).image; } } private AnimFrame getFrame(int i) { return (AnimFrame) frames.get(i); } private class AnimFrame { Image image; long endTime; public AnimFrame(Image image, long endTime) { this.image = image; this.endTime = endTime; } } } /** * The NullRepaintManager is a RepaintManager that doesn"t do any repainting. * Useful when all the rendering is done manually by the application. */ class NullRepaintManager extends RepaintManager { /** * Installs the NullRepaintManager. */ public static void install() { RepaintManager repaintManager = new NullRepaintManager(); repaintManager.setDoubleBufferingEnabled(false); RepaintManager.setCurrentManager(repaintManager); } public void addInvalidComponent(JComponent c) { // do nothing } public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { // do nothing } public void markCompletelyDirty(JComponent c) { // do nothing } public void paintDirtyRegions() { // do nothing } } </source>