響應www.J2MEdev.com站長mingJava的號召,我也和大家一起分享一下我的經驗,希望大家指教。同時www.J2MEdev.com 歡迎各位高手的原創文章。
前幾天看到tony在csdn上發布自己的學習作品“是男人就堅持60s”,覺得創意雖然簡單但是卻很耐玩,是學習手機游戲制作的入門經典,於是一時興起, clone了一下,圖片依然使用的是tony的圖片,純粹學習之用。如果大家對這個游戲感興趣可以與tony聯系或訪問他的blog。
從發展趨勢上說midp2.0是趨勢,最便宜的midp2.0手機如ot735i,已經1700元左右;而西門子一年前的高端機cx65,現在也只有 2500左右;並且2500-3000這個價位的midp2.0手機有多種選擇,西門子、se、N機都有。我個人挺喜歡cx65,如果將來手機制造商成本不斷降低,相信1500元的midp將不是夢…當然還要看應用是否豐富了。
言歸正傳,我們將使用midp 2.0 來開發我們的游戲,代號fly。開發工具jbulider。等文章全寫完了,會提供src下載。
目錄:
一、游戲的框架
二、完善周邊工具類(圖象、GameObject、Font)
三、控制飛機的移動
四、加入子彈群,實現碰撞運算
五、實現爆炸效果、並加入道具導彈
六、不足多多,你認為呢?
七、源碼
一、游戲的框架
我們的游戲需要一個通用的游戲框架,也方便以後的開發,但實現一個引擎是復雜的。作為初學者如果要你考慮太多的問題,恐怕會讓你偏離主線,這裡只給出canvas的代碼,不理解可以參看本站的另外一篇系列文章《使用MIDP2.0開發游戲》。
使用singlon實現,因為每個gamecanvas都需要很多的內存空間。另外對我們來說,只要改寫gameInit(),gameMain(),一次性初始化的代碼寫在構造函數中。
public class MyGameCanvas extends GameCanvas
implements Runnable, CommandListener{
private static MyGameCanvas instance;
Graphics g;
boolean running;
Thread t;
Command startcmd,exitcmd,restartcmd;
int keystate;
boolean keyevent;
boolean key_up,key_down,key_left,key_right,key_fire;
private boolean allowinput;
public int screenwidth;
public int screenheight;
boolean gameover;
//define your variable here
//define your variable end
protected MyGameCanvas() {
super(true);
g=getGraphics();
running=false;
t=null;
addCommand(startcmd=new Command("start",Command.OK,1));
addCommand(exitcmd=new Command("exit",Command.EXIT,1));
setCommandListener(this);
screenwidth=getWidth();
screenheight=getHeight();
//put your init once code here
//put your init once code end
}
synchronized public static MyGameCanvas getInstance() {
if (instance == null) {
instance = new MyGameCanvas();
System.out.println("new MyGameCanvas");
}
return instance;
}
public void run(){
System.out.println("MyGameCanvas run start");
long st=0,et=0,diff=0;
int rate=50;//16-17 frame per second
while(running){
st=System.currentTimeMillis();
gameinput();
gameMain();
et=System.currentTimeMillis();
diff=et-st;
if(diff<rate){
//System.out.println("Sleep "+(rate-diff));
try {
Thread.sleep(rate - diff);
}
catch (InterruptedException ex) {}
}else{
//System.out.println("rush , and the frame using time: á"+diff);
}
}
System.out.println("MyGameCanvas run end");
}
public void start(){
if(!running){
running=true;
t=new Thread(this);
t.start();
}
}
private void gameMain() {
g.setColor(0,0,0);//clear screen
g.fillRect(0,0,getWidth(),getHeight());
background.paint(g);//draw background
//g.setColor(255,255,255);
//g.drawString("hello",1,1,g.TOP|g.LEFT);
flushGraphics();
}
private void gameInit() {
gameover=false;
gametime=0;
gametimeoffset=System.currentTimeMillis();
allowinput=true;
key_up=key_down=key_left=key_right=key_fire=false;
}
public void stop(){
if(running){
running = false;
}
}
public void commandAction(Command c, Displayable d) {
String cmdstr=c.getLabel();
if(cmdstr.equals("start")){
gameInit();
start();
removeCommand(startcmd);
addCommand(restartcmd=new Command("restart",Command.OK,1));
}else if(cmdstr.equals("restart")){
stop();
while(t.isAlive());
gameInit();
start();
}else if(cmdstr.equals("exit")){
stop();
Navigate.midlet.destroyApp(false);
Navigate.midlet.notifyDestroyed();
}
}
private void gameinput() {
if(allowinput){
keystate=getKeyStates();
keyevent=false;
if((keystate & UP_PRESSED)!=0){//up
key_up=true;keyevent=true;
//deal your unstop job code here
//System.out.println("up press");
//deal your unstop job code end
}else if((keystate & UP_PRESSED)==0){//release key
if(key_up==true){
key_up=false;
//deal your one press-one job code here
//System.out.println("up release");
//deal your one press-one job code end
}
}
if((keystate & DOWN_PRESSED)!=0){//down
key_down=true;keyevent=true;
//deal your unstop job code here
//System.out.println("down press");
//deal your unstop job code end
}else if((keystate & DOWN_PRESSED)==0){//release key
if(key_down==true){
key_down=false;
//deal your one press-one job code here
//System.out.println("down release");
//deal your one press-one job code end
}
}
if((keystate & LEFT_PRESSED)!=0){//left
key_left=true;keyevent=true;
//deal your unstop job code here
//System.out.println("left press");
//deal your unstop job code end
}else if((keystate & LEFT_PRESSED)==0){//release key
if(key_left==true){
key_left=false;
//deal your one press-one job code here
//System.out.println("left release");
//deal your one press-one job code end
}
}
if((keystate & RIGHT_PRESSED)!=0){//right
key_right=true;keyevent=true;
//deal your unstop job code here
//System.out.println("right press");
//deal your unstop job code end
}else if((keystate & RIGHT_PRESSED)==0){//release key
if(key_right==true){
key_right=false;
//deal your one press-one job code here
//System.out.println("right release");
//deal your one press-one job code end
}
}
if((keystate & FIRE_PRESSED)!=0){//fire
key_fire=true;keyevent=true;
//deal your unstop job code here
//System.out.println("fire press");
//deal your unstop job code end
}else if((keystate & FIRE_PRESSED)==0){//release key
if(key_fire==true){
key_fire=false;
//deal your one press-one job code here
//System.out.println("fire release");
//deal your one press-one job code end
}
}
if(!keyevent){
//no keyevent here
//System.out.println("NO KEY press");
//no keyevent end
}
}
}
public static void cleanJob(){
instance=null;
}
}