J2ME 游戏开发之GameCanvas的使用

package com.slinw.gamecanvas;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;


/**
 * http://ajava.org/readbook/J2ME/3d/4327.html
 * @author 章伟
 * GameCanvas 类的主要功能:提供屏幕缓冲绘制机制,并能直接得到设备键盘的物理状态。
 * GameCanvas方法说明:
 *         getGraphics()  : 获得画布
 *         flushGraphics( ):刷新画布
 *         getKeyStates():得到当前按键状态
 *      flushGraphics(int x, int y, int width, int height): 局部刷新,意思是作者知道下次帧和上次帧图像的区别只是某个局部
 *为了将缓冲区中的内容刷新到屏幕上,所需要做的只是先调用getGraphics()方法,获得用来绘制缓冲区的Graphics对象。
 *刚创建的Graphics对象具有以下默认属性。

    n     绘制目标是这个GameCanvas的缓冲区。
    
    n     绘制区域覆盖整个缓冲区。
    
    n     当前颜色是黑色。
    
    n     字体和调用Font.getDefaultFont()返回的相同。
    
    n     绘图模式为SOLID。
    
    n     坐标系统的原点定位在缓冲区的左上角。
    
    返回的Graphics对象将用于绘制属于这个GameCanvas的后备屏幕缓冲区(off-screen buffer),但是绘制后的结果不会立即显示出来,
    直到调用flushGraphics()方法,将缓冲区中的内容一起绘制到屏幕上去。
    
    3.2.4  获取键盘状态
        前面已经提到,GameCanvas和Canvas的按键状态的响应是不一样的。在Canvas时代,如果想知道按键状态,
        必须实现keyPressed()/keyReleased()/keyRepeated(),每当有按键被按下时,这个方法就被调用,
        而在GameCanvas时代,如果要检查特定的按键是否被按下,只需要将getKeyStates()返回的值与这些键值进行按位与(&),
        并根据计算结果来判断即可。
        
        getKeyStates()返回的bit数据分别代表了不同的按键(例如Up、Down、Fire等)。当按下某个物理键盘时,其对应的位设置为1,
        否则将被设置为0,这样做的好处是,无论游戏主循环执行得多慢,键盘事件都不会被忽略。
        
        每一次getKeyStates()方法的调用都会清除当前键盘缓冲区,因此理论上说,连续调用两次getKeyStates(),前一次会清除之前锁定的键盘状态,而后一次会得到反映当前键盘状态的理想值。
        
        当然getKeyStates()的返回值会在另外一个线程中被更新,所以在游戏主循环中最好稍微等一会儿,以保证这个值被更新。GameCanvas中获得用户输入的代码:
        
        protected void input() {
        
        int keyState = getKeyStates();                    //获得键盘状态
        
        if ((keyState & LEFT_PRESSED) != 0) {             //如果左键被按下
        
        // do something
        
        }
        
        if ((keyState & RIGHT_PRESSED) != 0) {            //如果右键被按下
        
        // do something
        
        }
        
        if ((keyState & FIRE_PRESSED) != 0) {             //如果确定键被按下
        
        // do something
        
        }

}
 */




public class WGameCanvas extends GameCanvas implements Runnable{

        private Graphics g = null;
        private boolean isPlay; // Game Loop runs when isPlay is true
        private long delay; // To give thread consistency
        private int currentX, currentY; // To hold current position of the 'X'
        private int width; // To hold screen width
        private int height; // To hold screen height
     
        // Constructor and initialization
        public WGameCanvas() {
            super(true);
            width = getWidth();
            height = getHeight();
            currentX = width / 2;
            currentY = height / 2;
            delay = 20;
            g = getGraphics();
        }
     
        // Automatically start thread for game loop
        public void start() {
            isPlay = true;
            new Thread(this).start();
        }
     
        public void stop() {
            isPlay = false;
        }
     
        // Main Game Loop
        public void run() {
            while (isPlay) {
                keyEventInput();
                drawScreen(g);
                try {
                    Thread.sleep(delay);
                } catch (InterruptedException ie) {}
            }
        }
     
        // Method to Handle User Inputs
        private void keyEventInput() {
            int keyStates = getKeyStates();
            // Left
            if ((keyStates & LEFT_PRESSED) != 0) {
                currentX = Math.max(0, currentX - 1);
            }
            // Right
            if ((keyStates & RIGHT_PRESSED) != 0) {
                if (currentX + 5 < width) {
                    currentX = Math.min(width, currentX + 1);
                }
            }
            // Up
            if ((keyStates & UP_PRESSED) != 0) {
                currentY = Math.max(0, currentY - 1);
            }
            // Down
            if ((keyStates & DOWN_PRESSED) != 0) {
                if (currentY + 10 < height) {
                    currentY = Math.min(height, currentY + 1);
                }
            }
        }
     
        // Method to Display Graphics
        private void drawScreen(Graphics g) {
            g.setColor(0xffffff);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(0x0000ff);
            g.drawString("X", currentX, currentY, Graphics.TOP | Graphics.LEFT);
            flushGraphics();
        }
    }
原文地址:https://www.cnblogs.com/zhangweia/p/2145911.html