package _25增加配置文件;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
/**
* 这是这款游戏的主窗口,各个类都有他的引用
* @author ☆东★
*
*/
public class TankClient extends Frame{
private Image offScreamImage = null;
public static int WIDTH,HEIGHT;
public int times = 0;//用来表示发了几发炮弹
public List myBullets = new ArrayList();//代表还有几发炮弹
public List explodes = new ArrayList();
public List enemyTank = new ArrayList();
public Tank myTank = new Tank(50,500,true,Direction.STOP,this);//把TankClient对象传进去,使Tank可以操作TankClient里面的部分数据
public int width = Toolkit.getDefaultToolkit().getScreenSize().width;
public int height = Toolkit.getDefaultToolkit().getScreenSize().height;
public Wall wall1 = new Wall(100,100,20,200,this);
public Wall wall2 = new Wall(300,450,70,70,this);
public Blood b = new Blood(this);
private boolean GAME_OVER = false;
/**
* 这个方法时画出图形的主要方法,其他类实现的图形,最终都要放到这个方法中
*/
public void paint(Graphics g) {
wall1.draw(g);
wall2.draw(g);
b.draw(g);
myTank.drawTank(g);
myTank.eat(b);
/**
* 当敌人没有了,就再生成一些敌人
*/
if(enemyTank.size()==0){
int reinitTank = Integer.parseInt(GetProp.getProp("reTankCount"));
for(int i = 0;i=30){
g.drawString("还有多少发炮弹:"+0, 10, 50);
g.setColor(Color.red);
g.drawString("没炮弹了(充钱)", 20, 75);
}
else{
g.drawString("还有多少发炮弹:"+(30-times), 10, 50);
g.drawString("敌方坦克:"+enemyTank.size(), 10, 70);
}
/**
* 画子弹,当子弹没有了,就不能画子弹了
*/
if(myBullets.size()!=0)
for(int i=0;i
package _25增加配置文件;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
* 画坦克的主要类
* @author ☆东★
*
*/
public class Tank {
private int x,y;// x y 代表了tank现在的位置
private int oldX,oldY;//记录坦克上一步的位置
// private static final int WIDTH = 30,HEIGHT = 30;//坦克大小
private static final int WIDTH = 50,HEIGHT = 50;//坦克大小
private static final int XSPEED = 5,YSPEED = 5;//坦克xy方向运动速度
public int GAME_LEVEL = 14;//默认游戏难度为12 越高越简单,最高17 最低3
//想让Tank向8个方向走
private boolean bL = false ,bU = false ,bR = false ,bD = false;//用于记录 键盘按下的 上下左右 (按下之后就设置为True)
private Direction dir = Direction.STOP;//坦克的最开始的方向
private Direction ptDir = Direction.D;//炮筒最开始的方向
private TankClient tc = null;
private boolean good ;
private boolean live = true;
private static Random rand = new Random();
private int step = rand.nextInt(15)+3;//设置随机朝一个方向移动的步数,不然老是在同一个地方乱动
private int life = 100;//给我方坦克设置血量
private BloodBar bb = new BloodBar();
/**
* 增加图片
*/
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Map imags = new HashMap();
private static Image[] tankImage = null;
static {
tankImage = new Image[]{
tk.getImage(Explode.class.getClassLoader().getResource("images/tankL.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankLU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankRD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankR.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankRU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankLD.gif"))
};
imags.put("L", tankImage[0]);
imags.put("LU", tankImage[1]);
imags.put("U", tankImage[2]);
imags.put("RD", tankImage[3]);
imags.put("R", tankImage[4]);
imags.put("RU", tankImage[5]);
imags.put("D", tankImage[6]);
imags.put("LD", tankImage[7]);
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public void setGood(boolean good) {
this.good = good;
}
public boolean isGood() {
return good;
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public Tank(int x,int y,boolean good,Direction dir,TankClient tc){//获取TankClient的引用,让Tank可以调用TankClient里面的数据,因为子弹的方向是由Tank决定的,而TankClient要获取Bullets方向
this.x = x;
this.y = y;
this.good = good;
this.dir = dir;
this.tc = tc;
}
public void drawTank(Graphics g){//坦克自己画自己
if(!live){
tc.enemyTank.remove(this);
return;
}
if(good){
bb.draw(g);
}
ptDraw(g);//画炮筒
move();
}
/**
* 用于判断 tank 往哪个方向走 用枚举里面的数 来判断是往哪个方向走的 从此 x y 的改变就从move这个方法里面改变(原来是从KeyAdapter 里面改变的)
*/
private void move(){
oldX = x;//记录上一步的位置
oldY = y;
switch(dir){//dir决定最终坦克的方向
case L :
x-=XSPEED; break;
case LU :
x-=XSPEED; y-=YSPEED; break;
case U :
y-=XSPEED; break;
case RD :
x+=XSPEED; y+=YSPEED; break;
case R :
x+=XSPEED; break;
case RU :
x+=XSPEED; y-=YSPEED; break;
case D :
y+=YSPEED; break;
case LD :
x-=XSPEED; y+=YSPEED; break;
case STOP : break;
}
/**
* 判断是否出界
*/
if(x<=5)
x = 5;
if(y<=30)
y = 30;
if(x>=TankClient.WIDTH-Tank.WIDTH-5)
x = TankClient.WIDTH-Tank.WIDTH-5;
if(y>=TankClient.HEIGHT-Tank.HEIGHT-5)
y=TankClient.HEIGHT-Tank.HEIGHT-5;
/**
* 给炮筒一个方向
*/
if(this.dir != Direction.STOP)//如果地方坦克 坦克方向不为Stop,,那么改变炮筒方向(与坦克方向一样)
ptDir = dir;
/**
* 让炮筒发射子弹
*/
if(!good){//如果是敌方坦克
if(step == 0){
Direction[] arr = Direction.values();// 把enum转化为数组
int r = rand.nextInt(arr.length);//从0到arr的最大长度
dir = arr[r];
step = rand.nextInt(15)+3;//生成0---14之间的数
//给敌方tank增加炮弹。。不能太密集
if(step>=GAME_LEVEL) fire();
}
step--;
}
}
/**
* 画出炮筒
* @param g
*/
private void ptDraw(Graphics g){
switch(ptDir){
case L :
g.drawImage(imags.get("L"),x, y, null); break;
case LU :
g.drawImage(imags.get("LU"),x, y, null); break;
case U :
g.drawImage(imags.get("U"),x, y, null); break;
case RD :
g.drawImage(imags.get("RD"),x, y, null); break;
case R :
g.drawImage(imags.get("R"),x, y, null); break;
case RU :
g.drawImage(imags.get("RU"),x, y, null); break;
case D :
g.drawImage(imags.get("D"),x, y, null); break;
case LD :
g.drawImage(imags.get("LD"),x, y, null); break;
case STOP :
g.drawImage(imags.get("STOP"),x, y, null); break;
}
}
/**
* Tank真正走的方向 L, LU, U, RD, R, RU, D, LD, STOP 取决于dir的值
*/
private void realDirection(){
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.RD;
else if(!bL && !bU && bR && !bD)
dir = Direction.R;
else if(!bL && bU && bR && !bD)
dir = Direction.RU;
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;
}
/**
* Tank发射子弹 给子弹一个信号,,让子弹往自己指定的方向发子弹
*/
private void fire(){
if(good)
tc.times++;//每次 发子弹的时候,设置一个计数器
int x = this.x + Tank.WIDTH/2 - Bullets.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Bullets.HEIGHT/2;
Bullets b = new Bullets(x,y,ptDir,good,tc);
if(!good)//地方塔克可以一直创建子弹
tc.myBullets.add(b);
else if(tc.times<30 && live){//如果是我方坦克,发子弹次数少于20次,而且坦克活着,那么就装一发炮弹
tc.myBullets.add(b);
}//这样做保证了,当自己的子弹用完了,敌方还可以发炮弹
}
/**
* 超级炮筒
*/
private void superFire(){
Direction[] arr = dir.values();//转化为数组
for(int i = 0;i<8;i++){
fire(arr[i]);
}
tc.times += 4;//相当于给散弹多一点子弹 发一发相当于以前发4发
}
/**
* 发射超级炮弹
* @param dir 不受炮筒方向控制的炮弹
*/
private void fire(Direction dir){
int x = this.x + Tank.WIDTH/2 - Bullets.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Bullets.HEIGHT/2;
Bullets b = new Bullets(x,y,dir,good,tc);
if(tc.times<30 && live){//如果是我方坦克,发子弹次数少于80次
tc.myBullets.add(b);
}
}
/**
* 判断两个矩形是否相碰的方法
* @return 返回值在判断是否相碰会用到
*/
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
}
/**
* 判断是否撞墙
* @param w 墙
*/
public void hitWall(Wall w){
if(live && this.getRect().intersects(w.getRect())){
x = oldX;
y = oldY;
}
}
public void hitTank(java.util.List tanks){
for(int i = 0;i
package _25增加配置文件;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
/**
* 爆炸类
* @author ☆东★
*
*/
public class Explode {//爆炸
private int x , y;
private boolean live = true;
private int step = 0;//画到第几步了
private TankClient tc;
private static boolean init;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] image = {
tk.getImage(Explode.class.getClassLoader().getResource("images/0.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/1.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/2.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/4.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/6.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/7.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/8.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/9.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/10.gif"))
};
Explode(int x,int y,TankClient tc){
this.x = x;
this.y = y;
this.tc = tc;
}
public void draw(Graphics g){
if(!init){
for (int i = 0; i< image.length; i++) {//会发现第一次打敌人,不会出现爆炸。可能是系统第一次 加载图片的时候不会放到内存中
g.drawImage(image[i], 100, 100, null);
}
init = true;
}
if(!live){
tc.explodes.remove(this);//当爆炸不存在了,就从TankClient的爆炸集合中移除当前爆炸
return ;
}
if(step==11){
this.live = false;
this.step = 0;
return ;
}
g.drawImage(image[step++], x, y, null);
}
}
package _25增加配置文件;
/**
* 方向的枚举
* @author ☆东★
*
*/
public enum Direction {
L, LU, U, RD, R, RU, D, LD, STOP//用来表示Tank是朝 哪个方法走的 以后这个枚举就来代表坦克的走向
}
package _25增加配置文件;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 子弹类
* @author ☆东★
*
*/
public class Bullets {//子弹类
private int x,y;//坦克的位置,也是子弹的位置
private boolean live = true;
public static final int WIDTH = 10, HEIGHT = 10;//子弹大小
private static final int XSPEED = 10,YSPEED = 10;//子弹速度
private TankClient tc;
private boolean good;//用于标识子弹是哪一方的子弹
Direction dir;
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Map imags = new HashMap();
private static Image[] tankImage = null;
static {
tankImage = new Image[]{//L, LU, U, RD, R, RU, D, LD, STOP
tk.getImage(Explode.class.getClassLoader().getResource("images/missileL.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileLU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileRD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileR.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileRU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileLD.gif"))
};
imags.put("L", tankImage[0]);
imags.put("LU", tankImage[1]);
imags.put("U", tankImage[2]);
imags.put("RD", tankImage[3]);
imags.put("R", tankImage[4]);
imags.put("RU", tankImage[5]);
imags.put("D", tankImage[6]);
imags.put("LD", tankImage[7]);
}
public Bullets(int x,int y,Direction dir,boolean good,TankClient tc){
this.x = x;
this.y = y;
this.dir = dir;
this.good = good;
this.tc = tc;
}
public void draw(Graphics g){
if(!live){
tc.myBullets.remove(this);//用于删除子弹。不然这一发子弹打中敌人,另一个敌人来到这个地方也会死
return;
}
if(good){
Color c = g.getColor();
g.setColor(Color.black);
g.fillOval( x, y, WIDTH, HEIGHT);
g.setColor(c);
}
switch(dir){
case L :
g.drawImage(imags.get("L"),x, y, null); break;
case LU :
g.drawImage(imags.get("LU"),x, y, null); break;
case U :
g.drawImage(imags.get("U"),x, y, null); break;
case RD :
g.drawImage(imags.get("RD"),x, y, null); break;
case R :
g.drawImage(imags.get("R"),x, y, null); break;
case RU :
g.drawImage(imags.get("RU"),x, y, null); break;
case D :
g.drawImage(imags.get("D"),x, y, null); break;
case LD :
g.drawImage(imags.get("LD"),x, y, null); break;
case STOP :
g.drawImage(imags.get("STOP"),x, y, null); break;
}
move();
}
//子弹自己的移动方向速度
private void move() {
switch(dir){
case L :
x-=XSPEED; break;
case LU :
x-=XSPEED; y-=YSPEED; break;
case U :
y-=XSPEED; break;
case RD :
x+=XSPEED; y+=YSPEED; break;
case R :
x+=XSPEED; break;
case RU :
x+=XSPEED; y-=YSPEED; break;
case D :
y+=YSPEED; break;
case LD :
x-=XSPEED; y+=YSPEED; break;
}
if(x<0 || y<0 || x>TankClient.WIDTH || y>TankClient.HEIGHT){//子弹超出边界 就让他在子弹集合中删除
live = false;
}
}
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
}
//下面就是判断 坦克是否被击中,一级击中后会发生的事,一个函数可以解决,第一个函数里面就是循环,可以把它放在第二个函数里(只是不容易看而已)
public void hitTanks(List tanks){
for(int i=0;i
package _25增加配置文件;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
/**
* 血量类
* @author ☆东★
*
*/
public class Blood {
private int x ,y , w ,h;
private TankClient tc;
private boolean live = true;
private Random rand = new Random();
Blood(TankClient tc){
this.tc = tc;
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public void draw(Graphics g){
if(!live) return ;
x = rand.nextInt(tc.WIDTH/50)+600;
y = rand.nextInt(tc.HEIGHT/50)+150;
Color c = g.getColor();
g.setColor(Color.green);
g.fillRect(x, y, 20, 20);
g.setColor(c);
}
public Rectangle getRect(){
return new Rectangle(x, y, 20, 20);
}
}
package _25增加配置文件;
import java.awt.Graphics;
import java.awt.Rectangle;
/**
* 墙类
* @author ☆东★
*
*/
public class Wall {
private int x,y,w,h;
private TankClient tc;
public Wall(int x, int y, int w, int h, TankClient tc) {
super();
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.tc = tc;
}
public void draw(Graphics g){
g.fillRect(x, y, w, h);
}
public Rectangle getRect(){
return new Rectangle(x,y,w,h);
}
}
package _25增加配置文件;
import java.io.IOException;
import java.util.Properties;
/**
* 使用配置文件,,采用了单例设计模式
* @author ☆东★
*
*/
public class GetProp {
private static Properties prop = new Properties();
static{
try {
prop.load(GetProp.class.getClassLoader().getResourceAsStream("config/tank.properties"));
} catch (IOException e1) {
e1.printStackTrace();
}
}
private GetProp(){}
public static String getProp(String key){
return prop.getProperty(key);
}
}
initTankCount=15
reTankCount=10