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 |
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.
String[] say={"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);}
}
}
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 |
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.
byte[]
map;
//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ụ.
other[] ot;
//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(j, i, map[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(x, y);
}
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/16, b/16)<3;}
}
Kết quả :
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 |
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.
String[] say={"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);}}
}
Kết quả như sau :
1 nhận xét:
anh oi cai soure bi gi roi. Ko down dc
Đăng nhận xét