《Java 2D游戏编程入门》—— 2.2 键盘改进

简介: 尽管键盘输入类允许在游戏循环中访问键盘状态,但是实现起来还是有一些问题。首先,游戏循环代码执行的时候,如果键盘按键没有按下,将会错过keypress事件。尽管对于这些简单的示例来说,不太可能发生这种情况,但当应用程序变得更强大并且游戏循环需要更多的时间来处理代码时,游戏循环就可能变得太慢而导致错过了输入。

本节书摘来异步社区《Java 2D游戏编程入门》一书中的第2章,第2.2节,作者:【美】Timothy Wright(莱特),更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.2 键盘改进

尽管键盘输入类允许在游戏循环中访问键盘状态,但是实现起来还是有一些问题。首先,游戏循环代码执行的时候,如果键盘按键没有按下,将会错过keypress事件。尽管对于这些简单的示例来说,不太可能发生这种情况,但当应用程序变得更强大并且游戏循环需要更多的时间来处理代码时,游戏循环就可能变得太慢而导致错过了输入。现在,只需要知道这可能是一个问题就行了。我们将会在第11章中讨论确保事件不会被错过的一种解决方案。

第二个问题是,当按键第一次被按下的时候,很难进行测试。如果需要跟踪20个按键,并且其中一些按键会根据游戏的状态而改变行为,那么,试图使用类似下面的代码来跟踪所有这些状态,可能会变得非常糟糕:

// SimpleKeyboardExample.java
if( keys.keyDown( KeyEvent.VK_SPACE ) ) {
  if( !space ) {
    System.out.println( "VK_SPACE" );
  }
  space = true;
} else {
  space = false;
}```
为了更新KeyboardInput类来跟踪初始的按键事件以及键盘状态,添加了一个整数型数值的数组。这些值将会记录按键被按下了多少帧。实现KeyListener接口的代码并不会改变,但是keyDown()方法不再会从布尔的按键数组提取值。

poll()方法同步地保护共享的按键数组,将键盘状态从布尔型数组转换为整数型数组。如果按键按下,这个值将会增加1;否则的话,它将会设置为0。现在,keyDown()方法将检测这个值是否为0,并且当这个值确实为1的时候,新的方法keyDownOnce()将会返回真。

package javagames.util;
import java.awt.event.*;
public class KeyboardInput implements KeyListener {
  private boolean[] keys;
  private int[] polled;
  public KeyboardInput() {
    keys = new boolean[ 256 ];
    polled = new int[ 256 ];
  }
  public boolean keyDown( int keyCode ) {
    return polled[ keyCode ] > 0;
  }
  public boolean keyDownOnce( int keyCode ) {
    return polled[ keyCode ] == 1;
  }
  public synchronized void poll() {
    for( int i = 0; i < keys.length; ++i ) {
      if( keys[i] ) {
        polled[i]++;
      } else {
        polled[i] = 0;
      }
    }
  }
  public synchronized void keyPressed( KeyEvent e ) {
    int keyCode = e.getKeyCode();
    if( keyCode >= 0 && keyCode < keys.length ) {
      keys[ keyCode ] = true;
    }
  }
  public synchronized void keyReleased( KeyEvent e ) {
    int keyCode = e.getKeyCode();
    if( keyCode >= 0 && keyCode < keys.length ) {
      keys[ keyCode ] = false;
    }
  }
  public void keyTyped( KeyEvent e ) {
    // Not needed
  }
}`

别忘了,针对每一帧要调用KeyboardInput.poll() 方法。
通过使用如下代码替换前面例子中的游戏循环代码,可以使用这个新的类。检查空格键按下一次所需的代码大大简化了。

// replacing the game loop
public void gameLoop() {
  keys.poll(); 
  if( keys.keyDownOnce( KeyEvent.VK_SPACE ) ) {
    System.out.println( "VK_SPACE" );
  }
  if( keys.keyDown( KeyEvent.VK_UP ) ) {
    System.out.println( "VK_UP" );
  }
  if( keys.keyDown( KeyEvent.VK_DOWN ) ) {
    System.out.println( "VK_DOWN" );
  }
  if( keys.keyDown( KeyEvent.VK_LEFT ) ) {
    System.out.println( "VK_LEFT" );
  }
  if( keys.keyDown( KeyEvent.VK_RIGHT ) ) {
    System.out.println( "VK_RIGHT" );
  }
  try {
    Thread.sleep( 10 );
  } catch( InterruptedException ex ) { }
相关文章
|
20天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
38 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
16天前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
1月前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
1月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
1月前
|
存储 安全 Java
🌟Java零基础-反序列化:从入门到精通
【10月更文挑战第21天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
80 5
|
1月前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
36 1
|
1月前
|
Java 数据处理 开发者
Java多线程编程的艺术:从入门到精通####
【10月更文挑战第21天】 本文将深入探讨Java多线程编程的核心概念,通过生动实例和实用技巧,引导读者从基础认知迈向高效并发编程的殿堂。我们将一起揭开线程管理的神秘面纱,掌握同步机制的精髓,并学习如何在实际项目中灵活运用这些知识,以提升应用性能与响应速度。 ####
49 3
|
2月前
|
Java
Java中的多线程编程:从入门到精通
本文将带你深入了解Java中的多线程编程。我们将从基础概念开始,逐步深入探讨线程的创建、启动、同步和通信等关键知识点。通过阅读本文,你将能够掌握Java多线程编程的基本技能,为进一步学习和应用打下坚实的基础。
|
28天前
|
Java 程序员 数据库连接
Java中的异常处理:从入门到精通
在Java编程的海洋中,异常处理是一艘不可或缺的救生艇。它不仅保护你的代码免受错误数据的侵袭,还能确保用户体验的平稳航行。本文将带你领略异常处理的风浪,让你学会如何在Java中捕捉、处理和预防异常,从而成为一名真正的Java航海家。
|
2月前
|
Java
[Java]Socket套接字(网络编程入门)
本文介绍了基于Java Socket实现的一对一和多对多聊天模式。一对一模式通过Server和Client类实现简单的消息收发;多对多模式则通过Server类维护客户端集合,并使用多线程实现实时消息广播。文章旨在帮助读者理解Socket的基本原理和应用。
33 1
下一篇
DataWorks