服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

基于nokia s40的猜数字游戏之二

    现在我们已经有一能够接收用户输入事件的button类了,下面我们应该考虑如何实现游戏中相关的逻辑,猜数字中的游戏逻辑都比较简单,主要是产生一个4位随机数字且不能重复,其次是根据输入返回给用户结果。我们提供一个engine类来完成这个工作。
package com.j2medev.numbergame;

import java.util.random;

public class engine
{
    private int[] answer = new int[4];

    private random random = new random();

    public void init()
    {
        int[] number = new int[10];
        for (int i = 0; i < number.length; i++)
        {
            number[i] = i;
        }

        int n = 10;
        for (int index = 0; index < answer.length; index++)
        {
            int r = math.abs(random.nextint() % n);
            answer[index] = number[r];
            number[r] = number[n - 1];
            n--;
        }
    }

    public int[] getanswer()
    {
        return answer;
    }

    public int[] queryresult(int[] input)
    {
        int[] state = new int[2];
        int a = 0;
        int b = 0;
        for (int i = 0; i < answer.length; i++)
        {
            for (int j = 0; j < answer.length; j++)
            {

                if ((input[j] ^ answer[i]) == 0)
                {
                    if (i == j)
                    {
                        a++;
                    } else
                    {
                        b++;
                    }

                }
            }
        }
        state[0] = a;
        state[1] = b;
        return state;
    }
}

    在游戏的运行中,我们有时候需要提示用户它的操作有误,比如输入数字为空,或者显示给用户已经答对了,一个庆祝的界面。当然这些你可以通过midp中提供的alert来完成,我在这里实现了一个简单的界面类,这是一个抽象类,扩展了fullcanvas但是并没有实现paint()方法,把这个方法留给他的字类来实现。
/*
 * created on 2004-12-21
 *
 * todo to change the template for this generated file go to
 * window - preferences - java - code style - code templates
 */
package com.j2medev.numbergame;

import java.util.timer;
import java.util.timertask;

import javax.microedition.lcdui.display;
import javax.microedition.lcdui.font;

import com.nokia.mid.ui.fullcanvas;

public abstract class numscreen extends fullcanvas
{
    protected timer timer = new timer();
    protected display display;
    protected manager next;
    protected int timeout;
    protected font font;
   
    public numscreen(display display,manager next)
    {
        this.display = display;
        this.next = next;

        settimeout(3000);
    }
   
    public font getfont()
    {
        if(font == null)
        {
            font = font.getdefaultfont();
        }
        return font;
    }
   
    public void setfont(font font)
    {
        this.font = font;
    }
   
    public void settimeout(int time)
    {
        this.timeout = time;
    }
   
   
    public void dismiss()
    {
        timer.cancel();
        display.setcurrent(next);
    }
   
    public void shownotify()
    {
        timer.schedule(new timertask()
                {
              public void run()
              {
                  dismiss();
              }
                },3000);
    }
   
}
基于这个类,我们实现一个splashscreen用在程序启动的时候的欢迎界面上,还提供一个类congscreen用于显示用户的成绩和提示。

package com.j2medev.numbergame;

import java.io.ioexception;

import javax.microedition.lcdui.display;
import javax.microedition.lcdui.graphics;
import javax.microedition.lcdui.image;

public class splashscreen extends numscreen
{

    public splashscreen(display display,manager next)
    {
        super(display, next);
    }

    protected void paint(graphics arg0)
    {
        image welcome = null;
        try
        {
            welcome = image.createimage("/welcome.png");
        } catch (ioexception e)
        {
            e.printstacktrace();
        }

        arg0.drawimage(welcome, 2, 2, graphics.top | graphics.left);
       

    }
   

}


package com.j2medev.numbergame;

import java.io.ioexception;

import javax.microedition.lcdui.display;
import javax.microedition.lcdui.graphics;
import javax.microedition.lcdui.image;

public class congscreen extends numscreen
{

    private string title;

    private mark mark;

    private image image;
   
    private image star;
   
    private manager manager;
   
    private int type = cong;
   
    public static final int cong = 1;
    public static final int warning = 2;

    public congscreen(display display, manager next)
    {
        super(display, next);
       
    }

    public congscreen(display display,manager next, mark mark)
    {
        this(display, next);
        this.mark = mark;
    
    }


    protected void paint(graphics g)
    {
        int width = this.getwidth();
        int height = this.getheight();
        if (image == null)
        {
            try
            {
                image = image.createimage("/cong.png");
                star = image.createimage("/star.png");
            } catch (ioexception e)
            {
                e.printstacktrace();
            }
        }
        if (title != null)
        {
            g.drawstring(title, width / 2, 5, graphics.hcenter | graphics.top);
        }
        int offset = 10 + getfont().getheight();
        g.drawimage(image, 2, offset, graphics.top | graphics.left);
        offset = offset + image.getheight();
       
        if(type == cong)
        {
            int number = 5 - mark.getcount()/2;
            if(number ==0) number = 1;
           
            g.drawstring("成绩:",2,offset+3,graphics.top|graphics.left);
            for(int i = 0;i<number;i++)
            {
               g.drawimage(star,4+font.stringwidth("成绩:")+i*star.getwidth(),offset+3,graphics.left|graphics.top);
               
            }
           
        }
    }

    public void settype(int type)
    {
        this.type = type;
    }

    public string gettitle()
    {
        return title;
    }

    public void settitle(string title)
    {
        this.title = title;
    }

    public mark getmark()
    {
        return mark;
    }

    public void setmark(mark mark)
    {
        this.mark = mark;
    }
   

}

    至此我们程序需要的元素都有了,下面我们的任务是写游戏的midlet了。由于我是针对s40的手机写的游戏,因此在了解到他的屏幕为128*128之后,进行了界面布局的计算。并且用到了nokia ui提供的fullcanvas类,但是没有使用它提供的directgraphics,因为没有太多需要图形和动作的处理。

package com.j2medev.numbergame;

import javax.microedition.lcdui.display;
import javax.microedition.midlet.midlet;
import javax.microedition.midlet.midletstatechangeexception;

public class numbergame extends midlet implements buttonlistener
{

    private display display;

    private splashscreen welcome;

    private manager manager;

    private button[] buttons = new button[4];

    private button cmd;

    private mark mark;

    private engine engine;

    protected void startapp() throws midletstatechangeexception
    {
      
        initmidlet();

    }

    private void initmidlet()
    {
        display = display.getdisplay(this);
        manager = new manager();
        engine = new engine();
        engine.init();

        int screenwidth = manager.getwidth();
        int screenheight = manager.getheight();
        int balance = screenwidth / 5;
        int buttonwidth = balance - 1;
        int buttonheight = 15;
        for (int i = 0; i < buttons.length; i++)
        {
            buttons[i] = new button("", 1 + i * balance, 1, buttonwidth,
                    buttonheight);
            manager.add(buttons[i]);
            buttons[i].setmargin(8, 4);
            buttons[i].setlistener(this);
        }

        cmd = new button("ok", 1 + buttons.length * balance, 1, buttonwidth,
                buttonheight);
        manager.add(cmd);
        cmd.setlistener(this);
        cmd.setmodifiable(false);

        mark = new mark(1, 1 + cmd.getheight() + 2, screenwidth - 3,
                screenheight - 3 - cmd.getheight());
        manager.add(mark);

        welcome = new splashscreen(display, manager);
        display.setcurrent(welcome);

    }

    protected void pauseapp()
    {


    }

    protected void destroyapp(boolean arg0) throws midletstatechangeexception
    {
       
    }

    public void buttonpressed(button button)
    {
        string label = button.getlabel();
        if (label == "ok")
        {
            int[] res = getinput();
            if (res.length == 1)
            {
                congscreen cs = new congscreen(display, manager);
                cs.settitle("数字不能为空");
                cs.settype(congscreen.warning);
                display.setcurrent(cs);

                return;
            }
            int[] feedback = engine.queryresult(res);

            if (feedback[0] == 4)
            {

                congscreen cs = new congscreen(display, manager, mark);
                cs.settitle("恭喜您!");

                display.setcurrent(cs);

                resetgame();
                return;
            }
            if (mark.getcount() == 9 & feedback[0] != 4)
            {

                congscreen cs = new congscreen(display, manager, mark);
                cs.settitle("重新开始吧");
                cs.settype(congscreen.warning);

                display.setcurrent(cs);

                resetgame();
                return;
            }
            mark.setinput(res);
            mark.setab(feedback);
            mark.setopen(true);
            manager.repaintarea(mark, true);
            mark.setopen(false);

        }

    }

    public string input2string(int[] input)
    {
        string s = "";
        for (int i = 0; i < input.length; i++)
        {
            s = s + input[i];
        }
        return s;
    }

    private int[] getinput()
    {
        string[] inputstring = new string[4];
        for (int i = 0; i < buttons.length; i++)
        {
            inputstring[i] = buttons[i].getlabel();
        }

        for (int k = 0; k < inputstring.length; k++)
        {
            if (inputstring[k].equals(""))
            {
                return new int[] { 100 };
            }
        }

        int[] number = new int[4];
        for (int j = 0; j < inputstring.length; j++)
        {
            number[j] = integer.parseint(inputstring[j]);
        }
        return number;
    }

    private void resetbutton()
    {
        for (int i = 0; i < buttons.length; i++)
        {
            buttons[i].setlabel("");
        }
    }

    public void resetgame()
    {
        resetbutton();
        mark.reset();
        engine.init();
    }

}

    总结:这个游戏比较简单,但是其中组件的实现比较重要。我们从中可以学到回调以及容器管理组件的技术。由于本人没有游戏开发经验,因此在美工方面比较欠缺,只是随便画了几个图形。猜数字的界面也很淡薄,缺乏吸引力。我们的目的在于学习。希望游戏开发的高手多多分享一下自己的经验,我也会开始自己的下一个动作类游戏。

扫描关注微信公众号