80s toys - Atari. I still have
logo

Chatbox|Admin nhận làm wap/web, giá cả thương lượng... Thông tin admin tại mỗi bài viết.
Home · Bang hội ·
* Đăng Nhập hoặc Đăng Kí
để sử dụng hết chức năng của diễn đàn.
Hi, Khách!
HomeBang hội » Thủ thuật » Nokia s40 » Lập trình game j2me by holyeyed
Xuống dưới » Lập trình game j2me by holyeyed
avatar by Pham_loi Pham_loi
Chức vụ:
18:37:02, 31-05-2016

Đ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.
img

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:37:09, 31-05-2016

đ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
<?php
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 Stringtach(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);}
Stringrt=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;}
}
?>

Copy code

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
<?php
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(Strings){
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);}
}

?>

Copy code

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:
img
Source: mog-25113.zip
Jar: mog-97485.jar

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:37:40, 31-05-2016

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
<?php
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();
Stringacommand=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 
Stringtach(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);}
Stringrt=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(Strings){
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);}
}
?>

Copy code

• 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
<?php
public void keyPressed(int k){
this.k=k;
if(
k==-5){
command=tf.getString();
Stringacommand=tach(command,".");
Vector trb=new Vector();
for(
int i=0;i<acommand.length;i++){
    
Stringinfo=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;}}
}
?>

Copy code

• 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ế.
Source: mog-72176.zip

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:41:14, 31-05-2016

Giới hạn di chuyển
bài này không nói gì nhiều, chỉ có những chú thích trong file source. Trong ví dụ, đã xuất hiện được 3 nhân vật thông qua mảng other, và thêm điều hiện để kiểm tra xem có chạm tường hay không, nếu chạm thì không đi được nữa thế thôi. File map.java
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\map.java

<?php
import java
.io.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;

public class 
map {
    
//các thông số gồm có số cột, số hàng trong map, kích thước mỗi tile tw, th.
    //tọa độ map (x,y), phím bấm k, số lần di chuyển nhỏ.
    
int mw,mh,tw,th,x,y,k,step=0,w,h;
    
//chứa dữ liệu các tile trong map.
    
bytemap;
    
//hình ảnh dùng làm tile
    
Image tiles,other;
    
//dùng class TiledLayer có sẵn trong GameCanvas để tạo map.
    
TiledLayer tl;
    
//mốc thời gian di chuyển lần cuối
    
long lm=0;
    
//thêm một biến other ot dùng làm nhân vật phụ.
        
otherot;
    
//hàm khởi tạo sẽ tải hình ảnh làm tile vào class map.
    
public map(String im){
    try{
    
this.tiles=Image.createImage("/"+im);
    }catch(
Exception e){}}
    
//hàm load dùng tải file nguồn và phân tích các thông số trong đó vào map.
    //bây giờ ta có thông số xác định tọa độ ban đầu nhân vật, tại cột c, dòng r và so sánh với độ dài rộng màn hình.
public void load(String fn,int c,int r,int w,int h){
    
//file nguồn là dữ liệu với cấu trúc: [số cột-[số hàng-[tile width-[tile height-[dữ liệu map (số cột * số hàng)
try{
InputStream is=getClass().getResourceAsStream("/"+fn);
mw=is.read();
mh=is.read();
tw=is.read();
th=is.read();
map=new byte[is.available();
is.read(map);
//tạo TiledLayer tl từ những gì đã nhận được.
tl=new TiledLayer(mw,mh,tiles,tw,th);
//lát gạch vào TiledLayer tl.
for(int i=0;i<mh;i++){
for(
int j=0;j<mw;j++){
tl.setCell(jimap[i*mw+j);
}}
this.w=w;
this.h=h;
x=w/2-c*tw;
y=h/2-r*th;
//tạo file ảnh cho nhân vật phụ và khởi tạo ot ở vị trí cột 4 và hàng 6 trên map.
other=Image.createImage("/other.png");
ot=new other[3;
for(
int i=0;i<ot.length;i++)
{
ot[i=new other(other,(i+1)*12*16,(i+1)*13*16);
Thread.sleep(50);}
}catch(
Exception e){}} 
//hàm paint dùng vẽ tl lên Graphics g, và nhận giá trị phím bấm vào hàm move.
void paint(Graphics g,int k){
    
move(k);
tl.paint(g);
//vẽ nhân vật phụ lên map.
for(int i=0;i<ot.length;i++)
ot[i.paint(g,this);}
//hàm move nhận giá trị phím bấm k và kiểm tra điều kiện để thay đổi tọa độ của map.
void move(int k){
    
//do mỗi lần di chuyển ta cho chuyển 16 pixel, nên ta cần chia ra 4 lần di chuyễn nhỏ để hình ảnh mượt hơn.
    //nếu thấy không cần bước di chuyển nhỏ nào nữa thì cho di gán di chuyển tiếp
if(step==0){
    
//gán tọa độ cũ vào các biến gx gy.
    
int gx=x,gy=y;
    
//tính tọa độ mới.
    
switch(k){
        case -
1:
            
gy+=16;
    break;
    case -
2:
            
gy-=16;
    break;
    case -
3:
            
gx+=16;
    break;
    case -
4:
            
gx-=16;
    break;}
    
//kiểm tra xem toa6 độ mới có chạm tường không.
if(check(w/2-gx,h/2-gy)){
this.k=k;
step=4;}
}else{
    
//nếu còn lượt di chuyển nhỏ step!=0, thì xét đến thời gian di chuyển lần cuối.
    
if(lm<=curr()-30){
    
step--;
    switch(
this.k){
        case -
1:
            
y+=th/4;
    break;
        case -
2:
            
y-=th/4;
    break;
        case -
3:
            
x+=tw/4;
    break;
        case -
4:
            
x-=tw/4;
    break;}
    
lm=curr();}
}
//gán vị trí cho tl.
tl.setPosition(xy);
}
  
long curr(){return System.currentTimeMillis();}
  
//hàm kiểm tra xem có chạm tường không, tường là gạch số 3.
  
boolean check(int a,int b){
 return 
tl.getCell(a/16b/16)<3;}
}

?>

Copy code

File other.java :
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\other.java
<?php
import javax
.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.util.*;

public class 
other {
    
//bao gồm tọa độ của other (x,y), khung hình hiện tại f, phía di chuyển k, step
  
int x,y,f=0,k=1;
  
//dùng Sprite để tạo hình ảnh nhân vật phụ
  
Sprite other;
  
//mốc thời gian lần di chuyển cuối và lần đổi hướng cuối.
  
long lm,lc;
  
//hình ảnh dùng tạo Sprite
  
Image im;
  
//biến ngẫu nhiên dùng để tạo hướng ngẫu nhiên.
  
Random rd=new Random();
  
//hàm khởi tạo nhân các tham số hình ảnh và tọa độ ban đầu của other.
  
public other(Image im,int x,int y){
  
this.x=x;
  
this.y=y;
  
this.im=im;
  
other=new Sprite(im,16,16);
  
other.setFrame(f);
  }
  
//hàm paint dùng vẽ nhân vật other lên Graphics g.
  
void paint(Graphics g,map m){
  
move(m);
  
other.paint(g);
  }
  
//hàm move nhân giá trị là biến map m, sử dụng để điều hướng nhân vật phụ.
  
void move(map m){
      
//so sánh mốc chuyển hướng cuối cùng để cho cứ 1.5s thì chuyển hướng.
  
if(lc<m.curr()-1500){
      
//với phép chia dư này, k chỉ nhận giá trị từ 1-4.
  
k=Math.abs(rd.nextInt()%4)+1;
  
lc=m.curr();}
  
//so sánh với lần di chuyển cuối cùng, nếu cách 0.5s thì cho di chuyển.
  
if(lm<m.curr()-200){
      
f=f%2==0?(k-1)*2+1:(k-1)*2;
      
other.setFrame(f);
      
//gán tọa độ cũ vào các biến gx, gy.
      
int gx=x,gy=y;
      
//tính tọa độ mới.
      
switch(k){
          case 
1:
              
y-=4;
      break;
          case 
2:
              
y+=4;
      break;
          case 
3:
              
x-=4;
      break;
          case 
4:
              
x+=4;
      break;}
      
lm=m.curr();
      
//tọa độ của nhân vật phụ được hình thành từ tọa độ của bản đồ và tọa độ của nhân vật phụ.
  
     //kiểm tra xem tọa độ mới có chạm tường không, nếu có thì cho quay lại tọa độ cũ.
 
if(!m.check(xy))
  {
x=gxy=gy;}
  }
  
other.setPosition(x+m.x,y+m.y);
  }
}
?>

Copy code

Có vài sai sót nhỏ đã được chỉnh lại cho đúng, tại lúc khởi tạo nhân vật phụ trong map.java không phải thêm w/2- và h/2- mà xác định trực tiếp qua cột và hàng mà nhân vật phụ xuất hiện.

Source: RPG-44080.zip
Jar: RPG-72812.jar

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:45:23, 31-05-2016

Thoại dẫn truyện
Diều quan trọng nhất trong game RPG chính là cốt truyện, như vậy thì không thể nào mà không có lời thoại nào, trong bài này chúng ta sẽ tạo ra một loạt những nhân vật dẫn thoại và cho họ tham gia vào trò chơi.
Chúng ta tạo ra một class mới gọi là trail.java như sau :
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\trail.java


<?php
import javax
.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class 
trail {
    
//vị trí của những nhân vật dẫn chuyện.
int[[ pos={{2,3},{12,23},{19,6}};
//mỗi nhân vật dẫn chuyện nói một câu.
Stringsay={"hello world, this is role playing game","i am holyeyed, nice to meet you","in the end of world, we will found out how love is"};
//biến xác định xem đã có đang nói hay không.
boolean load=false;
//câu nói của nhân vật đang nói.
String lstr;
//vị trí của nhân vật đang nói.
int lpos=-1;
//hình ảnh vẽ nhân vật dẫn chuyện.
Image im;
//biến thời gian mốc load lời thoại.
long lload=0;
public 
trail(){
try{
im=Image.createImage("/trail.png");}catch(Exception e){}}
//hàm paint này sẽ vẽ lên map nhưng nhân vật dẫn chuyện.
public void paint(Graphics g,map m,int k){
    
//mỗi lần lập lại cho nhân vật đang nói là -1, tức là không ai đang nói.
    
lpos=-1;
    
//dùng for để vẽ ra từng nhân vật trong mảng, đồng thời so sánh xem nhân vật nào đang ở gần, để gán là nhân vật hiện hành.
for(int i=0;i<pos.length;i++){
g.drawRegion(im,i*16,0,16,16,0,pos[i[0*16+m.x,pos[i[1*16+m.y,0);
//tính vị khoảng cách giữ nhân vật chính và nhân vật dẫn.
int nx=Math.abs(pos[i[0*16+m.x-m.w/2),ny=Math.abs(pos[i[1*16+m.y-m.h/2);
//nếu cách nhau 1 ô, <=16 thì gán vào.
if(nx<=16&&ny<=16)lpos=i;
}
//nếu phím bấm là -5 thì xét tiếp.
if(k==-5){
    
//nếu như cách mốc thời gian là 150millis thì cho thực hiện kiểm tra.
    
if(lload<System.currentTimeMillis()-150){
        
//nếu gần nhân vật dẫn lpos!=-1 và load =false thì cho load.
if(!load&&lpos!=-1){
load=true;
lstr=say[lpos;}
//ngược thì thì bỏ load.
else{
load=false;}
//gán mốc thời gian load và unload.
    
lload=System.currentTimeMillis();}}
//nếu như đã load thì vẽ câu nói ra màn hình.
if(load){
g.setColor(0x0000ff);
g.fillRect(0,0,m.w,m.h/5);
g.setColor(0xf0f0f0);
g.drawString(lstr,0,0,Graphics.TOP|Graphics.LEFT);}
}
}
?>

Copy code

Và chúng ta sẽ sử dụng chúng trong file map.java như thế này, ở đây tôi dùng ảnh này để vẽ nhân vật dẫn chuyện :
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\map.java

<?php
import java
.io.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;

public class 
map {
    
//các thông số gồm có số cột, số hàng trong map, kích thước mỗi tile tw, th.
    //tọa độ map (x,y), phím bấm k, số lần di chuyển nhỏ.
    
int mw,mh,tw,th,x,y,k,step=0,w,h;
    
//chứa dữ liệu các tile trong map.
    
bytemap;
    
//hình ảnh dùng làm tile
    
Image tiles,other;
    
//dùng class TiledLayer có sẵn trong GameCanvas để tạo map.
    
TiledLayer tl;
    
//mốc thời gian di chuyển lần cuối
    
long lm=0;
    
//thêm một biến other ot dùng làm nhân vật phụ.
        
otherot;
        
//thêm biến vẽ nhân vật dẫn thoại.
        
trail tr=new trail();
    
//hàm khởi tạo sẽ tải hình ảnh làm tile vào class map.
    
public map(String im){
    try{
    
this.tiles=Image.createImage("/"+im);
    }catch(
Exception e){}}
    
//hàm load dùng tải file nguồn và phân tích các thông số trong đó vào map.
    //bây giờ ta có thông số xác định tọa độ ban đầu nhân vật, tại cột c, dòng r và so sánh với độ dài rộng màn hình.
public void load(String fn,int c,int r,int w,int h){
    
//file nguồn là dữ liệu với cấu trúc: [số cột-[số hàng-[tile width-[tile height-[dữ liệu map (số cột * số hàng)
try{
InputStream is=getClass().getResourceAsStream("/"+fn);
mw=is.read();
mh=is.read();
tw=is.read();
th=is.read();
map=new byte[is.available();
is.read(map);
//tạo TiledLayer tl từ những gì đã nhận được.
tl=new TiledLayer(mw,mh,tiles,tw,th);
//lát gạch vào TiledLayer tl.
for(int i=0;i<mh;i++){
for(
int j=0;j<mw;j++){
tl.setCell(jimap[i*mw+j);
}}
this.w=w;
this.h=h;
x=w/2-c*tw;
y=h/2-r*th;
//tạo file ảnh cho nhân vật phụ và khởi tạo ot ở vị trí cột 4 và hàng 6 trên map.
other=Image.createImage("/other.png");
ot=new other[3;
for(
int i=0;i<ot.length;i++)
{
ot[i=new other(other,(i+1)*12*16,(i+1)*13*16);
Thread.sleep(50);}
}catch(
Exception e){}}
//hàm paint dùng vẽ tl lên Graphics g, và nhận giá trị phím bấm vào hàm move.
void paint(Graphics g,int k){
    
move(k);
    
g.setColor(0);
    
g.drawRect(x,y,tl.getWidth(),tl.getHeight());
tl.paint(g);
//vẽ nhân vật phụ lên map.
for(int i=0;i<ot.length;i++)
ot[i.paint(g,this);
//vẽ nhân vật dẫn chuyện ra màn hình.
tr.paint(g,this,k);
}
//hàm move nhận giá trị phím bấm k và kiểm tra điều kiện để thay đổi tọa độ của map.
void move(int k){
    
//do mỗi lần di chuyển ta cho chuyển 16 pixel, nên ta cần chia ra 4 lần di chuyễn nhỏ để hình ảnh mượt hơn.
    //nếu thấy không cần bước di chuyển nhỏ nào nữa thì cho di gán di chuyển tiếp
if(step==0){
    
//gán tọa độ cũ vào các biến gx gy.
    
int gx=x,gy=y;
    
//tính tọa độ mới.
    
switch(k){
        case -
1:
            
gy+=16;
    break;
    case -
2:
            
gy-=16;
    break;
    case -
3:
            
gx+=16;
    break;
    case -
4:
            
gx-=16;
    break;}
    
//kiểm tra xem toa6 độ mới có chạm tường không.
if(check(w/2-gx,h/2-gy)){
this.k=k;
step=4;}
}else{
    
//nếu còn lượt di chuyển nhỏ step!=0, thì xét đến thời gian di chuyển lần cuối.
    
if(lm<=curr()-30){
    
step--;
    switch(
this.k){
        case -
1:
            
y+=th/4;
    break;
        case -
2:
            
y-=th/4;
    break;
        case -
3:
            
x+=tw/4;
    break;
        case -
4:
            
x-=tw/4;
    break;}
    
lm=curr();}
}
//gán vị trí cho tl.
tl.setPosition(xy);
}
  
long curr(){return System.currentTimeMillis();}
  
//hàm kiểm tra xem có chạm tường không, tường là gạch số 3.
  
boolean check(int a,int b){
 return 
tl.getCell(a/16b/16)<3;}
}
?>

Copy code

Kết quả :
img

Source: RPG-83907.zip
Jar: RPG-66920.jar
Vậy thôi, dù sao thì cũng đơn giản, câu thoại là câu đơn và chưa có hàm vẽ để tự động ngắt dòng. Chúng ta tiếp tục thêm vào trail.java như sau :
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\trail.java

<?php
import javax
.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class 
trail {
    
//vị trí của những nhân vật dẫn chuyện.
int[[ pos={{2,3},{12,23},{19,6}};
//mỗi nhân vật dẫn chuyện nói một câu.
Stringsay={"hello world, this is role playing game","i am holyeyed, nice to meet you, if you want to follow me, please visit me in http://holyeyed.99k.org, or http://j2medraw.blogspot.com. nice to see you there....","in the end of world, we will found out how love is"};
//biến xác định xem đã có đang nói hay không.
boolean load=false;
//câu nói của nhân vật đang nói.
String lstr;
//vị trí của nhân vật đang nói.
int lpos=-1;
//hình ảnh vẽ nhân vật dẫn chuyện.
Image im;
//biến thời gian mốc load lời thoại.
long lload=0;
public 
trail(){
try{
im=Image.createImage("/trail.png");}catch(Exception e){}}
//hàm paint này sẽ vẽ lên map nhưng nhân vật dẫn chuyện.
public void paint(Graphics g,map m,int k){
    
//mỗi lần lập lại cho nhân vật đang nói là -1, tức là không ai đang nói.
    
lpos=-1;
    
//dùng for để vẽ ra từng nhân vật trong mảng, đồng thời so sánh xem nhân vật nào đang ở gần, để gán là nhân vật hiện hành.
for(int i=0;i<pos.length;i++){
g.drawRegion(im,i*16,0,16,16,0,pos[i[0*16+m.x,pos[i[1*16+m.y,0);
//tính vị khoảng cách giữ nhân vật chính và nhân vật dẫn.
int nx=Math.abs(pos[i[0*16+m.x-m.w/2),ny=Math.abs(pos[i[1*16+m.y-m.h/2);
//nếu cách nhau 1 ô, <=16 thì gán vào.
if(nx<=16&&ny<=16)lpos=i;
}
//nếu phím bấm là -5 thì xét tiếp.
if(k==-5){
    
//nếu như cách mốc thời gian là 150millis thì cho thực hiện kiểm tra.
    
if(lload<System.currentTimeMillis()-150){
        
//nếu gần nhân vật dẫn lpos!=-1 và load =false thì cho load.
if(!load&&lpos!=-1){
load=true;
lstr=say[lpos;}
//ngược thì thì bỏ load.
else{
load=false;}
//gán mốc thời gian load và unload.
    
lload=System.currentTimeMillis();}}
//nếu như đã load thì vẽ câu nói ra màn hình.
if(load){
g.setColor(0x0000ff);
g.fillRect(0,0,m.w,m.h/5);
g.setColor(0xf0f0f0);
wrap(g,lstr,0,0,m.w,m.h);}
}
//hàm dùng để chia str thành nhiều đoạn nhỏ cho vừa màn hình.
public void wrap(Graphics g,String lstr,int x,int y,int w,int h){
Font f=g.getFont();
int fh=f.getHeight();
if(!
lstr.endsWith(" "))lstr+=" ";
int sa=0,ns=lstr.indexOf(" ",sa),line=0;
while(
ns!=-1){
    
String dstr=lstr.substring(sa,ns+1);
int d=f.stringWidth(dstr);
if(
d>=w-f.stringWidth("ww") ||ns==lstr.length()-1){
g.drawString(dstr,x,y+fh*line,Graphics.TOP|Graphics.LEFT);
line++;
sa=ns+1;}
ns=lstr.indexOf(" ",ns+1);}}
}
?>

Copy code

Kết quả như sau :
img


Source: RPG-79971.zip
Jar: RPG-47182.jar

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:46:03, 31-05-2016

A new World

Dù cho bản đồ của mình có rộng lớn đến đâu chăng nữa thì cũng không thể nào chỉ đi trong đó cho đến hết trò chơi. Bây giờ chúng ta cần làm cho nó rộng lớn hơn nhiều nữa, và chúng ta sẽ tạo một class mới gọi là hole.java, nó như sau:
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\hole.java

<?php
import javax
.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class 
hole {
    
//những điểm thông giữa 2 map.
int[[ hole={{0,3,5},{1,5,4}};
//những vị trí bản đồ mà từ đó sẽ thoát ra.
intout={1,0};
//kiểm tra xem có phải đang trong điểm chuyển không.
boolean inhole=true;
//bản đồ hiện tại.
int m;
//hàm kiểm tra xem có nằm trong điểm chuyển hay không.
public boolean check(int nm,int x,int y,map m){
    
//lần lượt check qua từng điểm chuyển.
for(int i=0;i<hole.length;i++){
   
int nx=x/16;
   
int ny=y/16;
if(
nm==hole[i[0&&nx==hole[i[1&&ny==hole[i[2){
    
this.m=out[i;
return 
true;}
}
return 
false;}
//hàm chuyển map.
public void change(int nm,int x,int y,map m){
if(
check(nm,x,y,m)){
if(!
inhole){
    
inhole=true;
m.m=hole[this.m[0;
m.load("m"+hole[this.m[0+".mbd",hole[this.m[1,hole[this.m[2,m.w,m.h);}}
else{
inhole=false;}
}
}
?>

Copy code

Nhưng khi thay đổi map thì nhân vật phụ cũng thay đổi luôn đó, cho nguyên nhân đó nên chúng ta cũng thay đổi cách tạo nhân vật phụ, nhân vật dẫn chuyện cũng nên thay đổi, nhưng ở đây tôi không nói nhiều về chuyện đó. Chúng ta chỉ thay đổi một chút để game không bị lỗi, file map.java thành thế này.
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\map.java
<?php
import java
.io.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;
import java.util.*;
public class 
map {
    
//các thông số gồm có số cột, số hàng trong map, kích thước mỗi tile tw, th.
    //tọa độ map (x,y), phím bấm k, số lần di chuyển nhỏ.
    
int mw,mh,tw,th,x,y,k,step=0,w,h,m=0;
    
//chứa dữ liệu các tile trong map.
    
bytemap;
    
//hình ảnh dùng làm tile
    
Image tiles,other;
    
//dùng class TiledLayer có sẵn trong GameCanvas để tạo map.
    
TiledLayer tl;
    
//mốc thời gian di chuyển lần cuối
    
long lm=0;
    
//thêm một biến other ot dùng làm nhân vật phụ.
        
otherot;
        
//thêm biến vẽ nhân vật dẫn thoại.
        
trail tr=new trail();
        
//tạo biến check để chuyển map
        
hole hl=new hole();
    
//hàm khởi tạo sẽ tải hình ảnh làm tile vào class map.
    
public map(String im){
    try{
    
this.tiles=Image.createImage("/"+im);
    }catch(
Exception e){}}
    
//hàm load dùng tải file nguồn và phân tích các thông số trong đó vào map.
    //bây giờ ta có thông số xác định tọa độ ban đầu nhân vật, tại cột c, dòng r và so sánh với độ dài rộng màn hình.
public void load(String fn,int c,int r,int w,int h){
    
//file nguồn là dữ liệu với cấu trúc: [số cột-[số hàng-[tile width-[tile height-[dữ liệu map (số cột * số hàng)
try{
InputStream is=getClass().getResourceAsStream("/"+fn);
mw=is.read();
mh=is.read();
tw=is.read();
th=is.read();
map=new byte[is.available();
is.read(map);
is.close();
//tạo TiledLayer tl từ những gì đã nhận được.
tl=new TiledLayer(mw,mh,tiles,tw,th);
//lát gạch vào TiledLayer tl.
for(int i=0;i<mh;i++){
for(
int j=0;j<mw;j++){
tl.setCell(jimap[i*mw+j);
}}
this.w=w;
this.h=h;
x=w/2-c*tw;
y=h/2-r*th;
//tạo file ảnh cho nhân vật phụ và khởi tạo ot ở vị trí cột 4 và hàng 6 trên map.
other=Image.createImage("/other.png");
ot=new other[3;
for(
int i=0;i<ot.length;i++)
{
    
Random d=new Random();
    
int cot=Math.abs(d.nextInt())%mw,rot=Math.abs(d.nextInt())%mh;
    
ot[i=new other(other,cot*16,rot*16);
Thread.sleep(50);}
}catch(
Exception e){}} 
//hàm paint dùng vẽ tl lên Graphics g, và nhận giá trị phím bấm vào hàm move.
void paint(Graphics g,int k){
    
move(k);
    
g.setColor(0);
    
g.drawRect(x,y,tl.getWidth(),tl.getHeight());
tl.paint(g);
//vẽ nhân vật phụ lên map.
for(int i=0;i<ot.length;i++)
ot[i.paint(g,this);
//vẽ nhân vật dẫn chuyện ra màn hình.
tr.paint(g,this,k);
//dùng hàm để chuyển map khi phát hiện đúng điều kiện.
hl.change(this.mw/2-xh/2-ythis);
}
//hàm move nhận giá trị phím bấm k và kiểm tra điều kiện để thay đổi tọa độ của map.
void move(int k){
    
//do mỗi lần di chuyển ta cho chuyển 16 pixel, nên ta cần chia ra 4 lần di chuyễn nhỏ để hình ảnh mượt hơn.
    //nếu thấy không cần bước di chuyển nhỏ nào nữa thì cho di gán di chuyển tiếp
if(step==0){
    
//gán tọa độ cũ vào các biến gx gy.
    
int gx=x,gy=y;
    
//tính tọa độ mới.
    
switch(k){
        case -
1:
            
gy+=16;
    break;
    case -
2:
            
gy-=16;
    break;
    case -
3:
            
gx+=16;
    break;
    case -
4:
            
gx-=16;
    break;}
    
//kiểm tra xem toa6 độ mới có chạm tường không.
if(check(w/2-gx,h/2-gy)){
this.k=k;
step=4;}
}else{
    
//nếu còn lượt di chuyển nhỏ step!=0, thì xét đến thời gian di chuyển lần cuối.
    
if(lm<=curr()-30){
    
step--;
    switch(
this.k){
        case -
1:
            
y+=th/4;
    break;
        case -
2:
            
y-=th/4;
    break;
        case -
3:
            
x+=tw/4;
    break;
        case -
4:
            
x-=tw/4;
    break;}
    
lm=curr();}
}
//gán vị trí cho tl.
tl.setPosition(xy);
}
  
long curr(){return System.currentTimeMillis();}
  
//hàm kiểm tra xem có chạm tường không, tường là gạch số 3.
  
boolean check(int a,int b){
      if(
a<0||b<0||a>mw*16-16||b>mh*16-16){return false;}
 return 
tl.getCell(a/16b/16)<3;}
}
?>

Copy code

Kết quả chúng ta như sau:
img
source: RPG-10766.zip
jar: RPG-51942.jar

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:47:13, 31-05-2016

Đến nơi tận cùng


Một khi bạn nhận ra rằng những người xung quanh bạn thật quá vô tình thì bạn cũng không còn trông mong gì họ nữa. Cách đây khoảng 2 năm gì đó tôi cũng quan tâm nhiều người lắm nhưng bây giờ thì điều đó không còn tồn tại nữa. Dù tôi biết là cho đến ngày tận cùng thì tôi vẫn nhớ tới họ. Liệu rồi sau này tôi còn quan tâm đến ai nữa không.
Tôi từng nhớ một câu nói rất hay, không biết có đúng hay không: tốt với tất cả thì cũng như không tốt với ai cả. Chuyện này cũng không phải là tại mình, những suy nghĩ của họ thì không phải mình có thể điều khiển được. Tôi không phải muốn mọi người phải trả lại những tình cảm mà tôi bỏ ra, nhưng vô tình quá đã khiến trái tim người ta tan nát.
Một hôm chợt thức dậy và phát hiện ra rằng, hình như mình đã già rồi mà không có một người bạn được gọi là tri kỉ. Có phải là mình xấu xa lắm không, nhưng nghĩ kĩ lại thì không phải như vậy. Có những người thật sự xấu hơn mình nhiều nhưng họ vẫn có cặp có đôi, và một câu hỏi tại sao lại xuất hiện. Tôi từng nhìn thấy cuộc sống thật nhàm chán khi mỗi ngày đều tìm kiếm hạnh phúc bằng việc giúp đỡ người khác, tại sao không có ai muốn nhìn thấy tôi hạnh phúc, muốn làm tôi hạnh phúc, tất nhiên không phải là người trong gia đình tôi.

img

Thật chất có nhiều câu chuyện làm tôi cảm thấy điều đó cũng bình thường như là final fantasy 7 vậy, dù Tifa có tốt với cloud đến đâu thì sao, cuối cùng cũng không là gì cả, chỉ chuốc thêm đau khổ về mình. Tôi cũng vậy, đã biết là vô vọng thì tại sao lại như vậy, dù cuộc sống này có đến đâu thì tôi cũng có những người thân bên cạnh. Những người cuối cùng vẫn không bỏ rơi tôi...

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:47:55, 31-05-2016

thế giới bất tử: phần tiếp theo

cũng đã lâu lắm rồi từ khi bắt đầu viết serial game thế giới bất tử, nhưng có lẽ là không sao quên được cái cảm giác được hiện thực hóa câu chuyện của mình thành game java. dù là đơn giản và không mấy ly kì như những game hiện thời, nhưng đó là những gì mà tôi có thể làm, tôi không thực sự nghĩ là nó sẽ mang lại lợi ích gì ngoài niềm vui cho chính bản thân mình. câu chuyện về một chàng trai bị lạc vào một thế giới khác lạ và nơi đó đã thật sự là nơi mà cậu không bao giờ quên được...

img

Jar: parapol-44699.jar

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:48:17, 31-05-2016

game tính nhẩm

game này chỉ là một phần nhỏ, trong đây người chơi sẽ xác định xem biều thức tính toán là đúng hay sai, game dùng hình ảnh để hiện thị những con số.
img
và game bao gồm: một class dùng vẽ chuỗi các phép tính:

C:\Users\thanhliem\Documents\NetBeansProjects\mathgame\src\font.java
<?php
import javax
.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class 
font {
    
//chuỗi kí tự dùng trong hình
    
String c "=+-0123456789";
//vị trí bắt đầu của từng kí tự trong hình
    
intpos = {0153447678097114133150169186205222};
    
Image im;

    public 
font() {
        try {
            
im Image.createImage("/math.png");
        } catch (
Exception e) {
        }
    }
//hàm vẽ chuỗi
    
void drawString(Graphics gint xint yString ch) {
        for (
int i 0ch.length(); i++) {
            
int cp c.indexOf(ch.charAt(i));
            
drawChar(gxycp);
            
+= pos[cp 1 - pos[cp;
        }
    }
//hàm vẽ kí tự
    
void drawChar(Graphics gint xint yint c) {
        
g.drawRegion(impos[c0pos[1 - pos[cim.getHeight(), 0xy0);
    }
}
?>

Copy code

-->
và một class xử lí game, sự kiện người dùng:
C:\Users\thanhliem\Documents\NetBeansProjects\mathgame\src\mathgame.java
<?php
import javax
.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;

public class 
mathgame extends Canvas implements Runnable {

    
int whcount 10score 0;
    
Random rd = new Random();
    
int k;
    
font f = new font();
    
int mode 0;
    
int abco;
    
String disdauok;
    
boolean t;

    public 
mathgame() {
        
setFullScreenMode(true);
        
getWidth();
        
getHeight();
        
general();
    }

    public 
void paint(Graphics g) {
        
//check xem chọn đúng hay sai
        
if (mode == 0) {
            if (
== -6) {
                if (!
t) {
                    
ok "ok";
                    
score++;
                } else {
                    
ok "bad";
                }
                
mode 1;
            }
            if (
== -7) {
                if (
t) {
                    
ok "ok";
                    
score++;
                } else {
                    
ok "bad";
                }
                
mode 1;
            }
            
0;
        }
        
g.setColor(0);
        
g.fillRect(00wh);
        
g.setColor(0xf0f0);
        switch (
mode) {
            case 
0: {//xem xét phép toán
                
f.drawString(g52dis);
                
g.drawString("còn lại " count " câu"040Graphics.LEFT Graphics.BOTTOM);
                
g.drawString("sai"0hGraphics.LEFT Graphics.BOTTOM);
                
g.drawString("đúng"whGraphics.RIGHT Graphics.BOTTOM);
            }
            break;
            case 
1: {//hiện thị kết quả chọn
                
g.drawString(ok02Graphics.LEFT Graphics.BOTTOM);
                if (
count 0) {
                    
general();
                    
mode 0;
                } else {
                    
mode 2;
                }
                
slept(2500);
            }
            break;
            case 
2: {
                
g.drawString("Điểm " score02Graphics.LEFT Graphics.BOTTOM);
                
slept(1000);
            }
            break;
        }
    }
    
    public 
void run(){
    while(
true){
    
repaint();}}
//hàm tổng hợp bài toán tiếp theo.
    
void general() {
        
count--;
        
hai();
        
hai() % 2;
        
hai();
        if (
== 0) {
            
dau "+";
            
b;
        } else {
            
dau "-";
            
b;
        }
        
hai() % == true false;
        if (
t) {
            
dis dau "=" c;
        } else {
            
dis dau "=" + (hai() % 1);
        }
    }
//hàm dừng lại một khoảng thời gian
    
void slept(long t) {
        try {
            
Thread.sleep(t);
        } catch (
Exception e) {
        }
    }
//hàm lấy về số nguyên 2 chữ số

    
int hai() {
        
slept(20);
        return 
Math.abs(rd.nextInt()) % 99;
    }
//hàm nhận biết phím bấm

    
public void keyPressed(int k) {
        
this.k;
    }
}
?>

Copy code

--> cuối cùng là một Midlet để hiện thị:
C:\Users\thanhliem\Documents\NetBeansProjects\mathgame\src\Midlet.java
<?php
import javax
.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class 
Midlet extends MIDlet {
    public 
void startApp() {
        
mathgame mg=new mathgame();
        new 
Thread(mg).start();
    
Display.getDisplay(this).setCurrent(mg);}

    public 
void pauseApp() {
    }

    public 
void destroyApp(boolean unconditional) {
    }
}
?>

Copy code

--> hình ảnh dùng trong game làm font số là:
img
source by holyeyed: mathgame-48942.zip

Like: 0
avatar by Pham_loi Pham_loi
Chức vụ:
18:49:59, 31-05-2016

game thế giới bất tử: Mirror World
lần trước kể đến lúc Orli đã đánh bại được nhện tinh Kidomaru, đến hôm nay thì Orli lại có cơ hội trở lại với thế giới thứ 2 nơi mà anh rất muốn trở lại lúc này. Orli được mọi người trong làng cho biết là Kame là người có thể giúp anh trở về thế giới thứ 2 và gặp lại những người bạn, Orli đi tìm Kame, nhưng không may Kame lại đang bị bắt cóc bởi một toán quái vật. Vậy là Orli đi tìm giết quái vật cứu lại Kame, để đền ơn Kame cho Orli thử cỗ máy thời gian của ông và anh đã trở lại được nơi mình mong muốn, ở đây Orli biết được thế giới đang bị đảo lộn bởi Snake vậy là anh lại vào trong một hành trình mới....

img
img

Jar: parapol-20003.jar

Like: 0
Lên trên  Tổng số: 42
« 1 2 3 4 5 »







Trực Tuyến: Khách: 1
Diễn đàn teen Việt Nam
CopyRight 2014