基于JAVA的简易坦克大战(六)

4.2.2 坦克类算法

1、坦克类是坦克大战的重要模块,这里包含了坦克应该有的成员属性(详见逻辑结构设计)。坦克大战管理类的按键监听使用的就是在坦克类中实现的keyPressed方法和KeyReleased方法。

2、在这个类中还包含了坦克的draw方法,方向判断方法以及移动方法(包含敌我双方坦克的相关操作)。

3、坦克类还实现了坦克血条的方法,实现了计算坦克分数和等级的功能,以及发射炮弹,击杀敌方的方法。我方击杀敌方一辆坦克将获得100分。子弹的有效攻击是通过判断子弹的类型和坦克的类型是否一致来实现的,有效的打击必须保证子弹的类型和坦克的类型相反,再通过碰撞检测来确定是否击中目标最终达到击杀的效果。

4、碰撞检测是通过判断两个对象所占的对应方框范围是否重合来实现的。

5、在坦克类的KeyReleased监听方法中实现了游戏的各种模式和功能。它们的实现都是通过修改对应的对象实例的信息来实现的。

6、敌方坦克的简易人工智能是通过随机步数,即让敌方坦克在移动随机的步数之后再随机的切换移动方向,在方向切换的同时打开敌方坦克的攻击开关。即完成敌方坦克的自我随机移动和攻击,达到基本人工智能的要求。

7、超级火力功能是通过连续创建8个不同方向的炮弹来实现的。而炮弹的移动采用的是只要赋予了方向便朝相应的方向移动,从而达到打开“超级火力”攻击按钮的时候,坦克可以朝8个方向同时发射炮弹的效果。

8、坦克类设计源码:
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Tank {

	private static final int Speech = 5;//坦克速度
	private static int Level = 0;//坦克等级
	private static int Score = 0;//坦克分数
    private int x;
    private int y;//坦克坐标
    private int oldX;
    private int oldY;
    private int life = 30;//坦克生命
    private int width = 30;
    private int height = 30;//坦克宽高
    private boolean live = true;//存活与否
	private boolean good;//坦克敌我分别
    private TankClient tc = null;
    private boolean bU = false,bL = false,bR = false,bD = false;
    enum Direction {L,LU,LD,R,RU,RD,U,D,STOP}
    Direction dir = Direction.STOP;//移动方向
    Direction ptDir = Direction.D;//炮筒方向
    //以下成员作为eTank()方法的成员使用
	Random r = new Random();
    private int step = r.nextInt(12) + 3;//移动的步数,移动随即的步数然后改变方向(加3是为了不让随机数为0)
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	public int getLife() {
		return life;
	}
	public void setLife(int life) {
		this.life = life;
	}
	public static void setLevel(int level) {
		Level = level;
	}
	public static void setScore(int score) {
		Score = score;
	}
	public static int getScore() {
		return Score;
	}
	public static int getLevel() {
		return Level;
	}
	public boolean isLive() {
		return live;
	}
	public void setLive(boolean live) {
		this.live = live;
	}
    public void setGood(boolean good) {
		this.good = good;
	}
	public Tank(int x,int y,boolean good,TankClient tc){
		this.x = x;
		this.y = y;
		this.good = good;
		this.tc = tc;
	}
	public void drawTank(Graphics g){
		Color c = g.getColor();
		
		if(this.isGood()){
			g.setColor(Color.RED);
			g.fillOval(x, y, width, height);
		}
		else{
		    g.setColor(Color.BLUE);
	    	g.fillOval(x, y, width, height);
		}
		g.setColor(c);
		drawPT(g);	
		if(isGood())
		{  
			drawBloodBar(g);  
			move();//每画一次调用移动方法一次 
		}
		
	}
	public void drawBloodBar(Graphics g){
		int bHeight = 10;
		Color c = g.getColor();
		g.setColor(Color.orange);
		g.drawRect(x, y - 10, 30, 10);
		g.setColor(Color.RED);
		g.fillRect(x, y - 10, life, bHeight);
		g.setColor(c);
	}
	//炮筒绘制
	public void drawPT(Graphics g){
		Color c = g.getColor();
		g.setColor(Color.WHITE);
		switch(ptDir){
		case L:g.drawLine(getX() + width/2, getY() + height/2, getX() - 5, getY() + height/2);break; 
		case LU:g.drawLine(getX() + width/2, getY() + height/2, getX(), getY());break; 
		case LD:g.drawLine(getX() + width/2, getY() + height/2, getX(), getY() + height);break; 
		case R:g.drawLine(getX() + width/2, getY() + height/2, getX() + width + 5, getY() + height/2);break; 
		case RU:g.drawLine(getX() + width/2, getY() + height/2, getX() + width, getY());break; 
		case RD:g.drawLine(getX() + width/2, getY() + height/2, getX() + width, getY() + height);break; 
		case U:g.drawLine(getX() + width/2, getY() + height/2, getX() + width/2, getY() - 5);break; 
		case D:g.drawLine(getX() + width/2, getY() + height/2, getX() + width/2, getY() + height + 5);break; 
		}
		g.setColor(c);
	}
	//敌方坦克移动
	public void eTank(){	

		if(!isGood())
		{   
			Direction[] dirs = Direction.values();
			if(step == 0)
			{
				step = r.nextInt(20) + 3;
				if(tc.isChallenge())
					superFire();
				else
				    fire();//敌方坦克开火  
				int rn = r.nextInt(dirs.length);
				dir = dirs[rn];		
			}  
			move();
			step--;
		}
	}
	//按键监听
	public void keyPressed(KeyEvent e){
		int key = e.getKeyCode();
		switch(key){
		case KeyEvent.VK_W:
			bU = true;break;
		case KeyEvent.VK_D:
			bR = true;break;
		case KeyEvent.VK_S:
			bD = true;break;
		case KeyEvent.VK_A:
			bL = true;break;
		}
		setDirection();
	}
	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();
		switch(key){
		case KeyEvent.VK_W:
			bU = false;break;
		case KeyEvent.VK_D:
			bR = false;break;
		case KeyEvent.VK_S:
			bD = false;break;
		case KeyEvent.VK_A:
			bL = false;break;
		case KeyEvent.VK_J:
			if(tc.myTank.isLive())
			fire();break;
		case KeyEvent.VK_F2:
			if(!tc.myTank.isLive())
				tc.myTank = new Tank(50,50,true,tc);
			break;
		case KeyEvent.VK_F3:
			tc.num += 1;		
			if(tc.tanks.size() == 0)
				for(int i = 0;i < 10 + tc.num;i++){
					tc.tanks.add(new Tank(200 + 40*i,30,false,tc));
				}	if(10 + tc.num == 15)
						tc.num -= 1;
			break;
		case KeyEvent.VK_O:
			if(tc.myTank.isLive() && tc.myTank.getLevel() >= 5 )
			    superFire();break;
		case KeyEvent.VK_F12:
			if(tc.myTank.isLive())
			tc.myTank.killmyTank();
			break;
		case KeyEvent.VK_F4:
			if(tc.tanks.size() != 0){
			if(!tc.isChallenge())
				tc.setChallenge(true);
			else
				tc.setChallenge(false);
			}
			break;
		}
		setDirection();
	}
	//设置坦克方向
	public void setDirection(){
		if(!bU && !bL && !bR && bD) dir = Direction.D;
		else if(!bU && !bL && bR && !bD) dir = Direction.R;
		else if(!bU && bL && !bR && !bD) dir = Direction.L;
		else if(bU && !bL && !bR && !bD) dir = Direction.U;
		else if(!bU && bL && !bR && bD) dir = Direction.LD;
		else if(!bU && !bL && bR && bD) dir = Direction.RD;
		else if(bU && bL && !bR && !bD) dir = Direction.LU;
		else if(bU && !bL && bR && !bD) dir = Direction.RU;
		else if(!bU && !bL && !bR && !bD) dir = Direction.STOP;
	}
	public void move(){
		oldX = getX();
		oldY = getY();
		//if(isGood())
		switch(dir){
		case L:x -= Speech;break; 
		case LU:x -= Speech;y -= Speech;break; 
		case LD:x -= Speech;y += Speech;break; 
		case R:x += Speech;break; 
		case RU:x += Speech;y -= Speech;break; 
		case RD:x += Speech;y += Speech;break; 
		case U:y -= Speech;break; 
		case D:y += Speech;break; 
		case STOP:stay();break;
		}
		if(dir != Direction.STOP)
		{
			ptDir = dir;
		}
		if(getX() < 0 || getY() < 30 || getX() > 770 || getY() > 570)
			stay();
	}
	public void stay(){
		x = oldX;
		y = oldY;
	}
	//超级火力
	public void superFire(){
		Direction dirs[] = Direction.values();
		Shell s = null;
		if(isGood())
		{
			for(int i = 0;i < dirs.length;i++)
			{
				if(dirs[i] != Direction.STOP){
				s = new Shell(getX() + 10,getY() + 10,true,dirs[i],tc);
				tc.shells.add(s);
				}
			}
		}
		else
		{
			for(int i = 0;i < dirs.length;i++)
			{
				if(dirs[i] != Direction.STOP){
				s = new Shell(getX() + 10,getY() + 10,false,dirs[i],tc);
				tc.shells.add(s);
				}
			}
		}
	}
	//一般火力
	public Shell fire(){
		Shell s = null;
		if(isGood())
		    s = new Shell(getX() + 10,getY() + 10,true,ptDir,tc);
		else
		{
			s = new Shell(getX() + 10,getY() + 10,false,ptDir,tc);
		}
		tc.shells.add(s);
		return s;
	}
	public int getX() {
		return x;
	}
	public int getY() {
		return y;
	}
	public boolean isGood() {
		return good;
	}
	//碰撞检测
	public boolean hitTank(Tank t,Graphics g){
		for(int i = 0;i < tc.shells.size();i++)
		{
			Shell s = tc.shells.get(i);
			//挡子弹的图形区域碰撞到坦克的图形区域,且子弹的类型与坦克的类型为敌对时,且子弹和坦克都还活着时,打击成功
			if(s.getRect().intersects(t.getRect()) && (s.isGood() != t.isGood()) && s.isLive() && t.isLive())
			{
				
				s.setLive(false);//子弹打中目标后死亡
				//tc.shells.remove(s);//从集合中去除子弹
				if(t.isGood() == tc.myTank.isGood())//如果被打中的是我放坦克
			    {	
					tc.myTank.life -= 10; 
			    	if(tc.myTank.life == 0)
			    	{
			    		tc.myTank.setLive(false);
			    		tc.myTank.setScore(0);
			    		tc.myTank.setLevel(0);
			    	}
			    }
				else{
				t.setLive(false);//坦克死亡
				tc.tanks.remove(t);//从集合中移除死亡坦克
				}
				Explosion e = new Explosion(t.getX(),t.getY(),tc);
			    e.drawExplosion(g);

				return true;
			}
		}
		return false;
	}
	public boolean hitTanks(Graphics g){
		for(int i = 0;i < tc.tanks.size();i++)
		{
			Tank t = tc.tanks.get(i);
			if(hitTank(t,g))
			{
				Score += 100;
				if(isGood())
				   levelUp(g);
				Explosion e = new Explosion(t.getX(),t.getY(),tc);
			    e.drawExplosion(g);
			    return true;
			}
		}
		return false;
	}
	//获取坦克图形区域(方块)
    public Rectangle getRect(){
    	return new Rectangle(x,y,width,height);
    }
    public void levelUp(Graphics g){
    	Color c = g.getColor();
    	if(Score % 1000 == 0 & Score > 0)
    	{
    		Level++;
    		g.setColor(Color.ORANGE);
    		for(int i = 0;i < 500;i++)
    		   g.drawString(" --LEVEL UP-- ", x - width/2 - 1, y + height/2);
    	} 
    	g.setColor(c);
    }
    public void killmyTank(){
    	setLive(false);
    	setLevel(0);
    	setScore(0);
    }
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值