Thứ Năm, 14 tháng 2, 2013

the Sky Fall

Không phải là phim đâu, mà là một trò chơi đơn giản: nhân vật của chúng ta sẽ rơi xuống vào một rừng mũi tên đang bắn lên, chúng ta sẽ điều khiển để nhân vật đừng chạm vào mũi tên nào hết. các bạn cần có 3 file sau, tôi đã chú thích trong từng file hết rồi, chắc các bạn cũng hiểu thôi. Đầu tiên là file muiten.java muiten.java
C:\Users\thanhliem\Documents\NetBeansProjects\SkyFall\src\muiten.java

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

public class muiten {
//các biến: độ rộng màn hình, cao màn hình, vị trí x, vị trí y, chiều dài mũi tên, tốc độ mũi tên
    int w, h, x, y, len, speed;
    //biến chỉ mốc thời gian di chuyển lần cuối
    long lm = 0;
//    biến số ngẫu nhiên
    Random rd = new Random();
    //biến đầu mũi tên, và biến đuôi mũi tên dùng vẽ hình mũi tên
    byte[][] mim = {
        {0, 1, 0},
        {1, 1, 1}},
            dim = {{1, 0, 1}};
//hàm khởi tạo nhận các giá trị rộng,cao màn hình và một số nguyên ngẩu nhiên
    public muiten(int w, int h, int rd) {
        this.w = w;
        this.h = h;
        this.rd = new Random(rd);
        //dùng hàm general để khởi tạo
        general();
    }
//hàm general xác định tọa độ x, y chiều dài và tốc độ ngẫu nhiên cho mũi tên
    public void general() {
        //hàm Math.abs(số nguyên) chỉ sang trị tuyệt đối, nextInt là lấy số nguyên ngẫu nhiên, dấu % là phép chia lấy dư.
        x = Math.abs(rd.nextInt()) % w;
        y = h + 3;
        len = Math.abs(rd.nextInt()) % (h / 10);
        speed = Math.abs(rd.nextInt()) % 3 + 2;
    }

    public void draw(Graphics g) {
        //lấy màu hiện tại lưu lại vào ocl
        int ocl = g.getColor();
        //dặt màu mới
        g.setColor(ocl & 0xff);
        //cho vẽ mũi tên qua hàm drawmuiten
        drawmuiten(g);
        //đặt lại màu cũ
        g.setColor(ocl);
        //kiểm tra nếu như cách khoảng 20 mili giây từ lần cuối di chuyển lm thì cho mũi tên di chuyển tiếp
        if (lm < System.currentTimeMillis() - 20) {
            y -= speed;
            lm = System.currentTimeMillis();
        }
        //nếu như tọa độ y bé hơn -h/10 thì cho tạo lại mũi tên.
        if (y < -h / 10) {
            general();
        }
    }
//hàm check dùng để kiểm tra xem nhân vật và mũi tên có chạm nhâu không, gồm tọa độ x,y của nhân vật và độ cao rộng của nhân vật
    boolean check(int x, int y, int w, int h) {
        int sx = (this.x - x);
        int sy = (this.y - y);
        if (sx > 0 && sy > 0 && sx <= w && sy <= h) {
            return true;
        }
        return false;
    }
//hàm vẽ mũi tên sẽ vẽ mũi tên theo tọa độ của nó
    public void drawmuiten(Graphics g) {
        //vẽ đầu mũi tên
        for (int i = 0; i < mim.length; i++) {
            for (int j = 0; j < mim[0].length; j++) {
                if (mim[i][j] != 0) {
                    g.fillRect(x + j, y + i, 1, 1);
                }
            }
        }
        //vẽ thân mũi tên
        g.drawLine(x + 1, y, x + 1, y + len);
        //vẽ đuôi mũi tên
        for (int i = 0; i < dim.length; i++) {
            for (int j = 0; j < dim[0].length; j++) {
                if (dim[i][j] != 0) {
                    g.fillRect(x + j, y + len + i, 1, 1);
                }
            }
        }
    }
}

Tiếp theo đó là file skyfall.java: skyfall.java
C:\Users\thanhliem\Documents\NetBeansProjects\SkyFall\src\skyfall.java

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

public class skyfall extends Canvas {
//biến mt chứa các mũi tên sẽ bay lên từ dưới màn hình
    muiten[] mt = new muiten[10];
    Midlet m;
    //biến ngẩu nhiên rd
    Random rd = new Random();
    //các biến: rộng cao màn hình, tọa độ x, y của nhân vật, biến t số ngẩu nhiên, phím bấm k
    int w, h, x, y, t = 0, k;
    //hình ảnh nhân vật dùng để vẽ
    Image man;
    //các biến đúng sai: di chuyển, chẳn lẻ, kết thúc
    boolean move = false, chan = true, over = false;
    //biến mốc di chuyển lần cuối để tính khoảng thời gian di chuyển
    long lm;

    public skyfall(Midlet m) {
        try {
            this.m = m;
            setFullScreenMode(true);
            //tạo ra các phân tử mũi tên cho mảng mt
            for (int i = 0; i < mt.length; i++) {
                //gồm chiều rộng cao màn hình và một số nguyên ngẫu nhiên
                mt[i] = new muiten(getWidth(), getHeight(), t);
                t = rd.nextInt();
            }
            //ban đầu cho tọa độ nhân vật ở giữa màn hình
            y = getHeight() / 2;
            x = getWidth() / 2;
            //tạo ra hình ảnh nhân vật là ảnh 32x32
            man = Image.createImage("/man.png");
        } catch (Exception e) {
        }
    }

    public void paint(Graphics g) {
        //kiểm tra xem đã bị trúng tên chưa
        over = over();
        //xét xem lần di chuyển cuối cùng và có di chuyển tiếp không, hàm System.currentTimeMillis() dùng lấy thời gian hiện tại ở dạng mili giây.
        if (move && lm < System.currentTimeMillis() - 10) {
            if (k == -3 || k == KEY_NUM4) {
                x--;
            }
            if (k == -4 || k == KEY_NUM6) {
                x++;
            }
            //sau đó gán giá trị thời gian hiện tại cho biến lm
            lm = System.currentTimeMillis();
        }
        //đặt màu mới và tô màn hình
        g.setColor(0x90b5ff);
        g.fillRect(0, 0, getWidth(), getHeight());
        //hàm vẽ này vẽ ra một phần của hình ảnh, bao gồm: hình ảnh, tọa độ x trên ảnh, tọa độ y trên ảnh, chiều rộng cần vẽ, chiểu cao cần vẽ, quay góc, tọa độ vẽ x, tọa độ vẽ y, điểm neo.
        g.drawRegion(man, chan ? 0 : 16, 0, 16, 32, 0, x, y, Graphics.TOP | Graphics.LEFT);
        //sau đó cho biến chẳn lẻ thay đổi, nếu chẳn thì thành lẻ và ngược lại
        chan = !chan;
        //đặt màu mới, vẽ các phần tử muiten trong mảng mt
        g.setColor(0xff);
        for (int i = 0; i < mt.length; i++) {
            mt[i].draw(g);
        }
        //nếu kết thúc over=true thì cho dừng lại, không thì vẽ tiếp.
        if (over) {
        } else {
            repaint();
        }
    }
//hàm over kiểm tra xem có chạm nhân vật và muiten không
    boolean over() {
        for (int i = 0; i < mt.length; i++) {
            if (mt[i].check(x, y, 16, 32)) {
                return true;
            }
        }
        return false;
    }
//hàm xử lí phím, bấm phím nào thì cho k= mã phím đó
    public void keyPressed(int k) {
        move = true;
        this.k = k;
        if (k == -7) {
            //hàm notifyDestroyed của MIDlet dùng để đóng ứng dụng.
            m.notifyDestroyed();
        }
    }
//nếu buông nút bấm thì không cho di chuyển nữa.
    public void keyReleased(int k) {
        move = false;
    }
}

Và cuối cùng là cho hiển thị thông qua một Midlet.java như ta vẫn thường hay dùng: Midlet.java
C:\Users\thanhliem\Documents\NetBeansProjects\SkyFall\src\Midlet.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * @author thanhliem
 */
public class Midlet extends MIDlet {

    public void startApp() {
        Display.getDisplay(this).setCurrent(new skyfall(this));
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}

Các bạn thấy đó, rất là đơn giản phải không nào, để trò chơi thêm phần hấp dẫn bạn có thể thêm biến điểm tính theo lượt những mũi tên được tạo lại sau mỗi lần general mới, trong muiten.java hay là thêm thắt những thứ khác nữa như mạng, vật phẩm chẳng hạn. và đây là file source jar.

ngày sinh của mình

khi tôi còn học lớp 11 tôi đã từng nghĩ về một ngày sinh nhật của mình như vậy. nhưng thật chất đó là sinh nhật lạ nhất của tôi, không có một người bạn, không có một lời chúc mừng. tôi không nghĩ về nó như vậy vì đó không phải là sinh nhật đầu tiên tôi như vậy, suốt trong những năm trước chưa bao giờ tôi được tổ chức sinh nhật hoặc chính mình tổ chức cho mình. năm đó thay vì nghĩ về chuyện mình là một người thất bại thì tôi cũng nghĩ như vậy nhưng là đem so sánh với những thần tượng của tôi ngày đó. tôi còn nhớ năm đó là năm mà người ta nói đến những thiên tài âm nhạc, những người nổi tiếng khi chỉ là một thiếu niên và tôi cảm thấy mình thật là nhỏ bé bất tài biết nhường nào. tôi không biết và thật sự không cần biết đến những thứ khác nữa và sau này tôi cũng không bao giờ muốn nhắc lại khoảng thời gian học cấp 3 của mình nữa. nhưng bạn biết không sinh nhật năm đó tôi có một món quà nhỏ mà không biết là nó được đưa cho tôi khi nào, đó thật sự là một điều gì đó thật sự kì lạ, nó làm trái tim tôi nhưng nóng bừng trở lại, nhưng lí trí của tôi lại nói rằng đó là một điều thật sự ngu ngốc và nó chỉ là một cái bẫy làm tan nát con tìm mà thôi. tôi đã nghĩ về nó, đã vẽ lại hình ảnh của món quà trong nhật kí và nói những chuyện điên rồ, nhưng rồi tôi cũng nghe theo lí trí mình. tôi không biết đó là món quà của ai tặng nhưng tôi xa lánh những người mà tôi nghĩ là có khả năng nhất, tôi luôn làm tốt chuyện như vậy. chạy trốn khỏi những cái bẫy trái tim. tôi thật sự không còn nghĩ đến nó nữa, nhưng trong suốt cuộc đời này tôi luôn cảm thấy thiếu nợ những người quanh tôi, tôi không thể nào tìm kiếm tình yêu cho chính mình được nữa. tôi nghĩ là nếu như tôi đợi mãi như thế này thì sẽ không có tội lỗi gì với ai cả, và cho đến khi tôi biết tất cả họ đều có một cuộc sống hạnh phúc, hoặc có ai đó có thể ở bên cạnh tôi bất chấp không có một sự ràng buột gì hôn nhân. thật sự điều đó là không thể xảy ra, ai cũng muốn có một cái gì đó ràng buột, dù họ có tin tôi đến đâu đi nữa thì bảo hiểm vẩn không phải là thứ bỏ đi. vừa qua sinh nhật tôi một lần nữa và tôi không có một người bạn nào ở bên mình cả, tôi nhận được duy nhất một tin nhắn chúc mừng sinh nhật từ một người mà tôi không biết mặt, nhưng dù sao nó cũng làm tôi vui lắm, và sau đó là buồn. có lẽ số phận của tôi ngày hôm nay chính là kết quả của tôi, sau khi tổn thương những trái tim muốn quan tâm san sẻ với tôi. cho dù thế nào đi nữa tôi cũng không thấy hối tiếc về những gì mà mình đã làm, tôi biết là chắc chắn mình đã làm đúng, vì tôi không bao giờ muốn ràng buộc bởi một cái gì cả, kể cả hôn nhân.

Chủ Nhật, 10 tháng 2, 2013

trò chơi chó cắn

Cờ chó cắn chắc là cờ đơn giản nhất mà tôi từng chơi khi còn nhỏ và ở bất cứ đâu cũng có thể chơi được. nó còn đơn giản hơn là tic tac toe nữa đấy, và hôm nay tôi sẽ hướng dẫn viết một bàn cờ chó cắn đơn giản. đầu tiên là quân cờ chó cắn, gồm có các thông tin sau: tree.java
C:\Users\thanhliem\Documents\NetBeansProjects\Tree\src\tree.java

10 
11 public class tree {
12     //vị trí hiện tại của quân cờ và màu của quân cờ
13     int position,color;
14     //hàm khởi tạo nhận giá trị vị trí và màu quân cờ
15     public tree(int pos,int color){
16     this.position=pos;
17     this.color=color;}
18 }
19 
Còn đây là file banco.java dùng để tiến hành các lệnh vẽ theo game, điều kiện trò chơi, cách chơi…. banco.java
C:\Users\thanhliem\Documents\NetBeansProjects\Tree\src\banco.java

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

public class banco extends Canvas {
    Midlet m;
    //biến các điểm tọa độ của bàn cờ
    int[][] moc;
    //biến các điểm có thể di chuyển trên bàn cờ
    boolean[] free=new boolean[5];
    int w,h,dx,dy,k;
    boolean mot=true,finish=false,win=false;
    //biến các quân cờ, vị trí của ta là 0, 2 của máy là 1, 3
    tree[] quan;
    //biến rd này dùng để chọn ngẫu nhiên nhân vật tự động
    Random rd=new Random();
    public banco(Midlet m){
    setFullScreenMode(true);
    w=getWidth(); h=getHeight();
    //điểm vẽ bàn cờ
    dx=(w-128)/2;
    dy=(h-128)/2;
    //tạo các tọa độ vẽ bàn cờ, 128x128
    moc=new int[5][2];
    for(int i=0;i<2;i++){
    for(int j=0;j<2;j++){
    moc[i*2+j][0]=i*128;
    moc[i*2+j][1]=j*128;}}
    moc[4][0]=64;
    moc[4][1]=64;
    //tạo các quân cờ ban đầu, của ta là số chẵn 0, 2
    quan=new tree[4];
    for(int i=0;i<quan.length;i++){
        //các điểm đặt quân không còn trống, không thể di chuyển vào
        free[i]=false;
        //đặt màu cho các quân cờ, quân ta màu xanh lá 0, 2 chia hết cho 2
        quan[i]=new tree(i,i%2==0?0x00f000:0x0000f0);}
    //điểm còn lại chưa đặt quân cờ trống là ở giữa bàn cờ vị trí 4
    free[4]=true;
    this.m=m;}
    public void paint(Graphics g){
    g.setColor(0);
    g.fillRect(0,0,w,h);
    //vẽ bàn cờ
    vebanco(g);
    //vẽ quân cờ
    vequanco(g);
    g.setColor(0xf000f0);
    //nếu kết thúc thì vẽ kết quả
    if(finish)
    g.drawString(win?"you win!":"you lose!",w/2,h,Graphics.BOTTOM|Graphics.HCENTER);
    //vẽ hướng dẫn chơi game
    g.drawString("nhấn 5 để di chuyển.",w/2,0,Graphics.TOP|Graphics.HCENTER); 
    g.drawString("nhấn * để thay đổi đối tượng",w/2,0+g.getFont().getHeight(),Graphics.TOP|Graphics.HCENTER);
    repaint();
    }
    protected void keyPressed(int k){
        //nếu mot==true thì ta điều khiển quân 0, sai ta điều khiển quân 2
        //tìm ra vị trí trống có thể đi tiếp
        int focus=mot?0:2,move=free();
        //nếu chưa xong game thì cho di chuyển
        if(!finish)
            //nếu như bấm phím 5 thì cho di chuyển
    if(k==KEY_NUM5||k==-5)
        //nếu di chuyển được thì cho auto di chuyển
    if(move(focus,move)){
    auto();}
    //nếu không thì chuyển qua quân còn lại di chuyển, nếu được thì auto di chuyển
    else if(move(focus==0?2:0,move)){
    auto();
    }
    //ngược lại thì thua và kết thúc trò chơi
    else{finish=true; win=false;}
        //nhấn phím * để thay đổi đối tượng điều khiển
   if(k==KEY_STAR)mot=!mot;}
    
    //di chuyển nhân vật tự động
    void auto(){
        //tìm ra vị trí còn trống
    int move=free();
    //chọn ngẫu nhiên nhân vật tự động giữa 1 và 3
    int focus=rd.nextInt()%2==0?1:3;
    //cho di chuyển, nếu 1 không di chuyển thì chuyển qua 3 và ngược lại
    if(move(focus,move)){}else{
        //nếu cả 1 và 3 đều không còn di chuyển được nữa thì kết thúc trò chơi, người chơi thắng
        if(!move(focus==1?3:1,move)){
        finish=true;
        win=true;}}}
    
    //vẽ bàn cờ
   void vebanco(Graphics g){
   g.setColor(0xf0f000);
   //vẽ 2 gạch chéo bàn cờ
   g.drawLine(dx+moc[0][0],dy+moc[0][1],dx+moc[3][0],dy+moc[3][1]);
   g.drawLine(dx+moc[1][0], dy+moc[1][1],dx+moc[2][0], dy+moc[2][1]);
   //vẽ khung vuông bàn cờ
   g.drawRect(dx, dy, 128, 128);
   //vẽ nơi dành cho con chó, chữ "chó"
   g.drawString("chó",dx+64,dy,Graphics.BASELINE|Graphics.HCENTER);
    }
   
   //vẽ các quân cờ
   void vequanco(Graphics g){
       //xác định đối tượng đang chọn, 0 hay là 2
       int focus=mot?0:2;
   for(int i=0;i<4;i++){
       //tìm ra vị trí hiện tại của quân được chọn
       int pos=quan[i].position;
       //vẽ con trỏ chọn đối tượng
       if(i==focus){
       g.setColor(0xf00000);
       g.fillArc(dx+moc[pos][0]-9, dy+moc[pos][1]-9, 18, 18, 0, 360);}
       g.setColor(quan[i].color);
   g.fillArc(dx+moc[pos][0]-8, dy+moc[pos][1]-8, 16, 16, 0, 360);
   }
   }
   
   //kiểm tra xem có thể chuyển từ vị trí này tới vị trí trống được ko
   boolean cango(int pos,int npos){
   if(pos==1&&npos==2)return false;
   if(pos==2&&npos==1)return false;
   if(pos==0&&npos==3)return false;
   if(pos==3&&npos==0)return false;
   if(pos==0&&npos==2)return false;
   if(pos==2&&npos==0)return false;
   return true;}
   
   //tìm ra vị trí còn trống
   int free(){
       //kiểm tra trong mảng free xem có vị trí nào trống thì trả lại
       for(int i=0;i<5;i++){
   if(free[i])return i;}
   return 0;}
   
   //cho di chuyển và nếu di chuyển được thì trả lại giá trị đúng sai
   boolean move(int pos,int npos){
       if(cango(quan[pos].position,npos)){
           //đặt vị trí đang đứng thành trống
       free[quan[pos].position]=true;
       //cho chuyển sang vị trí mới
       quan[pos].position=npos;
       //đặt vị trí mới không còn trống nữa
       free[quan[pos].position]=false;
       return true;}
   return false;}
}

Và cũng cần có file Midlet.java để ứng dụng có thể hiện thị được. Cái này thì cũng đơn giản và quen quá rồi. Midlet.java
C:\Users\thanhliem\Documents\NetBeansProjects\Tree\src\Midlet.java

public class Midlet extends MIDlet {

    public void startApp() {
        Display.getDisplay(this).setCurrent(new banco(this));
    }
    
    public void pauseApp() {
    }
    
    public void destroyApp(boolean unconditional) {
    }
}

source file jar

Thứ Hai, 28 tháng 1, 2013

Biết làm gì nữa bây giờ

Sắp tới tết rồi, chỉ còn có hơn mười ngày nữa. Năm nay tôi không có thời gian nghỉ tết dài nữa, tôi không có nhiều thời gian dành cho mình nữa, hay là tôi thấy thời gian là không đủ cho mình, tôi không biết.... Dù sao đi nữa thì sống và làm được những thứ mà mình muốn là tốt lắm rồi, sau này có nghĩ lại cũng chằng có gì phải hối tiếc. Điều mà tôi cảm thấy buồn nhất trong cuộc đời mình là tôi quá ích kỷ với chính bản thân mình, mọi người cũng nghĩ tôi như vậy. điều đó làm tôi thấy mình luôn cô đơn và không bao giờ thoát ra khỏi đó được. Hãy nghĩ, có những thứ mình suy nghĩ như chẳng bao giờ lý giải được là vì lý do gì, giống như khi bạn nhìn vào bầu trời đêm và thấy đó là một thứ xa xôi vô tận vậy. Cảm nhận của con người cũng vậy thôi, đó là thứ không thể nào lý giải nỗi. tôi thật sự không muốn mình mãi đơn độc, nhưng vì một lý do gì đó tôi vẫn khép mình trong vòng tròn của mình. Sau này nếu có một thay đổi nào khác tôi cũng không nghĩ về thay đổi bản thân mình, và tôi thật sự không muốn đánh đổi cuộc sống hiện tại của mình chút nào, dù rằng tôi chỉ có một mình nhưng tôi không cảm thấy khó chịu nhiều. Tôi thường hay tin tưởng vào những lời nói bâng quơ của những người xung quanh tôi, rồi cho đến khi tôi biết rằng những lời đó có thể chỉ là một lời trêu chọc không hơn không kém. Tôi cũng sợ khi có ai đó nói điều gì với mình và tôi không bao giờ còn trông mong chúng sẽ trở thành hiện thực nưa. Có bao giờ bạn nghĩ đến cảm giác chờ đợi về một điều gì mà không bao giờ tới. Tôi sợ mình sẽ làm điều tương tự, tôi không nói chắc những gì mà tôi sẽ làm, nếu như không làm được hay là tôi quên đi thì thật là một điều thất vọng. Tôi chỉ nhớ tới mà có thể là ai cũng nhớ tới những thứ làm cho mình cảm thấy khó chịu, không hoặc ít khi nghĩ tới những việc mình làm cho người khác khó chịu. dù sao thì cuối cùng, sẽ có ngày ta cũng nhớ tới tất cả, mong là không quá muộn để làm điều đó cuối cùng.

Chủ Nhật, 27 tháng 1, 2013

nhận thông tin từ những người chơi khác

Bài này sẽ là kết thúc của hướng dẫn về sự kết hợp giữa php và j2me, những ứng dụng trực tuyến ngày càng cho thấy hiệu quả của nó trong thời đại công nghệ thông tin. Bạn không thể nào thiếu internet trong một ngày và chiếc di động là thứ hỗ trợ đắc lực nhất, ứng dụng web luôn không làm cho người sử dụng phải nhàm chán vì tính mới mỗi ngày của nó. Tôi cũng kì vọng vào sức mạnh của di động như về j2me thì không còn nhiều nữa, ngày nay android và ios ngày càng chiếm lĩnh trên thị trường di động nhất là android. Có thể một ngày nào đó những bài viết này chỉ là vô ích, nhưng ít nhất là tôi đã viết nó, bằng những kiến thức của mình và hy vọng điều gì đó. Do form get.html và server.php mà tôi đã viết có sự lựa chọn để chỉ hiện thị thông tin về những người chơi khác chứ không cho phép lấy về thông tin của nhân vật của ta. Do đó, ít nhất bạn phải có thêm một ai đó nữa cùng đăng nhập vào một id khác thì các bạn mới nhìn thấy kết quả của việc nhận dữ liệu. Ta thêm một biến dt (String) nữa và sẽ nhận dữ liệu vào đây, đồng thời vẽ ra màn hình. Class canvas sẽ thành thế này: mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
class canvas extends Canvas{
//biến nhận dữ liệu của các id khác
    String dt;
textfield tf;
Vector rb=new Vector();
Font f=Font.getFont(0,0,8);
int w,h,k=0,fh;
String command="";
//tạo ra một biến robot để làm nhân vật của ta, tại vị trí (0,0)
robot me=new robot(0,0);
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);
//vẽ thông tin lên màn hình,
if(dt!=null)
g.drawString(dt,0,h,Graphics.LEFT|Graphics.BOTTOM);
if(rb!=null)
for(int i=0;i<rb.size();i++)
((robot)rb.elementAt(i)).paint(g);
//vẽ nhân vật chúng ta lên canvas qua hàm paint của class robot
me.paint(g);
k=0;
repaint();
}
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;}
//ta thêm đoạn này để điều khiển trực tiếp biến me (robot) thông qua nhấn phím
if(k==-4){me.nx=me.x+5;}
if(k==-3){me.nx=me.x-5;}
if(k==-2){me.ny=me.y+5;}
if(k==-1){me.ny=me.y-5;}
}
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);}
}
Đồng thời mog.java cũng thay đổi như sau đây: mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
public class mog extends MIDlet implements Runnable{
    //tạo biến nhận giá trị của user và pass
    String user,pass;
    
    //id là giá trị của trả về ứng với mỗi user có một số id riêng biệt
    int id,mode=0;
    canvas cv=new canvas();
public void startApp(){
    //chúng ta cho hiển thị form login là một class mở rộng từ class Form
Display.getDisplay(this).setCurrent(new login(this));}
public void destroyApp(boolean t){}
public void pauseApp(){}
//hàm cv này dùng để nhận giá trị từ login.java sau khi đã thực hiện nhấn lệnh ok 
public void cv(String user,String pass){
    this.user=user;
    this.pass=pass;
    //hàm send trả về dữ liệu lấy từ server là id nhưng có kèm theo mã BOM của utf-8
   String st= send("http://holyeyed.99k.org/game/server.php","submit=2&user="+user+"&pass="+pass);
   //nếu như trả về dữ liệu khác null thì cho hiện canvas.
   id=Integer.parseInt(st.substring(3));
   if(id>0){
Display.getDisplay(this).setCurrent(cv);
//chuyển mode sang 3, và cho khởi động thread
mode=3;
   new Thread(this).start();}}
//khi thread khởi động nó sẽ không dừng lại
public void run(){
    while(true){
        try{
            //cho ngừng một khoảng thời gian (500millis) sau mỗi lần gửi thông tin lên server
            Thread.sleep(500);
switch(mode){
    case 1:
break;
    case 2:
break;
    case 3:
        //thông qua hàm send gửi các thông tin gồm: id, mess, x, y lên server.
        send("http://holyeyed.99k.org/game/server.php","submit=3&id="+id+"&mess=holyeyed&x="+cv.me.x+"&y="+cv.me.y);
//cùng lúc gửi thông tin lên server, ta cho nhận dữ liệu về luôn một thể, submit=4 cùng với id
        cv.dt=send("http://holyeyed.99k.org/game/server.php","submit=4&id="+id);
        break;}}catch(Exception e){}}}
//hàm send dùng thực hiện kết nối, nhận 2 tham số là địa chỉ web và các thông số gửi đi
String send(String add,String para){
try{
HttpConnection hc=(HttpConnection)Connector.open(add);
//set method giống với form trên server
hc.setRequestMethod(HttpConnection.POST);
//khi method là POST thì phải có content-type
hc.setRequestProperty("Content-Type", 
           "application/x-www-form-urlencoded");
//phần sau là đọc và trả về chuỗi
OutputStream os=hc.openOutputStream();
os.write(para.getBytes());
InputStream is=hc.openDataInputStream();
int c;
StringBuffer sb=new StringBuffer();
while((c=is.read())!=-1){sb.append((char)c);}
is.close();
os.close();
hc.close();
System.out.println(sb.toString());
return sb.toString();
}catch(Exception e){}
return null;}}
Kết quả ta được như sau:
Bây giờ ta sẽ chuyển dt (String) trong cv (canvas) thì mã lệnh dùng cho điều khiển các biến robot như ta đã làm lúc trước, dữ liệu nhận về như bạn thấy trên hình trên bao gồm: Mã BOM | id | user name | chuỗi | x | y # id | username | chuỗi | x |y #.... Class robot.java của ta sẽ thay đổi để nhận thêm nhiều giá trị hơn như sau: mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
class robot{
int x,y,nx,ny,id;
String say,user;
long lm=0;
//class robot bây giờ có 4 tham số khởi tạo: id, user, x ,y
public robot(int id,String user,int x,int y){
    this.id=id;
    this.user=user;
this.x=x;
this.y=y;
this.nx=x;
this.ny=y;
}
public void getcommand(String[] s){
say=s[2];
nx=Integer.parseInt(s[3]);
ny=Integer.parseInt(s[4]);
}
public void paint(Graphics g){
if(System.currentTimeMillis()-lm>200)
move();
g.setColor(0xf000f0);
g.fillRect(x,y,16,16);
//vẽ thêm username cho dễ phân biệt
g.drawString(user,x,y-16,Graphics.TOP|Graphics.LEFT);
}

void move(){
x+=x>nx?-1:(x==nx?0:1);
y+=y>ny?-1:(y==ny?0:1);}

}
Trong canvas.java cũng có những thay đổi, cụ thể là ta tách việc [phân tích dữ liệu gửi về vào hàm khac(), và cho vào trong vòng lặp paint(g), như vậy sẽ làm cho mọi thứ trở nên liên tục hơn. Ta cũng cần chú ý, bây giờ khởi tạo biến robot phải cần tới 4 tham số, cho nhân vật của ta có id=0, user=”me”, x=0, y=0: mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
class canvas extends Canvas{
//biến nhận dữ liệu của các id khác
    String dt;
textfield tf;
Vector rb=new Vector();
Font f=Font.getFont(0,0,8);
int w,h,k=0,fh;
String command="";
//tạo ra một biến robot để làm nhân vật của ta, tại vị trí (0,0)
robot me=new robot(0,"me",0,0);
public canvas(){
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
tf=new textfield("command",0,0,w);
}
public void paint(Graphics g){
    //sử dụng hàm khác để phân tích thông tin gửi về.
    khac();
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);
//vẽ thông tin lên màn hình,
if(dt!=null)
g.drawString(dt,0,h,Graphics.LEFT|Graphics.BOTTOM);
if(rb!=null)
for(int i=0;i<rb.size();i++)
((robot)rb.elementAt(i)).paint(g);
//vẽ nhân vật chúng ta lên canvas qua hàm paint của class robot
me.paint(g);
k=0;
repaint();
}
public void keyPressed(int k){
this.k=k;

//ta thêm đoạn này để điều khiển trực tiếp biến me (robot) thông qua nhấn phím
if(k==-4){me.nx=me.x+5;}
if(k==-3){me.nx=me.x-5;}
if(k==-2){me.ny=me.y+5;}
if(k==-1){me.ny=me.y-5;}
}
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;}
//hàm này dùng chuyển nhanh chuỗi thành số nguyên.
int toint(String s){return Integer.parseInt(s);}
//ta thêm một hàm khac với việc phân tích dữ liệu nhận về và vẽ những thông tin đó ra
void khac(){
    //nếu như thông tin nhận về khác null, và dài hơn 3
    if(dt!=null&&dt.length()>3){
 //bỏ mã BOM, lấy từ kí tự thứ 3
command=dt.substring(3);
//tách ra thành những nhân vật khác nhau, cách nhau bằng dấu #
String[] acommand=tach(command,"#");
//tạo một Vector mới để nhận giá trị
Vector trb=new Vector();
for(int i=0;i<acommand.length;i++){
    //tách thông tin cho mỗi nhân vật, cách nhau bằng dấu |
    String[] info=tach(acommand[i],"|");
    if(info!=null){
        //biến robot bây giờ có tới 4 tham số khởi tạo: id, user , x, y
    robot nrb=new robot(toint(info[0]),info[1],toint(info[3]),toint(info[4]));
    //kiểm tra nếu như mà có id nào trong Vector cũ thì dùng lại thông tin đó.
    for(int j=0;j<rb.size();j++){
        //ta so sánh id để chắc là duy nhất id đó đại diện cho người chơi đó
    if(Integer.parseInt(info[0])==(((robot)rb.elementAt(j)).id)){nrb=(robot)rb.elementAt(j);
    System.out.println("dectect");}}
    nrb.getcommand(info);
    //thêm vào Vector mới
trb.addElement((robot)nrb);}}
//cho Vector mới bằng Vector rb
rb=trb;}}
Như vậy là xong, rủ ai đó cùng test ứng dụng, bạn sẽ thấy mọi thứ hoạt động khá tốt. source project jar test

Thứ Bảy, 12 tháng 1, 2013

Gửi thông tin đến server theo từng đợt

Bài trước chúng ta đã có thể đăng nhập vào một hệ thống thành viên đơn giản, code trước tôi cũng đã post hết mã source của server. Chúng ta ở bài này sẽ sử dụng form send.html và gửi thông tin đến server thông qua form này. Nhưng đầu tiên chúng ta cần tạo ra một nhân vật của mình, tôi cũng sử dụng class robot để tạo nhân vật, nhưng chúng ta sẽ trực tiếp điều khiển nó thông qua phím chứ không phải là mã lệnh nữa. class canvas của chúng ta sẽ thành như thế này: mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
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="";
//tạo ra một biến robot để làm nhân vật của ta, tại vị trí (0,0)
robot me=new robot(0,0);
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);
//vẽ nhân vật chúng ta lên canvas qua hàm paint của class robot
me.paint(g);
k=0;
repaint();
}
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;}
//ta thêm đoạn này để điều khiển trực tiếp biến me (robot) thông qua nhấn phím
if(k==-4){me.nx=me.x+5;}
if(k==-3){me.nx=me.x-5;}
if(k==-2){me.ny=me.y+5;}
if(k==-1){me.ny=me.y-5;}
}
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;}
}
Xong bây giờ thì chỉnh sửa một chút ở file mog.java để gửi thông tin lên server thông qua hàm send mà ta đã biết. địa chỉ vẫn là địa chỉ cũ, còn thông số thì có thay khác theo form send.html chúng ta đã biết (nghiên cứu html nhé). mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
public class mog extends MIDlet implements Runnable{
    //tạo biến nhận giá trị của user và pass
    String user,pass;
    //id là giá trị của trả về ứng với mỗi user có một số id riêng biệt
    int id,mode=0;
    canvas cv=new canvas();
public void startApp(){
    //chúng ta cho hiển thị form login là một class mở rộng từ class Form
Display.getDisplay(this).setCurrent(new login(this));}
public void destroyApp(boolean t){}
public void pauseApp(){}
//hàm cv này dùng để nhận giá trị từ login.java sau khi đã thực hiện nhấn lệnh ok 
public void cv(String user,String pass){
    this.user=user;
    this.pass=pass;
    //hàm send trả về dữ liệu lấy từ server là id nhưng có kèm theo mã BOM của utf-8
   String st= send("http://holyeyed.99k.org/game/server.php","submit=2&user="+user+"&pass="+pass);
   //nếu như trả về dữ liệu khác null thì cho hiện canvas.
   id=Integer.parseInt(st.substring(3));
   if(id>0){
Display.getDisplay(this).setCurrent(cv);
//chuyển mode sang 3, và cho khởi động thread
mode=3;
   new Thread(this).start();}}
//khi thread khởi động nó sẽ không dừng lại
public void run(){
    while(true){
        try{
            //cho ngừng một khoảng thời gian (500millis) sau mỗi lần gửi thông tin lên server
            Thread.sleep(500);
switch(mode){
    case 1:
break;
    case 2:
break;
    case 3:
        //thông qua hàm send gửi các thông tin gồm: id, mess, x, y lên server.
        send("http://holyeyed.99k.org/game/server.php","submit=3&id="+id+"&mess=holyeyed&x="+cv.me.x+"&y="+cv.me.y);
break;}}catch(Exception e){}}}
//hàm send dùng thực hiện kết nối, nhận 2 tham số là địa chỉ web và các thông số gửi đi
String send(String add,String para){
try{
HttpConnection hc=(HttpConnection)Connector.open(add);
//set method giống với form trên server
hc.setRequestMethod(HttpConnection.POST);
//khi method là POST thì phải có content-type
hc.setRequestProperty("Content-Type", 
           "application/x-www-form-urlencoded");
//phần sau là đọc và trả về chuỗi
OutputStream os=hc.openOutputStream();
os.write(para.getBytes());
InputStream is=hc.openDataInputStream();
int c;
StringBuffer sb=new StringBuffer();
while((c=is.read())!=-1){sb.append((char)c);}
is.close();
os.close();
hc.close();
System.out.println(sb.toString());
return sb.toString();
}catch(Exception e){}
return null;}}
Vậy thôi, dù bạn có chạy chương trình thì chỉ có thể thấy là điều khiển được nhân vật hình vuông thôi, chứ không biết nó có gửi thông tin đúng lên server hay không. Nhưng đừng lo, theo lý thuyết là vậy và bạn sẽ biết được là nó có thật sự gửi được hay không thì chờ bài sau nhé. http://holyeyed.99k.org/function/up/mog-84566.zip
http://holyeyed.99k.org/function/up/mog-57614.jar

một form login đơn giản

có vẻ như bài này không có liên quan gì đến bài trước cả, và cũng đừng có nghĩ là tôi đang chuyển qua nói về lập trình web. Chỉ là có những thứ cần thiết cho quá trình lập trình mà chúng ta cần biết. Chúng ta sẽ có một trang như thế này, code của nó tôi sẽ post cuối bài: http://holyeyed.99k.org/game/reg.html http://holyeyed.99k.org/game/login.html http://holyeyed.99k.org/game/get.html http://holyeyed.99k.org/game/send.html trong một lúc chúng ta sẽ phải gửi dữ liệu từ ứng dụng lên server đồng thời cũng nhận từ server về thông tin về những người chơi khác. Chúng ta sẽ tạo một form đăng nhập đơn giản, còn phần đăng kí các bạn tự viết nhé. bây giờ chúng ta hãy chú ý tới midlet của chúng ta. trong một lúc chúng ta sẽ phải gửi dữ liệu từ ứng dụng lên server đồng thời cũng nhận từ server về thông tin về những người chơi khác. Chúng ta sẽ tạo một form đăng nhập đơn giản, còn phần đăng kí các bạn tự viết nhé. File mog.java của chúng ta sẽ như thế này: mog.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\mog.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;
import java.io.*;
import javax.microedition.io.*;

public class mog extends MIDlet implements Runnable{
    //tạo biến nhận giá trị của user và pass
    String user,pass;
    //id là giá trị của trả về ứng với mỗi user có một số id riêng biệt
    int id,mode=0;
public void startApp(){
    //chúng ta cho hiển thị form login là một class mở rộng từ class Form
Display.getDisplay(this).setCurrent(new login(this));}
public void destroyApp(boolean t){}
public void pauseApp(){}
//hàm cv này dùng để nhận giá trị từ login.java sau khi đã thực hiện nhấn lệnh ok 
public void cv(String user,String pass){
    this.user=user;
    this.pass=pass;
    //hàm send trả về dữ liệu lấy từ server là id nhưng có kèm theo mã BOM của utf-8
   String st= send("http://holyeyed.99k.org/game/server.php","submit=2&user="+user+"&pass="+pass);
   if(st!=null)
Display.getDisplay(this).setCurrent(new canvas());}
public void run(){
switch(mode){
    case 1:
break;
    case 2:
break;}}
//hàm send dùng thực hiện kết nối, nhận 2 tham số là địa chỉ web và các thông số gửi đi
String send(String add,String para){
try{
HttpConnection hc=(HttpConnection)Connector.open(add);
//set method giống với form trên server
hc.setRequestMethod(HttpConnection.POST);
//khi method là POST thì phải có content-type
hc.setRequestProperty("Content-Type", 
           "application/x-www-form-urlencoded");
//phần sau là đọc và trả về chuỗi
OutputStream os=hc.openOutputStream();
os.write(para.getBytes());
InputStream is=hc.openDataInputStream();
int c;
StringBuffer sb=new StringBuffer();
while((c=is.read())!=-1){sb.append((char)c);}
is.close();
os.close();
hc.close();
System.out.println(sb.toString());
return sb.toString();
}catch(Exception e){}
return null;}}
Đó là trong mog.java, còn một file nữa đó là login.java, đây là class mở rộng từ Form và được tạo dựng sẵn có các field và command theo ý mình, khi sử dụng chỉ cần cho khởi tạo và hiện thị, như các bạn thấy ở trong class mog ở trên: login.java
C:\Users\thanhliem\Documents\NetBeansProjects\mog\src\login.java
import javax.microedition.lcdui.*;
//class login là một Form được tạo dựng sẵn
public class login extends Form implements CommandListener {
    //nó chứa 2 textfield và một command
    TextField user=new TextField("use","",15,0);
    TextField pass=new TextField("pass","",15,TextField.PASSWORD);
    Command ok=new Command("ok",Command.OK,2);
    mog m;
public login(mog m){
    //do mở rộng từ Form nên khi khởi tạo phải cho nó tiêu đề qua hàm super
    super("đăng nhập");
this.m=m;
//thêm và các field và command
append(user);
append(pass);
addCommand(ok);
setCommandListener(this);}    
public void commandAction(Command c,Displayable d){
    //khi nhấn phím ok thì nó sẽ chạy hàm cv trong class mog.java và nhận các giá trị từ các field
if(c==ok){m.cv(user.getString(),pass.getString());}}
}

• Do càng về sau bài càng phức tạp nên tôi sẽ nói ít thôi, hãy đọc là chính và rồi sẽ hiểu. • Như trên là chúng ta đã tạo ra một ứng dụng login đơn giản với việc đăng kí trên server rồi. http://holyeyed.99k.org/function/up/mog-74430.zip
http://holyeyed.99k.org/function/up/mog-38525.jar
source html