坦克大战GUI版(java)

这是一个使用Java编写的坦克大战GUI版游戏。玩家通过键盘操作(WASD移动,JK射击),控制红色坦克与蓝色敌方坦克进行战斗。我方坦克初始生命值100,每次受到攻击会减10血,阵亡后可按F2重启游戏。将所有Class放在同一包内,运行TankWarClient启动游戏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.操作方法与说明

操作:W:上     A:左     S:下     D:右          J:发子弹    K:大招

说明:红色坦克为自己的坦克,蓝色为敌方坦克,我防坦克右100血,每次被攻击到就会减少10血,直至死亡,我方坦克阵亡后,按F2可以重新开始。

2.坦克大战程序

将以下Class,放在一个包内,运行TankWarClient即可

效果图



	/**
	 * 坦克游戏主客户端,负责响应机制与主要操作等
	 */
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.*;

public class TankWarClient extends Frame {
	private static final long serialVersionUID = 1L;
	
    Tank MyTank=new Tank(50,50,true,this);//创建我方坦克
	List<Missile> missiles=new ArrayList<Missile>();//子弹容器
	List<Explode> explodes =new ArrayList<Explode>();//爆炸容器
	List<Tank> tanks =new ArrayList<Tank>();//坦克容器
	List<Wall> walls=new ArrayList<Wall>();//墙
	List<Blood>bloods=new ArrayList<Blood>();//血块
	Random r=new Random();
	Image offImage=null;
	public static final int GAME_WEITH=800;
	public static final int GAME_HEIGHT=600;
	
	
	public void paint(Graphics g) {
		
		g.drawString("missiles count:"+missiles.size(), 10, 50);//显示出子弹个数
		g.drawString("explodes count:"+explodes.size(), 10, 70);//爆炸个数
		g.drawString("tanks count:"+tanks.size(), 10, 90);//坦克个数
		g.drawString("tank life:"+MyTank.getGlife(), 10, 120);//坦克的剩余生命
		//画出血块
		for(int i=0;i<bloods.size();i++){
			Blood bl=bloods.get(i);
			bl.hitTanks(tanks);//血块碰撞坦克检测
			bl.draw(g);
		}
		
		for(int i=0;i<missiles.size();i++){
			Missile Mi=missiles.get(i);
			Mi.hitTanks(tanks);
			Mi.hitWalls(walls);
			Mi.draw(g);
		}
		
		for(int i=0;i<explodes.size();i++){
			Explode Ex=explodes.get(i);
			Ex.draw(g);
		}
		
		for(int i=0;i<tanks.size();i++){
			Tank tan=tanks.get(i);
			tan.hitWalls(walls);
			tan.hitTanks(tanks);
			tan.draw(g);
		}
		
		for(int i=0;i<walls.size();i++){
			Wall wa=walls.get(i);
			wa.draw(g);
		}
		
	    int ra=r.nextInt(400);
	    if(ra==10){
			//随机加入血块
			bloods.add(new Blood(200,200,this));
	    }
	}

	//设置双缓冲,防止图片闪烁
	public void update(Graphics g) {
		
		if(offImage==null){
			offImage=this.createImage(GAME_WEITH,GAME_HEIGHT);
		}
		Graphics goff=offImage.getGraphics();
		Color c=goff.getColor();
		goff.setColor(Color.white);
		goff.fillRect(0, 0, GAME_WEITH,GAME_HEIGHT);
		goff.setColor(c);
		paint(goff);
		g.drawImage(offImage, 0, 0, null);
	}
	
	void launchFram(){
		//增加10个对方坦克
		for(int i=0;i<10;i++){
			tanks.add(new Tank(200+50*i,200+50*i,false,this));
		}
		walls.add(new Wall(200,300,100,20,this));
		walls.add(new Wall(400,150,20,200,this));
		
		tanks.add(MyTank);
		this.setBounds(100, 100, GAME_WEITH,GAME_HEIGHT);
		this.setVisible(true);
		this.setTitle("TankWar");
		this.setResizable(false);
		this.setBackground(Color.white);
		this.addKeyListener(new KeyMonitor());
		//添加Window关闭响应
		this.addWindowListener(new WinClosed());
		new Thread(new MyRepaint()).start();
	}
	
	public static void main(String[] args) {
		TankWarClient twc=new TankWarClient();
		twc.launchFram();
	}

	//响应关闭装口
	class WinClosed extends WindowAdapter{
		public void windowClosing(WindowEvent e){
			System.exit(0);
		}
	}
	
	//启用新线程重画,画面显示的更均匀
	class MyRepaint implements Runnable{

		public void run() {
			while(true){
				repaint();
				try {
					Thread.sleep(45);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	class KeyMonitor extends KeyAdapter{
		
		public void keyPressed(KeyEvent ke){
			MyTank.keyPressed(ke);
		}
		
		public void keyReleased(KeyEvent e){
			MyTank.keyReleased(e);
		}
	}
}


/**
 * 坦克,敌方坦克与我方坦克均在此实现,用boolean good区分,其中我方坦克有血条大招
 * 敌方坦克被攻击一次就会消亡
 */
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;

public class Tank {


	int x,y;
	int oldX,oldY;
	private int glife=100;
	static final int dx=5,dy=5,WIDTH=30,HEIGHT=30;
	boolean L=false,D=false,R=false,U=false;
	boolean shoot=true,kshoot=true;
	
	private boolean good=true;
	private boolean live=true;
	private static Random r=new Random();
	private int mStep=r.nextInt(16);
	
			
	TankWarClient twc=null;
	
	Direction dir=Direction.STOP;
	Direction ptDir=Direction.U;
	
	public int getGlife() {
		return glife;
	}

	public void setGlife(int glife) {
		this.glife = glife;
	}
	
	public boolean isGood() {
		return good;
	}

	Tank(int x,int y,boolean good){
		this.x=x;
		this.y=y;
		this.oldX=x;
		this.oldY=y;
		this.good=good;
	}
	
	Tank(int x,int y,boolean good,TankWarClient twc){
		this(x,y,good);
		this.twc=twc;
	}
	
	public boolean isLive() {
		return live;
	}

	public void setLive(boolean live) {
		this.live = live;
	}
	
	//根据方向设置下一步要画的坦克位置
	void move(){
		oldX=x;
		oldY=y;
		switch(dir){
		case L: 
			x -=dx;
			break;
		case LU: 
			x -=dx;
			y -=dy;
			break;
		case U:
			y -=dy;
			break;
		case RU: 
			x +=dx;
			y -=dy;
			break;
		case R: 
			x +=dx;
			break;
		case RD: 
			x +=dx;
			y +=dy;
			break;
		case D: 
			y +=dy;
			break;
		case LD: 
			x -=dx;
			y +=dy;
			break;
		case STOP: 
			break;
		}
		if(dir!=Direction.STOP){
			ptDir=dir;
		}
		if(x<0) x=0;
		if(y<20) y=20;
		if(x>TankWarClient.GAME_WEITH-WIDTH) x=TankWarClient.GAME_WEITH-WIDTH;
		if(y>TankWarClient.GAME_HEIGHT-HEIGHT) y=TankWarClient.GAME_HEIGHT-HEIGHT;
		if(!good){	
			if(mStep==0){
				mStep=r.nextInt(20)+3;
				Direction []dirs=Direction.values() ;
				int rn=r.nextInt(dirs.length);
				dir=dirs[rn];
			}
			mStep--;
			int isShoot=r.nextInt(40);
			if(isShoot>=39){
				twc.missiles.add(shoot());
			}
		}
	}
	
	public void draw(Graphics g){
		if(!live){
			if(!good){
				twc.tanks.remove(this);
			}
			//好坦克死了就不画了
			if(good){
				twc.tanks.remove(this);
			}
		}
		Color c=g.getColor();
		if(good){
			g.setColor(Color.red);
		}else{
			g.setColor(Color.blue);
		}
		g.fillOval(x, y, WIDTH,HEIGHT);
		//还原g原来的颜色
		g.setColor(c);
		new BloodBar().drawBar(g);
		switch(ptDir){
		case L: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x-5,y+HEIGHT/2);;
			break;
		case LU: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x , y);;
			break;
		case U:
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH/2 , y-5);;
			break;
		case RU: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH , y);;
			break;
		case R: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH+5 , y+HEIGHT/2);;
			break;
		case RD: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH , y+HEIGHT);;
			break;
		case D: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x+WIDTH/2 , y+HEIGHT+5);;
			break;
		case LD: 
			g.drawLine(x+WIDTH/2, y+HEIGHT/2,x , y+HEIGHT);;
			break;
		default:
			break;
		}
		move();
	}
	
	public void keyPressed(KeyEvent ke){
		int key=ke.getKeyCode();
		switch(key){
		case KeyEvent.VK_F2:
			if(!live&&good)
			{
				twc.tanks.add(this);
				live=true;
				glife=100;
			}
			break;
		case KeyEvent.VK_J:
			if(shoot&&live){
				twc.missiles.add(shoot());
				shoot=false;
			}
			break;
		case KeyEvent.VK_K:
			if(kshoot&&live){
				Direction []pir=Direction.values();
				for(int i=0;i<8;i++){
					twc.missiles.add(new Missile(x,y,good,pir[i],this.twc));
				}
				kshoot=false;
			}
			break;
		case KeyEvent.VK_W:
			U=true;
			break;
		case KeyEvent.VK_D:
			R=true;
			break;
		case KeyEvent.VK_S:
			D=true;
			break;
		case KeyEvent.VK_A:
			L=true;
			break;
		}
		locateDirection();
	}
	
	private Missile shoot() {
		//大管家 this.twc
		Missile m=new Missile(x,y,good,ptDir,this.twc);
		return m;
		
	}
	
	public void keyReleased(KeyEvent ke){
		int key=ke.getKeyCode();
		switch(key){
		case KeyEvent.VK_J:
			shoot=true;
			break;
		case KeyEvent.VK_K:
			kshoot=true;
			break;
		case KeyEvent.VK_W:
			U=false;
			break;
		case KeyEvent.VK_D:
			R=false;
			break;
		case KeyEvent.VK_S:
			D=false;
			break;
		case KeyEvent.VK_A:
			L=false;
			break;
		}
		locateDirection();
	}
	
	//设置要移动的方向
	void locateDirection(){
		if(U&&!R&&!D&&!L) dir=Direction.U;
		else if(U&&R&&!D&&!L) dir=Direction.RU;
		else if(!U&&R&&!D&&!L) dir=Direction.R;
		else if(!U&&R&&D&&!L) dir=Direction.RD;
		else if(!U&&!R&&D&&!L) dir=Direction.D;
		else if(!U&&!R&&D&&L) dir=Direction.LD;
		else if(!U&&!R&&!D&&L) dir=Direction.L;
		else if(U&&!R&&!D&&L) dir=Direction.LU;
		else if(!U&&!R&&!D&&!L) dir=Direction.STOP;
	}
	
	public Rectangle getRect(){
		return new Rectangle(x,y,WIDTH,HEIGHT);
	}
	
	void stay(){
		x=oldX;
		y=oldY;
	}
	
	public boolean hitWall(Wall w){
		if(this.getRect().intersects(w.getRect())){
			stay();
			return true;
		}
		return false;
	}
	
	public boolean hitWalls(List<Wall> walls){
		for(int i=0;i<walls.size();i++){
			if(hitWall(walls.get(i))){
				return true;
			}
		}
		return false;
	}
	
	//判断坦克是否撞到坦克
	public boolean hitTank(Tank t){
		if(this.getRect().intersects(t.getRect())){
			stay();
			return true;
		}
		return false;
	}
	
	public boolean hitTanks(List<Tank> tanks){
		for(int i=0;i<tanks.size();i++){
			if(this==tanks.get(i))
				continue;
			if(hitTank(tanks.get(i))){
				return true;
			}
		}
		return false;
	}

	private class BloodBar{
		private void drawBar(Graphics g){
			if(!good) return;
			Color c=g.getColor();
			//goodTank的画血条
			if(glife>=60){
				g.setColor(Color.green);
			}else if(glife>=40){
				g.setColor(Color.orange);
			}
			else{	
				g.setColor(Color.red);
			}
				g.fillRect(x, y-15,glife, 10);
				g.drawRect(x+glife, y-15,100-glife, 10);
			g.setColor(c);
		}
	}
}

/**
 * 实现子弹
 */
import java.awt.*;
import java.util.List;

public class Missile {
	
	int x,y;
	Direction dir=null;
	private TankWarClient twc=null;
	static final int dx=8,dy=8,WIDTH=10,HEIGHT=10;	
	private boolean live =true;
	private boolean good;
	
	public boolean isGood() {
		return good;
	}
	
	public Missile(int x, int y,Direction dir) {
		this.x = x;
		this.y = y;
		this.dir = dir;
	}
	
	public Missile (int x,int y,boolean good,Direction dir,TankWarClient twc){
		this(x,y,dir);
		this.twc=twc;
		this.good=good;
	}
	
	
	public void draw(Graphics g){
		if(!live) {
			twc.missiles.remove(this);
			return;
		}
		Color c=g.getColor();
		if(good){
			g.setColor(Color.red);
		}else{
			g.setColor(Color.BLACK);
		}
		g.fillOval(x+Tank.WIDTH/2-WIDTH/2, y+Tank.WIDTH/2-HEIGHT/2,
				WIDTH, HEIGHT);
		g.setColor(c);
		
		move();
	}
	
	void move(){
		
		switch(dir){
		case L: 
			x -=dx;
			break;
		case LU: 
			x -=dx;
			y -=dy;
			break;
		case U:
			y -=dy;
			break;
			//buf
		case RU: 
			x +=dx;
			y -=dy;
			break;
		case R: 
			x +=dx;
			break;
		case RD: 
			x +=dx;
			y +=dy;
			break;
		case D: 
			y +=dy;
			break;
		case LD: 
			x -=dx;
			y +=dy;
			break;
		default:
			break;
		}
		//当子弹超出显示界面时消亡(从容器里将其删除)
		if(x<0||x>TankWarClient.GAME_WEITH||y<0||y>TankWarClient.GAME_HEIGHT||hitTanks(twc.tanks)){
			live=false;
		}
	}
	
	public boolean isLive() {
		return live;
	}

	public void setLive(boolean live) {
		this.live = live;
	}
	
	public Rectangle getRect(){
		return new Rectangle(x,y,WIDTH,HEIGHT);
	}
	
	//判断子弹是否打中坦克
	public boolean hitTank(Tank t){

		if(this.getRect().intersects(t.getRect())&&this.good!=t.isGood()){
		    //子弹消亡
		    this.live=false;
		    
			if(t.isGood()){
				t.setGlife(t.getGlife()-10);
				if(t.getGlife()<=0){
					t.setLive(false);
				}
			}else{
				//坦克消亡
				t.setLive(false);				
			}
			twc.explodes.add(new Explode(x,y,twc));

			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.getRect().intersects(w.getRect())){
			//子弹消亡
			live=false;
			return true;
		}
		return false;
	}
	
	public boolean hitWalls(List<Wall> walls){
		for(int i=0;i<walls.size();i++){
			if(hitWall(walls.get(i))){
				return true;
			}
		}
		return false;
	}
	
}

/**
 * 实现爆炸,坦克死亡时出现,接着消失
 */
import java.awt.*;
public class Explode {
	
	int x,y,step=0;
	TankWarClient twc=null;
	boolean live=true;
	int [] p={0,1,5,10,15,20,30,35,40,50,60,55,47,43,33,27,21,18,13,7,2,0};
	
	public Explode(int x, int y, TankWarClient twc) {
		super();
		this.x = x;
		this.y = y;
		this.twc = twc;
	}	
	
	public void draw(Graphics g){
		if(!live) {
			twc.explodes.remove(this);
			return;
		}
		if(step==p.length){
			live=false;
			step=0;
			return;
		}
		Color c=g.getColor();
		g.setColor(Color.orange);
		g.fillOval(x, y, p[step], p[step]);
		step++;
		g.setColor(c);
	}

}

/**
 * 实现血块,随机产生,一定时间消失,运动轨迹随机
 */
import java.awt.*;
import java.util.*;
import java.util.List;

public class Blood {

	int x,y;
	//血块生存的时间
	int time=300;
	//大管家
	TankWarClient twc=null;
	//设置移动的步长
	private final int  dx=5,dy=5;
	private final Random r=new Random(); 
	//血块的长宽
	private final int WIDTH=25,HEIGHT=25;
	//设置血块是否存在
	boolean live =true;
	
	//构造方法,把大管家交给Blood
	public Blood(int x, int y,TankWarClient twc) {
		this.x = x;
		this.y = y;
		this.twc=twc;
	}
	
	//定义8个移动的方向
	enum Direction {L,LU,U,RU,R,RD,D,LD,STOP}
	Direction dir=Direction.STOP;
	
	//把血块画出来
	void draw(Graphics g){
		if(!live){
			twc.bloods.remove(this);
		}
		Color c=g.getColor();
		g.setColor(Color.pink);
		g.fillRect(x, y, WIDTH,HEIGHT);
		g.setColor(c);
		time--;
		bloodMove();
	}
	
	//根据方向设置下一步要画的坦克位置
	void bloodMove(){
		Direction []dirs=Direction.values();
		int rn1=r.nextInt(20);
		if(rn1==19){
			int rn2=r.nextInt(dirs.length);
			dir=dirs[rn2];
		}
		switch(dir){
		case L: 
			x -=dx;
			break;
		case LU: 
			x -=dx;
			y -=dy;
			break;
		case U:
			y -=dy;
			break;
		case RU: 
			x +=dx;
			y -=dy;
			break;
		case R: 
			x +=dx;
			break;
		case RD: 
			x +=dx;
			y +=dy;
			break;
		case D: 
			y +=dy;
			break;
		case LD: 
			x -=dx;
			y +=dy;
			break;
		case STOP: 
			break;
		}
		if(x<0) x=0;
		if(y<20) y=20;
		if(x>TankWarClient.GAME_WEITH-WIDTH){
			x=TankWarClient.GAME_WEITH-WIDTH;
		}	
		if(y>TankWarClient.GAME_HEIGHT-HEIGHT){
			y=TankWarClient.GAME_HEIGHT-HEIGHT;
		}
		if(time<0){
			live =false;
		}
	}
	
	private Rectangle getRect(){
		return new Rectangle(x,y,WIDTH,HEIGHT);
	}
	
	//坦克是否吃到血块
	public boolean hitTank(Tank t){

		if(this.getRect().intersects(t.getRect())&&t.isGood()){
			
			if(t.getGlife()<=90){
				t.setGlife(t.getGlife()+10);
				//血块消亡
				live=false;
			}
			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;
	}
}

/**
 * 实现一堵墙,子弹碰到墙自己消失,坦克不能穿过墙
 */
import java.awt.*;
public class Wall {

	private int x,y,WIDTH,HEIGHT; 
	TankWarClient twc=null;
	
	public void draw(Graphics g){
		Color c=g.getColor();
		g.setColor(Color.DARK_GRAY);
		g.fillRect(x, y, WIDTH, HEIGHT);
		g.setColor(c);
	}

	public Wall(int x, int y, int wIDTH, int hEIGHT, TankWarClient twc) {
		super();
		this.x = x;
		this.y = y;
		WIDTH = wIDTH;
		HEIGHT = hEIGHT;
		this.twc = twc;
	}	

	public Rectangle getRect() {
		return new Rectangle(x,y,WIDTH,HEIGHT);
	}
	
}

package com.RudyGuo;
/**
 * 方向
 */
public enum Direction {
	L,LU,U,RU,R,RD,D,LD,STOP
}

























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值