Java自学之路

java基础之坦克大战极简版
分析:
Class Tank:实现功能——区分敌方坦克和我方坦克,按键上下左右控制我方坦克朝八个方向移动,敌方坦克随机移动,按键A发射子弹,按键Q朝八个方向开火,按键F2复活;
首先控制移动:`

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.Random;

public class Tank {
int x,y;
private boolean bl =false,bu = false, br = false, bd = false;
enum Direction{L,LU,U,UR,R,RD,D,LD,STOP};
private Direction dir = Direction.STOP;
private Direction ptdir = Direction.D;
private static final int XSPEED = 5;
private static final int YSPEED = 5;
private static final int WIDTH = 30;
private static final int HIGHT = 30;
private static final int FULLBLOOD = 100;
TankClient tc;
private boolean good ;
Blood b = new Blood();
private int oldX,oldY;
private int life = 100;
public int getLife() {
return life;
}

public void setLife(int life) {
	this.life = life;
}


public boolean isGood() {
	return good;
}


public void setGood(boolean good) {
	this.good = good;
}
private int step = r.nextInt(12)+3;
private boolean live= true;
private static Random r = new Random();
public boolean isLive() {
	return live;
}
public void setLive(boolean live) {
	this.live = live;
}
public  Tank(int x, int y) {
	this.x = x;
	this.y = y;
}

public void draw(Graphics g) {
	if(!live) {
		if(good)
		return;
		tc.robots.remove(this);
	}
	Color c = g.getColor();
	 if(good) g.setColor(Color.red);
	 else g.setColor(Color.blue);
	g.fillOval(x, y, WIDTH, HIGHT);
	g.setColor(c);
	if(good) b.draw(g);
	switch(ptdir) {
	case L:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x, y+HIGHT/2);
		break;
	case LU:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x, y);
		break;
	case U:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x+WIDTH/2, y);
		break;
	case UR:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x+WIDTH, y);
		break;
	case R:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x+WIDTH, y+HIGHT/2);
		break;
	case RD:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x+WIDTH, y+HIGHT);
		break;
	case D:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x+WIDTH/2, y+HIGHT);
		break;
	case LD:
		g.drawLine(x+WIDTH/2, y+HIGHT/2, x, y+HIGHT);
		break;
	}
	move();
}

void move() {
	
	this.oldX = x;
	this.oldY = y;
	
	switch(dir) {
	case L:
		x -=XSPEED;
		break;
	case LU:
		x -=XSPEED;
		y -=YSPEED;
		break;
	case U:
		y -=YSPEED;
		break;
	case UR:
		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(x >TankClient.GAME_WIDTH - this.WIDTH) {
		x = TankClient.GAME_WIDTH-this.WIDTH;
	}
	if(y<this.WIDTH) {
		y=this.WIDTH;
	}
	if(y >TankClient.GAME_HEIGHT - this.HIGHT) {
		y = TankClient.GAME_HEIGHT-this.HIGHT;
	}
	if(!good) {
		Direction[] dirs = Direction.values();
		if(step == 0) {
			step = r.nextInt(12)+3;
			int rn = r.nextInt(dirs.length);
			dir = dirs[rn];
		}
		step --;
		if(r.nextInt(40)>38)this.fire();
	}
}

public void stay() {
	x = this.oldX;
	y = this.oldY;
}

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.UR;
	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 void keyPressed(KeyEvent e) {
	int key = e.getKeyCode();
			switch(key) {
			case KeyEvent.VK_F2:
				if(!this.isLive()) {
					this.setLive(true);
					this.setLife(FULLBLOOD);
				}
			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_A:
		fire();
		break;
	case KeyEvent.VK_Q:
		superFire();
		break;
	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();
}

public Shot fire() {
	if(!live)return null;
	int x= this.x + Tank.WIDTH/2 -Shot.WIDTH/2;
	int y= this.y + Tank.HIGHT/2 -Shot.HIGHT/2;
	Shot s = new Shot(ptdir,x,y,this.tc,good);
	tc.shots.add(s);
	return s;
}

public Shot fire(Direction dir) {
	if(!live)return null;
	int x= this.x + Tank.WIDTH/2 -Shot.WIDTH/2;
	int y= this.y + Tank.HIGHT/2 -Shot.HIGHT/2;
	Shot s = new Shot(dir,x,y,this.tc,good);
	tc.shots.add(s);
	return s;
}
public void  superFire() {
	for(int i=0;i<8;i++) {
		Direction[] dirs = Direction.values();
		fire(dirs[i]);
	}
}

public boolean hitWall(Wall w) {
	if(this.getRect().intersects(w.getRect())) {
		stay();
		return true;
	}
	return false;
}

public boolean collidesWithTanks(java.util.List<Tank> tanks) {
	for(int i=0;i<tanks.size();i++) {
		Tank t = tanks.get(i);
		if(this != t) {
			if(this.live && t.isLive() && this.getRect().intersects(t.getRect())) {
				this.stay();
				t.stay();
				return true;
			}
		}
	}
	return false;
}

public Tank(int x, int y, TankClient tc) {
	this(x,y);
	this.tc = tc;
}


public Tank(int x, int y,TankClient tc, boolean good) {
	this(x,y,tc);
	this.good = good;
}

public Rectangle getRect() {
	return new Rectangle(x,y,WIDTH,HIGHT);
}

public Tank(int x, int y,TankClient tc, boolean good,Direction dir) {
	this(x,y,tc,good);
	this.dir = dir;
}

private class Blood{
	public void draw(Graphics g) {
		Color c = g.getColor();
		g.drawRect(x, y-10, WIDTH, 10);
		int w = WIDTH*life/100;
		g.fillRect(x, y-10, w,10);
		g.setColor(c);
	}
}

public boolean eat(AddBlood ab) {
	if(this.live && ab.isLive() && this.getRect().intersects(ab.getRect())) {
		this.life = FULLBLOOD;
		ab.setLive(false);
		return true;
	}
	return false;
}

}
Class Shot:实现功能——攻击坦克,区分敌方子弹与我方子弹,子弹不能穿墙;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;



public class Shot {
	private static final int XSPEED=10;
	private static final int YSPEED=10;
	public static final int WIDTH = 10; 
	public static final int HIGHT = 10; 
	Tank.Direction dir;
	public boolean live =true;
	private boolean good;

	int x,y;
	private TankClient tc;
	public Shot(Tank.Direction dir, int x, int y) {
		this.dir = dir;
		this.x = x;
		this.y = y;
	}
	
	public Shot(Tank.Direction dir, int x, int y,TankClient tc,boolean good) {
		this(dir,x,y);
		this.tc = tc;
		this.good = good;
	}
	public boolean isLive() {
		return live;
	}
	public void draw(Graphics g) {
		if(!live) {
			tc.shots.remove(this);
		}
		Color c = g.getColor();
		if(good)
		g.setColor(Color.RED);
		else g.setColor(Color.BLACK);
		g.fillOval(x, y, WIDTH, HIGHT);
		g.setColor(c);
		move();
	}

	private void move() {
		// TODO Auto-generated method stub
		switch(dir) {
		case L:
			x -=XSPEED;
			break;
		case LU:
			x -=XSPEED;
			y -=YSPEED;
			break;
		case U:
			y -=YSPEED;
			break;
		case UR:
			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>TankClient.GAME_WIDTH || y>TankClient.GAME_HEIGHT) {
			live = false;
		}
		
		}
	
	public boolean hitTank(Tank t) {
		if(this.getRect().intersects(t.getRect()) && t.isLive() && this.good!=t.isGood()) {
			if(t.isGood()) {
				t.setLife(t.getLife()-20);
				if(t.getLife() <=0) {
					t.setLive(false);
				}
			}else t.setLive(false);
			this.live=false;
			Boom b = new Boom(x,y,tc);
			tc.booms.add(b);
			return true;
		}
		return false;
	}
	
	public boolean hitTanks(List<Tank> tanks) {
		for(int i=0;i<tanks.size();i++) {
			if(hitTank(tanks.get(i))) 
				return true;
		}
		return false;
	}
	
	public boolean hitWall(Wall w) {
		if(this.live && this.getRect().intersects(w.getRect())) {
			live = false;
			return true;
		}
		return false;
	}
	
	public Rectangle getRect() {
		return new Rectangle(x,y,WIDTH,HIGHT);
	}
}

Class Boom:实现功能——子弹击中坦克时产生爆炸;

import java.awt.Color;
import java.awt.Graphics;

public class Boom {
	private int x,y;
	private int []diameter = {4,8,15,20,25,30,40,50,35,24,16,6};
	private boolean live = true;
	private TankClient tc;
	private int step;
	public Boom(int x, int y,TankClient tc) {
		this.x = x;
		this.y = y;
		this.tc = tc;
	}
	
	public void draw(Graphics g) {
		if(!live) tc.booms.remove(this);
		if(step == diameter.length) {
			live = false;
			step=0;
		}
		Color c = g.getColor();
		g.setColor(Color.ORANGE);
		g.fillOval(x,y, diameter[step], diameter[step]);
		step++;
		g.setColor(c);
	}
}

Class Wall:实现功能——子弹和坦克都不能穿墙;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

public class Wall {
	int x,y,width,height;
	TankClient tc;
	
	public void draw(Graphics g) {
		Color c = g.getColor();
		g.setColor(Color.gray);
		g.fillRect(x, y, width, height);
		g.setColor(c);
	}
	
	public Rectangle getRect() {
		return new Rectangle(x,y,width,height);
	}

	public Wall(int x, int y, int width, int height, TankClient tc) {
		super();
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.tc = tc;
	}
}

Class AddBlood:实现功能——当坦克吃到血块是满血;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;


public class AddBlood {
	int x,y,w,h;
	TankClient 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,450},{410,444},{405,440},{423,312},{323,313},{132,312},{312,433},{312,411},{133,132}
	};
	public AddBlood() {
		x = pos[0][0];
		y = pos[0][1];
		w = h = 20;
	}
	
	public void draw(Graphics g) {
		if(!live) return;
		Color c = g.getColor();
		g.setColor(Color.BLACK);
		g.fillRect(x, y, w, h);
		g.setColor(c);
		
		move();
	}

	private void move() {
		step ++;
		if(step == pos.length)step=0;
		if(live) {
			x = pos[step][0];
			y = pos[step][1];
		}
	}
	
	public Rectangle getRect() {
		return new Rectangle(x,y,w,h);
	}
}

主程序:



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;

import javax.swing.JFrame;


public class TankClient extends Frame {
	Tank myTank = new Tank(50,50,this,true);
	Wall wall1 = new Wall(500,300,10,200,this);
	Wall wall2 = new Wall(200,300,200,20,this);
	AddBlood ab = new AddBlood();
	//Tank robot = new Tank(100,100,this,false);
	//Boom boom = new Boom(80,80,this);
	List<Boom> booms = new ArrayList<Boom>();
	List<Shot> shots = new ArrayList<Shot>();
	List<Tank> robots = new ArrayList<Tank>();
	public static final int GAME_WIDTH =800;
	public static final int GAME_HEIGHT =600;
	Image offScreenImage = null;
	public void lunchJFrame() {
		for(int i=0;i<10;i++) {
			robots.add(new Tank(50+40*(i+1),50,this,false,Tank.Direction.D));
		}
		setLocation(300,100);
		setSize(GAME_WIDTH, GAME_HEIGHT);
		setTitle("TankWar");
		this.setBackground(Color.GREEN);
		//setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		setResizable(false);
		this.addKeyListener(new KeyMonitor());
		setVisible(true);
		new Thread(new RepaintThread()).start();
	}
	public TankClient() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void paint(Graphics g) {
		g.drawString("shouts count:" + shots.size(), 50, 50);
		g.drawString("booms count:" + booms.size(), 50, 70);
		g.drawString("robots count:" + robots.size(), 50, 90);
		g.drawString("maTank  life:" + myTank.getLife(), 50, 110);
		// TODO Auto-generated method stub
		myTank.draw(g);
		myTank.hitWall(wall1);
		myTank.hitWall(wall2);
		myTank.collidesWithTanks(robots);
		wall1.draw(g);
		wall2.draw(g);
		ab.draw(g);
		myTank.eat(ab);
		for(int i=0;i<shots.size();i++) {
			Shot s = shots.get(i);
			 s.draw(g);
			 s.hitTanks(robots);
			 s.hitTank(myTank);
			 s.hitWall(wall1);
			 s.hitWall(wall2);
		}
		for(int i=0;i<booms.size();i++) {
			Boom b = booms.get(i);
			b.draw(g);
		}
		
		for(int i=0;i<robots.size();i++) {
			Tank t = robots.get(i);
			t.draw(g);
			t.hitWall(wall1);
			t.hitWall(wall2);
			t.collidesWithTanks(robots);
		}
		
		if(robots.size()<=0) {
			for(int i=0;i<10;i++) {
				robots.add(new Tank(50+40*(i+1),50,this,false,Tank.Direction.D));
			}
		}
	}
	public void update(Graphics g) {
		if(offScreenImage == null) {
			offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
		}
		Graphics gOffScreen = offScreenImage.getGraphics();
		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);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TankClient tc = new TankClient();
		tc.lunchJFrame();
	}

	private class RepaintThread implements Runnable{

		@Override
		public void run() {
			while(true) {
			repaint();
			
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				}
			}
		}
		
	}
	
	private class KeyMonitor extends KeyAdapter{

		@Override
		public void keyReleased(KeyEvent e) {
			myTank.keyReleased(e);
		}

		@Override
		public void keyPressed(KeyEvent e) {
			myTank.keyPressed(e);
			}
			
			}
		}

运行结果:
Java自学之路
`