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