基本思想是利用多线程,画板是多线程每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 gameJMenuItem jmi2=null;  //2.exit JMenuItem jmi3=null;  //3.save and exitJMenuItem jmi4=null;  //4.continue previous gamepublic 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); }@Overridepublic void actionPerformed(ActionEvent e) {// TODO 自动生成的方法存根if(e.getSource()==jmi1){System.out.printf("hello");mp=new MyPanel(); //build game panelThread 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 timepublic 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);}}@Overridepublic void run() {// TODO 自动生成的方法存根while(true){//sleeptry {Thread.sleep(100);} catch (Exception e) {// TODO: handle exceptione.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 groupVector<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 backgroundg.setColor(Color.yellow); //draw informationg.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 tankif(tank.isLive){this.drawTank(g,tank.getX(), tank.getY(),tank.direct, 0);}//draw the enemytankfor(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 bulletif(bullet.isLive){g.fillOval(bullet.getX(), bullet.getY(), 10, 10);}//draw the enemy bulletfor(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 meswitch(type){case 0:g.setColor(Color.cyan);break;case 1:g.setColor(Color.yellow);break;}//judge which direct the tank isswitch(direct){// upcase 0:g.fill3DRect(x, y, 30, 40, false);g.fill3DRect(x+10, y-10, 10, 20, true);break;//downcase 1:g.fill3DRect(x, y, 30, 40, false);g.fill3DRect(x+10, y+30, 10, 20, true);break;  //leftcase 2:g.fill3DRect(x, y, 40, 30, false);g.fill3DRect(x-10, y+10, 20, 10, true);break;//rightcase 3:g.fill3DRect(x, y, 40, 30, false);g.fill3DRect(x+30, y+10, 20, 10, true);break;}}@Overridepublic void run() {// TODO 自动生成的方法存根int times=0;while(true){try {Thread.sleep(100);} catch (Exception e) {// TODO: handle exceptione.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 aliveif(x2>x1 && x2<x1+40 && y2>y1 && y2<y1+40){ scores++;bullet.isLive=false;enemyTankg.get(i).isLive=false;}//judge whether myself is aliveif(x3>x4 && x3<x4+40 && y3>y4 && y3<y4+40){ tank.isLive=false;System.out.println("Gamve over");}}//every other 50 times shoot one bulletif(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}//iftimes++;}//while}//run@Overridepublic void keyTyped(KeyEvent e) {// TODO 自动生成的方法存根}@Overridepublic 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());}}@Overridepublic void keyReleased(KeyEvent e) {// TODO 自动生成的方法存根}}// play sound classclass 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 exceptione.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 exceptione.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 locationint life=9; //lifetimeboolean isLive=true; public Bomb(int x,int y){this.x=x;this.y=y;}//cutdonw lifetimepublic 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;}@Overridepublic void run() {while(true){// TODO 自动生成的方法存根try {Thread.sleep(50);} catch (Exception e) {// TODO: handle exceptione.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 boderif(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:rightint 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 自动生成的构造函数存根}@Overridepublic void run() {int times=0;while(true){times++;// TODO 自动生成的方法存根try {Thread.sleep(50);} catch (Exception e) {// TODO: handle exceptione.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 directif(times%18==0) direct=(int)(Math.random()*4 );  }   }
}

TankGame1.0相关推荐

  1. 估算带卷积核二分类0,3的网络的收敛时间和迭代次数

    制作一个网络分类minst的0和3求出这网络的迭代次数曲线表达式n(δ),和准确率表达式p-max(δ),用预期准确率去估算n,并推算需要的时间. 将minst的28*28的图片缩小到9*9,网络用一 ...

  2. 神经网络收敛标准与准确率之间的数学关系

    制作一个带一个3*3卷积核的神经网络,测试集是minst的0和2图片集,将28*28的图片缩小成9*9,隐藏层30个节点所以网络的结构是 S(minst0)-(con3*3)49-30-2-(1,0) ...

  3. 用共振频率去进行图片分类的尝试

    假设有一种物质,这种物质的原子核的质子数和电子数可以不同,允许质子的带电量不同,并且质子带负电,同时这个原子的电子不满足鲍利不相容原理,环境温度是 (1/1.3806505)*10^23k,电子波的频 ...

  4. 收敛标准对迭代次数影响

    制作一个n*n的网络,将收敛标准分别设定在,0.001,0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.1,观察网络达到平衡时迭代次数的变化. 比如如图的 ...

  5. vue省市区三级联动mysql,js/json,html/jsp

    大家好,我是烤鸭: 省市区三级联动数据及页面: 测试的时候,发现少了几个地区,现在补上了,也优化了下排版. 如果你懒得复制和看的话,这里是打包的下载地址. 之前的资源地址也改了,http://down ...

  6. ZAM 3D 制作3D动画字幕 用于Xaml导出

    ZAM 3D 制作3D动画字幕 用于Xaml导出 原文:ZAM 3D 制作3D动画字幕 用于Xaml导出 原地址-> http://www.cnblogs.com/yk250/p/5662788 ...

  7. 将执行文件转化为bat批处理文件的工具(批处理文件方式提供)

    update 2006.4.25 15:20 支持64kb以上的执行文件/// @echo e 0100 4d 5a 90 0 3 0 0 0 4 0 0 0 ff ff 0 0 >>Da ...

  8. 完整的境外、港澳台、电信、移动、联通、教育网、国内其他ISP的IPv4列表(数据整理日期2022年4月)-IP列表太长只能份2篇发布(1/2)

    完整的境外.港澳台.电信.移动.联通.教育网.国内其他ISP的IPv4列表(数据整理日期2022年4月)-IP列表太长只能份2篇发布(1/2) 综述 境外(不含港澳台)IPv4地址 综述 企业所在地南 ...

  9. 聚宽JQData说明书

    由于内容较多,可使用Ctrl+F搜索您需要的数据. 注意:query函数的更多用法详见:sqlalchemy.orm.query.Query对象 JQData是什么 JQData是聚宽数据团队专门为金 ...

  10. 情人节程序员用HTML网页表白【520爱心背景3D相册】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript

    这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...

最新文章

  1. linux nat span端口镜像,端口镜像span、rspan实现数据检测
  2. what??|诞生才一年的BCH竟面临硬分叉的抉择
  3. 6. A Deeper Understanding of Deep Learning
  4. tensorflow实现回归
  5. 自动化测试,从入门到跑路1
  6. 一起学Android之Intent
  7. 锁php_基于 Redis 实现分布式锁及对应的 PHP 实现源码
  8. python通过什么对象连接数据库_Python(十一)数据库连接
  9. 第十三届蓝桥杯省赛Java-B组
  10. 软考中级软件设计师基础知识总结
  11. 语音情绪识别.PDF
  12. 全世界最好的编辑器VIM之Windows配置(gvim)
  13. Oracle---查询
  14. MySQL添加约束条件
  15. 抛弃flex执念:利用border-collapse实现顺序展示的快速方法
  16. Qt刷新UI界面问题
  17. 【UNIX网络编程】| 【03】TCP客户/服务器程序示例
  18. Html表格制作费用报销单
  19. 解决 pycharm 插件下载慢的问题
  20. x86服务器(HP/DELL/IBM)测试分析(下)

热门文章

  1. Introduction to Conditional Random Fields
  2. flume+kafka+storm+hdfs整合
  3. Widget Factory
  4. kotlin使用spring data jpa(三)
  5. 成为高级程序员的 10 个步骤
  6. 全国多地元旦迎雾霾天气 京津冀霾明天短暂减弱
  7. Linux配置自建 YUM 软件存储库
  8. C#温故而知新学习系列之面向对象编程—自动属性(十一)
  9. xp也可以将U盘格为NTFS
  10. VS2010与.NET4系列 19.ASP.NET4中新的HTML编码的%: %语法