使用J2ME技术开发RPG游戏(一)——程序框架

使用J2ME技术开发RPG游戏(一)——程序框架

作者:陈跃峰

出自:http://blog.csdn.net/mailbomb

       RPG(角色扮演游戏)是手机游戏中的一类主要类型,也是相对来说比较麻烦的一类游戏,下面通过一系列的文章来介绍如何使用J2ME技术来开发RPG游戏。

       首 先让我们来看一下游戏的骨架——程序框架的实现。程序框架主要包含三个方面:绘制结构、事件处理结构以及线程结构。在整个框架中,采用当前游戏编程中的通 用的状态控制机制,为每个界面,如菜单、帮助、游戏对话、商店界面设置一个唯一的状态值,使用该状态值控制界面的绘制、事件的处理以及线程处理。

       在程序的实现上为了通用,以MIDP1.0为基础来进行制作,这个要比使用MIDP2.0Game API实现起来要复杂一些。

       在类结构的划分上,为了节约减小jar文件大小,把这个程序代码划分为两个类,一个MIDlet类,一个界面类,所有逻辑代码以及线程实现均放置在界面类中。

       下面是MIDlet类的代码,主要实现显示界面、处理手机来电、释放资源以及退出功能,线程启动放在界面类中实现。源代码如下:

package myrpg;

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

/**

 * RPG结构的MIDlet

 * 包含如下功能:

 *    1、显示界面

 *    2、手机来电处理

 *    3、释放资源

 *    4、退出方法

 */

public class MyRPGMIDlet extends MIDlet {

    /**MyRPGMIDlet对象,用于实现退出功能*/

    static MyRPGMIDlet instance;

    /**界面类对象*/

    MyRPGCanvas mainScreen = new MyRPGCanvas();

    public MyRPGMIDlet() {

        //初始化

        instance = this;

        //显示界面

        Display.getDisplay(this).setCurrent(mainScreen);

    }

 

    public void startApp() {

        //开始或继续游戏

        if (mainScreen != null) {

            mainScreen.startGame();

        }

    }

 

    public void pauseApp() {

        //暂停游戏

        if (mainScreen != null) {

            mainScreen.pauseGame();

        }

    }

 

    public void destroyApp(boolean unconditional) {

        //释放资源

        if (mainScreen != null) {

            mainScreen.destroyGame();

            mainScreen = null;

        }

    }

 

    /**

     * 退出方法

     */

    public static void quitApp() {

        instance.destroyApp(true);

        instance.notifyDestroyed();

        instance = null;

    }

}

       游戏逻辑和界面绘制以及控制都放在一个类MyRPGCanvas中,这样实现没有使用面向对象容易修改和扩展,但是通过结构化代码,还是可以保证较高的可读性以及维护性。在MyRPGCanvas中,通过状态变量status控制界面的绘制以及线程逻辑,为了清晰,把每个处理逻辑都封装成一个方法,如果方法比较复杂还可以继续拆分为多个方法。

       关于绘制部分,如果每个界面都具有一张不透明的背景图片的话,可以省略清屏功能,这样可以提高程序的执行效率。

       关于线程部分主要实现了暂停控制,通过isPaused变量来控制逻辑是否执行,从而实现暂停功能,并实现精确的延时。

       关于资源加载和销毁,如果机器的内存不是很紧张的话,可以一次加载,如果内存比较紧张的话,需要编写专门的代码控制资源的加载和销毁。

       具体的实现代码如下:

package myrpg;

import javax.microedition.lcdui.*;

/**

 * 游戏界面,包含所有游戏界面、逻辑以及事件处理

 */

public class MyRPGCanvas extends Canvas implements Runnable {

    /**游戏是否处于运行状态,true代表处于运行状态*/

    private boolean isRunning = true;

    /**游戏是否处于暂停状态,true代表处于暂停状态*/

    private boolean isPaused = false;

 

    /**屏幕宽度*/

    private int width;

    /**屏幕高度*/

    private int height;

 

    /**时间间隔*/

    private final int INTERVAL_TIME = 100;

 

    /**游戏状态,使用该变量标示游戏的界面和逻辑*/

    private int status;

 

    //各个界面状态常量

    /**Logo界面状态*/

    private final int LOGO_STATUS = 0;

    /**菜单界面状态*/

    private final int MENU_STATUS = 1;

    /**帮助界面状态*/

    private final int HELP_STATUS = 2;

    /**关于界面状态*/

    private final int ABOUT_STATUS = 3;

    //游戏中各个状态常量

    /**地图1状态*/

    private final int GAME_MAP1_STATUS = 4;

    /**武器店1状态*/

    private final int GAME_WEAPONSHOP1_STATUS = 5;

    /**对话1状态*/

    private final int GAME_DIALOG1_STATUS = 6;

 

    public MyRPGCanvas() {

        //初始化

        init();

        //启动线程

        Thread thread = new Thread(this);

        thread.start();

    }

 

    /**

     * 初始化游戏

     * 导入资源和初始化游戏状态

     */

    private final void init() {

        //获得屏幕尺寸

        width = this.getWidth();

        height = this.getHeight();

        //初始化游戏状态,默认显示LOGO界面

        status = LOGO_STATUS;

        //导入图片和其他资源

 

    }

 

    protected void paint(Graphics g) {

        //清屏

        clearScreen(g);

        //绘制

        switch (status) {

        case LOGO_STATUS:

            paintLogo(g);

            break;

        case MENU_STATUS:

            paintMenu(g);

            break;

        case HELP_STATUS:

            paintHelp(g);

            break;

        case ABOUT_STATUS:

            paintAbout(g);

            break;

        case GAME_MAP1_STATUS:

            paintGame_Map1(g);

            break;

        case GAME_WEAPONSHOP1_STATUS:

            paintGame_WeaponShop1(g);

            break;

        case GAME_DIALOG1_STATUS:

            paintDialog1(g);

            break;

        }

    }

 

    /**

     * 绘制LOGO界面

     * @param g Graphics 画笔

     */

    private final void paintLogo(Graphics g) {

 

    }

 

    /**

     * 绘制菜单界面

     * @param g Graphics 画笔

     */

    private final void paintMenu(Graphics g) {

 

    }

 

    /**

     * 绘制帮助界面

     * @param g Graphics 画笔

     */

    private final void paintHelp(Graphics g) {

 

    }

 

    /**

     * 绘制关于界面

     * @param g Graphics 画笔

     */

    private final void paintAbout(Graphics g) {

 

    }

 

    /**

     * 绘制游戏地图1界面

     * @param g Graphics 画笔

     */

    private final void paintGame_Map1(Graphics g) {

 

    }

 

    /**

     * 绘制游戏武器店1界面

     * @param g Graphics 画笔

     */

    private final void paintGame_WeaponShop1(Graphics g) {

 

    }

 

    /**

     * 绘制游戏对话1界面

     * @param g Graphics 画笔

     */

    private final void paintDialog1(Graphics g) {

 

    }

 

    /**

     * 清屏

     * @param g Graphics 画笔

     */

    private final void clearScreen(Graphics g) {

        g.setColor(0xffffff);

        g.fillRect(0, 0, width, height);

    }

 

    /**

     * 开始和继续游戏

     */

    public void startGame() {

        isPaused = false;

    }

 

    /**

     * 暂停游戏

     */

    public void pauseGame() {

        isPaused = true;

    }

 

    /**

     * 释放资源

     * 包括图片、声音等资源

     */

    public void destroyGame() {

 

    }

    /**

     * logo界面线程逻辑

     */

    private final void doLogo() {

 

    }

    /**

     * 帮助界面线程逻辑

     */

    private final void doHelp() {

 

    }

    /**

     * 关于界面线程逻辑

     */

    private final void doAbout() {

 

    }

    /**

     * 菜单界面线程逻辑

     */

    private final void doMenu() {

 

    }

    /**

     * 游戏地图1界面线程逻辑

     */

    private final void doGame_Map1() {

 

    }

    /**

     * 游戏武器店1界面线程逻辑

     */

    private final void doGame_WeaponShop1() {

 

    }

    /**

     * 游戏对话1界面线程逻辑

     */

    private final void doDialog1() {

 

    }

 

    public void run() {

        try {

            while (isRunning) {

                //精确延时

                long start = System.currentTimeMillis();

 

                //逻辑处理

                if (!isPaused) {

                    switch (status) {

                    case LOGO_STATUS:

                        doLogo();

                        break;

                    case MENU_STATUS:

                        doMenu();

                        break;

                    case HELP_STATUS:

                        doHelp();

                        break;

                    case ABOUT_STATUS:

                        doAbout();

                        break;

                    case GAME_MAP1_STATUS:

                        doGame_Map1();

                        break;

                    case GAME_WEAPONSHOP1_STATUS:

                        doGame_WeaponShop1();

                        break;

                    case GAME_DIALOG1_STATUS:

                        doDialog1();

                        break;

                    }

 

                }

                //重绘

                repaint();

                serviceRepaints();

                long end = System.currentTimeMillis();

                //延时

                if ((end - start) < INTERVAL_TIME) {

                    Thread.sleep(INTERVAL_TIME - (end - start));

                }

            }

        } catch (Exception e) {}

    }

}

       这些只是一个简单的框架,包含了有些开发中的常见功能的实现,但是尚不包含按键处理方面的代码,如果大家有什么建议和意见也可以积极提出。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值