java制作简单的坦克大战
详情请参照注释,这里就不多废话了,实现一下儿时的经典而已。
Blood.java
packagecom.hkm.TankWar;
importjava.awt.*;
/**
*血块类,我方坦克吃了可回血;
*@authorHekangmin
*
*/
publicclassBlood{
privateintx,y,w,h;//血块的位置和宽度高度;
privateTankWarClienttc;
privateintstep=0;//纪录血块移动的步数;
privatebooleanlive=true;
publicbooleanisLive(){
returnlive;
}
publicvoidsetLive(booleanlive){
this.live=live;
}
/**
*纪录血块的位置;
*/
privateint[][]pos={{400,300},{400,320},{420,320},{440,300},{440,330},{480,400},{520,400},{540,400}};
publicBlood()
{
x=pos[0][0];
y=pos[0][1];
w=h=18;
}
publicvoiddraw(Graphicsg)
{
if(!live)return;
Colorc=g.getColor();
g.setColor(Color.CYAN);
g.fillOval(x,y,w,h);
g.setColor(c);
move();
}
/**
*移动血块
*/
publicvoidmove()
{
step++;
if(step>=pos.length)step=0;
else{
x=pos[step][0];
y=pos[step][1];
}
}
publicRectanglegetRect()
{
returnnewRectangle(x,y,w,h);
}
}
Explode.java
packagecom.hkm.TankWar;
importjava.awt.*;
/**
*爆炸类
*@authorHekangmin
*
*/
publicclassExplode{
privateintx,y;//爆炸发生的位置
privatebooleanLive=true;
intdia[]={4,8,12,16,32,40,20,14,4};//用园模拟,代表圆的直径;
intstep=0;//区别移到第几个直径
privateTankWarClienttc;//持有引用
publicExplode(intx,inty,TankWarClienttc)
{
this.x=x;
this.y=y;
this.tc=tc;
}
publicvoiddraw(Graphicsg)
{
if(!Live)
{
tc.explodes.remove(this);
return;
}
if(step==dia.length)//如果到了最后一个直径爆炸死亡;
{
Live=false;
step=0;
return;
}
Colorc=g.getColor();
g.setColor(Color.YELLOW);
g.fillOval(x,y,dia[step],dia[step]);
g.setColor(c);
step++;
}
}
Missile.java
packagecom.hkm.TankWar;
importjava.awt.*;
importjava.awt.Event.*;
importjava.awt.event.KeyEvent;
importjava.util.List;
/**
*子弹类
*@authorHekangmin
*
*/
publicclassMissile{
privateintx,y;//子弹的位置
privateTank.Directiondir;//坦克方向
privatestaticfinalintXSPEED=10;//坦克x方向的移动速度,
privatestaticfinalintYSPEED=10;//坦克y方向的移动速度,
publicstaticfinalintWIDTH=10;
publicstaticfinalintHEIGHT=10;
privatebooleanLive=true;//判断子弹是否活着
privatebooleangood;//区分敌军子弹和我军子弹
privateTankWarClienttc;
publicMissile(intx,inty,Tank.Directiondir){
this.x=x;
this.y=y;
this.dir=dir;
}
publicMissile(intx,inty,booleangood,Tank.Directiondir,TankWarClienttc)
{
this(x,y,dir);
this.good=good;//将坦克好坏的属性与子弹还坏属性设为相同;
this.tc=tc;
}
/**
*画出子弹
*@paramg为画笔
*/
publicvoiddraw(Graphicsg)
{
if(!Live)
{
tc.missiles.remove(this);
return;
}
Colorc=g.getColor();
if(good)
{
g.setColor(Color.BLUE);
}
elseg.setColor(Color.ORANGE);
g.fillOval(x,y,WIDTH,HEIGHT);
g.setColor(c);
move();
}
/**
*根据坦克的方向让子弹移动
*/
privatevoidmove(){
switch(dir)
{
caseL:
x-=XSPEED;
break;
caseLU:
x-=XSPEED;
y-=YSPEED;
break;
caseU:
y-=YSPEED;
break;
caseRU:
x+=XSPEED;
y-=YSPEED;
break;
caseR:
x+=XSPEED;
break;
caseRD:
x+=XSPEED;
y+=YSPEED;
break;
caseD:
y+=YSPEED;
break;
caseLD:
x-=XSPEED;
y+=YSPEED;
break;
}
if(x<0||y<0||x>TankWarClient.GAME_WIDTH||y>TankWarClient.GAME_HEIGHT)//子弹越界则让其死亡;
{
Live=false;
}
}
publicbooleanisLive()
{
returnLive;
}
publicRectanglegetRect()//获取子弹的矩形区域;
{
returnnewRectangle(this.x,this.y,this.WIDTH,this.HEIGHT);
}
/**
*判断子弹与坦克碰撞;
*@paramt为坦克
*@return返回true则表示发生碰撞,否则没有碰撞;
*/
publicbooleanhitTank(Tankt)
{
if(this.Live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood())
{
if(t.isGood())
{
t.setLife(t.getLife()-10);
if(t.getLife()<=0)t.setLive(false);
}else{
t.setLive(false);
}
this.Live=false;///将子弹设为死亡;
Explodee=newExplode(x,y,tc);//发生爆炸;
tc.explodes.add(e);
returntrue;
}
returnfalse;
}
/**
*判断子弹与敌军坦克相撞;
*@paramtanks敌军坦克
*@returntrue表示相撞,false没有相撞;
*/
publicbooleanhitTanks(List<Tank>tanks)
{
for(inti=0;i<tanks.size();i++)
{
if(hitTank(tc.tanks.get(i)))
{
returntrue;
}
}
returnfalse;
}
/**
*判断子弹是否撞墙
*@paramw墙
*@returntrue,撞上,false,未撞上;
*/
publicbooleanhitsWall(Wallw)
{
if(this.Live&&this.getRect().intersects(w.getRect()))
{
Live=false;
returntrue;
}
returnfalse;
}
}
Tank.java
packagecom.hkm.TankWar;
importjava.awt.*;
importjava.awt.event.KeyEvent;
importjava.util.*;
/**
*坦克类
*@authorHekangmin
*
*/
publicclassTank{
publicstaticfinalintXSPEED=5;//坦克x方向速度
publicstaticfinalintYSPEED=5;
publicstaticfinalintWIDTH=30;
publicstaticfinalintHEIGHT=30;
privateBloodBarbb=newBloodBar();//血条
privateintlife=100;
publicintgetLife(){
returnlife;
}
publicvoidsetLife(intlife){
this.life=life;
}
privatestaticRandomr=newRandom();
privatestaticintstep=r.nextInt(12)+3;//定义一个数表示敌军坦克随机东的步数;
privatebooleanbL=false,bU=false,bR=false,bD=false;
enumDirection{L,LU,U,RU,R,RD,D,LD,STOP};//利用枚举类型定义坦克方向;
privateintx,y;
privateintoldX,oldY;//纪录上一步坦克的位置;
privatebooleanlive=true;//判断是否活着
publicbooleanisLive(){
returnlive;
}
publicvoidsetLive(booleanlive){
this.live=live;
}
privatebooleangood;//坦克是好是坏
publicbooleanisGood(){
returngood;
}
privateDirectionptDir=Direction.D;//新增炮筒的方向;
TankWarClienttc;//为了持有对方的引用以可以方便访问其成员变量;
Directiondir=Direction.STOP;//一开始将坦克方向设为stop;
publicTank(intx,inty,booleangood,Directiondir,TankWarClienttc)
{
this.x=x;
this.y=y;
this.oldX=x;
this.oldY=y;
this.good=good;
this.dir=dir;
this.tc=tc;//持有对方的引用;
}
publicvoiddraw(Graphicsg)
{
if(!live)//如果死亡则不再draw;
{
if(!good)
{
tc.tanks.remove(this);
if(tc.tanks.size()<5)//少于5辆坦克时添加坦克;
{
for(inti=0;i<10;i++)
{
intposX=r.nextInt(800);
intposY=r.nextInt(600);
tc.tanks.add(newTank(posX,posY,false,Direction.D,tc));//使得坦克出现的位置随机
}
}
}
return;
}
Colorc=g.getColor();
if(good)
{
g.setColor(Color.RED);
bb.draw(g);
}
elseg.setColor(Color.BLACK);
g.fillOval(x,y,WIDTH,HEIGHT);
g.setColor(c);
switch(ptDir)//画出炮筒的方向;
{
caseL:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x-10,y+Tank.HEIGHT/2);//画出炮筒,画一条直线代替;
break;
caseLU:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x-7,y-7);
break;
caseU:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH/2,y-10);
break;
caseRU:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH+7,y-7);
break;
caseR:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH+10,y+Tank.HEIGHT/2);
break;
caseRD:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH+7,y+Tank.HEIGHT+7);
break;
caseD:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH/2,y+Tank.HEIGHT+10);
break;
caseLD:
g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x-7,y+HEIGHT+7);
break;
}
move();
}
publicvoidmove()
{
oldX=x;//纪录坦克上一步的位置
oldY=y;
switch(dir)
{
caseL:
x-=XSPEED;
break;
caseLU:
x-=XSPEED;
y-=YSPEED;
break;
caseU:
y-=YSPEED;
break;
caseRU:
x+=XSPEED;
y-=YSPEED;
break;
caseR:
x+=XSPEED;
break;
caseRD:
x+=XSPEED;
y+=YSPEED;
break;
caseD:
y+=YSPEED;
break;
caseLD:
x-=XSPEED;
y+=YSPEED;
break;
caseSTOP:
break;
}
if(this.dir!=Direction.STOP)
this.ptDir=this.dir;
/**
*防止坦克越界;
*/
if(x<0)x=0;
if(y<25)y=25;
if(x+Tank.WIDTH>TankWarClient.GAME_WIDTH)x=TankWarClient.GAME_WIDTH-30;
if(y+Tank.HEIGHT>TankWarClient.GAME_HEIGHT)y=TankWarClient.GAME_HEIGHT-30;
if(!good)
{
Direction[]dirs=Direction.values();//将枚举类型转化成数组;
if(step==0)
{
step=r.nextInt(12)+3;
intrn=r.nextInt(dirs.length);//产生length以内随机的整数;
dir=dirs[rn];
}
step--;
if(r.nextInt(40)>20)this.fire();//使敌军坦克发射子弹;
}
}
/**
*处理按键
*@parame键盘事件;
*/
publicvoidKeyPressed(KeyEvente)
{
intkey=e.getKeyCode();
switch(key)
{
caseKeyEvent.VK_LEFT:
bL=true;
break;
caseKeyEvent.VK_RIGHT:
bR=true;
break;
caseKeyEvent.VK_UP:
bU=true;
break;
caseKeyEvent.VK_DOWN:
bD=true;
break;
}
locationDir();
}
publicvoidkeyReleased(KeyEvente){
intkey=e.getKeyCode();
switch(key)
{
caseKeyEvent.VK_CONTROL:
fire();
break;
caseKeyEvent.VK_LEFT:
bL=false;
break;
caseKeyEvent.VK_RIGHT:
bR=false;
break;
caseKeyEvent.VK_UP:
bU=false;
break;
caseKeyEvent.VK_DOWN:
bD=false;
break;
caseKeyEvent.VK_A:
superFire();
break;
caseKeyEvent.VK_F2:
reBorn();
break;
}
locationDir();
}
/**
*发射子弹
*@return返回子弹类型
*/
publicMissilefire(){
if(!live)
returnnull;
intmx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;//计算子弹发射的位置;
intmy=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2;
Missilem=newMissile(mx,my,good,ptDir,this.tc);////根据炮筒方向发射子弹
tc.missiles.add(m);
returnm;
}
publicMissilefire(Directiondir)
{
if(!live)
returnnull;
intmx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;
intmy=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2;
Missilem=newMissile(mx,my,good,dir,this.tc);//根据坦克的方向发射子弹;
tc.missiles.add(m);
returnm;
}
publicvoidsuperFire()
{
Direction[]dirs=Direction.values();
for(inti=0;i<8;i++)
{
fire(dirs[i]);
}
}
publicvoidlocationDir()
{
if(bL&&!bU&&!bR&&!bD)
dir=Direction.L;
elseif(bL&&bU&&!bR&&!bD)
dir=Direction.LU;
elseif(!bL&&bU&&!bR&&!bD)
dir=Direction.U;
elseif(!bL&&bU&&bR&&!bD)
dir=Direction.RU;
elseif(!bL&&!bU&&bR&&!bD)
dir=Direction.R;
elseif(!bL&&!bU&&bR&&bD)
dir=Direction.RD;
elseif(!bL&&!bU&&!bR&&bD)
dir=Direction.D;
elseif(bL&&!bU&&!bR&&bD)
dir=Direction.LD;
elseif(!bL&&!bU&&!bR&&!bD)
dir=Direction.STOP;
}
publicRectanglegetRect()//获取tank的矩形区域
{
returnnewRectangle(this.x,this.y,this.WIDTH,this.HEIGHT);
}
/**
*坦克撞墙
*@paramw墙
*@returntrue撞上,false未撞上;
*/
publicbooleancolliedsWithWall(Wallw)
{
if(this.live&&this.getRect().intersects(w.getRect()))
{
this.stay();
returntrue;
}
returnfalse;
}
/**
*处理坦克与坦克相撞,防止其互相穿越;
*@paramtanks敌军坦克;
*@returntrue撞上,false未撞上;
*/
publicbooleancolliedsWithTanks(java.util.List<Tank>tanks)
{
for(inti=0;i<tanks.size();i++)
{
Tankt=tanks.get(i);
if(this!=t)
{
if(this.live&&this.isLive()&&this.getRect().intersects(t.getRect()))
{
this.stay();//返回上一步的位置;
t.stay();////返回上一步的位置
returntrue;
}
}
}
returnfalse;
}
privatevoidstay()
{
x=oldX;
y=oldY;
}
/**
*为Tank的内部类;血条,显示在我方坦克的头顶上;
*@authorHekangmin
*
*/
privateclassBloodBar
{
publicvoiddraw(Graphicsg)
{
Colorc=g.getColor();
g.setColor(Color.RED);
g.drawRect(x,y-10,WIDTH,10);
intw=WIDTH*life/100;
g.fillRect(x,y-10,w,10);
}
}
/**
*吃到血块加血;
*@paramb血块
*@returntrue吃到,false未吃到;
*/
publicbooleaneat(Bloodb)
{
if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect()))
{
this.life=100;
b.setLive(false);
returntrue;
}
returnfalse;
}
/**
*我军坦克死后复活;
*/
publicvoidreBorn()
{
if(this.isGood()&&!this.isLive())
{
this.setLive(true);
this.setLife(100);
}
}
}
TankWarClient.java
packagecom.hkm.TankWar;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.List;
importjava.util.ArrayList;
/**
*这个是游戏的运行窗口;
*@authorHekangmin
*
*/
publicclassTankWarClientextendsFrame{
/**
*游戏窗口的宽度;
*/
publicstaticfinalintGAME_WIDTH=800;
/**
*游戏窗口的高度;
*/
publicstaticfinalintGAME_HEIGHT=600;
TankMyTank=newTank(700,400,true,Tank.Direction.STOP,this);
List<Tank>tanks=newArrayList<Tank>();
List<Explode>explodes=newArrayList<Explode>();
List<Missile>missiles=newArrayList<Missile>();
Wallw1=newWall(300,200,20,200,this);
Wallw2=newWall(600,300,30,150,this);
Bloodb=newBlood();
/**
*画一张虚拟图片;
*/
ImageOffScreenImage=null;
publicTankWarClient(Stringname)//设置文字
{
super(name);
}
/**
*运行窗口;
*/
publicvoidlaunchFrame()
{
for(inti=0;i<10;i++)//添加十辆敌军坦克
{
tanks.add(newTank(50+40*(i+1),50,false,Tank.Direction.D,this));
}
this.setBounds(200,100,GAME_WIDTH,GAME_HEIGHT);
this.setBackground(Color.GREEN);
this.addWindowListener(newWindowAdapter()//匿名类
{
publicvoidwindowClosing(WindowEvente)
{
System.exit(0);
}
});
this.addKeyListener(newKeyMonitor());//加入键盘监听器;
this.setResizable(false);//不可改变窗口的大小;
this.setVisible(true);
newThread(newPaintThread()).start();//新建一个线程;
}
publicvoidpaint(Graphicsg)
{
g.drawString("Missilecount:"+missiles.size(),10,50);//显示字符串;
g.drawString("Explodescount:"+explodes.size(),10,70);
g.drawString("tankscount:"+tanks.size(),10,90);
g.drawString("Mytanklife:"+MyTank.getLife(),10,110);
/**
*画出墙;
*/
w1.draw(g);
w2.draw(g);
/**
*检测子弹与各类的事情;
*/
for(inti=0;i<missiles.size();i++)
{
Missilem=missiles.get(i);
m.hitsWall(w1);
m.hitsWall(w2);
m.hitTanks(tanks);
m.hitTank(MyTank);
m.draw(g);
//if(!m.isLive())
//missiles.remove(m);
//elsem.draw(g);
}
/**
*画出爆炸;
*/
for(inti=0;i<explodes.size();i++)
{
Explodee=explodes.get(i);
e.draw(g);
}
for(inti=0;i<tanks.size();i++)
{
Tankt=tanks.get(i);
t.colliedsWithWall(w1);
t.colliedsWithWall(w2);
t.colliedsWithTanks(tanks);
t.draw(g);
}
b.draw(g);
MyTank.eat(b);
MyTank.draw(g);
}
/**
*利用双缓冲技术消除坦克闪烁的现象;
*/
publicvoidupdate(Graphicsg)//g为画在屏幕上的画笔;
{
if(OffScreenImage==null)
OffScreenImage=this.createImage(GAME_WIDTH,GAME_HEIGHT);
GraphicsgOffScreen=OffScreenImage.getGraphics();//gOffScreen是OffScreenImage的画笔;
Colorc=gOffScreen.getColor();
gOffScreen.setColor(Color.GREEN);
gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);//画在虚拟图片上;
g.drawImage(OffScreenImage,0,0,null);//用g画笔将虚拟图片上的东西画在屏幕上
}
privateclassPaintThreadimplementsRunnable{
publicvoidrun(){
while(true)
{
repaint();//这里的repaint方法是Frame类的
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
privateclassKeyMonitorextendsKeyAdapter
{
publicvoidkeyReleased(KeyEvente){
MyTank.keyReleased(e);
}
publicvoidkeyPressed(KeyEvente){
MyTank.KeyPressed(e);
}
}
publicstaticvoidmain(String[]args){
newTankWarClient("MyTankWorld").launchFrame();
}
}
Wall.java
packagecom.hkm.TankWar;
importjava.awt.*;
/**
*生成阻碍物墙这个类;
*@authorHekangmin
*
*/
publicclassWall{
/**
*x,y为墙的位置,w,h为宽度高度;
*/
intx,y,w,h;
/**
*持有引用
*/
TankWarClienttc;
publicWall(intx,inty,intw,inth,TankWarClienttc){
this.x=x;
this.y=y;
this.w=w;
this.h=h;
this.tc=tc;
}
publicvoiddraw(Graphicsg)
{
Colorc=g.getColor();
g.setColor(Color.GRAY);
g.fillRect(x,y,w,h);
g.setColor(c);
}
/**
*得到墙的矩形区域;
*@return
*/
publicRectanglegetRect()
{
returnnewRectangle(x,y,w,h);
}
}
以上所述就是本文的全部内容了,希望大家能够喜欢。