用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

云代码会员    -  云代码空间

——

坦克大战

2017-11-11|890阅||

摘要:package mzxmzx; import java.awt.*; import java.awt.event.*; import java.util.Random; public class Tank { /** * 坦克的移动速度 */ public s

package mzxmzx;


import java.awt.*;
import java.awt.event.*;
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;//坦克的高度定义为常量
	
	private boolean live = true;//返回布尔类型,判断坦克的生死
	private int life = 100;
	private BloodBar bb = new BloodBar();//BloodBar一个bb出来
	public int getLife() {
		return life;
	}

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

	TankClient tc;
	
	private boolean good;//定义一个布尔变量,判断敌我坦克
	
	public boolean isGood() {
		return good;
	}

	private int x, y;
	private int oldX,oldY;
	private void stay(){//坦克撞到墙之后定义为stay
		x = oldX;
		y = oldY;
	}
	
	private static Random r = new Random();
	
	private boolean bL=false, bU=false, bR=false, bD = false;//用4个布尔类型的值代表是不是按下了4个键,当按下某个键时由FALSE变成true
	enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};//枚举
	
	private int step = r.nextInt(12) + 3; //最小值至少移动3步,最大值移动到14步
	private Direction dir = Direction.STOP;//给默认值为STOP
	private Direction ptDir = Direction.D;//炮筒的方向(向下的方向)

	public Tank(int x, int y, boolean good) {
		this.x = x;
		this.y = y;
		this.oldX = x;
		this.oldY = y;
		this.good = good;
	}
	
	public Tank(int x, int y, boolean good,Direction dir, TankClient tc) {
		this(x, y, good);
		this.dir = dir;
		this.tc = tc;
	}
	
	public void draw(Graphics g) {
		if(!live){
			if(!good){
				tc.tanks.remove(this);
			}return;
		} 
		
		Color c = g.getColor();//设置前景色
		if(good) g.setColor(Color.RED);//我们的坦克颜色设置
		else g.setColor(Color.BLUE);//敌方坦克设置
		g.fillOval(x, y, WIDTH, HEIGHT);//画一个实心圆(50,50为坐标,30,,30是圆的高度和宽度)
		g.setColor(c);;//把原来颜色设置回来
		if(good)bb.draw(g); //把我的坦克的血条画出来
		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();
	}
	
	void move() {
		this.oldX=x;
		this.oldY=y;//move之前记录上一步坦克x,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 < 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;
	    if(!good){
	    	 Direction[] dirs = Direction.values();   //将方向转化为数组
	    	 if(step == 0){      //只有STEP等于0时,才转方向
	    		 step = r.nextInt(12)  + 3;
	    		 int rn = r.nextInt(dirs.length);//move完成后,如果是敌军坦克的,随机产生一个数,来设定坦克下一个方向
	    	     dir = dirs[rn];     
	    	 }
	    	step --;
	    	if(r.nextInt(50)>48)this.fire();//防止敌军炮火太猛烈,生成大于48的随机数时才开火
	    }
	    
	}
	
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();//定义一个key,(获得按键的虚拟码)
		switch(key) {
		 /* case KeyEvent.VK_CONTROL:
	       // tc.missiles.add(fire());//一种调用方法:调用fire方法,返回值是一发炮弹
	        	fire();
	         break;*/       // 在KeyPressed中子弹太密集,将其设置为抬起发炮弹(released)
		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;
		case KeyEvent.VK_F2:
			if(!this.live){
				this.live = true;//复活
				this.life = 100;//100血
			}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 void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();//定义一个key,(获得按键的虚拟码)
		switch(key) {
		case KeyEvent.VK_CONTROL:
			fire();
			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;
		case KeyEvent.VK_A:
			superFire();
			break;
		}
		locateDirection();		
	}
	
	public Missile fire() {//fire方法返回值Missile
		if(!live) return null;//解决自己坦克被击杀后,仍然可以操作的问题
		int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;//计算x,y的位置
		int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
		Missile m = new Missile(x, y,good, ptDir, this.tc);//坦克的x,y
		tc.missiles.add(m);
		return m;
	}
	public Missile fire(Direction dir){//超级炮弹的fire方法
		if(!live) return null;//解决自己坦克被击杀后,仍然可以操作的问题
		int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;//计算x,y的位置
		int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
		Missile m = new Missile(x, y,good, dir, this.tc);//坦克的x,y
		tc.missiles.add(m);
		return m;
		
	}
	private void superFire() {//超级炮弹!!
		Direction[] dirs = Direction.values();
		for(int i=0; i<8; i++) {
			fire(dirs[i]);
		}
	}
	
	public Rectangle getRect() {//矩形,子弹左上角位置,宽度高度
		return new Rectangle(x, y, WIDTH, HEIGHT);
	}

	public boolean isLive() {
		return live;
	}

	public void setLive(boolean live) {
		this.live = live;
	}
	/**
	 *  为了解决坦克穿过墙这一问题
	 * @param w  坦克撞击的墙
	 * @return   坦克一旦撞上了枪,返回true,否则返回false
	 */
	public boolean collidesWithWall(Wall w) {//解决坦克穿过墙这一问题
		if(this.live && this.getRect().intersects(w.getRect())) {
			this.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;
	}
	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);
			g.setColor(c);
		}
	}
	public boolean eat(Blood b) {//吃掉血块
		if(this.live && b.isLive() && this.getRect().intersects(b.getRect())) {
			this.life = 100;//吃掉血块血量恢复至100
			b.setLive(false);//
			return true;
		}
		return false;
	}
}

顶 0踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: 云代码会员
    • 等级: 初级程序员
    • 积分: 22
    • 代码: 1 个
    • 文章: 2 篇
    • 随想: 0 条
    • 访问: 4 次
    • 关注

    人气文章

    人气代码

    标签

    最新提问

      站长推荐