Java 编写的 坦克大战小游戏

Java 编写的坦克大战小游戏

创作背景:n年前的学期末课题设计,从b站上学的,一个代码一个代码敲出来的。
小游戏介绍:
红色坦克是我们的操纵坦克,黑色是敌人坦克。
上下左右键控制坦克移动方向
按ctrl键发射炮弹
红色坦克可以穿墙,黑色不可以
对你有帮助求:点赞,收藏,关注

具体页面如下:
在这里插入图片描述
奉上全部源代码:
Tank.java

import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Tank {
	private int x;
	private int y;
	private  int oldx;
	private  int oldy;
	private int life = 100;
private boolean bL = false ,bU = false ,bR = false ,bD= false;
//产生随机数
private static Random r = new Random();
//九种坦克运动方向
enum Direction{L,LU,U,RU,R,RD,D,LD,STOP};
//初始化坦克方向
private Direction  dir = Direction.STOP;
//初始化炮筒方向
private Direction ptDir = Direction.U;
//坦克移动速度
private static final int XSPEED = 5;
private static final int  YSPEED = 5;
//坦克大小
private static final int WIDTH = 30;
private static final int HIGHT =30;
//定义TankClient类
TankClient tc;
public int getLife(){
	return  life;
	}
public void setLife(int life){
	this.life =life;
}
private boolean good =true ;//定义坦克类型,敌方还是我方
public boolean isgood()
{
	return good;
}
//定义坦克状态
private boolean live = true;
//设置enemy坦克随机移动步数
private static int step = r.nextInt(12)+3;
//构造坦克状态方法
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 Tank (int x,int y,Boolean good ,Direction dir,TankClient tc)
{
	this (x,y);
	this.good = 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==true)
			{g.setColor(Color.RED);}//定义我方坦克颜色
		else g.setColor(Color.BLACK);//定义敌方坦克颜色
		g.fillOval(x,y, WIDTH, HIGHT);//定义坦克位置及大小
		g.setColor(c);//?
		move();
		switch (ptDir)//画炮筒
		{
		case L:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x, y
					+ Tank.HIGHT / 2);
			break;
		case LU:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x, y);
			break;
		case U:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH
					/ 2, y);
			break;
		case RU:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH,
					y);
			break;
		case R:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH,
					y + Tank.HIGHT / 2);
			break;
		case RD:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH,
					y + Tank.HIGHT);
			break;
		case D:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH
					/ 2, y + Tank.HIGHT);
			break;
		case LD:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x, y
					+ Tank.HIGHT);
			break;
		}
	}

private void stay()
{
	this.x=oldx;
	this.y=oldy;
	}
//坦克移动
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 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)
	{
		ptDir = dir;
	}
	if (x<0) x=0;
	if (y<20) y=20;
	if (x>TankClient.WinWidth-Tank.WIDTH) x=TankClient.WinWidth-Tank.WIDTH;
	if (y>TankClient.WinHigh-Tank.HIGHT) y=TankClient.WinHigh-Tank.HIGHT;
	//让enemy坦克自由移动
	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();}
	}
}
//坦克方向
void localDirection()
{
	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 dir =Direction.STOP;
}
public void keyPressed(KeyEvent e) 
	{
		int key = e.getKeyCode();
			switch (key)
		{
			case KeyEvent.VK_CONTROL:
				fire();
				break;
			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;
		}
		localDirection();//获取执行方向

	}
public void keyReleased(KeyEvent e) {
	int key = e.getKeyCode();
	switch (key)
{
	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;
}
	localDirection();
	
}
//定义坦克发射子弹类
	public Missile fire()
	{
		if (!live) return null;
		int x= this.x+Tank.WIDTH/2-Missile.WIDTH/2;
		int y= this.y +Tank.HIGHT/2-Missile.HIGHT/2;
		Missile m = new Missile(x,y,ptDir,good,tc);
		tc.Missiles.add(m);
		return m;
	}
//《碰撞检测》获取坦克矩形属性
	public Rectangle getRect()
	{
		return new Rectangle(x,y,WIDTH,HIGHT);
	}
	//《碰撞检测》
	public boolean tankHitWall(Wall w)
	{
		if(this.getRect().intersects(w.getRect()))
		{
			stay();
			return true;
		}
		return false;
	}
	public boolean tankHitTank(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;
	}
}

Wall.java

import java.awt.*;
public class Wall {
	 int x;
	 int y;
	 int width;
	 int height;
	 TankClient tc;

	public Wall (int x,int y,int width,int height, TankClient tc)
	{
		this.x= x;
		this.y= y;
		this.width = width;
		this.height = height;
		this.tc = 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);
		}
	
}

TankClient.java

import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
public class TankClient extends Frame {
	Tank myTank = new Tank(400,430,true,Tank.Direction.STOP,this);//创建自己的坦克
	List <Tank>  tanks= new ArrayList<Tank>(); //创建敌人坦克容器
	List<Explode> Explodes = new ArrayList<Explode>();//创建爆炸容器
	List<Missile> Missiles = new ArrayList<Missile>();//定义容器,存放炮弹
	Wall wall1 = new Wall(100,100,30,400,this);
	Wall wall2 = new Wall(350,400,400,30,this);
	/*
	 * 定义窗口大小变量
	 */
	public static final int WinWidth=800;
	public static final int WinHigh=600;
	//定义框架大小
	public void launchFrame()
	{
		//添加10辆敌人坦克
		for (int i = 0;i<10;i++)
		{
			tanks.add(new Tank(50+40*i,100,false,Tank.Direction.D,this));
		}
		this.setLocation(40,40);//定义窗口位置
		this.setSize(WinWidth,WinHigh);//设置窗口大小
		this.setTitle("坦克大战");//设置窗口标题
		//设置监听器,使窗口关闭
		this.addWindowListener(new WindowAdapter()
				{
					public void windowClosing(WindowEvent e)
					{
						System.exit(0);
					}
				});
		this.setBackground(Color.WHITE);//设置窗口背景颜色
		this.setVisible(true);//设置窗口可见
		this.setResizable(false);//设置为不可调整窗口大小
		this.addKeyListener(new KeyMonitor());
		new Thread(new PaintThread()).start();
	}
	//定义一个新图片为空,双缓冲
	Image OffScreenImage = null;
	/*
	 * 定义画板
	 */
	public void paint(Graphics g)
	{	//g.drawString("当前炮弹数"+Missiles.size(), 40, 80);
		//g.drawString("当前爆炸数"+Explodes.size(), 40, 100);
		g.drawString("Tank数量"+tanks.size(),40,40);
		g.drawString("MyTank血量"+myTank.getLife(),40,60);
		for (int i=0;i<Missiles.size();i++)
		{
			Missile m = Missiles.get(i); 	
			m.hitTanks(tanks);
			m.hitTank(myTank);
			m.hitWall(wall1);
			m.hitWall(wall2);
			m.draw(g);
		}
		for (int i=0;i<Explodes.size();i++)
		{
			Explode e = Explodes.get(i);
			e.draw(g);
		}
		for (int i = 0;i<tanks.size();i++)
		{
			Tank t = tanks.get(i);
			t.tankHitWall(wall1);
			t.tankHitWall(wall2);
			t.tankHitTank(tanks);
			t.draw(g);
		}
		myTank.draw(g);
		wall1.draw(g);
		wall2.draw(g);
	}
	//重写update 刷新屏幕先调用update方法再调用画笔工具,故刷新屏幕让其直接调用update方法
	public void update (Graphics g)
	{
		if (OffScreenImage == null )
		{
			OffScreenImage = this.createImage(WinWidth,WinHigh);
		}
		Graphics gOffScreen = OffScreenImage.getGraphics();
		Color c = gOffScreen.getColor();
		gOffScreen.setColor(Color.WHITE);
		gOffScreen.fillRect(0,0,WinWidth,WinHigh);
		gOffScreen.setColor(c);
		paint(gOffScreen);
		g.drawImage(OffScreenImage,0,0,null);
	}
	public static void main(String[] args)
	{
		TankClient tankClient = new TankClient();
		tankClient.launchFrame();

	}
	//线程类--刷新屏幕
	private class PaintThread implements Runnable
	{
		public void run()
		{
			while(true)
			{
				repaint();  //刷新屏幕
				try
				{
					Thread.sleep(40);
				}catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
	/**
	 * 
	 * 内部类 添加键盘监听
	 *
	 */
		private class KeyMonitor extends KeyAdapter {
			//按键时
			public void keyPressed(KeyEvent e) {
				myTank.keyPressed(e);
			}
			//松键时
			public void keyReleased(KeyEvent e) 
			{
				myTank.keyReleased(e);
			}
			
		}
}

Explode.java

import java.awt.*;
public class Explode {
	int x;
	int y;
	private boolean live = true;
	private TankClient tc ;
	int[] diameter = {30,40,50,40,30,10,5};
	int step = 0;
	//结构
	public Explode (int x ,int y,TankClient tc) {
		this.x =x;
		this.y = y;
		this.tc = tc;
	}
	public void draw (Graphics g) {
		if(!live){
		tc.Explodes.remove(this);	
		return ;
		}
		if (step ==diameter.length) {
			live = false ;
			step = 0;
			return ;
		}
		Color c = g.getColor();
		g.setColor(Color.RED);
		g.fillOval(x, y, diameter[step], diameter[step]);
		g.setColor(c);
		step++;
	}
}

Missile.java

import java.awt.*;
import java.util.List;
//定义子弹类
public class Missile {
	//定义子弹速度
	public static final int XSPEED=10;
	public static final int YSPEED=10;
	//定义子弹大小
	public static final int WIDTH =10;
	public static final int HIGHT =10;
	private boolean live= true ;//定义炮弹状态
	//定义发出的炮弹归属
	private boolean good;
	public boolean islive()
	{
		return live;
	}
	int x,y ;//子弹坐标
	TankClient tc;
	Tank.Direction dir;
	public Missile (int x,int y ,Tank.Direction dir)
	{
		this.x=x;
		this.y=y;
		this.dir=dir; 
	}
	public Missile(int x,int y,Tank.Direction dir,boolean good,TankClient tc)
	{
		this(x,y,dir);
		this.good = good;
		this.tc=tc;
	}
	public void draw (Graphics g)
	{	if (!live) {
		tc.Missiles.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();
	}
	void move ()

	{
		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;
		}
		if (x<0||y<0||x>TankClient.WinWidth||y>TankClient.WinHigh)
		{
			live =false;
		}
	}
//《碰撞检测》获取子弹矩形属性
	public Rectangle getRect()
	{
		return new Rectangle(x,y,WIDTH,HIGHT);
	}
//《碰撞检测》
	public boolean hitTank(Tank t)
	{
		if(this.live&&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;
			Explode e = new Explode(x-10,y-10,tc);
			tc.Explodes.add(e);
			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()))
			{
				this.live =false;
				return true;
			}
			return false ;
		}
}

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大脑经常闹风暴@小猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值