TankGame1.0

在这里插入图片描述
在这里插入图片描述
基本思想是利用多线程,画板是多线程每100ms更新一次
子弹是一个多线程50ms更新一次
坦克是一个多线程50ms更新一次
自己的坦克的方向变换是根据键盘监听响应的,速度可以设置。
敌人的坦克的方向变换是每个一定时间随机变换的,在其run函数中实现
每个坦克有一个子弹,是一一对应关系,
还有一些基本的判断,敌人坦克碰到墙壁必须超反方向运动,
我的子弹碰到敌人坦克,敌人坦克就消失,加分
敌人的坦克打到我,我就消失,GameOver
另外游戏开始时载入了音乐,套用相应的声音类就行了

package com.test1;
import javax.imageio.ImageIO;
import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

import javax.sound.sampled.*;

public class Test extends JFrame implements ActionListener{
	MyPanel mp=null;
	MyStartPanel msp=null;
	JMenuBar jmb=null;
	JMenu jm1=null;
	JMenuItem jmi1=null;  //1.start new game
	JMenuItem jmi2=null;  //2.exit 
	JMenuItem jmi3=null;  //3.save and exit
	JMenuItem jmi4=null;  //4.continue previous game
	
	public static void main(String[] args)
	{
		Test test=new Test();
	}
	
	public Test()
	{
		jmb=new JMenuBar();
		jm1=new JMenu("Game(G)");
		jm1.setMnemonic('G');
		jmi1=new JMenuItem("start new game");
		jmi2=new JMenuItem("exit");
		jmi3=new JMenuItem("save and exit");
		jmi4=new JMenuItem("continue previous game");
		
		jmi1.addActionListener(this);
		jmi2.addActionListener(this);
		jmi3.addActionListener(this);
		jmi4.addActionListener(this);
		
		jm1.add(jmi1);
		jm1.add(jmi2);
		jm1.add(jmi3);
		jm1.add(jmi4);
		jmb.add(jm1);
		
		msp=new MyStartPanel();
		Thread t=new Thread(msp);
		t.start();
		this.setJMenuBar(jmb);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.add(msp);
		this.setSize(600,500);
		this.setVisible(true);	
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自动生成的方法存根
		if(e.getSource()==jmi1)
		{
			System.out.printf("hello");
			mp=new MyPanel(); //build game panel
			Thread t=new Thread(mp);
			t.start();
			this.remove(msp);
			this.add(mp);
			this.addKeyListener(mp);
			this.setVisible(true);
		}else if(e.getSource()==jmi2)
		{
			
		}else if(e.getSource()==jmi3)
		{
			
		}else if(e.getSource()==jmi4)
		{
			
		}
	}
}

class MyStartPanel extends JPanel implements Runnable
{

	int times=0;  //set time
	
	public void paint(Graphics g)
	{
		super.paint(g);
		g.fillRect(0,0,600,500);
		if(times%2==0)  //every other one second flash once
		{
			g.setColor(Color.yellow);
			Font myFont=new Font("华文新魏",Font.BOLD,60);
			g.setFont(myFont);
			g.drawString("Tank Game",150,150);
		}
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		while(true)
		{
			//sleep
			try {
				Thread.sleep(100);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			times++;
			this.repaint();
		}	
	}
}

class MyPanel extends JPanel implements KeyListener,Runnable
{
	Tank tank=null;
	Bullet bullet=null;
	Vector<Bullet> bullets=new Vector<Bullet>();
	//define a Enemy tank group
	Vector<EnemyTank> enemyTankg=new Vector<EnemyTank>();
	int enSize=10;
	int scores=0;
	public MyPanel()
	{
		tank=new Tank(100,100);
		tank.setSpeed(10);
		for(int i=0;i<enSize;i++)
		{
			EnemyTank et=new EnemyTank((i+1)*50,0);
			et.setColor(0);
			et.setDirect(1);
			
			Thread t=new Thread(et);
			t.start();
			enemyTankg.add(et);
		}
		
		//初始化子弹
		for(int i=0;i<enSize;i++)
		{
			Bullet bullet=new Bullet(0,0,1);
			Thread t=new Thread(bullet);
			t.start();
			bullets.add(bullet);
		}
		
		bullet=new Bullet(0,0,1);
		Thread t1=new Thread(bullet);
		t1.start();
		
		AePlayWave apw=new AePlayWave("./112.wav");
		apw.start();
	}
	
	
	public void paint(Graphics g)
	{
		super.paint(g);
		g.fillRect(0,0,600,500);  //draw background
		g.setColor(Color.yellow); //draw information
		g.drawString("score:"+String.valueOf(scores), 500, 450);
		if(tank.isLive==false)
		{
			g.setColor(Color.blue);
			Font myFont=new Font("华文新魏",Font.BOLD,60);
			g.setFont(myFont);
			g.drawString("Game Over",150,150);
		}
		//draw my tank
		if(tank.isLive)
		{
			this.drawTank(g,tank.getX(), tank.getY(),tank.direct, 0);
		}
		//draw the enemytank
		for(int i=0;i<enSize;i++)
		{
			if(enemyTankg.get(i).isLive)
			{
				this.drawTank(g, enemyTankg.get(i).getX(), enemyTankg.get(i).getY(),
						enemyTankg.get(i).getDirect(), 1);
			}
		}
		
		//draw my bullet
		if(bullet.isLive)
		{
			g.fillOval(bullet.getX(), bullet.getY(), 10, 10);
		}
		
		//draw the enemy bullet
		for(int j=0;j<enSize;j++)
		{
			if(bullets.get(j).isLive)
			{
				g.fillOval(bullets.get(j).getX(), bullets.get(j).getY(), 10, 10);
			}
		}	
		
	}
	
	public void showInfo(Graphics g)
	{
		g.drawString("Score:",20,20);
		
	}
	public void drawTank(Graphics g,int x,int y,int direct,int type)
	{
		//judge which kind of tank,whether enemy or me
		switch(type)
		{
		case 0:
			g.setColor(Color.cyan);
			break;
		case 1:
			g.setColor(Color.yellow);
			break;
		}
		
		//judge which direct the tank is
		switch(direct)
		{
		// up
		case 0:
			g.fill3DRect(x, y, 30, 40, false);
			g.fill3DRect(x+10, y-10, 10, 20, true);
			break;
		//down
		case 1:
			g.fill3DRect(x, y, 30, 40, false);
			g.fill3DRect(x+10, y+30, 10, 20, true);
			break;	
		//left
		case 2:
			g.fill3DRect(x, y, 40, 30, false);
			g.fill3DRect(x-10, y+10, 20, 10, true);
			break;
		//right
		case 3:
			g.fill3DRect(x, y, 40, 30, false);
			g.fill3DRect(x+30, y+10, 20, 10, true);
			break;
		}
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		int times=0;
		while(true)
		{
			try {
				Thread.sleep(100);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			this.repaint();
			
			for(int i=0;i<enSize;i++)
			{
				int x1=enemyTankg.get(i).getX();
				int x2=bullet.getX();
				int y1=enemyTankg.get(i).getY();
				int y2=bullet.getY();
				
				int x3=bullets.get(i).getX();
				int y3=bullets.get(i).getY();
				int x4=tank.getX();
				int y4=tank.getY();
				
				// judge whether the enemy alive
				if(x2>x1 && x2<x1+40 && y2>y1 && y2<y1+40)
				{ 
					scores++;
					bullet.isLive=false;
					enemyTankg.get(i).isLive=false;
				}
				
				//judge whether myself is alive
				if(x3>x4 && x3<x4+40 && y3>y4 && y3<y4+40)
				{ 
					tank.isLive=false;
					System.out.println("Gamve over");
				}
			}
			
			//every other 50 times shoot one bullet
			if(times%50==0)
			{
				for(int i=0;i<enSize;i++)
				{
					int x=enemyTankg.get(i).getX();
					int y=enemyTankg.get(i).getY();
					bullets.get(i).isLive=true;
					bullets.get(i).setDirect(enemyTankg.get(i).getDirect());
					switch(tank.getDirect())
					{
					case 0:
						bullets.get(i).setX(x+10);
						bullets.get(i).setY(y-20);
						break;
					case 1:
						bullets.get(i).setX(x+10);
						bullets.get(i).setY(y+40);
						break;
					case 2:
						bullets.get(i).setX(x-20);
						bullets.get(i).setY(y+10);
						break;
					case 3:
						bullets.get(i).setX(x+40);
						bullets.get(i).setY(y+10);
						break;
					}//switch
				}//for
			}//if
			times++;
		}//while
	}//run

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO 自动生成的方法存根
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO 自动生成的方法存根
		if(e.getKeyCode()==KeyEvent.VK_W)
		{
			this.tank.setDirect(0);
			this.tank.MoveUp();
		}else if(e.getKeyCode()==KeyEvent.VK_S)
		{
			this.tank.setDirect(1);
			this.tank.MoveDown();
		}else if(e.getKeyCode()==KeyEvent.VK_A)
		{
			this.tank.setDirect(2);
			this.tank.MoveLeft();
		}else if(e.getKeyCode()==KeyEvent.VK_D)
		{
			this.tank.setDirect(3);
			this.tank.MoveRight();
		}else if(e.getKeyCode()==KeyEvent.VK_J)
		{
			bullet.isLive=true;
			switch(tank.getDirect())
			{
			case 0:bullet.setX(tank.getX()+10);bullet.setY(tank.getY()-20);break;
			case 1:bullet.setY(tank.getY()+40);bullet.setX(tank.getX()+10);break;
			case 2:bullet.setX(tank.getX()-20);bullet.setY(tank.getY()+10);break;
			case 3:bullet.setY(tank.getY()+10);bullet.setX(tank.getX()+40);break;
			}
			bullet.setDirect(tank.getDirect());
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO 自动生成的方法存根
		
	}
	
}

// play sound class

class AePlayWave extends Thread{
	private String filename;
	public AePlayWave(String wavfile){
		filename=wavfile;
	}
	public void run(){
		File soundFile=new File(filename);
		AudioInputStream audioInputStream=null;
		try {
			audioInputStream=AudioSystem.getAudioInputStream(soundFile);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return;
		}
		AudioFormat format=audioInputStream.getFormat();
		SourceDataLine auline=null;
		DataLine.Info info=new DataLine.Info(SourceDataLine.class, format);
		try {
			auline=(SourceDataLine)AudioSystem.getLine(info);
			auline.open(format);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return;
		}
		auline.start();
		int nBytesRead=0;
		byte[] abdata=new byte[512];
		try{
			while(nBytesRead!=-1){
				nBytesRead=audioInputStream.read(abdata,0,abdata.length);
				if(nBytesRead>=0)
					auline.write(abdata, 0, nBytesRead);
			}
		}catch(IOException e){
			e.printStackTrace();return;
		}finally{
			auline.drain();auline.close();
		}
	}
}

class Bomb
{
	int x,y; //define Bullet location
	int life=9; //lifetime
	boolean isLive=true; 
	public Bomb(int x,int y)
	{
		this.x=x;
		this.y=y;
	}
	
	//cutdonw lifetime
	public void lifeDown()
	{
		if(life>0)
		{
			life--;
		}else{
			this.isLive=false;
		}
	}
}

class Bullet implements Runnable{
	int x;
	int y;
	int direct;
	int speed=3;
	
	boolean isLive=false;
	
	public Bullet(int x, int y,int direct)
	{
		this.x=x;
		this.y=y;
		this.direct=direct;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getDirect() {
		return direct;
	}
	public void setDirect(int direct) {
		this.direct = direct;
	}
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	@Override
	public void run() {
		while(true)
		{
			// TODO 自动生成的方法存根
			try {
				Thread.sleep(50);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			switch(direct)
			{
			case 0:y-=speed;break;
			case 1:y+=speed;break;
			case 2:x-=speed;break;
			case 3:x+=speed;break;
			}
			
			// judfe whether bullet get to the boder
			if(x<0 || x>600 ||y<0 ||y>500)
			{
				this.isLive=false;
			}
		}
		
	}
	
}

class Tank
{
	int x=0;
	int y=0;
	int direct=0; //0up 1:down 2:left 3:right
	int color;
	boolean isLive=true;
	int speed=3;
	public Tank(int x,int y)
	{
		this.x=x;
		this.y=y;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getDirect() {
		return direct;
	}
	public void setDirect(int direct) {
		this.direct = direct;
	}
	public int getColor() {
		return color;
	}
	public void setColor(int color) {
		this.color = color;
	}
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	
	void MoveUp()
	{
		this.y-=speed;
	}
	void MoveDown()
	{
		this.y+=speed;
	}
	void MoveLeft()
	{
		this.x-=speed;
	}
	void MoveRight()
	{
		this.x+=speed;
	}
	
}

class EnemyTank extends Tank implements Runnable
{
	public EnemyTank(int x, int y) {
		super(x, y);
		// TODO 自动生成的构造函数存根
	}

	@Override
	public void run() {
		int times=0;
		while(true)
		{
			times++;
			// TODO 自动生成的方法存根
			try {
				Thread.sleep(50);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			switch(direct)
			{
			case 0:y-=speed;if(y<0)direct=1;break;
			case 1:y+=speed;if(y>500)direct=0;break;
			case 2:x-=speed;if(x<0)direct=3;break;
			case 3:x+=speed;if(x>600)direct=2;break;
			}
			
			//every other 18 times change a random direct
			if(times%18==0) direct=(int)(Math.random()*4	);	}	
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值