JAVA小游戏----坦克大战(swing贴图版)(四)

实现我方坦克的操作后,就要定义一个敌人了,敌人也是坦克,于是定义一个继承Tank类的EnemyTank类

public class EnemyTank extends Tank {

	public EnemyTank(int local_x, int local_y, boolean is_enemy) {
		super(local_x, local_y, is_enemy);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void draw() {
	}

	@Override
	public void move() {
	}

	@Override
	public void fire() {
	}

	@Override
	public Rectangle getRec() {

		return null;
	}

	@Override
	public Rectangle getNextRec() {

		return null;
	}

}

我们平时的坦克大战,敌机都是随机移动的,因此构造坦克时属性全部随机

	// 随机对象
	Random r = new Random();
	//随机坐标
	int x = r.nextInt(TankFrame.Frame_Width)-50;//保证在边界内
	int y = r.nextInt(TankFrame.Frame_Height)/8;//仅在窗口上部出现
	//随机方向
	int dirNum = r.nextInt(4);

构造函数使属性全部随机(这里发现Tank类的构造函数并不适用全部坦克故删除)

	public EnemyTank() {
		super();
		// TODO Auto-generated constructor stub
		setLocal_x(x);
		setLocal_y(y);		
		switch (dirNum) {
		case 0:
			setPdir(Direction.U);
			break;
		case 1:
			setPdir(Direction.D);
			break;
		case 2:
			setPdir(Direction.L);
			break;
		case 3:
			setPdir(Direction.R);
			break;
		}
		setIs_enemy(true);
	}

重写draw()函数

	@Override
	public void draw() {
		switch (this.pdir) {
		case U:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1U.gif"));
			break;
		case D:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1D.gif"));
			break;
		case L:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1L.gif"));
			break;
		case R:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1R.gif"));
			break;
		default:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1U.gif"));
		}
	}

在TankPanel中new一个EnemyTank,绘制出来

EnemyTank etank = new EnemyTank();
//绘制敌方坦克
etank.draw();
g.drawImage(etank.getTankImage(), etank.getLocal_x(), etank.getLocal_y(), etank.getWidth(), etank.getHeight(),
				this);

效果如下,每次执行敌机位置都不一样:

接下来实现敌机的随机移动

定义一个随机数step,当走过step步后即改变方向

int step = r.nextInt(15) + 10;

重写move()函数

        @Override
	public void move() {
		switch (pdir) {
		case U:
			if(local_y - speed >= 0)
			setLocal_y(local_y - speed);
			break;
		case D:
			if(local_y + speed <= TankFrame.Frame_Height - (height * 2 + height / 3))
			setLocal_y(local_y + speed);
			break;
		case L:
			if(local_x - speed >= 0)
			setLocal_x(local_x - speed);
			break;
		case R:
			if(local_x + speed <= TankFrame.Frame_Width - (width + width / 4))
			setLocal_x(local_x + speed);
			break;
		default:// do nothing
		}	
		//随机行走的关键
		step--;
		if(step==0){
			step = r.nextInt(15) + 10;//随机数重置
			dirNum = r.nextInt(4);
			switch (dirNum) {
			case 0:
				setPdir(Direction.U);
				break;
			case 1:
				setPdir(Direction.D);
				break;
			case 2:
				setPdir(Direction.L);
				break;
			case 3:
				setPdir(Direction.R);
				break;
			}
		}
	}

在TankPanel中绘制敌方坦克后添加敌方move(),即可实现敌机随机移动,效果如下


接下来实现随机开火

int fireNum = r.nextInt(15) + 10;

在move()中添加

                // 实现随机开火
		fireNum--;
		if (fireNum == 0) {
			fire();
			fireNum = r.nextInt(15) + 10;
		}

重写fire()函数

@Override
public void fire() {
	this.bullets.add(new Bullet(local_x + (width - Bullet.width) / 2, local_y + (height - Bullet.height) / 2, pdir,
				is_enemy));
}

然后在TankPanel中绘制子弹

		//绘制敌方子弹
		for(int i=0;i<etank.getBullets().size();i++){
			Bullet b = etank.getBullets().get(i);//存在b中减少代码长度
			if(b.isIs_Dead()){
				etank.getBullets().remove(i);
			}else{
				b.draw();
				g.drawImage(b.getBulletIamge(), b.getLocal_x(), b.getLocal_y(),
                                         Bullet.width, Bullet.height, this);
			}
			b.move();//绘制后移动
		}

完整源码如下:

TankFrame:

public class TankFrame extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static int Frame_Width = 500;
	public static int Frame_Height = 500;

	TankPanel TP = new TankPanel();

	public void launchFrame() {
		// 窗口大小及位置
		setSize(Frame_Width, Frame_Height);
		setLocation(1000, 100);

		add(TP);
		addKeyListener(TP.mtank.kc);// 添加键盘控制

		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setVisible(true);
		setResizable(false);

		new Thread(TP).start();// 启动线程
	}

	public static void main(String[] args) {
		new TankFrame().launchFrame();
	}

}

TankPanel:

public class TankPanel extends JPanel implements Runnable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	MyTank mtank = new MyTank(100, 100, false);
	EnemyTank etank = new EnemyTank();

	@Override
	protected void paintComponent(Graphics g) {

		super.paintComponent(g);
		g.fillRect(0, 0, TankFrame.Frame_Width, TankFrame.Frame_Height);

		// 绘制我方坦克
		mtank.draw();
		g.drawImage(mtank.getTankImage(), mtank.getLocal_x(), mtank.getLocal_y(), mtank.getWidth(), mtank.getHeight(),
				this);
		mtank.move();

		// 绘制我方子弹
		for (int i = 0; i < mtank.getBullets().size(); i++) {
			Bullet b = mtank.getBullets().get(i);
			if (b.isIs_Dead() == true) {
				mtank.getBullets().remove(i);// 死亡则移除
			} else {
				b.draw();
				g.drawImage(b.getBulletIamge(), b.getLocal_x(), b.getLocal_y(), Bullet.width, Bullet.height, this);
				b.move();
			}
		}
		
		//绘制敌方坦克
		etank.draw();
		g.drawImage(etank.getTankImage(), etank.getLocal_x(), etank.getLocal_y(), etank.getWidth(), etank.getHeight(),
				this);
		etank.move();
		
		//绘制敌方子弹
		for(int i=0;i<etank.getBullets().size();i++){
			Bullet b = etank.getBullets().get(i);//存在b中减少代码长度
			if(b.isIs_Dead()){
				etank.getBullets().remove(i);
			}else{
				b.draw();
				g.drawImage(b.getBulletIamge(), b.getLocal_x(), b.getLocal_y(), Bullet.width, Bullet.height, this);
			}
			System.out.println("子弹"+i);
			b.move();
		}

	}

	@Override
	public void run() {
		while (true) {
			repaint();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

Tank:

public abstract class Tank {
	// 位置
	int local_x;
	int local_y;
	// 大小
	int width = 20;
	int height = 20;
	// 速度
	int speed = 5;
	// 运动方向
	Direction dir;
	// 炮筒方向
	Direction pdir;
	// 坦克图片
	Image tankImage;
	// 敌我
	boolean is_enemy;
	// 死亡
	boolean is_Dead;
	// 子弹集
	ArrayList<Bullet> bullets = new ArrayList<>();

	public int getLocal_x() {
		return local_x;
	}

	public void setLocal_x(int local_x) {
		this.local_x = local_x;
	}

	public int getLocal_y() {
		return local_y;
	}

	public void setLocal_y(int local_y) {
		this.local_y = local_y;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public Direction getDir() {
		return dir;
	}

	public void setDir(Direction dir) {
		this.dir = dir;
	}

	public Direction getPdir() {
		return pdir;
	}

	public void setPdir(Direction pdir) {
		this.pdir = pdir;
	}

	public Image getTankImage() {
		return tankImage;
	}

	public void setTankImage(Image tankImage) {
		this.tankImage = tankImage;
	}

	public boolean isIs_enemy() {
		return is_enemy;
	}

	public void setIs_enemy(boolean is_enemy) {
		this.is_enemy = is_enemy;
	}

	public boolean isIs_Dead() {
		return is_Dead;
	}

	public void setIs_Dead(boolean is_Dead) {
		this.is_Dead = is_Dead;
	}

	public ArrayList<Bullet> getBullets() {
		return bullets;
	}

	public void setBullets(ArrayList<Bullet> bullets) {
		this.bullets = bullets;
	}

	public abstract void draw();// 绘制相关函数(获取图片)

	public abstract void move();// 移动函数

	public abstract void fire();// 开火

	public abstract Rectangle getRec();// 获取当前位置,返回对应矩形

	public abstract Rectangle getNextRec();// 获取移动后的位置,返回对应矩形

}

MyTank:

public class MyTank extends Tank {
	// 坦克移动方向
	Direction dir = Direction.Stop;
	// 坦克炮筒方向
	Direction pdir = Direction.U;

	public KeyContral kc = new KeyContral();

	public MyTank(int local_x, int local_y, boolean is_enemy) {
		super();
		this.local_x = local_x;
		this.local_y = local_y;
		this.is_enemy = is_enemy;
	}

	@Override
	public void draw() {
		switch (pdir) {
		case U:// 注意不能用Direction.U
			setTankImage(Toolkit.getDefaultToolkit().getImage("p2tankU.gif"));
			break;
		case D:
			setTankImage(Toolkit.getDefaultToolkit().getImage("p2tankD.gif"));
			break;
		case L:
			setTankImage(Toolkit.getDefaultToolkit().getImage("p2tankL.gif"));
			break;
		case R:
			setTankImage(Toolkit.getDefaultToolkit().getImage("p2tankR.gif"));
			break;
		default:
			setTankImage(Toolkit.getDefaultToolkit().getImage("p2tankU.gif"));
		}
	}

	@Override
	public void move() {// 实现移动,并控制不越界
		if (dir == Direction.U) {
			if (local_y - speed >= 0)
				setLocal_y(local_y - speed);
		} else if (dir == Direction.D) {
			if (local_y + speed <= TankFrame.Frame_Height - (height * 2 + height / 3))
				setLocal_y(local_y + speed);
		} else if (dir == Direction.L) {
			if (local_x - speed >= 0)
				setLocal_x(local_x - speed);
		} else if (dir == Direction.R) {
			if (local_x + speed <= TankFrame.Frame_Width - (width + width / 4))
				setLocal_x(local_x + speed);
		} else {

		}
	}

	@Override
	public Rectangle getRec() {

		return null;
	}

	@Override
	public Rectangle getNextRec() {

		return null;
	}

	public class KeyContral extends KeyAdapter {// 按下方向改变
		@Override
		public void keyPressed(KeyEvent e) {

			super.keyPressed(e);
			int key = e.getKeyCode();
			switch (key) {
			case KeyEvent.VK_SPACE:// 空格开火
				fire();
				break;
			case KeyEvent.VK_UP:
				pdir = dir = Direction.U;
				break;
			case KeyEvent.VK_DOWN:
				pdir = dir = Direction.D;
				break;
			case KeyEvent.VK_LEFT:
				pdir = dir = Direction.L;
				break;
			case KeyEvent.VK_RIGHT:
				pdir = dir = Direction.R;
				break;
			default:
				dir = Direction.Stop;
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {// 释放移动方向改变恢复,指向不改变

			super.keyReleased(e);
			int key = e.getKeyCode();
			switch (key) {
			case KeyEvent.VK_UP:
				dir = Direction.Stop;
				break;
			case KeyEvent.VK_DOWN:
				dir = Direction.Stop;
				break;
			case KeyEvent.VK_LEFT:
				dir = Direction.Stop;
				break;
			case KeyEvent.VK_RIGHT:
				dir = Direction.Stop;
				break;
			}
		}
	}

	@Override
	public void fire() {
		this.bullets.add(new Bullet(local_x + (width - Bullet.width) / 2, local_y + (height - Bullet.height) / 2, pdir,
				is_enemy));//子弹居中,稍微画图计算一下即可
	}

}

EnemyTank:

public class EnemyTank extends Tank {
	// 随机对象
	Random r = new Random();
	// 随机坐标
	int x = r.nextInt(TankFrame.Frame_Width) - 50;
	int y = r.nextInt(TankFrame.Frame_Height) / 8;
	// 随机方向
	int dirNum = r.nextInt(4);
	int step = r.nextInt(15) + 10;
	int fireNum = r.nextInt(15) + 10;

	public EnemyTank() {
		super();
		// TODO Auto-generated constructor stub
		setLocal_x(x);
		setLocal_y(y);
		switch (dirNum) {
		case 0:
			setPdir(Direction.U);
			break;
		case 1:
			setPdir(Direction.D);
			break;
		case 2:
			setPdir(Direction.L);
			break;
		case 3:
			setPdir(Direction.R);
			break;
		}
		setIs_enemy(true);
	}

	@Override
	public void draw() {
		switch (this.pdir) {
		case U:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1U.gif"));
			break;
		case D:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1D.gif"));
			break;
		case L:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1L.gif"));
			break;
		case R:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1R.gif"));
			break;
		default:
			setTankImage(Toolkit.getDefaultToolkit().getImage("enemy1U.gif"));
		}
	}

	@Override
	public void move() {
		switch (pdir) {
		case U:
			if (local_y - speed >= 0)
				setLocal_y(local_y - speed);
			break;
		case D:
			if (local_y + speed <= TankFrame.Frame_Height - (height * 2 + height / 3))
				setLocal_y(local_y + speed);
			break;
		case L:
			if (local_x - speed >= 0)
				setLocal_x(local_x - speed);
			break;
		case R:
			if (local_x + speed <= TankFrame.Frame_Width - (width + width / 4))
				setLocal_x(local_x + speed);
			break;
		default:// do nothing
		}
		// 随机行走的关键
		step--;
		if (step == 0) {
			step = r.nextInt(15) + 10;
			dirNum = r.nextInt(4);
			switch (dirNum) {
			case 0:
				setPdir(Direction.U);
				break;
			case 1:
				setPdir(Direction.D);
				break;
			case 2:
				setPdir(Direction.L);
				break;
			case 3:
				setPdir(Direction.R);
				break;
			}
		}
		// 实现随机开火
		fireNum--;
		if (fireNum == 0) {
			fire();
			fireNum = r.nextInt(15) + 10;
		}
	}

	@Override
	public void fire() {
		this.bullets.add(new Bullet(local_x + (width - Bullet.width) / 2, local_y + (height - Bullet.height) / 2, pdir,
				is_enemy));
	}

	@Override
	public Rectangle getRec() {

		return null;
	}

	@Override
	public Rectangle getNextRec() {

		return null;
	}

}

Bullet:

public class Bullet {
	// 位置
	int local_x;
	int local_y;
	// 大小
	public static int width = 4;
	public static int height = 4;
	// 方向
	Direction dir;
	// 速度
	int speed = 8;
	// 存活
	boolean is_Dead;
	// 敌我
	boolean is_enemy;
	// 图片
	Image BulletIamge;

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public int getLocal_x() {
		return local_x;
	}

	public void setLocal_x(int local_x) {
		this.local_x = local_x;
	}

	public int getLocal_y() {
		return local_y;
	}

	public void setLocal_y(int local_y) {
		this.local_y = local_y;
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public Direction getDir() {
		return dir;
	}

	public void setDir(Direction dir) {
		this.dir = dir;
	}

	public boolean isIs_Dead() {
		return is_Dead;
	}

	public void setIs_Dead(boolean is_Dead) {
		this.is_Dead = is_Dead;
	}

	public boolean isIs_enemy() {
		return is_enemy;
	}

	public void setIs_enemy(boolean is_enemy) {
		this.is_enemy = is_enemy;
	}

	public Image getBulletIamge() {
		return BulletIamge;
	}

	public void setBulletIamge(Image bulletIamge) {
		BulletIamge = bulletIamge;
	}

	public Bullet(int local_x, int local_y, Direction dir, boolean is_enemy) {
		super();
		this.local_x = local_x;
		this.local_y = local_y;
		this.dir = dir;
		this.is_enemy = is_enemy;
	}

	public void draw() {// 获取子弹图片
		if (!isIs_enemy()) {
			setBulletIamge(Toolkit.getDefaultToolkit().getImage("tankmissile.gif"));
		} else {
			setBulletIamge(Toolkit.getDefaultToolkit().getImage("enemymissile.gif"));
		}
	}

	public void move() {
		if (this.local_x < 0 || this.local_x > TankFrame.Frame_Width || this.local_y < 0
				|| this.local_y > TankFrame.Frame_Height) {
			setIs_Dead(true);// 触边界死亡
		} else {
			switch (this.dir) {
			case U:
				setLocal_y(local_y - speed);
				break;
			case D:
				setLocal_y(local_y + speed);
				break;
			case L:
				setLocal_x(local_x - speed);
				break;
			case R:
				setLocal_x(local_x + speed);
				break;
			default:
				setLocal_y(local_y - speed);
			}
		}
	}
}

Direction:

public enum Direction {
	U,D,L,R,Stop
}



  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java坦克大战小游戏是一款基于Java语言开发的经典游戏。在游戏中,玩家扮演一辆坦克,通过控制坦克的移动和射击来击败敌方坦克,完成各种任务。 要实现Java坦克大战小游戏,可以按照以下步骤进行: 1. 创建游戏窗口:使用Java的图形库(如AWT或Swing)创建一个窗口,作为游戏的显示界面。 2. 绘制游戏场景:在游戏窗口中绘制游戏场景,包括地图、坦克、子弹等元素。可以使用Java的图形绘制API(如Graphics类)来实现。 3. 实现坦克的移动:通过监听键盘事件,控制坦克的移动。根据按下的方向键来改变坦克的位置。 4. 实现坦克的射击:通过监听键盘事件,控制坦克的射击。根据按下的射击键来创建子弹对象,并将其添加到游戏场景中。 5. 实现敌方坦克的AI:为敌方坦克添加AI逻辑,使其能够自动移动和射击。可以使用简单的算法来实现敌方坦克的行为。 6. 碰撞检测:在游戏中实现碰撞检测,判断坦克和子弹之间是否发生碰撞。如果发生碰撞,根据游戏规则进行相应的处理。 7. 实现游戏逻辑:根据游戏规则,实现游戏的逻辑,包括判断胜负、计分等。 8. 添加音效和特效:为游戏添加音效和特效,增加游戏的趣味性和可玩性。 以上是实现Java坦克大战小游戏的一般步骤,具体的实现细节可以根据个人的需求和技术水平进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值