Chủ Nhật, 18 tháng 11, 2012

một đội quân địch, cấp độ khó

trong trò chơi mà chơi với những AI thì lúc nào chúng cũng thua mình thôi, do đó cần tạo ra độ khó bằng cách tăng số lượng của chúng. tôi sẽ tạo ra một đạo quân địch từ những gì mà ta đã có và thêm vào đó một vài thứ khác.
ta sẽ tạo ra một class E, bao gồm một biến xe T và những giá trị như mã key, biến đúng sai die , như sau:
//E.java
import javax.microedition.lcdui.*;

public class E {
T x;
boolean die;
int k;
public E(int x, int y, int color, int w,int h){
die=false;
this.x=new T(x,y,color,w,h);}
void paint(Graphics g,int k){
x.paint(g,k);}
}

. Sau đó trong game.java ta sửa lại như sau:
//game.java

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

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k,ak,cx=3;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;
E[] e;
long lai=0;
Random rd=new Random();

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0,w,h);
x=new T(w-16*3,h-16*3,0x6060f0,w,h);
//khởi tạo e
e=new E[cx];
for(int i=0;i<e.length;i++){
e[i]=new E(w-16*3,h-16*3,0x6060f0,w,h);}
}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, (ak=ai(x,ak)));
if(check(t,x)){x.color-=0x000010;}
if(check(x,t)){t.color-=0x100000;}

//biến n đếm số xe đã được vẽ trong e
int n=0;
for(int i=0;i<e.length;i++){
//chỉ vẽ ra tới 3 xe tăng, nếu nhiều hơn thì chờ đến lượt
if(n==2)continue;
//nếu chưa trúng đạn thì vẽ ra
if(!e[i].die)
{n++;
e[i].k=ai(e[i].x,e[i].k);
e[i].paint(g,e[i].k);

//check xem có trúng đạn của ta không, nếu có thì cho chết die=true
if(check(t,e[i].x))e[i].die=true;
if(check(e[i].x,t)){
//xe ta bị trúng đạn
//game over, kết thúc trò chơi, hay mất mạng, mất máu gì đó
}}
}
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}

//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0)mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;
//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}

boolean check(T a, T b){
int xc=(a.d.x-b.x)/16/3;
int yc=(a.d.y-b.y)/16/3;
if(xc==0&amp;&amp;yc==0&amp;&amp;a.d.f!=-1){
b.color-=0x100010;
return true;}
return false;}

int ai(T a,int ak){
if(lai<System.currentTimeMillis()-2000){
lai=System.currentTimeMillis();
int k=Math.abs(rd.nextInt())%4;
return -(k+1);}
if(System.currentTimeMillis()%25==0)
return -(1+a.f);
if(rd.nextInt()%3==0&amp;&amp;a.d.f==-1){return -5;}
return 0;}
}

. Kết quả đây, trò chơi gần như hoàn thiện, các bạn có thể thêm phần level cho trò chơi hoặc gì đó hay ho một chút...

source here

giới hạn màn hình

tức nhiên nếu cứ để cho những chiếc xe chạy ra khỏi giới hạn của màn hình thì chẳng biết nó sẽ đi tới đâu, thật sự thì nó không thể nào đi quá giới hạn của biến int nhưng mà ta cũng có thể coi là đó là một nơi vô tận. bây giờ ta sẽ giới hạn khả năng di chuyển của chúng, nhưng chiếc xe khi gặp khung màn hình thì không di chuyển thêm nữa. ta biến đổi T.java như sau:

//T.java

import javax.microedition.lcdui.*;

public class T {
F d;
int x,y,f,color,w,h;
long lm=0;
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};

public T(int x,int y,int color,int w, int h){
this.x=x;
this.y=y;
this.color=color;
d=new F(x+16,y+16,0xf00000,50);
this.w=w;
this.h=h;
}

boolean check(){return (lm<System.currentTimeMillis()-60);}

public void paint(Graphics g,int k){
switch(k){
case -1: f=0; if(check()){y-=16; if(y<0)y=0; lm=System.currentTimeMillis();} break;
case -2: f=1; if(check()){y+=16; if(y>h-16*3)y=h-16*3; lm=System.currentTimeMillis();} break;
case -3: f=2; if(check()){x-=16; if(x<0)x=0; lm=System.currentTimeMillis();} break;
case -4: f=3; if(check()){x+=16; if(x>w-16*3) x=w-16*3; lm=System.currentTimeMillis();}break;
case -5: d.f=this.f; break;}
g.setColor(color);
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
d.fire(g,x+16,y+16);
}
}

. Do hàm khởi tạo trong T.java đã thay đổi nên trong game.java ta cũng thay đổi khởi tạo cho biến tx

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0,w,h);
x=new T(w-16*3,h-16*3,0x6060f0,w,h);}

* Kết quả rất mãn nguyện:

AI tự động giải quyết vấn đề.

thật ra không có gì thông minh cho lắm, người lập trình nghĩ sao viết vậy thì các nhân vật tự động cũng làm theo như vậy. nhưng cũng có những Artificial inteligence thật sự làm người ta ngạc nhiên, điều đó phụ thuộc vào người lập trình như thế nào, có khi họ không phải là người truyền cách thức hoạt động vào code mà là một người khác có trí tuệ cao hơn họ, người này có thể không biết gì về lập trình cả.
Ở đây tôi chỉ làm cho xe của địch có khả năng tự di chuyển và nả đạn khi cần thiết, như vậy thì mới thật sự là một trò chơi. trong game.java tôi thêm một hàm mới, hàm này tổng hợp một mã phím theo thời gian.
//game.java

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

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k,ak;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;
long lai=0;

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index

g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, (ak=ai(x,ak)));
if(check(t,x)){x.color-=0x000010;}
if(check(x,t))t.color-=0x100000;
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0)mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;
//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}

boolean check(T a, T b){
int xc=(a.d.x-b.x)/16/3;
int yc=(a.d.y-b.y)/16/3;
if(xc==0&amp;&amp;yc==0&amp;&amp;a.d.f!=-1){return true;}
return false;}

//đây là hàm tổng hợp theo thời gian mã key cho xe tự động
int ai(T a,int ak){
Random rd=new Random();
// điều kiệm để đổi hướng xe là sau 2 giây (2000millis giây)
if(lai<System.currentTimeMillis()-2000){
lai=System.currentTimeMillis();
int k=Math.abs(rd.nextInt())%4;
return -(k+1);}

//nếu như không có gì thay đổi thì cứ sau 25 millis giây cho tiến về trước 1 bước
if(System.currentTimeMillis()%25==0)
return -(1+a.f);

//nếu không thì trả về key không, tức không di chuyển
return 0;}

}


. Kết quả của ta sẽ là xe tự động di chuyển
Và sửa lại một chút cho khả năng tự nhả đạn:
int ai(T a,int ak){
Random rd=new Random();

if(lai<System.currentTimeMillis()-2000){
lai=System.currentTimeMillis();
int k=Math.abs(rd.nextInt())%4;
return -(k+1);}
if(System.currentTimeMillis()%25==0)
return -(1+a.f);
if(rd.nextInt()%3==0&amp;&amp;a.d.f==-1){return -5;}
return 0;}

trúng đạn

bây giờ tôi sẽ thêm một hàm vào trong game.java để phát hiện xem khi nào thì xe ta bị trúng đạn hoặc là xe địch bị ta bắn trúng.

//game.java

import javax.microedition.lcdui.*;

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;


public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, 0);

//nếu như là kiểm tra thấy đạn của xe này chạm xe kia thì cho xe kia bị đổi màu, tức nhiên là trong thực tế bạn có thể cho nó biến mất

if(check(t,x)){x.color-=0x000010;}
if(check(x,t)){t.color-=0x100000;}

break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0)mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;
//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}


 //hàm check này nhận giá trị là 2 kiểu T và sau đó kiểm tra xem tọa độ đạn của xe đầu và tọa độ của xe sau nếu như mà chạm nhau thì trả lại giá trị true, tương đương với nghĩa là đã bắn trúng.
boolean check(T a, T b){
int xc=(a.d.x-b.x)/16/3;
int yc=(a.d.y-b.y)/16/3;
if(xc==0&&yc==0&&a.d.f!=-1){return true;}
return false;}

}

* kết quả như sau, sau khi trúng đạn xe địch thay đổi màu:

chuẩn bị các nguyên liệu cho game

trong game có các thành phần như là nhân vật, chướng ngại vật, kẻ thù, và những vật dụng khác cũng như ngoại cảnh. tùy theo ý thích của mỗi người mà chúng ta có thể chuẩn bị đủ mọi thứ. cũng như việc lắp ráp một chiếc xe cần phải có những thứ tạo nên chiếc xe đó như khung xe, bánh xe, dây xích, bulong, ốc vít....
bây giờ tôi sẽ làm một game đơn giản thôi và sẽ sử dụng hoàn toàn bằng lệnh, tức là không dung thêm bất cứ file nào ngoài code java. game mà tôi sắp viết nên đây là một trò bắn tăng cổ điển, giống như trò chơi trên các máy bấm hộp nhỏ nhỏ xài pin mà ngoài chợ thường bán.
. Ta cần các hình sau:
- xe tăng của ta gọi là T
- xe tăng chướng vật gọi là X
- đạn bắn ra gọi là F
mỗi một hình như vậy chúng ta sẽ tạo trên một class riêng và chúng phải có những thuộc tính sau:
- tọa độ x
- tọa độ y
1. đầu tiên tôi viết class vẽ T, như sau:
import javax.microedition.lcdui.*;

public class T {

//T này ngoài tọa độ x,y còn có thêm biến frame, và biến màu sắc
int x,y,f,color;

//biến lm ghi lại lần di chuyển cuối cùng của T
long lm=0;

//biến shape là các frame của T, gồm có 4 frame
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};

//hàm khởi tạo nhận giá trị tọa độ ban đầu và màu sắc của T
public T(int x,int y,int color){
this.x=x;
this.y=y;
this.color=color;}

//hàm paint dùng để nhận biến Graphics và vẽ trên đó, cùng với biến k là phím nhấn trên bàn phím
public void paint(Graphics g,int k){

//check xem lần cuối cùng di chuyển và khoảng thời gian hiện tại có cách nhau 60 millis giây
if(lm<System.currentTimeMillis()-60){
switch(k){
case -1: f=0; y-=16; break;
case -2: f=1; y+=16; break;
case -3: f=2; x-=16; break;
case -4: f=3; x+=16; break;}
lm=System.currentTimeMillis();}

//đặt màu cho xe tăng này
g.setColor(color);

//vẽ xe tăng theo frame, nếu là 0 thì không vẽ ra được gì, nếu 1 thì vẽ 1 ô vuông, tạo nên hình chiếc xe
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
}
}

kết quả của ta sẽ như thế này. ta không cần phải thiết kế thêm class X nữa mà chúng ta dùng class T để tạo luôn xe tăng chướng ngại, chỉ cần đổi màu một chút là được, và kết quả ta được như sau:


Tất nhiên trong file game.java chúng ta cũng phải thay đổi một chút để đưa hai đối tượng T này vào:

import javax.microedition.lcdui.*;

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, k);
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0 )mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;

//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}
}

. Bây giờ thì viết thêm class F nữa, đây sẽ là đạn bắn ra từ các xe.
//F.java
import javax.microedition.lcdui.*;
public class F {
int x,y,color,f=-1,speed;
long lm=0;
public F(int x,int y,int color,int speed){
this.x=x;
this.y=y;
this.color=color;
this.speed=speed;}
public void fire(Graphics g,int x,int y){
if(f==-1){this.x=x; this.y=y;}
g.setColor(color);
if(System.currentTimeMillis()%500<250)
g.fillRect(this.x,this.y,16,16);

if(f!=-1&amp;&amp;lm<System.currentTimeMillis()-speed){
switch(f){
case 0: this.y-=16; break;
case 1: this.y+=16; break;
case 2: this.x-=16; break;
case 3: this.x+=16; break;}
lm=System.currentTimeMillis();}
if(f!=-1&amp;&amp;(Math.abs(this.x-x)&gt;240||Math.abs(this.y-y)&gt;320)){f=-1;}
}
}

. cuối cùng thì mỗi xe đều có khả năng nhả đạn, nên trong T class ta chỉnh sửa lại một chút để tạo khả năng bắn đạn cho các xe này.
//T.java
import javax.microedition.lcdui.*;

public class T {
F d;
int x,y,f,color;
long lm=0;
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};
public T(int x,int y,int color){
this.x=x;
this.y=y;
this.color=color;
d=new F(x+16,y+16,0xf00000,500);}
boolean check(){return (lm<System.currentTimeMillis()-60);}

public void paint(Graphics g,int k){
switch(k){
case -1: f=0; if(check()){y-=16; lm=System.currentTimeMillis();} break;
case -2: f=1; if(check()){y+=16; lm=System.currentTimeMillis();} break;
case -3: f=2; if(check()){x-=16; lm=System.currentTimeMillis();} break;
case -4: f=3; if(check()){x+=16; lm=System.currentTimeMillis();}break;
case -5: d.f=this.f; break;}
g.setColor(color);
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
d.fire(g,x+16,y+16);
}
}

kết quả ta được như thế này.

Thứ Bảy, 17 tháng 11, 2012

chia các phần trong một trò chơi

hãy tưởng tượng, khi mở một trò chơi ra bạn sẽ có thể gặp một phần giới thiệu trước, sau đó là menu, mỗi một lựa chọn trong menu lại đưa ra một màn hình khác nhau, như màn chơi, phần hướng dẫn, phần tóm tắt...
bài này sẽ tạo ra một class hiển thị các phần như vậy, và menu của chúng ta chỉ có 3 mục: play game, help, about, với một nút exit ở dưới trái màn hình.
file Midlet của chúng ta sẽ chỉ có thêm một dòng so với ban đầu:
//Midlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;


public class Midlet extends MIDlet {
public void startApp() {
Display.getDisplay(this).setCurrent(new game(this));
}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}
}
tạo một class mới đặt tên là game, có nội dung như sau:
//game.java

import javax.microedition.lcdui.*;
public class game extends Canvas {

String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0;
Midlet m;
Font f=Font.getDefaultFont();

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

public void keyPressed(int k){

//cho di chuyển vị trí thanh menu
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0) mindex=smenu.length-1;
if(mindex==smenu.length) mindex=0;

//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;

//các lệnh cho menu góc màn hình
if(k==-7)mode=0;
if(k==-6)m.notifyDestroyed();}
}


công cụ sử dụng trong bài viết

. đối với người dùng windows thì netbean hay java wireless toolkit là những phần mềm hỗ trợ lập trình J2ME tốt nhất. ngoài ra các bạn còn cần phải tải gói java hỗ trợ là jdk.
. để tiện lợi, tôi sẽ sử dụng netbean để tiến hành hướng dẫn trong những bài viết này, giao diện và các phần bổ trợ gần như đầy đủ.
netbean download vào trang download và chn download gói all (240Mb)
jdk gói java bổ trợ cung cấp thư viện và môi trường chạy giả lập
. Bạn cài gói JDK trước sau đó cài netBean sau, quá trình khởi động đầu tiên NetBean sẽ kiểm tra phần cứng và cấu hình hơi lâu một chút.
. để tạo một Project mới bạn bấm vào File -> new Project -> (cataloge) Java ME -> (Project) Mobile Application. sau đó nhấn Next
- tiếp theo đặt tên cho Project, bỏ chọn create Hello Midlet, bấm finish
- ở khung bên trái dưới tên project, chọn source package, click phải vào và chọn new -> Midlet, bấm finish, đây là main class của chúng ta.
- để tạo thêm những class phụ chúng ta cũng bấm phải vào source package và chọn new -> class, đặt tên và nhấn finish.
- để mở một file source chỉ cần nhấp đúp vào tên của nó bên khung bên trái.
Đã xảy ra lỗi trong tiện ích này