手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏07游戏输入管理

简介: 手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏07游戏输入管理

项目源码


项目源码


输入管理

package managers;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class InputManager implements KeyListener {
    private static InputManager singleton = null;
    protected InputManager() {
    }
    public static InputManager getInstance() {
         if(singleton==null) {
              singleton = new InputManager();
         }
         return singleton;
    }
    private int[] keys = new int[256];
    private boolean[] key_state_up = new boolean[256];
    private boolean[] key_state_down = new boolean[256];
    private boolean keyPressed = false;
    private boolean keyReleased = false; 
    private char keyChar;
    @Override
    public void keyTyped(KeyEvent e) {
    }
    public void keyPressed(KeyEvent e) {
        if( e.getKeyCode() >= 0 && e.getKeyCode() < 256 ) {
            keys[e.getKeyCode()] = (int) System.currentTimeMillis();
            key_state_down[e.getKeyCode()] = true;
            key_state_up[e.getKeyCode()] = false;
            keyPressed = true;
            keyReleased = false;
        }
    }
    public char getKeyChar(){
        return keyChar;
    }
    public void keyReleased(KeyEvent e) {
        if( e.getKeyCode() >= 0 && e.getKeyCode() < 256 ) {
            keys[e.getKeyCode()] = 0;
            key_state_up[e.getKeyCode()] = true;
            key_state_down[e.getKeyCode()] = false;
            keyChar = e.getKeyChar();
            keyPressed = false;
            keyReleased = true;
        }
    }
    public boolean isKeyDown( int key ) {
        return key_state_down[key];
    }
    public boolean isKeyUp( int key ) {
        return key_state_up[key];
    }
    public boolean isAnyKeyDown() {
        return keyPressed;
    }
    public boolean isAnyKeyUp() {
        return keyReleased;
    }
    public void update() {
        key_state_up = new boolean[256];
        keyReleased = false;
    }
}

InputManager类实现KeyListener接口,监听keyPressed键按下事件和keyReleased键释放事件。

接下来我们在game主循环中就可以调用isKeyDown和isKeyUp方法来查询是否某个键被按下或释放。并且我们在每一次游戏循环中

都需要调用update方法重新分配key_state_up数组,这样可以保证每次循环最多检测到一次isKeyUp。

下面是一个测试类。


InputManager测试类

package main;
import managers.InputManager;
import java.awt.*;
import java.awt.event.*;
/**
 * This is just a simple test example for the input manager snippet. It is
 * just a simple frame and a threaded loop that runs about every 16 milliseconds
 * or so which is 62.5 times per second.
 */
public class InputManagerTest extends Frame implements Runnable {
    // The test input manager
    private final InputManager input;
    // Used to only start the looping thread once.
    private boolean             isTestLoopRunning   = false;
    /**
     * Add the InputManager as the KeyListener to the Frame.
     */
    public InputManagerTest() {
        input = InputManager.getInstance();
        this.addKeyListener(input);
        this.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentShown(ComponentEvent e) {
                startTestLoop();
            }
        });
    }
    /**
     * Starts a new thread using this class as the Runnable instance for that
     * thread.
     */
    public void startTestLoop() {
        //only want to run once.
        if (!isTestLoopRunning) {
            (new Thread(this)).start();
            isTestLoopRunning = true;
        }
    }
    /**
     * The meat of the test to check and make sure the input manager is working
     * correctly.
     */
    @Override
    public void run() {
        System.out.println("Start Test Loop");
        //use this to test how many times the loop detects a key is down
        int count = 0;
        //run while the frame is showing
        while (this.isShowing()) {
            // run test cases
            if (input.isAnyKeyDown()) {
                System.out.println("Some key is down");
            }
            if (input.isAnyKeyUp()) {
                System.out.println("Some key is up");
            }
            if(input.isKeyDown(KeyEvent.VK_SPACE)) {
                ++count;
                System.out.println("Spacebar is down");
            }
            if(input.isKeyUp(KeyEvent.VK_SPACE)) {
                System.out.println("Spacebar is up");
                System.out.format("Spacebar detected down %d times\n", count);
                count = 0; //reset the counter
            }
            input.update();
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } // just do a constant 16 milliseconds
        }
        System.out.println("End Test Loop");
    }
    /**
     * Main method to use to run the test from, it creates a basic awt frame and
     * displays the frame.
     * 
     * @param args Command line arguments.
     */
    public static void main(String[] args) {
        final Frame frame = new InputManagerTest(); //create our test class.
        // set a default size for the window, basically just give it some area.
        frame.setSize(640, 480);
        frame.setLocationRelativeTo(null); // centers window on screen
        // Need to add this to handle window closing events with the awt Frame.
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent arg0) {
                frame.setVisible(false);
                frame.dispose();
                System.exit(0);
            }
        });
        // show the frame
        frame.setVisible(true);
    }
}

该类不详细解释了,执行InputManagerTest,按一下空格键,得到以下输出:

Start Test Loop
Some key is down
Spacebar is down
Some key is down
Spacebar is down
Some key is down
Spacebar is down
Some key is down
Spacebar is down
Some key is down
Spacebar is down
Some key is down
Spacebar is down
Some key is up
Spacebar is up
Spacebar detected down 6 times
End Test Loop
Process finished with exit code 0

为什么检测到多次isKeyDown事件,而只有一次isKeyUp事件?

注意上面

input.update();


每次循环我们都会调用InputManager的update方法,重新分配key_state_up数组。

我们按下空格键这个短暂的时间,主循环循环了多次,但因为每次我们都重新分配了key_state_up数组,

故检测到多次isKeyDown事件,而只有一次isKeyUp事件。


目录
相关文章
|
3天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
28 3
|
5天前
|
JavaScript Java 测试技术
基于Java的同城蔬菜配送管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的同城蔬菜配送管理系统的设计与实现(源码+lw+部署文档+讲解等)
10 0
|
5天前
|
JavaScript Java 测试技术
基于Java的心理预约咨询管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的心理预约咨询管理系统的设计与实现(源码+lw+部署文档+讲解等)
21 0
基于Java的心理预约咨询管理系统的设计与实现(源码+lw+部署文档+讲解等)
|
5天前
|
JavaScript Java 测试技术
基于Java的高校毕业生就业管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的高校毕业生就业管理系统的设计与实现(源码+lw+部署文档+讲解等)
21 0
基于Java的高校毕业生就业管理系统的设计与实现(源码+lw+部署文档+讲解等)
|
5天前
|
JavaScript Java 测试技术
基于Java的西安旅游管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的西安旅游管理系统的设计与实现(源码+lw+部署文档+讲解等)
17 0
|
5天前
|
JavaScript Java 测试技术
基于Java的学生奖惩管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的学生奖惩管理系统的设计与实现(源码+lw+部署文档+讲解等)
5 0
|
5天前
|
JavaScript Java 测试技术
基于Java的校园兼职管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的校园兼职管理系统的设计与实现(源码+lw+部署文档+讲解等)
17 0
|
5天前
|
JavaScript Java 测试技术
基于Java的西藏民族大学创新学分管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的西藏民族大学创新学分管理系统的设计与实现(源码+lw+部署文档+讲解等)
14 0
|
5天前
|
JavaScript Java 测试技术
基于Java的政务大厅管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的政务大厅管理系统的设计与实现(源码+lw+部署文档+讲解等)
20 0
|
5天前
|
IDE Java 数据库连接
使用 Java 进行桌面应用开发
【4月更文挑战第19天】Java 是一款广泛应用于企业级、网络和桌面应用开发的编程语言。其跨平台特性使Java程序能在不同操作系统上运行,而JDK提供了开发所需工具和库。使用Swing等GUI库构建用户界面,结合JDBC进行数据库操作,Socket实现网络通信。虽然面临性能和用户体验的挑战,但通过优化和选用合适的IDE,Java仍能开发出高效稳定的桌面应用。