Thứ Tư, 14 tháng 8, 2013

Chúng ta không chỉ có một mình

Hôm trước đã nói tới chuyện thông qua command mà điểu khiển một biến robot rồi, hôm nay cũng với command và robot này nhưng chúng ta không chỉ điều khiển một mà là nhiều. tức là khi viết lệnh chúng ta viết cho nhiều robot và với phân cách là dấu chấm (.) có bao nhiêu lệnh thì có bấy nhiêu biến robot được vẽ trên màn hình. Hãy xét một lệnh tổng hợp ví dụ như sau: 1 robot: string,x,y Nhiều robot: string1,x1,y1.srting,x2,y2.string3,x3,y3.(string_n,x_n,y_n) Giả sử ta có lệnh tổng hợp sau: Abc,10,50.bcd,30,100.def,120,5 vậy là ta có 3 biến robot được tạo ra và màn hình sẽ thực hiện việc vẽ 3 biến này lên màn hình. Để làm như vậy, bây giờ ta sẽ sử dụng biến rb là một Vector của lớp robot Ta đặt: Vector rb; Chưa vội gán giá trị cho nó bao nhiêu đối tượng mà ta sẽ phân tích từ lệnh. Lớp canvas.java sẽ như thế này:
C:\Users\WIN7\Documents\NetBeansProjects\mog\src\mog.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;

public class mog extends MIDlet {
public void startApp(){
Display.getDisplay(this).setCurrent(new canvas());}
public void destroyApp(boolean t){}
public void pauseApp(){}}

class canvas extends Canvas{
textfield tf;
Vector rb=new Vector();
Font f=Font.getFont(0,0,8);
int w,h,k=0,fh;
String command="";
public canvas(){
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
tf=new textfield("command",0,0,w);
}
public void paint(Graphics g){
g.setFont(f);
g.setColor(0);
g.fillRect(0,0,w,h);
tf.paint(g,k,true);
g.setColor(0xf0f0);
g.setClip(0,0,w,h);
g.drawString(command,0,fh*2,Graphics.TOP|Graphics.LEFT);
if(rb!=null)
for(int i=0;i<rb.size();i++)
((robot)rb.elementAt(i)).paint(g);
k=0;
repaint();
}
public void keyPressed(int k){
this.k=k;
if(k==-5){
command=tf.getString();
String[] acommand=tach(command,".");
for(int i=0;i<acommand.length;i++){
    robot nrb=new robot(w/2,h/2);
    nrb.getcommand(tach(acommand[i],","));
rb.addElement((robot)nrb);}}}
public void keyReleased(int k){this.k=0;}

public String[] tach(String s,String c){
Vector v=new Vector();
if(!s.endsWith(c)){s+=c;}
int st=0,np=s.indexOf(c,st);
while(np!=-1){
v.addElement((String)s.substring(st,np));
st=np+c.length();
np=s.indexOf(c,st);}
String[] rt=new String[v.size()];
v.copyInto((String[])rt);
for(int i=0;i<rt.length;i++){System.out.println(rt[i]+rt[i].length());}
return rt;}
}

class robot{
int x,y,nx,ny;
String say;
long lm=0;
public robot(int x,int y){
this.x=x;
this.y=y;
this.nx=x;
this.ny=y;
}
public void getcommand(String[] s){
say=s[0];
nx=Integer.parseInt(s[1]);
ny=Integer.parseInt(s[2]);
}
public void paint(Graphics g){
if(System.currentTimeMillis()-lm>200)
move();
g.setColor(0xf000f0);
g.fillRect(x,y,16,16);
}

void move(){
x+=x>nx?-1:(x==nx?0:1);
y+=y>ny?-1:(y==ny?0:1);}
}
• Như chúng ta thấy đó, sau khi ta nhấn phím 5, lệnh sẽ được lấy ra từ textfield (tf) và phân tích thành mảng của các lệnh con qua String[] acommand=tach(command,"."); • Và sau đó lại được phân tích và gán vào biến robot bình thường. for(int i=0;i
C:\Users\WIN7\Documents\NetBeansProjects\mog\src\mog.java
public void keyPressed(int k){
this.k=k;
if(k==-5){
command=tf.getString();
String[] acommand=tach(command,".");
Vector trb=new Vector();
for(int i=0;i<acommand.length;i++){
    String[] info=tach(acommand[i],",");
    robot nrb=new robot(w/2,h/2);
    for(int j=0;j<rb.size();j++){
   if(info[0].equals(((robot)rb.elementAt(j)).say)){nrb=(robot)rb.elementAt(j);
    System.out.println("dectect");}}
    nrb.getcommand(info);
trb.addElement((robot)nrb);}
rb=trb;}}
}
• Lúc này ta cần tạo thêm một biến trb dùng để tạo một vùng thêm các biến robot vào và so sánh với biến rb cũ, nếu không làm như vậy mà thêm trực tiếp vào biến cũ ta sẽ không thể nào kiểm soát được các đối tượng mà ta đã ra lệnh trước đó. • Bài này vậy là xong, nếu đến đây các bạn vẫn chưa hiểu được là ta đang làm cái gì thì bài sau các bạn sẽ rõ. Đây không phải chỉ là chuyện rèn kỹ năng giải thuật mà nó phải có sử dụng thực tế. Tải zip

Đi lệch quỹ đạo

một lập trình viên thường không thể nào kiểm soát hết mọi trường hợp có thể xảy ra trong thực tế, dù rằng đó là ứng dụng do chính họ tạo ra. một thế giới nhỏ bé cũng có những sự cố của chính nó, tôi cũng gặp nhiều những sự cố như vậy, tôi cố gắng sửa chữa chúng nhưng dường như cứ để như vậy thì lại hay hơn. mình có thề sửa cái này vì nó ngay trước mặt mình nhưng còn những thứ không bao giờ hiện ra ngay trước mắt. tôi không biết mình có đi lệch quỹ đạo hay không và thật sự đâu là quĩ đạo của chính tôi. dù sao thì tôi cũng sống cho chính bản thân mình và không chịu sự điều khiển của ai cả, nếu như tôi không còn là tôi của những ngày ban đầu thì tôi vẫn đi trong chính con đường của mình chứ không ai khác. trong những gì mà ta đầu tư cũng có thể bỏ đi hết, nếu tự nhiên có thứ gì đó thu hút ta hơn. tôi thường xem việc lập trình hoặc là viết bài hướng dẫn như là một sự giải thoát khỏi sự chán nản của cuộc sống nhưng thỉnh thoảng cái cô độc vẫn ám ảnh tôi nhiều hơn. và bây giờ tôi muốn nói gì đó cho nó khuây khỏa, muốn quên đi những thứ mà tôi chưa kịp hoàn thành. bế tắc trong bất cứ chuyện gì cũng không có nghĩa lí gì hết nếu như có một cái gì đó cho ta nhìn ra ngoài. hãy thử tưởng tượng khi bạn đang cố gắng suy nghĩ về cuộc đời mình rồi sẽ ra sao và có một người đến nói với bạn rằng hãy đi chơi với họ thì bạn sẽ nghĩ sao. tự nhiên ta sẽ quên hết mọi thứ đang dang dở và hào hứng đến với họ hơn là việc ta đang làm. tôi không biết, thường thì tôi sẽ làm vậy, và ngay cả trong việc viết hướng dẫn như thế này tôi cũng không muốn bó buộc vào điều gì hết, đừng phiền lòng nếu như bài biết này làm phí thời gian của bạn, vì nó là những gì mà tôi thấy là có ý nghĩa với một vài người và ít nhất là đối với tôi. nhiều khi nằm trên giường và nhìn ra ngoài cửa sổ tôi lại thấy nó như hấp dẫn tôi rất nhiều, tôi thích nhìn chỉ một góc như vậy và suy nghĩ xem những phần còn lại của thế giới đang diễn ra như thế nào. hay chuyện vào một thời gian nào đó bạn nghĩ về một người bạn của mình hiện giờ đang làm gì và như thế nào, có những chuyện gì làm cho họ buồn hay vui và họ có nhớ tới bạn không. thật sự là ta có thể nghĩ đến hàng vô số những chuyện xảy ra trên thế giới này và mọi thứ điều tuyệt diệu.
"hãy thử nhìn xung quanh và nghĩ xem điều gì đang diễn ra ở đó"

điều khiển nhân vật thông qua lệnh

Bài trước đã hướng dẫn cách viết một class textfield hiển thị và nhập trên Canvas, bài này sẽ sử dụng đến textfield đó để làm vài thứ: Đầu tiên chúng ta sẽ tạo một class nhận giá trị là một chuổi và sau đó là phân tích chuỗi đó để thực hiện những lệnh mà ta muốn, lệnh ở đây bao gồm (chuỗi,tọa độ x, tọa độ y) và sau khi nhận chuỗi này nó sẽ tự cập nhật thông tin vào trong các biến của nó, ta viết như sau:
C:\Users\WIN7\Documents\NetBeansProjects\textfield\src\NewClass.java
import javax.microedition.lcdui.*;
import java.util.*;

class canvas extends Canvas{
textfield tf;
//robot là một đối tượng nhận lệnh và điều khiển bởi lệnh
robot rb;
Font f=Font.getFont(0,0,8);
int w,h,k=0,fh;
String command="";
public canvas(){
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
tf=new textfield("command",0,0,w);
rb=new robot(w/2,h/2);
}
public void paint(Graphics g){
g.setFont(f);
g.setColor(0);
g.fillRect(0,0,w,h);
//vẽ hộp nhập văn bản lên canvas
tf.paint(g,k,true);
g.setColor(0xf0f0);
g.setClip(0,0,w,h);
//vẽ chuỗi lệnh ra màn hình
g.drawString(command,0,fh*2,Graphics.TOP|Graphics.LEFT);
//vẽ đối tượng nhận lệnh ra màn hình
rb.paint(g);
k=0;
repaint();
}
public void keyPressed(int k){
this.k=k;
//nếu nhấn mã -5 (phím ok) thì cho command nhận giá trị của textfield (tf), 
if(k==-5){
command=tf.getString();
//sau đó truyền tham số vào trong đối tượng hoạt động robot(rb), trước đó ta cho nó tách thành từng phần qua method tach trước, cách nhau bởi dấu phẩy (có dạng: say,x,y)
rb.getcommand(tach(command,","));}}
public void keyReleased(int k){this.k=0;}
//chức năng tách chuỗi ra thành từng phần
public String[] tach(String s,String c){
Vector v=new Vector();
if(!s.endsWith(c)){s+=c;}
int st=0,np=s.indexOf(c,st);
while(np!=-1){
v.addElement((String)s.substring(st,np));
st=np+c.length();
np=s.indexOf(c,st);}
String[] rt=new String[v.size()];
v.copyInto((String[])rt);
for(int i=0;i<rt.length;i++){System.out.println(rt[i]+rt[i].length());}
return rt;}
}


Lớp robot là một dạng như sau, nó sẽ nhận các giá trị lệnh và xử lí để hoạt động theo lệnh đó:
C:\Users\WIN7\Documents\NetBeansProjects\textfield\src\NewClass.java
class robot{
int x,y,nx,ny;
String say;
long lm=0;
//hàm khởi tạo robot nhận 2 giá trị x, y là tọa độ đầu tiên của nó
public robot(int x,int y){
this.x=x;
this.y=y;
this.nx=x;
this.ny=y;
}
//hàm getcommand này nhận một mảng chuỗi bao gồm các giá trị truyền vào say, nx, ny 
public void getcommand(String[] s){
say=s[0];
nx=Integer.parseInt(s[1]);
ny=Integer.parseInt(s[2]);
}
//hàm paint sẽ vẽ đối tượng này lên Graphics của canvas, đồng thời cũng di chuyển nó thông qua hàm move
public void paint(Graphics g){
    //cũng cần phải cho nghỉ một khoảng thời gian để nó không di chuyển quá nhanh mà ta không kịp theo dõi
if(System.currentTimeMillis()-lm>200)
move();
g.setColor(0xf000f0);
g.fillRect(x,y,16,16);
}
//hàm move này so sánh giá trị tọa độ x,y với nx,ny để từ đó tính toán và thay đổi giá trị của x,y cho đến khi bằng nx,ny
void move(){
    //so sánh x và nx nếu như x lớn hơn nx thì cho x trừ đi 1, nếu x bằng nx thì không thay đổi x, ngược lại thì cho x tăng lên 1 khi x nhỏ hơn nx
x+=x>nx?-1:(x==nx?0:1);
//tương tự với y và ny
y+=y>ny?-1:(y==ny?0:1);}
}


Xong như vậy là chúng ta đã hoàn thành rồi, chỉ cần ghép nó vào MIDlet nữa là thấy:http://holyeyed.99k.org/function/up/mog-25113.zip http://holyeyed.99k.org/function/up/mog-97485.jar

nhập văn bản trực tiếp từ Canvas

thường thì muốn nhập chuỗi thì ta thiết kế sử dụng TextBox hoặc là TextField trên Form, nhưng trong game nên hạn chế cho người dùng sử dụng giao diện bậc cao như vậy. Ta sẽ cho nhập văn bản trực tiếp từ bàn phím trên Canvas dựa vào hàm keyPressed(int i) :
C:\Users\WIN7\Documents\NetBeansProjects\textfield\src\textfield.java
  1 //textfield.java
  2 import javax.microedition.lcdui.*;
  3 
  4 public class textfield {
  5 
  6     int x, y, w, lk = 0, np = 0, fh, tcolor = 0, bgcolor = 0xf0f0f0;
  7     String s = "", title;
  8     //mảng ac chứa các kí tự cần thiết tương ứng với các phím bấm từ 0 đến 9
  9     String[] ac = {" 0", ".,1", "abc2", "def3", "ghi4", "jkl5", "mno6", "pqrs7", "tuv8", "wxyz9"};
 10     long lp = 0, rr = 0;
 11     boolean focus = false;
 12     Font f = Font.getFont(0, 0, 8);
 13 //hàm khởi tạo textfield nhận các giá trị tiêu đề (title), vị trí đặt hộp text(x, y), và chiều rộng hộp (w)
 14     public textfield(String title, int x, int y, int w) {
 15         this.title = title;
 16         this.x = x;
 17         this.y = y;
 18         this.w = w;
 19         fh = f.getHeight();
 20     }
 21 
 22     String getString() {
 23         return s;
 24     }
 25 //hàm paint này dùng vẽ textfield lên Graphic (g) và được dùng trên Canvas, nó nhận các biến tham số: Graphics g, biến mã phím int k, và biến boolean focus chỉ định là có thực hiện thao tác với textfield này không
 26     public void paint(Graphics g, int k, boolean focus) {
 27         g.setFont(f);
 28         this.focus = focus;
 29         //nếu có tác động focus==true thì cho thực hiện vẽ chuỗi theo mã phím
 30         if (focus && cr() - lp > rr) {
 31             add(k);
 32         }
 33         //các hàm vẽ liên quan đến việc vẽ chuỗi s ra màn hình
 34         int slen = f.stringWidth(s);
 35         int kh = slen - w;
 36         g.setColor(bgcolor);
 37         g.fillRect(x, y + fh, w, fh);
 38         g.drawString(title + ":", x, y, Graphics.TOP | Graphics.LEFT);
 39         g.setColor(tcolor);
 40         g.setClip(x, y + fh, w, fh);
 41         g.drawString(s + (focus ? "|" : ""), x - (kh > 0 ? kh : 0), y + fh, Graphics.TOP | Graphics.LEFT);
 42 
 43 
 44     }
 45 
 46     void add(int k) {
 47         //nếu key là -3(phím qua trái) thì cho xóa kí tự
 48         if (k == -3 && s.length() > 0) {
 49             s = s.substring(0, s.length() - 1);
 50             lk = k;
 51             lp = cr();
 52         } else if (k == -6) {//nếu key là -6 thì thôi không tác động đến textfield này nữa
 53             focus = false;
 54         } else {
 55             //tìm vị trí của phím bấm từ 0 đến 9, do phím 0 có mã phím là 48 nên ta lần lượt trừ cho 48 sẽ tương ứng với vị trí của bảng kí tự trong mảng chuổi ac
 56             int sk = k - 48;
 57             //nếu như sk lớn hơn 0 thì cho thực hiện tiếp, tương đương là bấm các phím từ 0->9
 58             if (sk >= 0) {
 59                 //nếu thời gian hiện tại trừ lp(lần nhấn sau cùng) <800 và phím nhấn lần này giống với phím bấm lần sau cùng thì cho tăng np (index cần lấy của kí tự trong chuỗi).
 60                 if (cr() - 800 < lp && lk == sk) {
 61                     np++;
 62                     if (np == ac[sk].length()) {
 63                         np = 0;
 64                     }
 65                     s = s.substring(0, s.length() - 1);
 66                     s += ac[sk].charAt(np);
 67                 } else {//ngược lại thì cho thêm vào kí tự thích hợp với phím bấm(kí tự đầu tiên tương ứng các mảng giá trị)
 68                     np = 0;
 69                     s += ac[sk].charAt(np);
 70                 }
 71                 //đặt mả phím sau cùng và lk (phím bấm sau cùng) và thời gian bấm sau cùng lp (lần nhấn sau cùng)
 72                 lk = sk;
 73                 lp = cr();
 74             }
 75 
 76         }
 77     }
 78 //hàm cr() trả lại thời gian hiện thời
 79     long cr() {
 80         return System.currentTimeMillis();
 81     }
 82 }
 83 
 84 class canvas extends Canvas {
 85 //tạo một biến textfield mới, với tiêu đề là "nhập văn bản", ở tọa độ (0,120) và chiều rông màn hình
 86     textfield tf = new textfield("nhập văn bản", 0, 120, 40);
 87     int w = getWidth(), h = getHeight(), k = 0;
 88 
 89     public canvas() {
 90     }
 91 
 92     public void paint(Graphics g) {
 93         g.setColor(0);
 94         g.fillRect(0, 0, w, h);
 95         //thực hiện lệnnh vẽ textfield ra màn hình lên Graphics g và với mã phím k
 96         tf.paint(g, k, true);
 97         k=0;
 98         repaint();
 99     }
100 
101     public void keyPressed(int k) {
102         this.k = k;
103     }
104 
105     public void keyReleased(int k) {
106         this.k = 0;
107     }
108 }
• ở đây chúng ta chỉ cần lưu ý là trong textfield.java có các biến đảm nhận thời gian như là lp, để xác định lần nhấn phím sau cùng mà người dùng nhấn. sau đó so sánh với giá trị thời gian hiện tại lấy từ hàm cr(), nếu như mà hai giá trị này chênh nhau quá 800ms thì cho cộng vào chuỗi một kí tự mới tương ứng với index 0 trong giá trị của phím trong mảng chuỗi ac. Còn nếu như mà thấy thời gian chênh nhau giữa lp và cr() trong 800ms trở lại và mã phím cũng là mã phím nhấn sau cùng thì cho tăng index lấy kí tự trong mã phím hiện tại và kết quả là thay đổi kí tự vừa mới ghi lúc nãy chứ không thêm kí tự mới nào. • Tải jar •Tải zip

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 tvà x

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: