TankGame1.0

mac2023-06-10  31

基本思想是利用多线程,画板是多线程每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)