注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

gmd20的个人空间

// 编程和生活

 
 
 

日志

 
 

初学J2ME 手机游戏编程  

2008-06-24 19:34:17|  分类: 程序设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

具体的开发环境配置,请看我前面的一篇文档。今天参考《J2ME Game Development with MIDP2.pdf》一书上面的例子,试了一下 图形绘制和 简单游戏循环中 键盘的响应等。

闪屏功能的图像绘制类:


package YXHW;

import java.util.Timer;
import javax.microedition.lcdui.*;
import java.util.TimerTask;

/**
*
* @author widebright
*
*/

public final class SplashScreen extends Canvas {

    private Display display;
    private Displayable next;
    private Timer timer;
    private Image image;
    private int dismissTime;

    public SplashScreen(Display display, Displayable next, Image image, int dismissTime) {
        timer = new Timer();
        this.display = display;
        this.next = next;
        this.image = image;
        this.dismissTime = dismissTime;
        display.setCurrent(this);
    }

    static void access(SplashScreen splashScreen) {
        splashScreen.dismiss();
    }

    private void dismiss() {
        timer.cancel();
        display.setCurrent(next);
    }

    protected void keyPressed(int keyCode) {
        dismiss();
    }

    protected void paint(Graphics g) {
        g.setColor(0x00FFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(0x00000000);
        g.drawImage(image, getWidth() / 2, getHeight() / 2 - 5, 3);
    }

    protected void pointerPressed(int x, int y) {
        dismiss();
    }

    protected void showNotify() {
        if (dismissTime > 0) {
            timer.schedule(new CountDown(this), dismissTime);
        }
    }

    class CountDown extends TimerTask {

        private final SplashScreen splashScreen;

        CountDown(SplashScreen splashScreen) {
            this.splashScreen = splashScreen;
        }

        public void run() {
            SplashScreen.access(this.splashScreen);
        }
    }
}

运行效果如图,中间的很可爱的小孩就是绘制上去的,

初学J2ME 手机游戏编程 - widebright - widebright的个人空间

一个简单的游戏循环实现类:


package YXHW;

/**
*
* @author widebright
*/
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class MainGameCanvas extends GameCanvas implements Runnable {

    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 MainGameCanvas() {
        super(true);
        width = getWidth();
        height = getHeight();
        currentX = width / 2;
        currentY = height / 2;
        delay = 20;
    }
// 启动游戏循环
    public void start() {
        isPlay = true;
        Thread t = new Thread(this);
        t.start();
    }

    public void stop() {
        isPlay = false;
    }
   
// 游戏主循环,Runnable的run方法实现,启动Thread时会自动调用此方法
    public void run() {
        Graphics g = getGraphics(); //获取一个后台图像对象
        while (isPlay == true) {
            input();
            drawScreen(g);
            try {
                Thread.sleep(delay);
            } catch (InterruptedException ie) {
            }
        }
    }
// Method to Handle User Inputs
    private void input() {
        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);
            }
        }
       
        if ((keyStates & FIRE_PRESSED ) != 0) {
                this.stop();
        }
    }
// Method to Display Graphics
    private void drawScreen(Graphics g) {
        g.setColor(0xffffff);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(0x0000ff);
        g.drawString("widebright", currentX, currentY, Graphics.TOP | Graphics.LEFT);
        flushGraphics(); //是缓冲区中内容绘制到屏幕
    }
}

运行之后如图,按下 “上下左右”键,屏幕上的“widebright” 几个字将向不同方向移动。

初学J2ME 手机游戏编程 - widebright - widebright的个人空间

MIDlet 的主类是:

package YXHW;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
* @author widebright
*/
public class YXHWMIDlet extends MIDlet implements CommandListener {

    private boolean midletPaused = false;

    //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">
    private Command exitCommand;
    private Form form;
    private StringItem stringItem;
    //</editor-fold>

    /**
     * The YXHWMIDlet constructor.
     */
    public YXHWMIDlet() {
    }

    //<editor-fold defaultstate="collapsed" desc=" Generated Methods ">
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">
    /**
     * Initilizes the application.
     * It is called only once when the MIDlet is started. The method is called before the <code>startMIDlet</code> method.
     */
    private void initialize() {
        // write pre-initialize user code here

        // write post-initialize user code here
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: startMIDlet ">
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Started point.
     */
    public void startMIDlet() {
        // write pre-action user code here
        try {
//             Image start = Image.createImage("/YXHW/images/start.PNG");
//             new SplashScreen(getDisplay(), getForm(), start, 5000);
//           
             MainGameCanvas gameCanvas = new MainGameCanvas();
             gameCanvas.start();
             switchDisplayable(null, gameCanvas );
        } catch (Exception ex) {
             switchDisplayable(null, getForm());
        }
    
        // write post-action user code here
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: resumeMIDlet ">
    /**
     * Performs an action assigned to the Mobile Device - MIDlet Resumed point.
     */
    public void resumeMIDlet() {
        // write pre-action user code here

        // write post-action user code here
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: switchDisplayable ">
    /**
     * Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.
     * @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately
     * @param nextDisplayable the Displayable to be set
     */
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {
        // write pre-switch user code here
        Display display = getDisplay();
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }
        // write post-switch user code here
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Method: commandAction for Displayables ">
    /**
     * Called by a system to indicated that a command has been invoked on a particular displayable.
     * @param command the Command that was invoked
     * @param displayable the Displayable where the command was invoked
     */
    public void commandAction(Command command, Displayable displayable) {
        // write pre-action user code here
        if (displayable == form) {
            if (command == exitCommand) {
                // write pre-action user code here
                exitMIDlet();
                // write post-action user code here
            }
        }
        // write post-action user code here
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand ">
    /**
     * Returns an initiliazed instance of exitCommand component.
     * @return the initialized component instance
     */
    public Command getExitCommand() {
        if (exitCommand == null) {
            // write pre-init user code here
            exitCommand = new Command("Exit", Command.EXIT, 0);
            // write post-init user code here
        }
        return exitCommand;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: form ">
    /**
     * Returns an initiliazed instance of form component.
     * @return the initialized component instance
     */
    public Form getForm() {
        if (form == null) {
            // write pre-init user code here
            form = new Form("Welcome", new Item[] { getStringItem() });
            form.addCommand(getExitCommand());
            form.setCommandListener(this);
            // write post-init user code here
        }
        return form;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: stringItem ">
    /**
     * Returns an initiliazed instance of stringItem component.
     * @return the initialized component instance
     */
    public StringItem getStringItem() {
        if (stringItem == null) {
            // write pre-init user code here
            stringItem = new StringItem("Hello", "Hello, World!");
            // write post-init user code here
        }
        return stringItem;
    }
    //</editor-fold>

    /**
     * Returns a display instance.
     * @return the display instance.
     */
    public Display getDisplay () {
        return Display.getDisplay(this);
    }

    /**
     * Exits MIDlet.
     */
    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */
    public void startApp() {
        if (midletPaused) {
            resumeMIDlet ();
        } else {
            initialize ();
            startMIDlet ();
        }
        midletPaused = false;
    }

    /**
     * Called when MIDlet is paused.
     */
    public void pauseApp() {
        midletPaused = true;
    }

    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */
    public void destroyApp(boolean unconditional) {
        System.gc();
    }

}

  评论这张
 
阅读(559)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017