当前位置: 移动技术网 > IT编程>开发语言>Java > java制作简单的坦克大战

java制作简单的坦克大战

2019年07月22日  | 移动技术网IT编程  | 我要评论
详情请参照注释,这里就不多废话了,实现一下儿时的经典而已。 blood.java package com.hkm.tankwar; import java.a

详情请参照注释,这里就不多废话了,实现一下儿时的经典而已。

blood.java

package com.hkm.tankwar;
import java.awt.*;
/**
 * 血块类,我方坦克吃了可回血;
 * @author hekangmin
 *
 */
public class blood {
  private int x,y,w,h;//血块的位置和宽度高度;
   
  private tankwarclient tc;
   
  private int step=0;//纪录血块移动的步数;
   
  private boolean live=true;
  public boolean islive() {
    return live;
  }
 
  public void setlive(boolean live) {
    this.live = live;
  }
    /**
     * 纪录血块的位置;
     */
  private int[][] pos={{400,300},{400,320},{420,320},{440,300},{440,330},{480,400},{520,400},{540,400}};
        
  public blood()
  {
    x=pos[0][0];
    y=pos[0][1];
    w=h=18;
  }
   
  public void draw(graphics g)
  {
    if(!live) return;
     
    color c=g.getcolor();
    g.setcolor(color.cyan);
    g.filloval(x, y, w, h);
    g.setcolor(c);
     
    move();
  }
  /**
   * 移动血块
   */
  public void move()
  {
    step++;
    if(step>=pos.length) step=0;
    else{
    x=pos[step][0];
    y=pos[step][1];
    }
  }
   
   
  public rectangle getrect()
  {
    return new rectangle(x,y,w,h);
  }
   
   
}

explode.java

package com.hkm.tankwar;
import java.awt.*;
/**
 * 爆炸类
 * @author hekangmin
 *
 */
public class explode {
  private int x,y;//爆炸发生的位置
   
  private boolean live=true;
   
  int dia[]={4,8,12,16,32,40,20,14,4};//用园模拟,代表圆的直径;
   
  int step=0;//区别移到第几个直径
   
  private tankwarclient tc;//持有引用
   
  public explode(int x,int y,tankwarclient tc)
  {
    this.x=x;
    this.y=y;
    this.tc=tc;
  }
  public void draw(graphics g)
  {
    if(!live)
    {
      tc.explodes.remove(this);
      return;
    }
    if(step==dia.length)//如果到了最后一个直径爆炸死亡;
    {
      live=false;
      step=0;
      return;
    }
    color c=g.getcolor();
    g.setcolor(color.yellow);
    g.filloval(x, y, dia[step], dia[step]);
    g.setcolor(c);
    step++;
  }
   
}

missile.java

package com.hkm.tankwar;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.keyevent;
import java.util.list;
/**
 * 子弹类
 * @author hekangmin
 *
 */
 public class missile {
    private int x,y;//子弹的位置
    private tank.direction dir;//坦克方向
     
    private static final int xspeed=10;//坦克x方向的移动速度,
    private static final int yspeed=10;//坦克y方向的移动速度,
     
    public static final int width=10;
    public static final int height=10;
     
    private boolean live=true;//判断子弹是否活着
     
    private boolean good;//区分敌军子弹和我军子弹
     
    private tankwarclient tc;
     
  public missile(int x, int y, tank.direction dir) {
    this.x = x;
    this.y = y;
    this.dir = dir;
  }
   
  public missile(int x,int y,boolean good,tank.direction dir,tankwarclient tc)
  {
    this(x,y,dir);
    this.good=good;//将坦克好坏的属性与子弹还坏属性设为相同;
    this.tc=tc;
  }
   
  /**
   * 画出子弹
   * @param g为画笔
   */
  public void draw(graphics g)
  {
    if(!live)
      {
      tc.missiles.remove(this);
      return;
      }
    color c=g.getcolor();
    if(good)
    {
      g.setcolor(color.blue);
    }
    else g.setcolor(color.orange);
    g.filloval(x, y, width, height);
    g.setcolor(c);
     
    move();
  }
   
  /**
   * 根据坦克的方向让子弹移动
   */
  private void move() {
    switch(dir)
    {
    case l:
      x-=xspeed;
      break;
    case lu:
      x-=xspeed;
      y-=yspeed;
      break;
    case u:
      y-=yspeed;
      break;
    case ru:
      x+=xspeed;
      y-=yspeed;
      break;
    case r:
      x+=xspeed;
      break;
    case rd:
      x+=xspeed;
      y+=yspeed;
      break;
    case d:
      y+=yspeed;
      break;
    case ld:
      x-=xspeed;
      y+=yspeed;
      break;
    }
     
    if(x<0||y<0||x>tankwarclient.game_width||y>tankwarclient.game_height)//子弹越界则让其死亡;
    {
      live=false;
    }
  }
   
   
  public boolean islive()
  {
    return live;
  }
 
  public rectangle getrect()//获取子弹的矩形区域;
  {
    return new rectangle(this.x,this.y,this.width,this.height);
  }
   
  /**
   * 判断子弹与坦克碰撞;
   * @param t为坦克
   * @return返回true则表示发生碰撞,否则没有碰撞;
   */
  public boolean hittank(tank t)
  {
    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;///将子弹设为死亡;
      explode e=new explode(x,y,tc);//发生爆炸;
      tc.explodes.add(e);
      return true;
       
    }
    return false;
  }
  /**
   * 判断子弹与敌军坦克相撞;
   * @param tanks敌军坦克
   * @returntrue表示相撞,false没有相撞;
   */
  public boolean hittanks(list<tank> tanks)
  {
    for(int i=0;i<tanks.size();i++)
    {
      if(hittank(tc.tanks.get(i)))
      {
        return true;
      }
    }
     
    return false;
  }
   
  /**
   * 判断子弹是否撞墙
   * @param w墙
   * @returntrue,撞上,false,未撞上;
   */
  public boolean hitswall(wall w)
  {
    if(this.live&&this.getrect().intersects(w.getrect()))
    {
      live=false;
      return true;
    }
    return false;
  }
   
   
}

tank.java

package com.hkm.tankwar;
import java.awt.*;
import java.awt.event.keyevent;
import java.util.*;
/**
 * 坦克类
 * @author hekangmin
 *
 */
public class tank {
  public static final int xspeed=5;//坦克x方向速度
  public static final int yspeed=5;
   
  public static final int width=30;
  public static final int height=30;
   
  private bloodbar bb=new bloodbar();//血条
   
  private int life=100;
   
  public int getlife() {
    return life;
  }
 
  public void setlife(int life) {
    this.life = life;
  }
 
 
  private static random r=new random();
   
  private static int step=r.nextint(12)+3;//定义一个数表示敌军坦克随机东的步数;
   
  private boolean bl=false,bu=false,br=false,bd=false;
   
  enum direction{l,lu,u,ru,r,rd,d,ld,stop};//利用枚举类型定义坦克方向;
  private int x,y;
   
  private int oldx,oldy;//纪录上一步坦克的位置;
   
  private boolean live=true;//判断是否活着
   
  public boolean islive() {
    return live;
  }
 
  public void setlive(boolean live) {
    this.live = live;
  }
 
 
  private boolean good;//坦克是好是坏
   
  public boolean isgood() {
    return good;
  }
 
 
  private direction ptdir=direction.d;//新增炮筒的方向;
   
  tankwarclient tc;//为了持有对方的引用以可以方便访问其成员变量;
   
  direction dir=direction.stop;//一开始将坦克方向设为stop;
   
   
   
  public tank(int x,int y,boolean good,direction dir,tankwarclient tc)
  {
    this.x=x;
    this.y=y;
    this.oldx=x;
    this.oldy=y;
    this.good=good;
    this.dir=dir;
    this.tc=tc;//持有对方的引用;
  }
   
   
  public void draw(graphics g)
  {
    if(!live)//如果死亡则不再draw;
    {  
      if(!good)
      {
        tc.tanks.remove(this);
        if(tc.tanks.size()<5)//少于5辆坦克时添加坦克;
        {
          for(int i=0;i<10;i++)
          {
            int posx=r.nextint(800);
            int posy=r.nextint(600);
            tc.tanks.add(new tank(posx,posy,false,direction.d,tc));//使得坦克出现的位置随机
          }
        }
      }
       
      return;
    }
     
    color c=g.getcolor();
    if(good) 
    {
      g.setcolor(color.red);
      bb.draw(g);
    }
    else g.setcolor(color.black);
    g.filloval(x, y, width, height);
    g.setcolor(c);
     
    switch(ptdir)//画出炮筒的方向;
    {
    case l:
       g.drawline(x+tank.width/2, y+tank.height/2, x-10, y+tank.height/2);//画出炮筒,画一条直线代替;
      break;
    case lu:
       g.drawline(x+tank.width/2, y+tank.height/2, x-7, y-7);
      break;
    case u:
       g.drawline(x+tank.width/2, y+tank.height/2, x+tank.width/2, y-10);
      break;
    case ru:
       g.drawline(x+tank.width/2, y+tank.height/2, x+tank.width+7, y-7);
      break;
    case r:
       g.drawline(x+tank.width/2, y+tank.height/2, x+tank.width+10, y+tank.height/2);
      break;
    case rd:
       g.drawline(x+tank.width/2, y+tank.height/2, x+tank.width+7, y+tank.height+7);
      break;
    case d:
       g.drawline(x+tank.width/2, y+tank.height/2, x+tank.width/2, y+tank.height+10);
      break;
    case ld:
       g.drawline(x+tank.width/2, y+tank.height/2, x-7, y+height+7);
      break;
    }
    move();
  }
   
   
  public void move()
  {
    oldx=x;//纪录坦克上一步的位置
    oldy=y;
     
    switch(dir)
    {
    case l:
      x-=xspeed;
      break;
    case lu:
      x-=xspeed;
      y-=yspeed;
      break;
    case u:
      y-=yspeed;
      break;
    case ru:
      x+=xspeed;
      y-=yspeed;
      break;
    case r:
      x+=xspeed;
      break;
    case rd:
      x+=xspeed;
      y+=yspeed;
      break;
    case d:
      y+=yspeed;
      break;
    case ld:
      x-=xspeed;
      y+=yspeed;
      break;
    case stop:
      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;
        int rn=r.nextint(dirs.length);//产生length以内随机的整数;
        dir=dirs[rn];
      }
      step--;
      if(r.nextint(40)>20) this.fire();//使敌军坦克发射子弹;
    }
     
  }
   
  /**
   * 处理按键
   * @param e键盘事件;
   */
  public void keypressed(keyevent e)
  {
    int key=e.getkeycode();
    switch(key)
    {
     
    case keyevent.vk_left:
      bl=true;
      break;
    case keyevent.vk_right:
      br=true;
      break;
    case keyevent.vk_up:
      bu=true;
       break;
    case keyevent.vk_down:
      bd=true;
      break;
    }
    locationdir();
  }
   
   
  public void keyreleased(keyevent e) {
    int key=e.getkeycode();
    switch(key)
    {
    case keyevent.vk_control:
      fire();
      break;
    case keyevent.vk_left:
      bl=false;
      break;
    case keyevent.vk_right:
      br=false;
      break;
    case keyevent.vk_up:
      bu=false;
       break;
    case keyevent.vk_down:
      bd=false;
      break;
    case keyevent.vk_a:
      superfire();
      break;
    case keyevent.vk_f2:
      reborn();
      break;
    }
    locationdir();
  }
   
  /**
   * 发射子弹
   * @return返回子弹类型
   */
  public missile fire() {
    if(!live)
      return null;
    int mx=this.x+tank.width/2-missile.width/2;//计算子弹发射的位置;
    int my=this.y+tank.height/2-missile.height/2;
    missile m=new missile(mx,my,good,ptdir,this.tc);////根据炮筒方向发射子弹
    tc.missiles.add(m);
    return m;
  }
   
   
  public missile fire(direction dir)
  {
    if(!live)
      return null;
    int mx=this.x+tank.width/2-missile.width/2;
    int my=this.y+tank.height/2-missile.height/2;
    missile m=new missile(mx,my,good,dir,this.tc);//根据坦克的方向发射子弹;
    tc.missiles.add(m);
    return m;
  }
   
  public void superfire()
  {
    direction[] dirs=direction.values();
    for(int i=0;i<8;i++)
    {
      fire(dirs[i]);
    }
  }
   
   
  public void locationdir()
  {
    if(bl&&!bu&&!br&&!bd)
      dir=direction.l;
    else if(bl&&bu&&!br&&!bd)
      dir=direction.lu;
    else if(!bl&&bu&&!br&&!bd)
      dir=direction.u;
    else if(!bl&&bu&&br&&!bd)
      dir=direction.ru;
    else if(!bl&&!bu&&br&&!bd)
      dir=direction.r;
    else if(!bl&&!bu&&br&&bd)
      dir=direction.rd;
    else if(!bl&&!bu&&!br&&bd)
      dir=direction.d;
    else if(bl&&!bu&&!br&&bd)
      dir=direction.ld;
    else if(!bl&&!bu&&!br&&!bd)
      dir=direction.stop;
  }
 
   
   
  public rectangle getrect()//获取tank的矩形区域
  {
    return new rectangle(this.x,this.y,this.width,this.height);
  }
   
  /**
   * 坦克撞墙
   * @param w墙
   * @returntrue撞上,false未撞上;
   */
  public boolean colliedswithwall(wall w)
  {
    if(this.live&&this.getrect().intersects(w.getrect()))
    {
      this.stay();
      return true;
    }
    return false;
  }
   
  /**
   * 处理坦克与坦克相撞,防止其互相穿越;
   * @param tanks敌军坦克;
   * @return true撞上,false未撞上;
   */
  public boolean colliedswithtanks(java.util.list<tank> tanks)
  {
    for(int i=0;i<tanks.size();i++)
    {
      tank t=tanks.get(i);
      if(this!=t)
      {
        if(this.live&&this.islive()&&this.getrect().intersects(t.getrect()))
        {
          this.stay();//返回上一步的位置;
          t.stay();////返回上一步的位置
          return true;
        }
         
      }  
    }
    return false;
  }
   
 
  private void stay()
  {
    x=oldx;
    y=oldy;
  }
   
  /**
   * 为tank的内部类;血条,显示在我方坦克的头顶上;
   * @author hekangmin
   *
   */
  private class bloodbar
  {
    public void draw(graphics g)
    {
      color c=g.getcolor();
      g.setcolor(color.red);
      g.drawrect(x,y-10,width,10);
      int w=width*life/100;
      g.fillrect(x,y-10,w,10);
    }
  }
   
  /**
   * 吃到血块加血;
   * @param b血块
   * @returntrue吃到,false未吃到;
   */
  public boolean eat(blood b)
  {
    if(this.live&&b.islive()&&this.getrect().intersects(b.getrect()))
    {
      this.life=100;
      b.setlive(false);
      return true;
    }
    return false;
  }
   
  /**
   * 我军坦克死后复活;
   */
  public void reborn()
  {
    if(this.isgood()&&!this.islive())
    {
      this.setlive(true);
      this.setlife(100);
    }
  }
}

tankwarclient.java

package com.hkm.tankwar;
import java.awt.*;
import java.awt.event.*;
import java.util.list;
import java.util.arraylist;
 
/**
 * 这个是游戏的运行窗口;
 * @author hekangmin
 *
 */
public class tankwarclient extends frame{
/**
 * 游戏窗口的宽度;
 */
  public static final int game_width=800;
   
  /**
   * 游戏窗口的高度;
   */
  public static final int game_height=600;
   
  tank mytank=new tank(700,400,true,tank.direction.stop,this);
  list<tank> tanks=new arraylist<tank>();
  list<explode> explodes=new arraylist<explode>();
  list<missile> missiles=new arraylist<missile>();
  wall w1=new wall(300,200,20,200,this);
  wall w2=new wall(600,300,30,150,this);
  blood b=new blood();
   
  /**
   * 画一张虚拟图片;
   */
  image offscreenimage=null;
   
  public tankwarclient(string name)//设置文字
  {
    super(name);
  }
   
  /**
   * 运行窗口;
   */
   
  public void launchframe()
  {
    for(int i=0;i<10;i++)//添加十辆敌军坦克
    {
      tanks.add(new tank(50+40*(i+1),50,false,tank.direction.d,this));
    }
     
    this.setbounds(200,100,game_width,game_height);
    this.setbackground(color.green);
    this.addwindowlistener(new windowadapter()//匿名类
    {
      public void windowclosing(windowevent e)
      {
        system.exit(0);
      }
    });
    this.addkeylistener(new keymonitor());//加入键盘监听器;
    this.setresizable(false);//不可改变窗口的大小;
     
    this.setvisible(true);
     
    new thread(new paintthread()).start();//新建一个线程;
  }
   
  public void paint(graphics g)
  {
    g.drawstring("missile count: "+missiles.size(), 10, 50);//显示字符串;
    g.drawstring("explodes count: "+explodes.size(),10,70);
    g.drawstring("tanks count: "+tanks.size(),10,90);
    g.drawstring("mytank life: "+mytank.getlife(),10,110);
    /**
     * 画出墙;
     */
    w1.draw(g);
    w2.draw(g);
     
    /**
     * 检测子弹与各类的事情;
     */
    for(int i=0;i<missiles.size();i++)
    {
      missile m=missiles.get(i);
      m.hitswall(w1);
      m.hitswall(w2);
      m.hittanks(tanks);
      m.hittank(mytank);
      m.draw(g);
       
      //if(!m.islive())
        //missiles.remove(m);
      //else m.draw(g);
    }
    /**
     * 画出爆炸;
     */
    for(int i=0;i<explodes.size();i++)
    {
      explode e=explodes.get(i);
      e.draw(g);
    }
     
    for(int i=0;i<tanks.size();i++)
    {
      tank t=tanks.get(i);
      t.colliedswithwall(w1);
      t.colliedswithwall(w2);
      t.colliedswithtanks(tanks);
      t.draw(g);
    }
     
    b.draw(g);
    mytank.eat(b);
    mytank.draw(g);
  }
   
  /**
   * 利用双缓冲技术消除坦克闪烁的现象;
   */
  public void update(graphics g) //g为画在屏幕上的画笔;
  {
    if(offscreenimage==null)
      offscreenimage=this.createimage(game_width, game_height);
    graphics goffscreen=offscreenimage.getgraphics();//goffscreen是offscreenimage的画笔;
    color c=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画笔将虚拟图片上的东西画在屏幕上
     
  }
   
   
  private class paintthread implements runnable{
 
    public void run() {
      while(true)
      {
        repaint();//这里的repaint方法是frame类的
        try{
        thread.sleep(100);
        }catch(interruptedexception e){
          e.printstacktrace();
        }
      }
    }
  }
   
  private class keymonitor extends keyadapter
  {
    public void keyreleased(keyevent e) {
      mytank.keyreleased(e);
    }
 
    public void keypressed(keyevent e) {
      mytank.keypressed(e);
      }
     
     
  }
   
   
   
  public static void main(string[] args) {
    new tankwarclient("my tank world").launchframe();
  }
   
   
   
   
}

wall.java

package com.hkm.tankwar;
import java.awt.*;
/**
 * 生成阻碍物墙这个类;
 * @author hekangmin
 *
 */
 
public class wall {
  /**
   * x,y为墙的位置,w,h为宽度高度;
   */
  int x,y,w,h;
  /**
   * 持有引用
   */
  tankwarclient tc;
   
  public wall(int x, int y, int w, int h, tankwarclient tc) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.tc = tc;
  }
   
  public void draw(graphics g)
  {
    color c=g.getcolor();
    g.setcolor(color.gray);
    g.fillrect(x,y,w,h);
    g.setcolor(c);
  }
   
  /**
   * 得到墙的矩形区域;
   * @return
   */
  public rectangle getrect()
  {
    return new rectangle(x,y,w,h);
  }
   
}

以上所述就是本文的全部内容了,希望大家能够喜欢。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网