Key Config Test : 输入 « 游戏 « Java

En
Java
1. 图形用户界面
2. 三维图形动画
3. 高级图形
4. 蚂蚁编译
5. Apache类库
6. 统计图
7. 
8. 集合数据结构
9. 数据类型
10. 数据库JDBC
11. 设计模式
12. 开发相关类
13. EJB3
14. 电子邮件
15. 事件
16. 文件输入输出
17. 游戏
18. 泛型
19. GWT
20. Hibernate
21. 本地化
22. J2EE平台
23. 基于J2ME
24. JDK-6
25. JNDI的LDAP
26. JPA
27. JSP技术
28. JSTL
29. 语言基础知识
30. 网络协议
31. PDF格式RTF格式
32. 映射
33. 常规表达式
34. 脚本
35. 安全
36. Servlets
37. Spring
38. Swing组件
39. 图形用户界面
40. SWT-JFace-Eclipse
41. 线程
42. 应用程序
43. Velocity
44. Web服务SOA
45. 可扩展标记语言
Java 教程
Java » 游戏 » 输入屏幕截图 
Key Config Test

       /*
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.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
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.GridLayout;
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.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;

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

/**
 * The KeyConfigTest class extends the MenuTest demo to add a dialog to
 * configure the keyboard keys.
 */
public class KeyConfigTest extends MenuTest {

  public static void main(String[] args) {
    new KeyConfigTest().run();
  }

  private static final String INSTRUCTIONS = "<html>Click an action's input box to change it's keys."
      "<br>An action can have at most three keys associated "
      "with it.<br>Press Backspace to clear an action's keys.";

  private JPanel dialog;

  private JButton okButton;

  private List inputs;

  public void init() {
    super.init();

    inputs = new ArrayList();

    // create the list of GameActions and mapped keys
    JPanel configPanel = new JPanel(new GridLayout(5222));
    addActionConfig(configPanel, moveLeft);
    addActionConfig(configPanel, moveRight);
    addActionConfig(configPanel, jump);
    addActionConfig(configPanel, pause);
    addActionConfig(configPanel, exit);

    // create the panel containing the OK button
    JPanel bottomPanel = new JPanel(new FlowLayout());
    okButton = new JButton("OK");
    okButton.setFocusable(false);
    okButton.addActionListener(this);
    bottomPanel.add(okButton);

    // create the panel containing the instructions.
    JPanel topPanel = new JPanel(new FlowLayout());
    topPanel.add(new JLabel(INSTRUCTIONS));

    // create the dialog border
    Border border = BorderFactory.createLineBorder(Color.black);

    // create the config dialog.
    dialog = new JPanel(new BorderLayout());
    dialog.add(topPanel, BorderLayout.NORTH);
    dialog.add(configPanel, BorderLayout.CENTER);
    dialog.add(bottomPanel, BorderLayout.SOUTH);
    dialog.setBorder(border);
    dialog.setVisible(false);
    dialog.setSize(dialog.getPreferredSize());

    // center the dialog
    dialog.setLocation((screen.getWidth() - dialog.getWidth()) 2(screen
        .getHeight() - dialog.getHeight()) 2);

    // add the dialog to the "modal dialog" layer of the
    // screen's layered pane.
    screen.getFullScreenWindow().getLayeredPane().add(dialog,
        JLayeredPane.MODAL_LAYER);
  }

  /**
   * Adds a label containing the name of the GameAction and an InputComponent
   * used for changing the mapped keys.
   */
  private void addActionConfig(JPanel configPanel, GameAction action) {
    JLabel label = new JLabel(action.getName(), JLabel.RIGHT);
    InputComponent input = new InputComponent(action);
    configPanel.add(label);
    configPanel.add(input);
    inputs.add(input);
  }

  public void actionPerformed(ActionEvent e) {
    super.actionPerformed(e);
    if (e.getSource() == okButton) {
      // hides the config dialog
      configAction.tap();
    }
  }

  public void checkSystemInput() {
    super.checkSystemInput();
    if (configAction.isPressed()) {
      // hide or show the config dialog
      boolean show = !dialog.isVisible();
      dialog.setVisible(show);
      setPaused(show);
    }
  }

  /**
   * Resets the text displayed in each InputComponent, which is the names of
   * the mapped keys.
   */
  private void resetInputs() {
    for (int i = 0; i < inputs.size(); i++) {
      ((InputComponentinputs.get(i)).setText();
    }
  }

  /**
   * The InputComponent class displays the keys mapped to a particular action
   * and allows the user to change the mapped keys. The user selects an
   * InputComponent by clicking it, then can press any key or mouse button
   * (including the mouse wheel) to change the mapped value.
   */
  class InputComponent extends JTextField {

    private GameAction action;

    /**
     * Creates a new InputComponent for the specified GameAction.
     */
    public InputComponent(GameAction action) {
      this.action = action;
      setText();
      enableEvents(KeyEvent.KEY_EVENT_MASK | MouseEvent.MOUSE_EVENT_MASK
          | MouseEvent.MOUSE_MOTION_EVENT_MASK
          | MouseEvent.MOUSE_WHEEL_EVENT_MASK);
    }

    /**
     * Sets the displayed text of this InputComponent to the names of the
     * mapped keys.
     */
    private void setText() {
      String text = "";
      List list = inputManager.getMaps(action);
      if (list.size() 0) {
        for (int i = 0; i < list.size(); i++) {
          text += (Stringlist.get(i", ";
        }
        // remove the last comma
        text = text.substring(0, text.length() 2);
      }

      // make sure we don't get deadlock
      synchronized (getTreeLock()) {
        setText(text);
      }

    }

    /**
     * Maps the GameAction for this InputComponent to the specified key or
     * mouse action.
     */
    private void mapGameAction(int code, boolean isMouseMap) {
      if (inputManager.getMaps(action).size() >= 3) {
        inputManager.clearMap(action);
      }
      if (isMouseMap) {
        inputManager.mapToMouse(action, code);
      else {
        inputManager.mapToKey(action, code);
      }
      resetInputs();
      screen.getFullScreenWindow().requestFocus();
    }

    // alternative way to intercept key events
    protected void processKeyEvent(KeyEvent e) {
      if (e.getID() == e.KEY_PRESSED) {
        // if backspace is pressed, clear the map
        if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE
            && inputManager.getMaps(action).size() 0) {
          inputManager.clearMap(action);
          setText("");
          screen.getFullScreenWindow().requestFocus();
        else {
          mapGameAction(e.getKeyCode()false);
        }
      }
      e.consume();
    }

    // alternative way to intercept mouse events
    protected void processMouseEvent(MouseEvent e) {
      if (e.getID() == e.MOUSE_PRESSED) {
        if (hasFocus()) {
          int code = InputManager.getMouseButtonCode(e);
          mapGameAction(code, true);
        else {
          requestFocus();
        }
      }
      e.consume();
    }

    // alternative way to intercept mouse events
    protected void processMouseMotionEvent(MouseEvent e) {
      e.consume();
    }

    // alternative way to intercept mouse events
    protected void processMouseWheelEvent(MouseWheelEvent e) {
      if (hasFocus()) {
        int code = InputManager.MOUSE_WHEEL_DOWN;
        if (e.getWheelRotation() 0) {
          code = InputManager.MOUSE_WHEEL_UP;
        }
        mapGameAction(code, true);
      }
      e.consume();
    }
  }
}

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

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) {
      ((JComponentcontentPane).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).
   * <p>
   * 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 = (Graphics2Dimage.getGraphics();
    Composite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
        .5f);
    g.setComposite(alpha);
    g.drawImage(iconRollover.getImage()00null);
    g.dispose();
    ImageIcon iconDefault = new ImageIcon(image);

    // make a pressed iamge
    image = screen.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
    g = (Graphics2Dimage.getGraphics();
    g.drawImage(iconRollover.getImage()22null);
    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, 00null);

    // 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(800600320)new DisplayMode(800600240),
      new DisplayMode(800600160)new DisplayMode(640480320),
      new DisplayMode(640480240)new DisplayMode(640480160) };

  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 (Graphics2Dstrategy.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 (JFramedevice.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(00)"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.comp = 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[inull;
      }
    }

    for (int i = 0; i < mouseActions.length; i++) {
      if (mouseActions[i== gameAction) {
        mouseActions[inull;
      }
    }

    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 (AnimFrameframes.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
  }

}
   
           
       
Related examples in the same category
1. Input Manager Test
2. 一个简单的键盘测试一个简单的键盘测试
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.