教您如何解决J2ME开发中的连续按键问题

2016-02-19 13:38 1 1 收藏

下面,图老师小编带您去了解一下教您如何解决J2ME开发中的连续按键问题,生活就是不断的发现新事物,get新技能~

【 tulaoshi.com - 编程语言 】

本文主要讲述在MIDP1.0情况下处理开发过程碰到的连续按键事件,结合具体的实例给出一种实用的解决方案。我们知道MIDP中的低级事件处理是通过keyPressed()、keyReleased()和keyRepeated()来处理的,分别在按键被按下、释放和重复按键的时候被触发。
  
  当方法被调用的时候,系统会把所按下键的键值传递给上述的三个方法,根据按键的键值我们可以进行相关的处理。在MIDP中定义了如下的按键值分别是: KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_STAR 和 KEY_POUND。
  
  在游戏开发中为了保证程序的可移植性,通常我们都会把键值转换为游戏动作,在MIDP中定义了如下的游戏动作: UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C,GAME_D。转换非常简单,可以通过Canvas提供的方法getGameAction()。
  
  一般来说处理keyPressed()和keyReleased()都比较轻易,但是处理按键一直被按下的情况稍微复杂一些。因为我们使用的设备并不一定支持连续按键的事件。你可以通过方法hasRepeatEvents()来检测平台是否支持当按键持续按下的时候产生重复事件。假如支持那么你可以在keyRepeated()的方法中处理相关逻辑,假如不支持那么你必须采取其他的方法。
  
  这里笔者介绍一种通过设置标志位的方式来处理连续按键的方法。其实原理非常的简单,我们通过设置标志位判定按键是否被按下了,比如我们判定LEFT是不是被按下了。当LEFT被按下的时候,我们把成员变量leFTPressed设置为true,代码如下:
  
  public void keyPressed(int keyCode)
  {
  int action = getGameAction(keyCode);
  
  switch (action)
  {
  
  case LEFT:
  left();
  leftPressed = true;
  break;
  
  case RIGHT:
  right();
  rightPressed = true;
  break;
  
  default:
  break;
  
  }
  repaint();
  
  }
  
  当按键被释放的时候,我们就把相关的标记位设置为false。
  
  public void keyReleased(int keyCode)
  {
  int action = getGameAction(keyCode);
  
  switch (action)
  {
  case LEFT:
  leftPressed = false;
  buttonPressed = "";
  break;
  
  case RIGHT:
  rightPressed = false;
  buttonPressed = "";
  break;
  default:
  break;
  }
  repaint();
  
  }
  
  这样我们在重新绘制屏幕的时候就可以根据标记位的状态进行绘画了:
  
  if (leftPressed)
  {
  left();
  }
  if (rightPressed)
  {
  right();
  }
  
  笔者给出一个简单的实例来进行论证,我们制作一个MIDlet,当用户按下LEFT的时候,J2ME字符串向左侧移动,当用户按下RIGHT的时候,J2ME字符串向右侧移动。简单起见,我没有处理DOWN和UP的情况。下面是应用程序截图和源代码。
  
  package com.j2medev;
  
  import Javax.microedition.lcdui.*;
  import javax.microedition
  .midlet.MIDlet;
  import javax.microedition
  .midlet.MIDletStateChangeException;
  
  public class KeyActionMIDlet
  extends MIDlet
  {
  
  private Display display;
  
  private MainCanvas mainCanvas;
  
  protected void startApp()
  throws MIDletStateChangeException
  {
  
  display = Display.getDisplay(this);
  mainCanvas = new MainCanvas();
  new Thread(mainCanvas).start();
  display.setCurrent(mainCanvas);
  
  }
  
  protected void pauseApp()
  {
  
  }
  
  protected void destroyApp
  (boolean arg0)
  throws MIDletStateChangeException
  {
  
  }
  
  }
  
  package com.j2medev;
  
  import javax.microedition.lcdui.*;
  
  public class MainCanvas extends
  Canvas implements Runnable
  {
  private String buttonPressed;
  
  private boolean leftPressed;
  
  private boolean rightPressed;
  
  private int px = getWidth() / 2;
  
  public final int py = getHeight() / 2;
  
  public MainCanvas()
  {
  buttonPressed = " ";
  }
  
  private void left()
  {
  if (px = 0)
  {
  px--;
  }
  buttonPressed = "LEFT";
  repaint();
  }
  
  private void right()
  {
  if (px = getWidth())
  {
  px++;
  }
  buttonPressed = "RIGHT";
  repaint();
  }
  
  public void run()
  {
  while (true)
  {
  if (leftPressed)
  {
  left();
  }
  if (rightPressed)
  {
  right();
  }
  
  try
  {
  Thread.sleep(50);
  } catch (InterruptedException e)
  {
  e.printStackTrace();
  }
  }
  
  }
  
  public void paint(Graphics g)
  {
  g.setColor(0xFFFFFF);
  g.fillRect(0, 0, getWidth(),
  getHeight());
  g.setColor(0x000000);
  
  g.drawString(buttonPressed, 20,
  20, Graphics.LEFT Graphics.TOP);
  g.drawString("J2ME", px, py,
  Graphics.HCENTER Graphics.TOP);
  
  }
  
  public void keyReleased(int keyCode)
  {
  int action = getGameAction(keyCode);
  
  switch (action)
  {
  case LEFT:
  leftPressed = false;
  buttonPressed = "";
  break;
  
  case RIGHT:
  rightPressed = false;
  buttonPressed = "";
  break;
  default:
  break;
  }
  repaint();
  
  }
  
  public void keyPressed(int keyCode)
  {
  int action = getGameAction(keyCode);
  
  switch (action)
  {
  
  case LEFT:
  left();
  leftPressed = true;
  break;
  
  case RIGHT:
  right();
  rightPressed = true;
  break;
  
  default:
  break;
  
  }
  repaint();
  
  }
  
  public void keyRepeated(int keyCode)
  {
  int action = getGameAction(keyCode);
  switch (action)
  {
  case LEFT:
  left();
  break;
  case RIGHT:
  right();
  break;
  
  default:
  break;
  }
  repaint();
  
  }
  }

来源:https://www.tulaoshi.com/n/20160219/1604828.html

延伸阅读
一.代码优化 内存会溢出肯定和代码逃不了关系,99.99%学java的人都知道垃圾回收器是java的一大优点并据此来嘲笑C++。显然这个特性为代码编写者省了不少事,但这个特性却带来了不少隐患。举个例子在游戏当中经常有不同场景的切换,如从游戏逻辑退到主菜单逻辑,对游戏逻辑对象的态度很多人会选择忘记等待垃圾回收器来收尸。乍看之下似乎并无不...
在游戏逻辑类里有几十行的变量定义也不足为奇。特别对于j2me来说更是如此,为了节省内存空间很多人舍弃了面向对象的特性把代码挤在一块。通常的情况是自已被自已的代码给淹死了!!所以在做结构设计时我很注重这一点,总是试图让代码节省一点扩展性多一点。这件事并不算很难只要认真去推敲总可以发现一些可以优化的东西,变量就是一例。大...
不知道主题为"J2ME中的内存泄漏"是否妥当,不过在J2ME中假如处理不好资源的创建和释放问题,也会出现类似在CC++中的内存泄漏现象。 J2ME中最常使用的资源无非是图片和声音。为了提高游戏的运行速度,我们通常把它们声明为全局变量,又由于手机的内存的关系,我们不能把这些资源同时加载进内存,所以我们会在使用的时候导入资源(创建对...
一、序言 昨天在网上闲逛,发现一篇讲解用delphi实现华容道游戏的文章,颇受启发.于是,产生了将华容道游戏移植到手机中去的冲动.现在手机游戏琳琅满目,不一而足,华容道的实现版本也很多.正巧不久前笔者对J2ME下了一番功夫,正想借这个机会小试牛刀。选用J2ME的原因还有一个就是目前Java开发大行其到,无线增殖业务迅猛发展,J2M...
七、测试 作为一个真正的产品要经过单体测试、结合测试和系统测试。由于项目本身简单,而且大部分代码已经是相对成熟的,我们跳过单体测试;又由于笔者的实际环境所限,无法搞到Java手机,无法架设OTA服务器,因此我们也只能放弃系统测试。那么就让我们开始结合测试吧。测试之前要先出一个测试式样书,也就是测试的计划。我们将它简化一下,...

经验教程

204

收藏

91
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部