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

原创 2013年12月05日 09:45:30

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);
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

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

4.2.5 爆炸效果类算法 1、爆炸效果类通过在子弹有效打击的时候,在子弹和击杀坦克接触的坐标上按规定的爆炸步数,画出不同半径的圆来模拟爆炸效果的。 2、爆炸效果类的设计源码: import j...

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

第四章 算法详细设计   4.1 程序描述 本坦克大战游戏通过监听用户的键盘输入对我方坦克即游戏的相关模式进行相应的操作。 用户只要给出坦克方向,坦克便会根据方向相应的改变坦克的坐标,再通过坦...

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

第三章 算法概要设计   3.1 软件结构 1.坦克大战游戏概念详见:2.3缩写及缩略语。 2.本坦克大战游戏按类(详见2.3)可以分为六大模块: (1)坦克大战管理类(Tankclient)。 (2...

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

4.2.3 炮弹类算法 1、炮弹类实现了炮弹的draw方法和子弹的move方法。 2、Draw方法是通过调用JAVA封装的内部方法来实现的。Move方法是根据坦克炮筒的方向和子弹的速度来改变子弹的...

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

第一章 运行环境(软、硬件环境)   1.1 坦克大战游戏的运行软件环境   本坦克大战游戏是基于JAVA语言程序设计,利用Eclipse 3.7.0在Windows操作系统环境下开发测试实现...

坦克大战-java简易版

  • 2013-04-22 17:32
  • 21KB
  • 下载

Java坦克大战 (六) 之增加可玩性

本文来自:小易博客专栏。转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样...

Java之详解坦克大战游戏(六)

现在代码已经越写越多了,这里我们又新建一个包com.TankGame4,复制原来的两个java文件,首先我们来实现一个功能:防止敌人的坦克重叠运动。我们把判断是否碰撞的函数写到EnemyTank类中 ...

简易坦克大战单机版

  • 2013-01-07 09:54
  • 394B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)