Pham_loi
Chức vụ: 02:44:47, 02-06-2016 |
di chuyển bản đồ mà tưởng nhân vật đang di chuyển vậy
Thay vì di chuyển nhân vật, nhân vật ta luôn làm trung tâm và chúng ta chỉ cho bản đồ di chuyển. mọi thứ sẽ thay đổi nhiều so với lần trước, nhưng cũng không đến nổi khó hiểu cho lắm.
Mỗi lần bản đồ di chuyển một khoảng là một ô gạch, như vậy thì ta sẽ thấy nó rất giật, cho nên mỗi lần bấm phím di chuyển ta cho bản đồ di chuyển thành nhiều bước nhỏ, mỗi bước nhỏ là một ước số của kích thước ô gạch. Làm như vậy, nhân vật và bản đồ luôn khớp với nhau tại từng ô, chứ nhân vật không bao giờ nằm lưng chừng giữa 2 ô gạch, điều này sẽ giúp ta xác định điểm chạm ở bài sau.
File map.java trở 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.*;
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;
//chứa dữ liệu các tile trong map.
byte[ map;
//hình ảnh dùng làm tile
Image tiles;
//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;
//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);
}}
x=w/2-c*tw;
y=h/2-r*th;
System.out.println("finish");
}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);}
//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){
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();}
}
?>
Copy code
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;
//chứa dữ liệu các tile trong map.
byte[ map;
//hình ảnh dùng làm tile
Image tiles;
//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;
//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);
}}
x=w/2-c*tw;
y=h/2-r*th;
System.out.println("finish");
}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);}
//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){
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();}
}
?>
Copy code
Và vì vậy trong RPG.java ta cũng thay đổi cách sử dụng các hàm trong map.java, nhân vật chúng ta sẽ di chuyển, nhưng thật chất là thay đổi vị trí bản đồ trên màn hình.
C:\Users\thanhliem\Documents\NetBeansProjects\RPG\src\RPG.java
<?php
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
public class RPG extends Canvas{
//các biến này bao gồm kích thước màn hình w,h, khung hiện tại hiện thị f, phím nhấn k
int w,h,f=2,k;
//biến thời gian ghi lại mốc thời gian di chuyển cuối cùng
long lm=0;
//nhân vật được tạo qua lớp Sprite là có sẵn trong GameCanvas
Sprite nv;
//hình ảnh sử dụng
Image im;
//tạo biến load map m, với hình ảnh là tiles.png .
map m=new map("tiles.png");
public RPG(){
setFullScreenMode(true);
w=getWidth();
h=getHeight();
try{
//tạo hình ảnh trước
im=Image.createImage("/nv.png");
//tạo Sprite sau khi đã có hình ảnh, mỗi khung nhỏ là 16x16
nv=new Sprite(im,16,16);}catch(Exception e){}
//load map m0.mbd vào biến map m, nhân vật ở vị trí cột 3, dòng 4 trên map.
m.load("m0.mbd",3,4,w,h);}
public void paint(Graphics g){
//lệnh tô màn hình
g.setColor(0x6060a0);
g.fillRect(0,0,w,h);
//hàm xử lí di chuyển theo phím bấm
move();
//vẽ map ở vị trí (0,0).
m.paint(g,k);
//vẽ nhân vật ra màn hình thông qua hàm paint có sẵn của lớp Sprite
nv.paint(g);
//cho vẽ lại
repaint();}
public void keyPressed(int k){this.k=k;}
public void keyReleased(int k){this.k=0;}
//hàm di chuyển sẽ xữ lí phím bấm k để xác định khung của nhân vật
void move(){
//ở đây cho kiểm tra nếu lần di chuyển cuối cùng cách thời gian hiện tại 20 milli giây thì cho di chuyển tiếp.
if(lm<curr()-20&&k!=0){
//công thức xử lí phím và khung hiện tại để cho ra khung ảnh phù hợp, bạn tự thế vào và xem nó có đúng không nhé.
f=f%2==0?(-k-1)*2+1:(-k-1)*2;
//sau khi di chuyển thì cho mốc thời gian lần cuối thay đổi.
lm=curr();
}
//đặt giá trị khung ảnh và vị trí nhân vật trên màn hình.
nv.setFrame(f);
nv.setPosition(w/2,h/2);
}
//hàm trả về thời gian hiện tại, do sử dụng nhiều lần nên làm riêng một hàm cho khõi phải mất công viết lại.
long curr(){return System.currentTimeMillis();}
}
?>
Copy code
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
public class RPG extends Canvas{
//các biến này bao gồm kích thước màn hình w,h, khung hiện tại hiện thị f, phím nhấn k
int w,h,f=2,k;
//biến thời gian ghi lại mốc thời gian di chuyển cuối cùng
long lm=0;
//nhân vật được tạo qua lớp Sprite là có sẵn trong GameCanvas
Sprite nv;
//hình ảnh sử dụng
Image im;
//tạo biến load map m, với hình ảnh là tiles.png .
map m=new map("tiles.png");
public RPG(){
setFullScreenMode(true);
w=getWidth();
h=getHeight();
try{
//tạo hình ảnh trước
im=Image.createImage("/nv.png");
//tạo Sprite sau khi đã có hình ảnh, mỗi khung nhỏ là 16x16
nv=new Sprite(im,16,16);}catch(Exception e){}
//load map m0.mbd vào biến map m, nhân vật ở vị trí cột 3, dòng 4 trên map.
m.load("m0.mbd",3,4,w,h);}
public void paint(Graphics g){
//lệnh tô màn hình
g.setColor(0x6060a0);
g.fillRect(0,0,w,h);
//hàm xử lí di chuyển theo phím bấm
move();
//vẽ map ở vị trí (0,0).
m.paint(g,k);
//vẽ nhân vật ra màn hình thông qua hàm paint có sẵn của lớp Sprite
nv.paint(g);
//cho vẽ lại
repaint();}
public void keyPressed(int k){this.k=k;}
public void keyReleased(int k){this.k=0;}
//hàm di chuyển sẽ xữ lí phím bấm k để xác định khung của nhân vật
void move(){
//ở đây cho kiểm tra nếu lần di chuyển cuối cùng cách thời gian hiện tại 20 milli giây thì cho di chuyển tiếp.
if(lm<curr()-20&&k!=0){
//công thức xử lí phím và khung hiện tại để cho ra khung ảnh phù hợp, bạn tự thế vào và xem nó có đúng không nhé.
f=f%2==0?(-k-1)*2+1:(-k-1)*2;
//sau khi di chuyển thì cho mốc thời gian lần cuối thay đổi.
lm=curr();
}
//đặt giá trị khung ảnh và vị trí nhân vật trên màn hình.
nv.setFrame(f);
nv.setPosition(w/2,h/2);
}
//hàm trả về thời gian hiện tại, do sử dụng nhiều lần nên làm riêng một hàm cho khõi phải mất công viết lại.
long curr(){return System.currentTimeMillis();}
}
?>
Copy code
Kết quả là đây :
Source: RPG-07641.zip
Jar: RPG-17847.jar
: 0 ♥
Trực Tuyến:
Khách: 1