`
mfcai
  • 浏览: 409218 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

J2me中使用Canvas创建高级菜单总结

阅读更多
看了<<J2me中使用Canvas创建高级菜单>>后,将canvas创建高级菜单归结为两个问题:菜单的绘制和菜单事件的处理.设计了三个类:MenuMidlet,MenuScreen,Menu。
MenuMidlet是主类,该类继承了MIDlet类;
MenuScreen类负责事件处理;
Menu类负责菜单的绘制

2.菜单绘制
菜单有两种状态:激活状态和非激活状态.
在激活状态下,显示菜单项,并且可以接受用户的上下选择事件
在非激活状态下,隐藏菜单项,不接受用户的上下选择事件
菜单的绘制包括激活状态下的菜单绘制和非激活状态下的菜单绘制
非激活状态下的菜单绘制包括:左菜单(options)和右菜单(exit)绘制
激活状态下的菜单绘制包括:左菜单(options)和右菜单(cancel)绘制,左菜单项(新建,设定,记录,帮助,关于)绘制。如图:

3.菜单事件处理
Canvas提供了keyPressed(int key)来响应用户的按键 。
Canvas中的gameAction是将手机键盘映射成为游戏动作的机制。
需要响应UP,DOWN,FIRE,左菜单键,右菜单键事件
以下是源代码,在WTK2.5.2下编译通过

1)MenuMidlet类
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.lcdui.*;
public class MenuMidlet extends MIDlet  {
    private   MenuScreen menuScreen;
    Display display;
 public MenuMidlet() {
  display= Display.getDisplay(this);
  menuScreen = new MenuScreen(this);
 }

 protected void startApp() throws MIDletStateChangeException {
 }

 protected void pauseApp() {
 }

 protected void destroyApp(boolean unconditional)
   throws MIDletStateChangeException {
 }
}


2)MenuScreen类
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.media.*;
public class MenuScreen  extends GameCanvas {
 static int width; // screen width
 static int height; // screen height
 private int LEFT_SOFTKEY_CODE = -6;
 private int RIGHT_SOFTKEY_CODE = -7;
 // Menu Item Labels
 static final String[] menuOptions = { "新建", "设置",
   "记录", "帮助", "关于" };
 static int menuIdx;// 记录是在第几个菜单处按下的确定键。
 private int currentlySelectedIndex = 0;
 private boolean menuIsActive = false;
 private MenuMidlet midlet;
 private String leftOption;
 private String rightOption;
 private Graphics g;
 private Menu menu;

 // Constructor
 public MenuScreen(MenuMidlet midlet) {
  super(false);
  this.midlet = midlet;
  // Get Width and Height of Canvas
  width = getWidth();
  height = getHeight();
  setFullScreenMode(true);
  menuIdx = 0;
  g = getGraphics();
  leftOption = "Options";
  rightOption = "Exit";
  menu = new Menu(leftOption, rightOption, menuOptions);
  start();
  midlet.display.setCurrent(this);
 }

 public void start() {
  clearScreen();
  menu.drawInactiveMenu(this, g);
 }

 public void clearScreen() {
  g.setColor(0xffffff); // white
  g.fillRect(0, 0, width, height);
  flushGraphics();
 }
 
 protected void keyPressed(int keyCode) {
  if (menuIsActive) {
   if (keyCode == RIGHT_SOFTKEY_CODE) {
    // draw inactive menu again
    clearScreen();
    menu.drawInactiveMenu(this, g);
    menuIsActive = false;
   }
   keyCode = getGameAction(keyCode);
   if (keyCode == UP) {
    currentlySelectedIndex--;
    if (currentlySelectedIndex < 0) {
     currentlySelectedIndex = 0; // stay within limits
    }
    menu.drawActiveMenu(this, g, currentlySelectedIndex);
   }
   else if (keyCode == DOWN) {
    currentlySelectedIndex++;
    if (currentlySelectedIndex >= menuOptions.length) {
     currentlySelectedIndex = menuOptions.length - 1;
    }
    menu.drawActiveMenu(this, g, currentlySelectedIndex);
   }
   else if (keyCode == FIRE) {
    clearScreen();
    g.setColor(0x000000);
    g.drawString("[" + menuOptions[currentlySelectedIndex]
      + "] was selected", 10, 15, g.LEFT | g.TOP);
    menu.drawInactiveMenu(this, g);
    menuIsActive = false;
   }
  }
  else {
   if (keyCode == LEFT_SOFTKEY_CODE) { // "Options" pressed
    menu.drawActiveMenu(this, g, currentlySelectedIndex);
    menuIsActive = true;
   }
   else if (keyCode == RIGHT_SOFTKEY_CODE) {
    
   }
  }
 }
}


3)Menu类
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
public class Menu {
 private String leftOption;
 private String rightOption;
 private String cancelOption = "Cancel";
 private String[] menuOptions;
 private int padding = 5;
 //颜色设置
 private static final int defaultFontColor = 0x000000; // 默认字体颜色
 private static final int selectedFontColor=0xfff000;  //选中后字体颜色
 private static final int bgColor = 0xCCCCCC;// 菜单背景色
 private static final int highLight=0x0000ff;//选中的菜单高亮显示颜色
 
 public Menu(String leftOption, String rightOption, String[] menuOptions) {
  this.leftOption = leftOption;
  this.rightOption = rightOption;
  this.menuOptions = menuOptions;
 } // end constructor

 public void drawInactiveMenu(GameCanvas canvas, Graphics g) {
  // create inactive menu font
  Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
    Font.SIZE_MEDIUM);
  int fontHeight = font.getHeight();
  // clear inactive menu background
  int width = canvas.getWidth();
  int height = canvas.getHeight();
  g.setColor(bgColor); // grey color
  g.fillRect(0, height - fontHeight - 2 * padding, width, height);
  // draw left and right menu options
  g.setFont(font);
  g.setColor(defaultFontColor); // black
  g.drawString(leftOption, padding, height - padding, g.LEFT | g.BOTTOM);
  g.drawString(rightOption, width - padding, height - padding, g.RIGHT
    | g.BOTTOM);
  canvas.flushGraphics();
 } // end drawInactiveMenu

 public void drawActiveMenu(GameCanvas canvas, Graphics g,
   int selectedOptionIndex) {
  Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
    Font.SIZE_MEDIUM);
  int fontHeight = font.getHeight();
  int width = canvas.getWidth();
  int height = canvas.getHeight();
  g.setColor(bgColor);
  g.fillRect(0, height - fontHeight - 2 * padding, width, height);
  // draw default menu bar options
  g.setFont(font);
  g.setColor(0x000000); // black
  g.drawString(leftOption, padding, height - padding, g.LEFT | g.BOTTOM);
  // draw "Cancel" option
  g.drawString(cancelOption, width - padding, height - padding, g.RIGHT
    | g.BOTTOM);
  canvas.flushGraphics();
  // draw menu options
  if (menuOptions != null) {
   //确定菜单的最大宽度、最大高度
   int menuMaxWidth = 0;
   int menuMaxHeight = 0;
   int currentWidth = 0;
   for (int i = 0; i < menuOptions.length; i++) {
    currentWidth = font.stringWidth(menuOptions[i]);
    if (currentWidth > menuMaxWidth) {
     menuMaxWidth = currentWidth;
    }
    menuMaxHeight += fontHeight + padding;
   }
   menuMaxWidth += 6 * padding;
   g.setColor(bgColor);
   g.fillRect(0, // x
     height - fontHeight - 2 * padding - menuMaxHeight, // y
     menuMaxWidth, menuMaxHeight);


   g.setFont(font);
   int menuOptionX = padding;
   int menuOptionY = height - fontHeight - 2 * padding - menuMaxHeight
     + padding;
    for(int i=0; i<=menuOptions.length; i++) {
     g.setColor(highLight);
     int lineOptionY= height-fontHeight - 2 * padding- menuMaxHeight+i*(fontHeight + padding);
              g.drawLine(0, lineOptionY,
                menuMaxWidth-1, lineOptionY);
          }
   for (int i = 0; i < menuOptions.length; i++) {
    if (i != selectedOptionIndex) {
     // draw unselected menu option
     g.setColor(defaultFontColor); // black
     g.drawString(menuOptions[i], menuOptionX, menuOptionY, g.LEFT
       | g.TOP);
    }
    else {
     // draw selected menu option
     g.setColor(highLight);
     int highOptionY=height - fontHeight - 2 * padding - menuMaxHeight+i*(fontHeight + padding);
     g.fillRect(0,highOptionY,menuMaxWidth,fontHeight + padding);
     g.setColor(selectedFontColor);
     g.drawString(menuOptions[i], menuOptionX, menuOptionY, g.LEFT
       | g.TOP);
     
    } 
    menuOptionY += padding + fontHeight;
   }
   canvas.flushGraphics();
  }
 }
}

分享到:
评论

相关推荐

    j2me高级界面和低级界面的切换

    这篇博客“j2me高级界面和低级界面的切换”可能探讨了如何在MIDP应用中有效地在Form和Canvas之间进行导航。通常,这涉及到以下几个关键知识点: 1. **Form**:Form是MIDP中的一个基本组件,用于展示文本和可选的...

    J2ME中高级面试题

    **J2ME中高级面试题详解** 在移动设备开发领域,Java 2 Micro Edition (J2ME) 是一种广泛使用的平台,尤其适用于嵌入式系统和早期的智能手机。对于那些致力于成为高级工程师或架构师的开发者来说,深入理解J2ME技术...

    J2ME手机游戏

    - **状态管理**:游戏通常包含多个状态(如主菜单、游戏进行中、暂停等),使用StateMachine设计模式可以方便地管理这些状态。 **4. 注意事项** - **性能优化**:由于J2ME运行在资源有限的设备上,性能优化是必要...

    j2me游戏引擎详解

    在J2ME的环境中,游戏引擎扮演着至关重要的角色,它们简化了开发过程,使得开发者能够创建出丰富的、交互性强的游戏,尤其在资源有限的移动设备上。 **J2ME游戏引擎的核心组件** 1. **图形渲染**:J2ME游戏引擎...

    j2me for development

    在J2ME中,可以通过继承Canvas类并重写paint方法来实现基本的游戏循环逻辑。开发者需要关注线程同步问题以避免死锁或竞态条件。 ##### 2.3 图形与动画处理 图形处理是游戏开发中不可或缺的一部分,尤其是在移动...

    j2me开发的rpg

    【J2ME开发的RPG】是一...它展示了如何在资源受限的环境中利用Java语言和J2ME API创建一款具有完整功能的游戏。通过深入研究这个项目,新手可以逐步掌握游戏开发的基本技术和流程,为进一步的项目开发打下坚实的基础。

    精通J2ME无线编程.pdf

    4. **用户界面设计**:讲解如何使用LWUIT(Lightweight User Interface Toolkit)或MIDP API创建简单的到复杂的用户界面,包括按钮、文本框、列表和菜单等元素的使用。 5. **网络编程**:J2ME支持通过HTTP、WAP等...

    用Eclipse开发J2ME手机游戏入门讲座

    在"Eclipse"菜单中选择"File" &gt; "New" &gt; "Other",然后在弹出的对话框中找到"Mobile and Devices"下的"J2ME Project"。输入项目名称,选择合适的设备配置,如CLDC(Connected Limited Device Configuration)和MIDP...

    手机游戏 j2me

    更高级的动画技术可能需要使用精灵(Sprites)和帧动画。 **6. 存储管理** 由于手机内存和存储空间有限,J2ME游戏需要有效管理资源。RecordStore系统可用于保存用户数据和游戏进度,而内部或外部文件系统则可用于...

    j2me游戏,太空之战

    开发者需要了解如何使用MIDP中的Canvas类来绘制游戏画面,以及怎样处理用户的输入事件。 3. **CLDC(Connected Limited Device Configuration)**:这是J2ME的基础配置,用于处理低内存、有限网络连接的设备。...

    王者归来的j2me源码

    - 图片资源(Images):游戏中使用的图像文件,通常以.jpg或.png格式存储。 - 音效资源(Sounds):MIDI或WAV格式的音频文件。 - 数据文件(Data Files):可能包含关卡布局、游戏设置等数据。 5. **学习价值** ...

    J2ME通讯录

    2. **用户界面**:在J2ME中,用户界面通常使用MIDP提供的Canvas或Form组件构建。Canvas提供基本的绘图功能,适合自定义界面;Form则用于创建文本和按钮等标准UI元素。 3. **数据存储**:由于资源有限,J2ME通常使用...

    j2me3D开发源码3D滑雪

    然而,由于“3D滑雪”游戏是基于J2ME的,我们推测它可能没有使用这些高级库,而是依赖于MIDP内置的低级图形API,如Canvas,进行3D建模和渲染。 “EA_Snowboarding.jad”是Java应用描述文件,它包含了游戏的元数据,...

    J2ME培训实验手册v2.0

    创建MIDlet文件通常是通过右键点击项目名称,在弹出的菜单中选择“New”-&gt;“MIDlet Class”。 **1.4.3 执行MIDlet** 执行MIDlet通常是在集成了模拟器的环境中进行。在Eclipse中,可以直接运行MIDlet来查看其在不同...

    J2ME 3D API

    Maze3D MIDlet 是一个使用 J2ME 3D API 创建的迷宫游戏示例。接下来我们将详细介绍这个示例。 ##### 3.1 引言 Maze3D 是一个基于 J2ME 3D API 开发的简单迷宫游戏,旨在展示如何使用 M3G API 来创建交互式的 3D ...

    J2ME & Gaming

    4. **MIDP 2.0的新游戏类:**这部分内容是本书的重点,详细介绍了MIDP 2.0中新增的游戏类,包括Canvas、Graphics和Image类的增强功能,以及如何利用它们来创建更加生动和复杂的移动游戏。 **四、本书目标读者** ...

    JAVA基于J2ME的手机游戏开发(论文+源代码).zip

    它提供了轻量级组件( Lightweight Components ),如Canvas和Form,用于创建游戏画面和交互元素。Canvas是自定义绘图的基础,允许开发者直接操作像素,实现复杂的游戏图形效果。 网络功能在J2ME游戏中可能用于在线...

    JAVA基于J2ME的手机游戏开发(文档+源代码).zip

    Java基于J2ME的手机游戏开发是一个广泛的领域,涉及到许多...总的来说,通过研究这个压缩包中的资料和源代码,你可以深入了解J2ME手机游戏开发的各个方面,从基础知识到高级技巧,为自己的游戏开发之旅打下坚实的基础。

    j2me的课件一章大家参考

    如List组件用于创建菜单列表,Canvas组件用于精细控制像素级别的界面设计。RMS(Record Management System)是MIDP的一个重要子系统,它提供了一种持久化数据存储的解决方案,即使设备重启或更换电池,数据也能保持...

Global site tag (gtag.js) - Google Analytics