Chủ Nhật, 18 tháng 11, 2012

chuẩn bị các nguyên liệu cho game

trong game có các thành phần như là nhân vật, chướng ngại vật, kẻ thù, và những vật dụng khác cũng như ngoại cảnh. tùy theo ý thích của mỗi người mà chúng ta có thể chuẩn bị đủ mọi thứ. cũng như việc lắp ráp một chiếc xe cần phải có những thứ tạo nên chiếc xe đó như khung xe, bánh xe, dây xích, bulong, ốc vít....
bây giờ tôi sẽ làm một game đơn giản thôi và sẽ sử dụng hoàn toàn bằng lệnh, tức là không dung thêm bất cứ file nào ngoài code java. game mà tôi sắp viết nên đây là một trò bắn tăng cổ điển, giống như trò chơi trên các máy bấm hộp nhỏ nhỏ xài pin mà ngoài chợ thường bán.
. Ta cần các hình sau:
- xe tăng của ta gọi là T
- xe tăng chướng vật gọi là X
- đạn bắn ra gọi là F
mỗi một hình như vậy chúng ta sẽ tạo trên một class riêng và chúng phải có những thuộc tính sau:
- tọa độ x
- tọa độ y
1. đầu tiên tôi viết class vẽ T, như sau:
import javax.microedition.lcdui.*;

public class T {

//T này ngoài tọa độ x,y còn có thêm biến frame, và biến màu sắc
int x,y,f,color;

//biến lm ghi lại lần di chuyển cuối cùng của T
long lm=0;

//biến shape là các frame của T, gồm có 4 frame
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};

//hàm khởi tạo nhận giá trị tọa độ ban đầu và màu sắc của T
public T(int x,int y,int color){
this.x=x;
this.y=y;
this.color=color;}

//hàm paint dùng để nhận biến Graphics và vẽ trên đó, cùng với biến k là phím nhấn trên bàn phím
public void paint(Graphics g,int k){

//check xem lần cuối cùng di chuyển và khoảng thời gian hiện tại có cách nhau 60 millis giây
if(lm<System.currentTimeMillis()-60){
switch(k){
case -1: f=0; y-=16; break;
case -2: f=1; y+=16; break;
case -3: f=2; x-=16; break;
case -4: f=3; x+=16; break;}
lm=System.currentTimeMillis();}

//đặt màu cho xe tăng này
g.setColor(color);

//vẽ xe tăng theo frame, nếu là 0 thì không vẽ ra được gì, nếu 1 thì vẽ 1 ô vuông, tạo nên hình chiếc xe
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
}
}

kết quả của ta sẽ như thế này. ta không cần phải thiết kế thêm class X nữa mà chúng ta dùng class T để tạo luôn xe tăng chướng ngại, chỉ cần đổi màu một chút là được, và kết quả ta được như sau:


Tất nhiên trong file game.java chúng ta cũng phải thay đổi một chút để đưa hai đối tượng T này vào:

import javax.microedition.lcdui.*;

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, k);
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0 )mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;

//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}
}

. Bây giờ thì viết thêm class F nữa, đây sẽ là đạn bắn ra từ các xe.
//F.java
import javax.microedition.lcdui.*;
public class F {
int x,y,color,f=-1,speed;
long lm=0;
public F(int x,int y,int color,int speed){
this.x=x;
this.y=y;
this.color=color;
this.speed=speed;}
public void fire(Graphics g,int x,int y){
if(f==-1){this.x=x; this.y=y;}
g.setColor(color);
if(System.currentTimeMillis()%500<250)
g.fillRect(this.x,this.y,16,16);

if(f!=-1&amp;&amp;lm<System.currentTimeMillis()-speed){
switch(f){
case 0: this.y-=16; break;
case 1: this.y+=16; break;
case 2: this.x-=16; break;
case 3: this.x+=16; break;}
lm=System.currentTimeMillis();}
if(f!=-1&amp;&amp;(Math.abs(this.x-x)&gt;240||Math.abs(this.y-y)&gt;320)){f=-1;}
}
}

. cuối cùng thì mỗi xe đều có khả năng nhả đạn, nên trong T class ta chỉnh sửa lại một chút để tạo khả năng bắn đạn cho các xe này.
//T.java
import javax.microedition.lcdui.*;

public class T {
F d;
int x,y,f,color;
long lm=0;
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};
public T(int x,int y,int color){
this.x=x;
this.y=y;
this.color=color;
d=new F(x+16,y+16,0xf00000,500);}
boolean check(){return (lm<System.currentTimeMillis()-60);}

public void paint(Graphics g,int k){
switch(k){
case -1: f=0; if(check()){y-=16; lm=System.currentTimeMillis();} break;
case -2: f=1; if(check()){y+=16; lm=System.currentTimeMillis();} break;
case -3: f=2; if(check()){x-=16; lm=System.currentTimeMillis();} break;
case -4: f=3; if(check()){x+=16; lm=System.currentTimeMillis();}break;
case -5: d.f=this.f; break;}
g.setColor(color);
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
d.fire(g,x+16,y+16);
}
}

kết quả ta được như thế này.

Không có nhận xét nào: