这个版本,只能算是一个雏形,把最基本的东西给完成了,不过,后面可添加的也不多。有一点,还是想去实现,那就是敌方坦克自己寻找对手!也就是游戏AI.

emmm, 什么时候可以了解一下这个AI。顺便学学python。

这个帖子只是为了贴上代码,对后续的代码作为优化和添加游戏AI做准备的。


1. 各类接口

package Event;
/*
*具有攻击力的接口
*/
public interface Attackable {
/*
* 校验具有攻击力的实物, 和, 具有被攻击的实物,是否能撞在一起
*
*/
boolean checkAttack(Hitable hit);
}
package Event;
/*
* 具有阻挡功能的实物
*/
public interface Blockable { }
package Event;
/*
* 能被销毁的类
*/
import domain.Blast;
/*
* 销毁接口
*/
public interface Destoryable {
/*
* 判断是否需要销毁
*/
boolean isDestoryable(); /*
* 销毁时,绘制爆炸物
*/
Blast showDestory();
}
package Event;

import domain.Blast;
/*
* 能被攻击的类
*/
public interface Hitable {
Blast showAttack();
}
package Event;
/*
* 具有移动功能的事物
*
*/
public interface Moveable {
boolean checkHit(Blockable blockable);
}

2.各类游戏元素的父类

package domain;

/*
* 父类:
* 是砖墙,坦克,水墙等所有元素的抽象出来的抽象类
*/
public abstract class Element {
/*
* 属性
* 坐标
*/
protected int x;
protected int y;
//宽高
protected int width;
protected int hight; //构造函数
//空参构造函数
public Element() {super();} //可以不写super(),java会自己调用,也就是调用抽象类的父类 public Element(int x, int y) {
this.x=x; this.y=y;
} /*
* 绘制元素
*/
public abstract void draw(); /*
* 设置元素的渲染级别,数字越高,渲染级别越高
*/
public int getOrder() {return 0;}
}

坦克的父类

package domain;

import org.itheima.game.utils.CollisionUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;
import Event.Moveable;
/*
* 所有坦克的父类\
* 坦克具有移动,阻挡,被攻击,被销毁的功能
*
*/
public abstract class Tank extends Element implements Moveable, Blockable, Hitable,Destoryable{
/*
* 属性
*/
//攻击力
protected int power=1;
//血量
protected int blood=5; //坦克的移动方向
protected Direction direction=Direction.UP; //每次移动的速度
protected int speed=3; //记录最后一颗子弹的发射时间
protected long lastTime; //记录坦克不能移动的方向
protected Direction badDirection; //记录坦克碰撞的最小移动距离
protected int badSpeed; /*
* 构造函数
*/
public Tank() {super();}
public Tank(int x, int y) {super(x, y);} /*
* 绘制坦克
*/
public abstract void draw(); /*
* 发射子弹
*/
public Bullet shot() {
//思路:如歌最后一颗子弹 - 当前发射的时间 > 650ms 就发射子弹
//获取当前时间
long newTime=System.currentTimeMillis();
if(newTime-lastTime<650) {
return null; //不发射子弹
}else {
lastTime=newTime;
return new Bullet(this); //谁调用了就是谁的子弹
}
} /*
* 获取坦克的移动方向
*/
public Direction getDirection() {return direction;} /*
* 校验:移动物(坦克)是否与障碍物是否撞上
*/
public boolean checkHit(Blockable block){
Element e=(Element)block;
int x1=e.x;
int y1=e.y;
int w1=e.width;
int h1=e.hight; //预判坦克的坐标
int x2=x;
int y2=y;
switch (direction) {
case UP:
y2-=speed;
break;
case DOWN:
y2+=speed;
break;
case LEFT:
x2-=speed;
break;
case RIGHT:
x2+=speed;
break;
default:
break;
}
boolean flag=CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x2, y2, width, hight);
if(flag) {
//说明预判可以撞上,不仅要记录不能移动的方向,还要记录最小间隙
badDirection=direction;
switch (direction) {
case UP:
badSpeed=y-y1-h1;
break;
case DOWN:
badSpeed = y1 - y - hight;
break;
case LEFT:
badSpeed = x - x1 - w1;
break;
case RIGHT:
badSpeed = x1 - w1 - width;
break;
default:
break;
}
}else {
badDirection=null; //没有撞上的话,就没有坏的方向
}
return flag;
} /*
* 销毁的方法
*/
public boolean isDestory() {return blood<=0;} /*
* 被销毁物,在被销毁时的表现。
*/
public Blast showDestory() {return new Blast(this);} }

各种游戏元素

package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;
import org.itheima.game.utils.SoundUtils; import Event.Blockable;
import Event.Destoryable;
import Event.Hitable; /*
*
* 爆炸物类
*
*/
public class Blast extends Element implements Destoryable{
/*
* 属性
*/
//1.图片
private String[]arr= {"res/img/blast_1.gif", "res/img/blast_2.gif", "res/img/blast_3.gif", "res/img/blast_4.gif",
"res/img/blast_5.gif", "res/img/blast_6.gif", "res/img/blast_7.gif", "res/img/blast_8.gif"};
//2.定义变量,记录要绘制的图片索引
private int index; //3.定义变量,记录是否需要销毁该爆炸物
//true:销毁, false :不销毁
private boolean isDestory; /*
* 构造方法
* 爆炸物的坐标依赖墙的坐标
*/
public Blast(Hitable hit) {
this(hit, false);
try {
SoundUtils.play("res/snd/blast.wav");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* flag :true表示挨打,绘制1~4的图片
* false 说明是销毁,绘制1~8的图片
*/
public Blast(Hitable hit, boolean flag) {
Element element=(Element)hit;
//计算爆炸物的位置
//获取墙的坐标和宽高
int x1=element.x;
int y1=element.y;
int w1=element.width;
int h1=element.hight;
//获取爆炸物的宽度
try {
int size[]=DrawUtils.getSize("res/img/blast_1.gif");
width=size[0]; hight=size[1]; //计算爆炸物的坐标
x=x1+(w1-width)/2;
y=y1+(h1-hight)/2;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} if(flag) {
arr=new String[] {"res/img/blast_1.gif", "res/img/blast_2.gif", "res/img/blast_3.gif", "res/img/blast_4.gif"};
try {
SoundUtils.play("res/snd/hit.wav");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void draw() {
// TODO Auto-generated method stub
//定义变量,记录要绘制的图片的路径
String res=arr[index++];
if(index>=arr.length) {
index=0;
//说明爆炸物已经绘制过一次了可以销毁
isDestory=true;
}
try {
DrawUtils.draw(res, x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 获取爆炸物的状态
*/
public boolean isDestoryable() {
// TODO Auto-generated method stub
return isDestory;
}
/*
* 销毁时,绘制销毁的爆炸物
*/
public Blast showDestory() {return null;} }
package domain;

import java.io.IOException;

import org.itheima.game.utils.CollisionUtils;
import org.itheima.game.utils.DrawUtils;
import org.itheima.game.utils.SoundUtils; import Event.Attackable;
import Event.Destoryable;
import Event.Hitable;
import Grame.config; /*
* 子弹类,具有攻击能力,被销毁的能力
*/
public class Bullet extends Element implements Attackable, Destoryable { //记录子弹移动的方向
private Direction direction;
//记录子弹的速度
private int speed=7;
//定义变量,记录子弹所属的坦克
private Tank tank; /*
* 构造函数(non-Javadoc)
* @see Event.Destoryable#isDestoryable()
*/
//子弹的坐标依赖坦克
public Bullet(Tank tank) {
// TODO Auto-generated constructor stub
super();
//用变量tank记录,子弹所属的坦克
this.tank=tank; //获取坦克的坐标,宽高,方向
int tankX=tank.x;
int tankY=tank.y;
int tankWidth=tank.width;
int tankHight=tank.hight;
direction=tank.getDirection(); //获取子弹的宽高
try {
int size[]=DrawUtils.getSize("res/img/bullet_u.gif");
width=size[0]; hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //计算子弹的坐标
switch (direction) {
case UP:
x = tankX + (tankWidth - width)/2;
y = tankY - hight / 2;
break;
case DOWN:
x = tankX + (tankWidth - width)/2;
y = tankY + tankHight - hight /2;
break;
case LEFT:
x=tankX-width;
y=tankY+(tankHight-hight)/2;
break;
case RIGHT:
x = tankX + tankWidth - width / 2;
y = tankY + (tankHight - hight)/2;
break;
default:
break;
} try {
SoundUtils.play("res/snd/fire.wav");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /* 出边界
* 销毁子弹 true:销毁,false:不销毁(non-Javadoc)
* @see Event.Destoryable#isDestoryable()
*/
@Override
public boolean isDestoryable() {
// TODO Auto-generated method stub
if(x<0||x>config.WIDTH||y<0||y>config.HIGHT) return true;
return false;
} /*
* 子弹销毁时的反映(non-Javadoc)
* @see Event.Destoryable#showDestory()
*/
@Override
public Blast showDestory() {
// TODO Auto-generated method stub
return null;
}
/*校验是否与阻碍物碰上
* (non-Javadoc)
* @see Event.Attackable#checkAttack(Event.Hitable)
*/
@Override
public boolean checkAttack(Hitable hit) {
// TODO Auto-generated method stub
Element e=(Element)hit;
int x1=e.x;
int y1=e.y;
int w1=e.width;
int h1=e.hight;
//第一个矩形:障碍物,第二个撞击物:子弹
return CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x, y, width, hight);
} /*
* 绘制子弹(non-Javadoc)
* @see domain.Element#draw()
*/
@Override
public void draw() {
// TODO Auto-generated method stub
String res="";
//判断坦克方向
switch (direction) {
case UP:
res = "res/img/bullet_u.gif";
y-=speed;
break;
case DOWN:
res = "res/img/bullet_d.gif";
y += speed;
break;
case LEFT:
res = "res/img/bullet_l.gif";
x -= speed;
break;
case RIGHT:
res = "res/img/bullet_r.gif";
x += speed;
break;
default:
break;
} try {
DrawUtils.draw(res, x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 获取子弹所属坦克
*/
public Tank getTank() {
return tank;
}
}
package domain;
/*
* 枚举四个方向
*/
public enum Direction {
UP,DOWN,LEFT,RIGHT;
}

package domain;

import java.io.IOException;
import java.util.Random; import org.itheima.game.utils.DrawUtils; import Grame.config; public class EnemyTank extends Tank{ /*
* 属性(non-Javadoc)
* @see Event.Hitable#showAttack()
*/
public EnemyTank(int x, int y) {
super(x, y);
try {
int size[]=DrawUtils.getSize("res/img/enemy_u.gif");
width=size[0]; hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public EnemyTank() {super();} @Override
public Blast showAttack() {
// TODO Auto-generated method stub
//扣血
blood-=new Mytank().power;
return new Blast(this, true);
} @Override
public boolean isDestoryable() {
// TODO Auto-generated method stub
return blood<=0;
} /*
* 坦克的绘制(non-Javadoc)
* @see domain.Tank#draw()
*/
@Override
public void draw() {
// TODO Auto-generated method stub
String res="";
//判断坦克的方向
switch (direction) {
case UP:
res = "res/img/enemy_u.gif";
break;
case DOWN:
res = "res/img/enemy_d.gif";
break;
case LEFT:
res = "res/img/enemy_l.gif";
break;
case RIGHT:
res = "res/img/enemy_r.gif";
break;
default:
break;
} try {
DrawUtils.draw(res, x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 随机获取敌方坦克的方向
*/
public Direction getRandDirection() {
int num=new Random().nextInt(4);
switch (num) {
case 0:
return Direction.UP;
case 1:
return Direction.DOWN;
case 2:
return Direction.LEFT;
case 3:
return Direction.RIGHT;
default:
break;
}
return Direction.UP;
} /*
* 移动
*/
public void move() {
//如果传过来的方向,与坦克不能移动的方向相同,则移动最小距离
if(direction==badDirection) {
switch (direction) {
case UP:
y-=badSpeed;
break;
case DOWN:
y+=badSpeed;
break;
case LEFT:
x-=badSpeed;
break;
case RIGHT:
x+=badSpeed;
break;
default:
break;
}
//不能移动就随机换一下方向
direction=getRandDirection();
return ;
} switch (direction) {
case UP:
y-=speed;
break;
case DOWN:
y+=speed;
break;
case LEFT:
x-=speed;
break;
case RIGHT:
x+=speed;
break;
default:
break;
} //边界处理
if(x<0) {
x=0;
direction=getRandDirection();
}
if(x>config.WIDTH-64) {
x=config.WIDTH-64;
direction=getRandDirection();
}
if(y<0) {
y=0;
direction=getRandDirection();
}
if(y>config.HIGHT-64) {
y=config.HIGHT-64;
direction=getRandDirection();
}
}
}
 
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;
/*
* 草坪
*/
public class Grass extends Element{ public Grass(int x, int y) {
// TODO Auto-generated constructor stub
super(x, y);
//获取宽高
try {
int size[]=DrawUtils.getSize("res/img/grass.gif");
width=size[0]; hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void draw() {
// TODO Auto-generated method stub
try {
DrawUtils.draw("res/img/grass.gif", x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 修改草坪的渲染级别
*/
public int getOrder() {return 1;}
}
package domain;

import java.io.IOException;

import javax.swing.plaf.DimensionUIResource;

import org.itheima.game.utils.DrawUtils;

import Grame.config;

public class Mytank extends Tank{
public Mytank(int x, int y) {
// TODO Auto-generated constructor stub
super(x, y);
//初始化速度
speed=30; power=2; blood=10; //获取坦克的宽高
try {
int size[] = DrawUtils.getSize("res/img/tank_u.gif");
width=size[0];
hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public Mytank() {
// TODO Auto-generated constructor stub
super();
power=2;
} /*
* 挨打方法(non-Javadoc)
* @see Event.Hitable#showAttack()
*/
@Override
public Blast showAttack() {
// TODO Auto-generated method stub
//扣血
blood-=new EnemyTank().power;
return new Blast(this, true);
} @Override
public boolean isDestoryable() {
// TODO Auto-generated method stub
return blood<=0;
} @Override
public void draw() {
// TODO Auto-generated method stub
String res="";
switch (direction) {
case UP:
res = "res/img/tank_u.gif";
break;
case DOWN:
res = "res/img/tank_d.gif";
break;
case LEFT:
res = "res/img/tank_l.gif";
break;
case RIGHT:
res = "res/img/tank_r.gif";
break;
default:
break;
}
try {
DrawUtils.draw(res, x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 坦克的移动
*/
public void move(Direction direction) {
//如果传过来的方向和坦克不能动的方向一致,则移动最小
if(badDirection==direction) {
//移动最小间距
switch (direction) {
case UP:
y -= badSpeed;
break;
case DOWN:
y += badSpeed;
break;
case LEFT:
x -= badSpeed;
break;
case RIGHT:
x += badSpeed;
break;
default:
break;
}
return ;
} //刷新方向,用户按下的方向传给坦克:坦克的方向
if(this.direction!=direction)
{
this.direction=direction;
return ;
} switch (direction) {
case UP:
y -= speed;
break;
case DOWN:
y += speed;
break;
case LEFT:
x -= speed;
break;
case RIGHT:
x += speed;
break;
default:
break;
} /*
* 边界处理
*/
if(x<0) {x=0;}
if(x>config.WIDTH-64) {x=config.WIDTH-64;}
if(y<0) {y=0;}
if(y>config.HIGHT-64) {y=config.HIGHT-64;}
} }

package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable; public class Steel extends Element implements Blockable, Hitable, Destoryable{
/*
* 属性:
*/
//1.血量
private int blood=5; public Steel(int x, int y) {
super(x, y); //获取铁墙的宽高
try {
int size[]=DrawUtils.getSize("res/img/steel.gif");
width=size[0];
hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} @Override
public void draw() {
// TODO Auto-generated method stub
try {
DrawUtils.draw("res/img/steel.gif", x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 挨打后的反映(non-Javadoc)
* @see Event.Hitable#showAttack()
*/
@Override
public Blast showAttack() {
// TODO Auto-generated method stub
blood--;
return new Blast(this,true);
} /*
* 销毁时响应的动作(non-Javadoc)
* @see Event.Destoryable#showDestory()
*/
@Override
public Blast showDestory() {
// TODO Auto-generated method stub
return new Blast(this);
} /*
* 销毁铁墙(non-Javadoc)
* @see Event.Destoryable#isDestoryable()
*/
@Override
public boolean isDestoryable() {
// TODO Auto-generated method stub
return blood<=0;
}
}
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;

import Event.Blockable;
import Event.Destoryable;
import Event.Hitable; public class Wall extends Element implements Hitable, Blockable, Destoryable{ //血量
private int blood=3; /*
* 含参数的构造函数
*/
public Wall(int x, int y) {
// TODO Auto-generated constructor stub
super(x, y); //获取宽度,长度
try {
int size[]=DrawUtils.getSize("res/img/wall.gif");
width=size[0];
hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
/*
*绘制
* @see domain.Element#draw()
*/
@Override
public void draw() {
try {
DrawUtils.draw("res/img/wall.gif", x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /*
* 挨打
* Blast爆炸类
*/
public Blast showAttack() {
blood--; //挨打一次血量减少
return new Blast(this, true);
} /*
* 销毁判断,血量小于等于0时,就销毁
*/
public boolean isDestoryable() {return blood<=0;} /*
* 销毁响应动作
*/
public Blast showDestory() {return new Blast(this);} }
package domain;

import java.io.IOException;

import org.itheima.game.utils.DrawUtils;

import Event.Blockable;

public class Water extends Element implements Blockable{

    public Water(int x, int y) {
super(x, y);
try {
int size[]=DrawUtils.getSize("res/img/water.gif");
width=size[0]; hight=size[1];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
@Override
public void draw() {
try {
DrawUtils.draw("res/img/water.gif", x, y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
package Grame;

public class APP {
/*
* 游戏的主入口,所有代码的主入口
*/
public static void main(String[] args) {
//绘制窗口
MyWindows gr=new MyWindows(config.TITLE, config.WIDTH, config.HIGHT, config.PFS); //开始游戏
gr.start(); } }

package Grame;

public interface config {
String TITLE="坦克大战";
int WIDTH=64*15;
int HIGHT=64*10;
int PFS=50;
}
package Grame;

import java.awt.HeadlessException;
import java.awt.Window;
import java.io.IOException;
import java.nio.file.Watchable;
import java.util.Comparator;
import java.util.concurrent.CopyOnWriteArrayList; import org.itheima.game.utils.DrawUtils;
import org.itheima.game.utils.SoundUtils;
import org.lwjgl.input.Keyboard;
import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID; import Event.Attackable;
import Event.Blockable;
import Event.Destoryable;
import Event.Hitable;
import Event.Moveable;
import domain.Blast;
import domain.Bullet;
import domain.Direction;
import domain.Element;
import domain.EnemyTank;
import domain.Grass;
import domain.Mytank;
import domain.Steel;
import domain.Tank;
import domain.Wall;
import domain.Water; /*
* 游戏窗口类
*
*/
public class MyWindows extends org.itheima.game.Window{ //定义:集合,存储元素
//CopyOnWeiteArrayList 可以解决并发修改异常的集合
CopyOnWriteArrayList<Element>list=new CopyOnWriteArrayList<>();
//创建坦克对象
Mytank mt;
//创建敌方坦克
EnemyTank et1;
EnemyTank et2; public MyWindows(String title, int width, int height, int fps) {super(title, width, height, fps);} /*
* 绘制窗口时运行
*/
@Override
protected void onCreate() {
//播放开始音乐
try {
SoundUtils.play("res/snd/start.wav");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //创建砖墙
for(int i=0;i<config.WIDTH/64-1;++i) {
Wall wall=new Wall(i*64, 64);
addElement(wall);
}
//创建水墙
for(int i=1;i<config.WIDTH/64;++i) {
Water water=new Water(i*64, 64*3);
addElement(water);
}
//绘制铁墙
for(int i=0;i<config.WIDTH/64-1;++i) {
Steel steel=new Steel(i*64, 64*5);
addElement(steel);
}
//创造草坪
for(int i=1;i<config.WIDTH/64;++i) {
Grass grass=new Grass(i*64, 64*7);
addElement(grass);
} //创造己方坦克
mt=new Mytank(config.WIDTH/2-32, config.HIGHT-64);
addElement(mt);
//创建敌方坦克
et1=new EnemyTank(0, 0);
et2=new EnemyTank(config.WIDTH-64, 0);
addElement(et1);
addElement(et2);
} //鼠标事件
@Override
protected void onMouseEvent(int key, int x, int y) {
// TODO Auto-generated method stub } //键盘事件
@Override
protected void onKeyEvent(int key) {
// TODO Auto-generated method stub
switch (key) {
case Keyboard.KEY_UP:
mt.move(Direction.UP);
break;
case Keyboard.KEY_DOWN:
mt.move(Direction.DOWN);
break;
case Keyboard.KEY_LEFT:
mt.move(Direction.LEFT);
break;
case Keyboard.KEY_RIGHT:
mt.move(Direction.RIGHT);
break;
case Keyboard.KEY_SPACE: //回车键
Bullet shot=mt.shot(); //发射子弹
//对子弹进行非空校验
if(shot!=null) {
addElement(shot);
}
break;
default:
break;
}
} //事实刷新
@Override
protected void onDisplayUpdate() {
// TODO Auto-generated method stub
//如果己方坦克已经销毁,或者敌方坦克都销毁,则游戏结束
if(mt.isDestory()||(et1.isDestory()&&et2.isDestory())) {
list.clear();
//绘制结束图片
try {
DrawUtils.draw("res/img/gameover.gif", (config.WIDTH-96)/2, (config.HIGHT-96)/2);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//停止所有音乐
SoundUtils.stop("res/snd/fire.wav"); return;
} //绘制元素
for(Element e:list) {
e.draw();
} //调用敌方坦克的随机移动的功能
for(Element e:list) {
if(e instanceof EnemyTank) {
//如果是敌方坦克,就随机移动
((EnemyTank)e).move(); //如果是敌方坦克,就调用其发射子弹的能力
Bullet shot=((EnemyTank)e).shot();
if(shot!=null) {
addElement(shot);
}
}
} //销毁出界子弹
for(Element e:list) {
//如果是子弹
if(e instanceof Bullet) {
//判断子弹是否出界
boolean flag=((Bullet)e).isDestoryable();
if(flag) {
list.remove(e);
}
}
} //销毁所有需要销毁的实物
for(Element e:list) {
//判断事物是否需要销毁
if( e instanceof Destoryable) {
boolean blast=((Destoryable)e).isDestoryable();
if(blast) {
//说明事物需要销毁
//1.绘制销毁时的爆炸物
Blast blast2=((Destoryable)e).showDestory();
if(blast2!=null) {
addElement(blast2);
} //消除该事物
list.remove(e);
}
}
} /*
* 校验:运动物体 与 障碍物 的碰撞
*/
for(Element e1:list) {
for(Element e2:list) {
if(e1!=e2&&e1 instanceof Moveable&&e2 instanceof Blockable) {
//说明 e1运动物 与 e2 障碍物
boolean flag=((Moveable)e1).checkHit((Blockable)e2);
if(flag) { //说明碰撞了
break;
}
}
}
} /*
* 攻击者 与 被攻击者 是否碰撞
*/
for(Element e1: list) {
for(Element e2: list) {
if(e1 instanceof Attackable&&e2 instanceof Hitable) {
//说明 e1 攻击者 e2 被攻击者
boolean flag=((Attackable)e1).checkAttack((Hitable)e2);
if(flag) {
//校验:是己方坦克发过来的子弹,是则不能攻击,否则能产生攻击
if(((Bullet)e1).getTank().getClass()==e2.getClass()) {
continue;
} //校验:能不能攻击敌军
//子弹销毁
list.remove(e1);
//被攻击者受到攻击,绘制出爆炸物
Blast blast=((Hitable)e2).showAttack();
addElement(blast);
}
}
}
} } /*
* 添加元素
*/
public void addElement(Element e) {
list.add(e); //对集合按照渲染级别进行排序
list.sort(new Comparator<Element>() { @Override
public int compare(Element o1, Element o2) {
// TODO Auto-generated method stub
return o1.getOrder()-o2.getOrder();
}
});
} }


(java项目)坦克大战 2.0的更多相关文章

  1. Java小项目--坦克大战(version1.0)

    Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...

  2. Java实例-坦克大战

    Java实例-坦克大战 一.样例图片 二.类图结构 坦克大战中的所有类 类的关系图 我的坦克类 三.说明 1.每一个新的独立运行的东西就是一个线程,像我方坦克,像敌方坦克,像所有的子弹 2.每一个线程 ...

  3. 【java版坦克大战---准备篇】 java 绘图

    要写坦克大战当然要先画出坦克.java画图是基础. package com.game; import java.awt.*; import javax.swing.*; public class Pr ...

  4. 例子:web版坦克大战1.0

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Unity项目 - 坦克大战3D TankBattle

    目录 游戏原型 项目演示 绘图资源 代码实现 技术探讨 参考来源 游戏原型 游戏玩法:在有界的战场上,玩家将驾驶坦克,代表绿色阵营,与你的队友一起击溃红蓝阵营的敌人,在这场三方大战中夺得胜利! 操作指 ...

  6. java的坦克大战

    一个渣渣写坦克大战的步骤: 1.首先创造好一个坦克和一个GAME框架,并且坦克能够跟着键盘键位移动 案例:在我的博客文件中保存,它的名字是:tankwar0100.rar 主要解决了:1.坦克背景框 ...

  7. 【 java版坦克大战--事件处理】 坦克动起来了

    折腾了这么久,坦克总算能动了.只贴代码编辑不给上首页,花了半个小时的时间写了n多注释. 再顺便把绘图的原理发在这里: 绘图原理 Component类提供了两个和绘图有关的重要方法: ①   paint ...

  8. 【 java版坦克大战--绘图技术】 绘制坦克

    通过上一节,我们学会的用java绘图.那现在就用java绘制自己坦克. 首先通过分析坦克由这几部分组成.如图 各个部件的长宽如图.15,10为圆心. /** * 坦克游戏的1.0版 * 1.画出坦克 ...

  9. 【 java版坦克大战--事件处理】 键盘控制小球上下左右移动

    上一节已经学习了事件处理,这一节需要完成通过键盘的上下左右键控制小球移动. 然后再通过应用到我们绘制的坦克上. /** * 加深对事件处理机制的理解 * 通过光标的上下左右键,控制小球的左右上下移动. ...

随机推荐

  1. 【转】Git 教程之协同开发

    前面我们已经介绍过远程仓库的相关概念,不过那时并没有深入探讨,只是讲解了如何创建远程仓库以及推送最新工作成果到远程仓库,实际上远程仓库对于团队协同开发很重要,不仅仅是团队协同开发的基础,也是代码备份的 ...

  2. java Spring 各版本jar包下载地址

    http://repo.spring.io/simple/libs-release-local/org/springframework/

  3. 【RabbitMQ】3、win7下安装RabbitMQ

    RabbitMQ依赖erlang,所以先安装erlang,然后再安装RabbitMQ; erlang,下载地址:http://www.erlang.org/download RabbitMQ,下载地址 ...

  4. Why in the code “456”+1, output is “56”

    Question: #include <iostream> int main() { std::cout << "25"+1; return 0; } I ...

  5. 微信小程序实现验证码倒计时效果

    效果图 wxml <input class='input-pwd' placeholder="新密码" placeholder-style='color: #000' pas ...

  6. Rxjava学习(二操作符)

    操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件 1.filter filter()操作符是可 ...

  7. (网页)web性能优化(转)

    转自CSDN: Web性能优化分为服务器端和浏览器端两个方面. 一.浏览器端,关于浏览器端优化,分很多个方面1.压缩源码和图片JavaScript文件源代码可以采用混淆压缩的方式,CSS文件源代码进行 ...

  8. JAVA学习笔记:注释、变量的声明和定义、

    本文内容: 注释 变量的声明和定义 成员变量和局部变量 首发时间:2018-03-16 15:59 注释: 单行注释:// 多行注释:/* - */ 变量: 变量是内存中的一个存储区域,变量的定义就是 ...

  9. python自动化报告的输出

    1.设计简单的用例 2.设计用例 以TestBaiduLinks.py命名 # coding:utf-8 from selenium import webdriver import unittest ...

  10. MHA官方文档翻译

    英文官方文档 http://code.google.com/p/mysql-master-ha/wiki/TableOfContents?tm=6 转载请注明出处 Overview MHA能够在较短的 ...