马士兵的坦克大战,以前做过,今天又找出来看了看

总结:

事件处理机制一般用Adapter形式

常用Monitor继承Adapter

 

线程每秒都在不停地刷新Runnable接口熟练

 

懒汉式:把main函数写在class里面

 

枚举

enum  color {red,blue,green,write};

color c=red;

 

public static final int定义一些常量,不能实例化,一变全变,不能改变

代码重构
将以后可能需要多处改变的量定义为常量

 

new 一个tank

tank的draw 从paint里面抽取,KeyPressed从KeyMonitor里面抽取

 

把tankClient的引用当做参数传入tank,missile里面去,当一个大管家

 

ArrayList来装载炮弹misssile,定义生命值,死亡就remove

以及超级for循环的使用

 

定义友好量,判断是自己人还是敌人   

 

爆炸这种动画用一个数组来存储,改变脚标,改变值

 

superFire很简单

booldBar也很简单

 

怎么生成压缩格式的jar忘了!!!

怎么生成文档也忘了!!!

 

TankClient.java 

package ytdx.ruanjian;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;


class TankClient extends Frame 
{
	public static  final int GAME_WIDTH=800;
	public static final int GAME_HEIGHT=600;
	
	Tank tank=new Tank(50, 500,true,Tank.Direction.STOP,this);
		
	List<Tank> tanks=new ArrayList<Tank>();
	List<Missile> missiles=new ArrayList<Missile>();//容器来存炮弹
	List<Explode> explodes=new ArrayList<Explode>();
	
	private Wall wall=new Wall(375, 100, this);
	private Blood blood=new Blood();
		
	Image offscreenImage =null;
	
	TankClient ()
	{
		for(int i=0;i<15;i++)
		{
			tanks.add(new Tank(50+40*(i+1), 50, false,Tank.Direction.D,this));
		}
		
		setBounds(10,10,GAME_WIDTH,GAME_HEIGHT);
		setVisible(true);
		setTitle("TankWar");
		setResizable(false);
		setBackground(Color.GREEN);
		this.addKeyListener(new KeyMonitor());
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		new Thread(new paintThread()).start();
	}
	
	public void paint(Graphics g) {
		
		
		tank.draw(g);
//		tank.tankAndwall(wall);
		tank.tankAndblood(blood);
		tank.tankAndtanks(tanks);
		for(Missile m:missiles)
		{
			m.hitTanks(tanks);
			m.hitTank(tank);
			m.hitWall(wall);
			m.draw(g);			
		}
		for(Explode e:explodes)
		{
			e.draw(g);
		}
			
		for(Tank tank:tanks)
		{
			tank.draw(g);
			tank.tankAndwall(wall);
			tank.tankAndtank(this.tank);
			tank.tankAndtanks(tanks);
		}
		wall.draw(g);
		blood.paint(g);
		
		g.drawString("tanks count"+" "+tanks.size(), 10, 50);
		g.drawString("missile count"+" "+missiles.size(), 10, 70);
		g.drawString("explodes count"+" "+explodes.size(), 10, 90);
		g.drawString("tank life"+" "+tank.getLife(), 10, 110);
						
	} 

	public void update(Graphics g) {
		if(offscreenImage==null)
		{
			offscreenImage=this.createImage(GAME_WIDTH,GAME_HEIGHT);
		}
		Graphics gofferScreen=offscreenImage.getGraphics();
		Color c=gofferScreen.getColor();
		gofferScreen.setColor(Color.GREEN);
		gofferScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
		paint(gofferScreen);
		g.drawImage(offscreenImage, 0, 0, null);
	}
	public static void main(String[] args) 
	{
		TankClient client=new TankClient();
	
	}
private class paintThread implements Runnable
{
	public void run() {
		while(true)
		{
			repaint();
			System.out.println("线程不停地重画");
			try {
				Thread.sleep(30);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		
	}
	
}

private class KeyMonitor extends KeyAdapter
{

	public void keyReleased(KeyEvent e) {
		tank.keyReleased(e);
	}

	public void keyPressed(KeyEvent e) {
		tank.keyPressed(e);
		int Key=e.getKeyCode();
		switch(Key)
		{
		case KeyEvent.VK_F1:
			if(tanks.size()==0)
			{
				for(int i=0;i<10;i++)
				{
					tanks.add(new Tank(50+60*(i+1), 50, false,Tank.Direction.D,TankClient.this));//类名。this
				}
			}
		}
		
		}
			
	}
	
}



Tank.java


 

package ytdx.ruanjian;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;


public class Tank {	
	
	public static final int XSPEED=5;
	public static final int YSPEED=5;
	
	public static final int WIDTH = 30;
	public static final int HEIGHT = 30;
	
	public static Random random=new Random();///随机产生器Random
	private int step=random.nextInt(12)+3;
	
	TankClient tc=null;
	
	private int x,y;
	private int Oldx,Oldy;
	private boolean bL=false,bU=false,bR =false,bD=false;
	enum Direction {L,LU,U,RU,R,RD,D,LD,STOP};
	
	private Direction dir=Direction.STOP;
	private Direction ptDir=Direction.D;
	
	private boolean good;
	public boolean isGood() {
		return good;
	}
	public void setGood(boolean good) {
		this.good = good;
	}
	private boolean live=true;
		
	public boolean isLive() {
		return live;
	}
	public void setLive(boolean live) {
		this.live = live;
	}
	
	private int life=100;
	private BloodBar bar=new BloodBar();	
	public int getLife() {
	return life;
	}
	public void setLife(int life) {
	this.life = life;
	}
	public Tank(int x, int y,boolean good,Direction dir) 
	{
		this.x = x;
		this.y = y;
		this.good=good;
		this.dir=dir;
	}
	public Tank(int x, int y,boolean good,Direction dir,TankClient tc) 
	{
		this(x,y,good,dir);
		this.tc=tc;
		
	}
/*
 * 
 */
	public void draw(Graphics g)
	{
		
		if(!live)
			{
			tc.tanks.remove(this);
			return;			
			}
		if(isGood())
			bar.draw(g);
		Color c=g.getColor();
		if(good)
		g.setColor(Color.RED);
		else 
		g.setColor(Color.BLUE);	
		g.fillOval(x, y, WIDTH, HEIGHT);
		g.setColor(c);
		//画炮筒
		g.setColor(Color.BLACK);
		switch(ptDir)
		{
		
		case L:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x, y+Tank.HEIGHT/2);
			break;
		case LU:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x, y);
			break;
		case U:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y);
			break;
		case RU:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH, y);
			break;
		case R:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2,x+Tank.WIDTH, y+Tank.HEIGHT/2);
			break;
		case RD:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2,x+Tank.WIDTH, y+Tank.HEIGHT);
			break;
		case D:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2,x+Tank.WIDTH/2, y+Tank.HEIGHT);
			break;
		case LD:
			g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2,x, y+Tank.HEIGHT);
			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(x < 0) x = 0;
		if(y < 30) y = 30;
		if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
		if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
		
		//每次move后根据Tank新的方向确定炮筒的方向
		if(this.dir!=Direction.STOP)
			this.ptDir=this.dir;
		
		if(!good)
		{
			Direction dirs[]=Direction.values();/方向转化成数组
			if(step==15)
			{
				step=random.nextInt(12)+3;
				int d=random.nextInt(dirs.length);
				dir=dirs[d];
			}
			if(random.nextInt(40)>38)
			this.fire();
			step++;
		}
		
	}
	public void stay()
	{
		x=Oldx;
		y=Oldy;
	}
	
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		switch(key) {
		case KeyEvent.VK_F2:
			if(!this.isLive())
			{
				this.live=true;
				this.life=100;
			}
			break;
		case KeyEvent.VK_CONTROL:
			fire();
			break;
		case KeyEvent.VK_A:
			superFire();
			break;
		case KeyEvent.VK_S:
			powerfulFire();
			break;
		case KeyEvent.VK_LEFT :
			bL = true;
			break;
		case KeyEvent.VK_UP :
			bU = true;
			break;
		case KeyEvent.VK_RIGHT :
			bR = true;
			break;
		case KeyEvent.VK_DOWN :
			bD = true;
			break;
		}
		locateDirection();
	}
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		int key = e.getKeyCode();
		switch(key) {
		
		case KeyEvent.VK_LEFT :
			bL = false;
			break;
		case KeyEvent.VK_UP :
			bU = false;
			break;
		case KeyEvent.VK_RIGHT :
			bR = false;
			break;
		case KeyEvent.VK_DOWN :
			bD = false;
			break;
		}
		
		locateDirection();
		
	}
	
	void locateDirection() {
		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 Missile fire() {
		if(!live)return null;//死了就别发炮弹了》》》》》》》》》》》》
		int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
		int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
		Missile m = new Missile(x, y, ptDir,good,tc);
		tc.missiles.add(m);
		return m;
	}
	public Missile fire(Direction dir) {
		if(!live)return null;//死了就别发炮弹了》》》》》》》》》》》》
		int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
		int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
		Missile m = new Missile(x, y, dir,good,tc);
		tc.missiles.add(m);
		return m;
		
	}
	public Missile powerfulFire() {
		if(!live)return null;//死了就别发炮弹了》》》》》》》》》》》》
		int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
		int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
		for(int i=-1;i<=1;i++)
		{
			if(ptDir==Direction.L||ptDir==Direction.R)
			{
				Missile m = new Missile(x, y+20*i, ptDir,good,tc);
				tc.missiles.add(m);
			}
			else
				{
				Missile m = new Missile(x+20*i, y, ptDir,good,tc);
				tc.missiles.add(m);
				}
		}
		return null;
	}
	public void superFire()
	{
		Direction dir[]=Direction.values();
		for(int i=0;i<8;i++)
		{
			fire(dir[i]);
		}
	}
	
	public Rectangle getRect()
	{
		return new  Rectangle(x, y, WIDTH, HEIGHT);
	}
	
	public boolean tankAndwall(Wall wall)
	{		
		if(this.live&&this.getRect().intersects(wall.getRect()))
			{
				stay();//this.dir=Direction.STOP;粘棉花糖现象//live=false;坦克消失
				return true;
			}
		return false;
	}
	public boolean tankAndtank(Tank tank)
	{	
		if(this!=tank&&this.live&&this.getRect().intersects(tank.getRect()))
			{
				stay();
				return true;
			}
		return false;
	}
	public boolean tankAndtanks(List<Tank> tanks)
	{	
		for(Tank tank:tanks)
		{
			if(this.tankAndtank(tank))
				return true;
		}
		return false;
	}
	public boolean tankAndblood(Blood blood)
	{	
		if(this.live&&blood.isLive()&&this.getRect().intersects(blood.getRect()))
			{
				if(this.good&&this.life<80)
					{
					this.life+=20;
					}
				blood.setLive(false);
					return true;
			}
		return false;
	}
	private class BloodBar
	{
		public void draw(Graphics g)
		{
			Color c=g.getColor();
			g.setColor(Color.PINK);
			g.drawRect(x, y-10, WIDTH, 10);
			g.fillRect(x, y-10, WIDTH*life/100, 10);
			g.setColor(c);
		}
	}
}


Missible.java

package ytdx.ruanjian;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.List;



public class Missile {
	
	public static final int XSPEED=10;
	public static final int YSPEED=10;
	public static final int WIDTH = 10;
	public static final int HEIGHT = 10;
	
	private int x,y;
	Tank.Direction dir;
	
	private TankClient tc;

	private boolean live=true;
	private boolean good;
	
	public boolean isLive() {
		return live;
	}
	
	public Missile(int x, int y,Tank.Direction dir) {
		super();
		this.x = x;
		this.y = y;
		this.dir = dir;
	}
	public Missile(int x, int y, Tank.Direction dir,boolean good, TankClient tc) {
		super();
		this.x = x;
		this.y = y;
		this.dir = dir;
		this.good=good;
		this.tc = tc;
	}
	
	public void draw (Graphics g)
	{
		if(!live)
		{
			tc.missiles.remove(this);
			return;
		}
		Color c =g.getColor();
		g.setColor(Color.BLACK);
		g.fillOval(x, y, WIDTH, HEIGHT );
		g.setColor(c);
		move();
			
	}
	public 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;
		case STOP:
			
			break;
			
		}
		if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT)
				live=false;
			
	}	
	public Rectangle getRect()
	{
		return new  Rectangle(x, y, WIDTH, HEIGHT);
		
	}
	public boolean hitTank(Tank t)
	{
		if(this.live&&this.getRect().intersects(t.getRect())&&t.isLive()&&t.isGood()!=this.good)
			{
				if(t.isGood())
				{
					t.setLife(t.getLife()-20);
					if(t.getLife()<=0)
						t.setLive(false);
				}
				else
					t.setLive(false);
				
				live=false; 
				Explode e=new Explode(x, y, tc);
				tc.explodes.add(e);
				return true;
			}
			
		return false;
	}	
	public boolean hitTanks(List<Tank>tanks)
	{
		for(Tank tank:tanks)
		{
			if(hitTank(tank))
			return true;
		}
		return false;
	}
	public boolean hitWall(Wall wall)
	{
		if(this.live&&this.getRect().intersects(wall.getRect())&&this.good==false)//穿墙啊啊啊啊啊啊啊
			{
				live=false; 
				return true;
			}			
		return false;
	}	
}
							


Explode.java

 

package ytdx.ruanjian;
import java.awt.Color;
import java.awt.Graphics;


public class Explode {
	
	int x,y;
	private boolean live =true;
	private TankClient tc;

	public Explode(int x, int y, TankClient tc) {
		super();
		this.x = x;
		this.y = y;
		this.tc = tc;
	}
	
	int[] diameter ={4,7,12,18,26,32,49,60,230,14,6};
	int step=0;
		
	public void draw (Graphics g)
	{
		
		if(step==diameter.length)
		{
			live =false;
			step=0;
			return;
		}
		if(!live)
		{
			tc.explodes.remove(this);
			return;
		}
		Color c=g.getColor();
		g.setColor(Color.ORANGE);
		g.fillOval(x, y, diameter[step],diameter[step] );
		g.setColor(c);
		step++;
		
	}

}


Wall.java

package ytdx.ruanjian;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;


public class Wall {
	private int WIDTH=50;
	private int HEIGHT=400;
	private int x,y;	
	private TankClient tc=null;
	
	public Wall(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	public Wall(int x, int y, TankClient tc) {
		super();
		this.x = x;
		this.y = y;
		this.tc = tc;
	}
	public void draw(Graphics g)
	{
		Color c=g.getColor();
		g.setColor(Color.ORANGE);
		g.fillRect(x, y, WIDTH, HEIGHT);
		g.setColor(c);
	}
	public Rectangle getRect()
	{
		return new  Rectangle(x, y, WIDTH, HEIGHT);
		
	}

}


Blood.java

package ytdx.ruanjian;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;


public class Blood {
	private int x,y;
	private int width=20;
	private int height=20;
	private int step=0;
	private boolean live=true;
	public boolean isLive() {
		return live;
	}
	public void setLive(boolean live) {
		this.live = live;
	}

	private int a[][]={
			{100,100},
			{100,125},{100,150},{100,175},
			{100,200},
			{125,200},{150,200},{175,200},
			{200,200},
			{200,175},{200,150},{200,125},
			{200,100},
			{175,100},{150,100},{125,100}
			
	};
	
	public Blood() {
		super();
		this.x = a[step][0];
		this.y = a[step][1];
	}
	public void paint(Graphics g)
	{
		if(!live)return;
		Color c=g.getColor();
		g.setColor(Color.MAGENTA);
		g.fillRect(x, y, width, height);
		g.setColor(c);
		move();
	}
	
	private void move() {
		step++;
		if(step==a.length)
		{
			step=0;
		}
		this.x = a[step][0];
		this.y = a[step][1];
	}

	public Rectangle getRect()
	{
		return new  Rectangle(x, y, width, height);
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值