//In this version Tank will be a Class. Then I doubt why I need to do that...
//instant--->use capital formal and --> public static final
//This is a import version, I will make the change for OOP.
//********I have already make the Tank, Bullet to be an object ....
//I think about that: how can I do not need to give the Bullet with the reference of TankClient, and it can repaint() when the Bullet changed.
//I used refresh in the TankClient~~~~~
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class TankClient extends Frame {
Tank N1=new Tank(100,100,this);
Image offScreen;
// Tank N2=new Tank(200,200,1,this);
public void paint(Graphics g) {
N1.draw(g);
N1.drawBullets(g);
// N2.draw(g);
// N2.drawBullets(g);
}
public void update(Graphics g) {
if(offScreen==null) {
offScreen =this.createImage(700, 550);
}
Graphics osg= offScreen.getGraphics();
osg.setColor(Color.yellow);
osg.fillRect(0, 0, 700, 550);
paint(osg);
g.drawImage(offScreen, 0, 0, null);
}
public static void main(String[] args) {
TankClient tc=new TankClient();
tc.launchTank();
while(true) {
try {
Thread.sleep(5);
tc.repaint();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void launchTank() {
setLocation(500,150);
setSize(700,550);
setBackground(Color.yellow);
this.setResizable(false);
setTitle("TankWar");
setVisible(true);
this.addKeyListener(new KeyMonitor1());
this.addKeyListener(new KeyMonitor2());
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
class KeyMonitor1 extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
N1.keyReleased(e);
}
public void keyPressed(KeyEvent e) {
N1.keyAciton(e);
// N2.keyAciton(e);
// repaint();
}
}
class KeyMonitor2 extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==e.VK_SPACE) {
N1.shoot(e);
// N2.shoot(e);
}
}
}
}
这个版本将程序使用面向对象的思维进行了修改...下面是Tank和Bullet的类.
//在上一个版本中...我们设置了键盘按下时设置为true来标记被按下了...可是这样并不能按照我们需求的方式运行...
//设置这里的解决方案是设置键盘释放时设置键盘的标记为false.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.ArrayList;
public class Tank {
int i;
int j;
int k=i+30;
int m=j+5;
// int tankDir;
TankClient tc;
private static final int X_SD=15;
private static final int Y_SD=15;
enum tankDir {L,LU,U,RU,R,RD,D,LD,STOP};
tankDir tdr=tankDir.STOP;
private static boolean VL,VR,VU,VD=false;
ArrayList<Bullet> BTA=new ArrayList<Bullet>();
public Tank(int i,int j,TankClient tc) {
this.i=i;
this.j=j;
this.tc=tc;
}
public void draw(Graphics g) {
g.setColor(Color.green);
g.fillRoundRect(i, j, 30, 20, 10, 10);
g.fillOval(k, m, 10, 10);
}
public void keyAciton(KeyEvent e) {
if(e.getKeyCode()==e.VK_LEFT||e.getKeyCode()==e.VK_RIGHT||e.getKeyCode()==e.VK_UP||e.getKeyCode()==e.VK_DOWN) {
if(e.getKeyCode()==e.VK_LEFT) {
VL=true;
}
if(e.getKeyCode()==e.VK_RIGHT) {
VR=true;
}
if(e.getKeyCode()==e.VK_UP) {
VU=true;
}
if(e.getKeyCode()==e.VK_DOWN) {
VD=true;
}
move(direction());
// tc.repaint();
}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode()==e.VK_LEFT||e.getKeyCode()==e.VK_RIGHT||e.getKeyCode()==e.VK_UP||e.getKeyCode()==e.VK_DOWN) {
if(e.getKeyCode()==e.VK_LEFT) {
VL=false;
}
if(e.getKeyCode()==e.VK_RIGHT) {
VR=false;
}
if(e.getKeyCode()==e.VK_UP) {
VU=false;
}
if(e.getKeyCode()==e.VK_DOWN) {
VD=false;
}
// tc.repaint();
}
}
public void move(tankDir tdr) {
if(tdr==tankDir.L) {
i=i-X_SD;
k=i-5;
m=j+5;
}
else if(tdr==tankDir.R) {
i=i+X_SD;
k=i+25;
m=j+5;
}
else if(tdr==tankDir.U) {
j=j-Y_SD;
k=i+10;
m=j-8;
}
else if(tdr==tankDir.D) {
j=j+Y_SD;
k=i+10;
m=j+18;
}else if(tdr==tankDir.RD) {
i=i+X_SD;
j=j+Y_SD;
k=i+25;
m=j+13;
}
else if(tdr==tankDir.RU) {
i=i+X_SD;
j=j-Y_SD;
k=i+25;
m=j-3;
}
else if(tdr==tankDir.LD) {
i=i-X_SD;
j=j+Y_SD;
k=i-5;
m=j+15;
}
else if(tdr==tankDir.LU) {
i=i-X_SD;
j=j-Y_SD;
k=i-5;
m=j-5;
}
}
public tankDir direction() {
if(VL&&!VR&&!VU&&!VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.L;
}
else if(VL&&!VR&&VU&&!VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.LU;
}
else if(!VL&&!VR&&VU&&!VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.U;
}
else if(!VL&&VR&&VU&&!VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.RU;
}
else if(!VL&&VR&&!VU&&!VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.R;
}
else if(!VL&&VR&&!VU&&VD) {
// VL=VR=VU=VD=false;
//System.out.println("TEST FOR RD");
return tdr=tankDir.RD;
}
else if(!VL&&!VR&&!VU&&VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.D;
}
else if(VL&&!VR&&!VU&&VD) {
// VL=VR=VU=VD=false;
return tdr=tankDir.LD;
}
else return tdr=tankDir.STOP;
}
public void shoot(KeyEvent e) {
if(tdr==tankDir.L) {
Bullet tep=new Bullet(k,m+2,1,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.R) {
Bullet tep=new Bullet(k+10,m+2,2,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.U) {
Bullet tep=new Bullet(k+2,m,3,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.D) {
Bullet tep=new Bullet(k+2,m+10,4,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.LU) {
Bullet tep=new Bullet(k,m+2,5,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.RU) {
Bullet tep=new Bullet(k,m+2,6,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.LD) {
Bullet tep=new Bullet(k,m+2,7,this,tc);
BTA.add(tep);
tep.start();
}
if(tdr==tankDir.RD) {
Bullet tep=new Bullet(k,m+2,8,this,tc);
BTA.add(tep);
tep.start();
}
}
public void drawBullets(Graphics g) {
g.setColor(Color.red);
int k=BTA.size();
Bullet tp;
while(k!=0) {
tp=BTA.get(k-1);
g.fillOval(tp.x,tp.y, 5, 5);
k--;
}
}
public static void main(String[] args) {
}
}
import java.awt.*;
public class Bullet extends Thread{
int dir;
int x;
int y;
Tank tk;
TankClient tc;
Bullet(int x,int y,int dir,Tank tk,TankClient tc) {
this.x=x;
this.y=y;
this.dir=dir;
this.tk=tk;
this.tc=tc;
}
public void run() {
while((x!=0)&&(x!=700)&&(y!=0)&&(y!=550)) {
if(dir==1) {
x=x-5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//tc.repaint();
}
if(dir==2) {
x=x+5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
if(dir==3) {
y=y-5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
if(dir==4) {
y=y+5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
if(dir==5) {
y=y-5;
x=x-5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
if(dir==6) {
y=y-5;
x=x+5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
if(dir==7) {
y=y+5;
x=x-5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
if(dir==8) {
y=y+5;
x=x+5;
try {
Bullet.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// tc.repaint();
}
} tk.BTA.remove(this);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
1.需要说明的:在TankClient中加入了使整个画面自动刷新...这样就不用每次做修改的时候刷新界面...这样在子弹中就不用传入TankClient的引用...这样会比较乱...
2.在进行方向确定的过程中,使用了键盘按下设置成true,键盘释放设置成false. 同时我们在键盘按下的事件中才调用MOVE方法和direction方法....这个做使得我们释放键盘的时候方向的值会保留释放前的结果...这样就不会导致我们将键盘释放后...子弹类中要用到的方向参数出错.