今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的java进行一下实战。

每个程序版本代码中,都附有相关注释,看完注释大家就可以对本程序设计有个很明显的思路。真的很有趣,想对java重新温习的同学完全不必再对厚厚的java基础书籍进行阅读了,在跟着本次代码练习并分析后,大家一定会对java各方面基础知识 尤其是线程的知识有更深一步的了解!!!

本次坦克大战系列的各个版本都是在一步步的升级改进,难度逐渐加大,功能愈加完善;话不多说,先给大家分享一下代码(●ˇ∀ˇ●)

Tank大战 version1.0

实现功能:
  1.绘制出我方Tank;

2.可以通过键盘上下左右键 控制移动;

 package com.test;

 import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*; import javax.swing.*; public class MyTankGame extends JFrame {
Mypanel mp=null;
public static void main(String[] args) {
// TODO 自动生成的方法存根
MyTankGame mtg=new MyTankGame();
}
//构造函数
public MyTankGame()
{
mp=new Mypanel();
this.add(mp);
this.setSize(800,600);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } //坦克类
class Tank
{
//表示坦克横坐标
int x=0;
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;
} //表示坦克纵坐标
int y=0; public Tank(int x,int y)
{
this.x=x;
this.y=y;
}
} //我的Tank
class Hero extends Tank
{ public Hero(int x, int y) {
super(x, y);
// TODO 自动生成的构造函数存根
} } //我的面板
class Mypanel extends JPanel
{
//定义一个我的坦克
Hero hero=null; //构造函数
public Mypanel()
{
hero=new Hero(100,100);
}
public void paint(Graphics g)
{
super.paint(g);
//设置面板背景色,全部填充即可,默认为黑色
g.fillRect(0, 0, 800, 600);
//画出我的tank,放到paint函数中
this.DrawTank(hero.getX(), hero.getY(), g,0,0);//hero.getX(), hero.getY()就将x,y传过去了
} //画出tank
public void DrawTank(int x,int y,Graphics g,int direct,int type)
{
//判断是什么类型坦克
switch(type)
{
case 0://我的tank
g.setColor(Color.cyan);
break;
case 1://敌人的tank
g.setColor(Color.orange);
break;
}
//判断坦克的方向
switch(direct)
{
//向上
case 0:
//画出左边矩形
g.fill3DRect(x, y, 5, 30, false);
//画出右边矩形
g.fill3DRect(x+15, y, 5, 30, false);
//画出中间矩形
g.fill3DRect(x+5, y+5, 10, 20, false);
//画出中间圆形
g.fillOval(x+5, y+10, 10, 10);
//画出中间直线
g.fillRect(x+9, y, 2, 10);
break;
}
}
} /*
画出左边矩形
g.fill3DRect(hero.getX(), hero.getY(), 5, 30, false);
//画出右边矩形
g.fill3DRect(hero.getX()+15, hero.getY(), 5, 30, false);
//画出中间矩形
g.fill3DRect(hero.getX()+5, hero.getY()+5, 10, 20, false);
//画出中间圆形
g.fillOval(hero.getX()+5, hero.getY()+10, 10, 10);
//画出中间直线
g.drawLine(hero.getX()+10, hero.getY()+15, 10, 20);
break; */

Tank大战 version2.0

java练习---->坦克大战2.0------>引入多线程

实现功能:
  1.有敌方tank与我方tank;

2.我方tank可以控制移动;

3.我方tank可以发射炮弹;

4.敌方tank未作处理;

 package TankGame2;

 import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.*;
import javax.swing.*;
public class MyTankGame2 extends JFrame
{
MyPanel mp=null;
public static void main(String[] args)
{
MyTankGame2 mytankgame1=new MyTankGame2();
} public MyTankGame2()
{
mp=new MyPanel();
//启动mp线程 Thread t=new Thread(mp);
t.start(); this.add(mp);
this.addKeyListener(mp); this.setSize(400,300);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
} class MyPanel extends JPanel implements KeyListener,Runnable
{
//定义我的坦克,成员变量
Hero hero=null; //定义敌人的坦克组 Vector<EnemyTank> ets=new Vector<EnemyTank>();
int enSize=3; public void paint (Graphics g)
{
super.paint(g);
g.fillRect(0,0,400,300); //画出自己的坦克
this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); //画出子弹
if (hero.s!=null&&hero.s.isLive==true)
{
g.draw3DRect(hero.s.x, hero.s.y, 1, 1, false); } //画出敌人的坦克
for(int i=0;i<ets.size();i++)
{ this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); } } //画出坦克函数(扩展)
public void drawTank(int x,int y,Graphics g,int direct,int type)
{
//判断类型
switch (type)
{
case 0:
g.setColor(Color.cyan);break;
case 1:
g.setColor(Color.yellow);break;
}
//判断方向 switch(direct)
{
//向上
case 0:
//画出我的坦克(到时候再封装成一个函数)
//1.画出左面的矩形
//g.drawRect(hero.getX(), hero.getY(), 5, 30);
g.fill3DRect(x,y,5,30,false); //2.画出右边的矩形
g.fill3DRect(x+15,y,5,30,false); //3.画出坦克的中间矩形
g.fill3DRect(x+5, y+5, 10, 20,false);
//画出中间的圆
g.fillOval(x+4, y+10,10,10);
//画出线
g.drawLine(x+9, y+15, x+9, y);
break;
case 1:
//炮筒向右
//画出上面的矩形
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x+30, y+10); break;
case 2:
//向下
g.fill3DRect(x,y,5,30,false);
g.fill3DRect(x+15,y,5,30,false);
g.fill3DRect(x+5, y+5, 10, 20,false);
g.fillOval(x+4, y+10,10,10);
g.drawLine(x+10, y+15, x+10, y+30);
break; case 3:
//向左
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x, y+10);
break;
} } public MyPanel()
{
hero=new Hero(100,100); //初始化敌人的坦克
for(int i=0;i<enSize;i++)
{
//创建敌人的坦克对象
EnemyTank et=new EnemyTank((i+1)*50,0);
et.setColor(0);
et.setDirect(2);
ets.add(et);
} } //键按下处理a表示左,s表示向下,w表示向上,d表示向右
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_UP)
{
// 设置我的坦克的方向
this.hero.setDirect(0);
this.hero.moveUp();
} else if (e.getKeyCode()==KeyEvent.VK_DOWN)
{
this.hero.setDirect(2);
this.hero.moveDown();
} else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
{
this.hero.setDirect(1);
this.hero.moveRight(); }
else if (e.getKeyCode()==KeyEvent.VK_LEFT)
{
this.hero.setDirect(3);
this.hero.moveLeft();
} if (e.getKeyCode()==KeyEvent.VK_SPACE)
{
this.hero.shotEnemy(); } //必须重新绘制Panel
this.repaint();
} public void keyReleased(KeyEvent e) //有什么用?!!!!!!!!!!!
{ }
public void keyTyped(KeyEvent e)
{ }
public void run()
{
//每个一百毫秒去重画子弹
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.repaint(); }
} } class Tank
{ //设置坦克的速度
int speed=1;
public int getSpeed()
{
return speed;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
//表示坦克的横坐标
int x=0;
//坦克的纵坐标
int y=0;
int direct=0;
int color; //坦克方向,0表示上,1表示右,2表示下,3表示左
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getDirect()
{
return direct;
} public void setDirect(int direct)
{
this.direct = direct;
}
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;
} } class EnemyTank extends Tank
{
public EnemyTank(int x,int y)
{
super(x,y); //super的用法??? }
} //我的坦克
class Hero extends Tank
{
//子弹
Shot s=null;
public Hero(int x, int y)
{
super(x,y);
}
//坦克向上移动 //坦克的开火的能力和动作
public void shotEnemy()
{
switch(this.direct)
{
case 0:
s=new Shot(x+9,y-1,0);
break;
case 1:
s=new Shot(x+30,y+10,1);
break;
case 2:
s=new Shot(x+9,y+30,2);
break;
case 3:
s=new Shot(x-1,y+9,3);
break;
} Thread t=new Thread(s);
t.start(); } public void moveUp()
{
this.y-=speed;
}
public void moveRight()
{
this.x+=speed;
} public void moveDown()
{
this.y+=speed;
}
public void moveLeft()
{
this.x-=speed;
}
} class Shot implements Runnable //runnable的用法????
{
int x;
int y;
int direct;
int speed=1;
//是否活着 boolean isLive=true;
public Shot(int x,int y,int direct)
{
this.x=x;
this.y=y;
this.direct=direct;
}
public void run()
{
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} switch(direct)
{
case 0:
//向上
y-=speed;break;
case 1:
x+=speed;break;
case 2:
y+=speed;break;
case 3:
x-=speed;break; } //判断该子弹是否碰到边缘
if(x<0||x>400||y<0||y>300)
{
this.isLive=false;
break; } } }
}

Tank大战 version3.0

java练习---->坦克大战3.0

实现功能:
  1.有敌方tank与我方tank;

2.我方tank可以控制移动,可以发射炮弹;

3.写一个函数专门判断子弹是否击中敌人坦克;

4.判断tank是否活着;

(注:本版本中,Tank是不可以发射炮弹的······)

 package TankGame3;

 import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.*;
import javax.swing.*;
import java.util.Vector;
public class MyTankGame4 extends JFrame
{
MyPanel mp=null;
public static void main(String[] args)
{
MyTankGame4 mytankgame1=new MyTankGame4();
} public MyTankGame4()
{
mp=new MyPanel();
//启动mp线程 Thread t=new Thread(mp);
t.start(); this.add(mp);
this.addKeyListener(mp); this.setSize(400,300);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class MyPanel extends JPanel implements KeyListener,Runnable
{
//定义我的坦克,成员变量
Hero hero=null; //定义敌人的坦克组 Vector<EnemyTank> ets=new Vector<EnemyTank>();
int enSize=3; public void paint (Graphics g)
{
super.paint(g);
g.fillRect(0,0,400,300); //画出自己的坦克
this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); //从Vector ss中取出每一颗子弹,并画出
for(int i=0;i<this.hero.ss.size();i++)
{
Shot myShot=hero.ss.get(i); //画出子弹,只画一颗子弹
if (myShot!=null&&myShot.isLive==true)
{
g.draw3DRect(myShot.x, myShot.y, 1, 1, false); }
if (myShot.isLive==false)
{
//从ss中删除该子弹
hero.ss.remove(myShot); }
} //画出敌人的坦克
for(int i=0;i<ets.size();i++)
{
EnemyTank et=ets.get(i);
if(et.isLive)
{
this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
}
} } //写一个函数专门判断子弹是否击中敌人坦克
public void hitTank(Shot s,EnemyTank et)
{
//判断该坦克的方向
switch(et.direct)
{
//如果敌人的方向是上或者是下
case 0:
case 2:
if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
{
//击中了
//子弹死亡
s.isLive=false;
//敌人坦克也要死亡
et.isLive=false;
}
case 1:
case 3:
if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
{
//击中了
//子弹死亡
s.isLive=false;
//敌人坦克也要死亡
et.isLive=false; } } } //画出坦克函数(扩展)
public void drawTank(int x,int y,Graphics g,int direct,int type)
{
//判断类型
switch (type)
{
case 0:
g.setColor(Color.cyan);break;
case 1:
g.setColor(Color.yellow);break;
}
//判断方向 switch(direct)
{
//向上
case 0:
//画出我的坦克(到时候再封装成一个函数)
//1.画出左面的矩形
//g.drawRect(hero.getX(), hero.getY(), 5, 30);
g.fill3DRect(x,y,5,30,false); //2.画出右边的矩形
g.fill3DRect(x+15,y,5,30,false); //3.画出坦克的中间矩形
g.fill3DRect(x+5, y+5, 10, 20,false);
//画出中间的圆
g.fillOval(x+4, y+10,10,10);
//画出线
g.drawLine(x+9, y+15, x+9, y);
break;
case 1:
//炮筒向右
//画出上面的矩形
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x+30, y+10); break;
case 2:
//向下
g.fill3DRect(x,y,5,30,false);
g.fill3DRect(x+15,y,5,30,false);
g.fill3DRect(x+5, y+5, 10, 20,false);
g.fillOval(x+4, y+10,10,10);
g.drawLine(x+10, y+15, x+10, y+30);
break; case 3:
//向左
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x, y+10);
break;
} } public MyPanel()
{
hero=new Hero(100,100); //初始化敌人的坦克
for(int i=0;i<enSize;i++)
{
//创建敌人的坦克对象
EnemyTank et=new EnemyTank((i+1)*50,0);
et.setColor(0);
et.setDirect(2);
ets.add(et);
} } //键按下处理a表示左,s表示向下,w表示向上,d表示向右
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_W)
{
// 设置我的坦克的方向
this.hero.setDirect(0);
this.hero.moveUp();
} else if (e.getKeyCode()==KeyEvent.VK_S)
{
this.hero.setDirect(2);
this.hero.moveDown();
} else if (e.getKeyCode()==KeyEvent.VK_D)
{
this.hero.setDirect(1);
this.hero.moveRight(); }
else if (e.getKeyCode()==KeyEvent.VK_A)
{
this.hero.setDirect(3);
this.hero.moveLeft();
} if (e.getKeyCode()==KeyEvent.VK_J)
{
this.hero.shotEnemy();
} //必须重新绘制Panel
this.repaint();
}
public void keyReleased(KeyEvent e)
{ }
public void keyTyped(KeyEvent e)
{ }
public void run()
{
//每个一百毫秒去重画子弹
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} for(int i=0;i<hero.ss.size();i++)
{
Shot myShot=hero.ss.get(i);
//判断子弹是否有效
if(myShot.isLive)
{
//取出每个坦克,与它判断
for(int j=0;j<ets.size();j++)
{
//取出坦克
EnemyTank et=ets.get(j);
if(et.isLive)
{
this.hitTank(myShot,et); } } }
} this.repaint(); }
} } //package MyTankGame4;
//import java.util.Vector;
//import MyTankGame4.Shot;
//import MyTankGame4.Tank;
class Tank
{ //设置坦克的速度
int speed=1;
public int getSpeed()
{
return speed;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
//表示坦克的横坐标
int x=0;
//坦克的纵坐标
int y=0;
int direct=0;
int color; //坦克方向,0表示上,1表示右,2表示下,3表示左
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getDirect()
{
return direct;
} public void setDirect(int direct)
{
this.direct = direct;
}
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;
} } class EnemyTank extends Tank
{
boolean isLive=true;
public EnemyTank(int x,int y)
{
super(x,y); }
} //我的坦克
class Hero extends Tank
{
//子弹
//Shot s=null;
Vector<Shot> ss=new Vector<Shot>();
Shot s=null; public Hero(int x, int y)
{
super(x,y);
}
//坦克向上移动 //坦克的开火的能力和动作
public void shotEnemy()
{
switch(this.direct)
{
case 0:
s=new Shot(x+9,y-1,0);
ss.add(s);
break;
case 1:
s=new Shot(x+30,y+10,1);
ss.add(s);
break;
case 2:
s=new Shot(x+9,y+30,2);
ss.add(s);
break;
case 3:
s=new Shot(x-1,y+9,3); ss.add(s);
ss.add(s);
break;
} Thread t=new Thread(s);
t.start(); } public void moveUp()
{
this.y-=speed;
}
public void moveRight()
{
this.x+=speed;
} public void moveDown()
{
this.y+=speed;
}
public void moveLeft()
{
this.x-=speed;
}
}
class Shot implements Runnable
{
int x;
int y;
int direct;
int speed=1;
//是否活着 boolean isLive=true;
public Shot(int x,int y,int direct)
{
this.x=x;
this.y=y;
this.direct=direct;
}
public void run()
{
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} switch(direct)
{
case 0:
//向上
y-=speed;break;
case 1:
x+=speed;break;
case 2:
y+=speed;break;
case 3:
x-=speed;break; } //判断该子弹是否碰到边缘
if(x<0||x>400||y<0||y>300)
{
this.isLive=false;
break; } } }
}

Tank大战 version4.0

java练习---->坦克大战4.0

实现功能:
  1.有敌方tank与我方tank;

2.双方都可以控制移动,可以发射炮弹;

3.敌方坦克可以被击中消失

4.有爆炸效果;

5.可以计算生命值和炸弹生命;

 package TankGame4;
//package MyTankGame4;
import java.util.Vector;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.*;
import javax.swing.*;
public class MyTankGame4 extends JFrame
{
MyPanel mp=null;
public static void main(String[] args)
{
MyTankGame4 mytankgame1=new MyTankGame4();
} public MyTankGame4()
{
mp=new MyPanel();
//启动mp线程 Thread t=new Thread(mp); t.start(); this.add(mp);
this.addKeyListener(mp); this.setSize(400,300);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class MyPanel extends JPanel implements KeyListener,Runnable
{
//定义我的坦克,成员变量
Hero hero=null; //定义敌人的坦克组 Vector<EnemyTank> ets=new Vector<EnemyTank>();
int enSize=5; //定义炸弹集合
Vector<Bomb> bombs=new Vector<Bomb>(); public void run()
{
//每个一百毫秒去重画子弹
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} for(int i=0;i<hero.ss.size();i++)
{
Shot myShot=hero.ss.get(i);
//判断子弹是否有效
if(myShot.isLive)
{
//取出每个坦克,与它判断
for(int j=0;j<ets.size();j++)
{
//取出坦克
EnemyTank et=ets.get(j);
if(et.isLive)
{
this.hitTank(myShot,et); }
} }
} this.repaint();
//判断是否需要给坦克加入新的子弹
for(int i=0;i<ets.size();i++)
{
EnemyTank et=ets.get(i);
if(et.isLive)
{
if (et.ss.size()<5&&(int)(100*Math.random())>75)
{
//每辆坦克的子弹少于5发的话
//添加
Shot s=null;
switch(et.direct)
{
case 0:
s=new Shot(et.x+9,et.y-1,0);
et.ss.add(s);
break;
case 1:
s=new Shot(et.x+30,et.y+10,1);
et.ss.add(s);
break;
case 2:
s=new Shot(et.x+9,et.y+30,2);
et.ss.add(s);
break;
case 3:
s=new Shot(et.x-1,et.y+9,3);
et.ss.add(s);
break;
} //启动子弹线程
Thread t=new Thread(s);
t.start(); } }
} } } public void paint (Graphics g)
{
super.paint(g);
g.fillRect(0,0,400,300); //画出自己的坦克
this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); //从Vector ss中取出每一颗子弹,并画出
for(int i=0;i<this.hero.ss.size();i++)
{
Shot myShot=hero.ss.get(i); //画出子弹,只画一颗子弹
if (myShot!=null&&myShot.isLive==true)
{
g.draw3DRect(myShot.x, myShot.y, 1, 1, false); }
if (myShot.isLive==false)
{
//从ss中删除该子弹
hero.ss.remove(myShot); }
} //画出炸弹
for(int i=0;i<bombs.size();i++)
{
// 取出炸弹
Bomb b=bombs.get(i); if(b.life>6)
{
g.drawImage(image1, b.x, b.y, 30,30,this);
}
else if(b.life>3)
{
g.drawImage(image2, b.x, b.y, 30,30,this);
}
else
{
g.drawImage(image3, b.x, b.y, 30,30,this);
}
//让b的生命值减小
b.lifeDown();
//如果炸弹的生命值为0,我们就剔除
if(b.life==0) bombs.remove(b); } //画出敌人的坦克
for(int i=0;i<ets.size();i++)
{
EnemyTank et=ets.get(i);
if(et.isLive)
{
this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
//画出敌人的子弹 for(int j=0;j<et.ss.size();j++)
{
//取出子弹
Shot enemyShot=et.ss.get(j);
if(enemyShot.isLive)
{
g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
}
else
{
//如果敌人的坦克死亡就从Vector去掉
et.ss.remove(enemyShot); } }
}
} } //写一个函数专门判断子弹是否击中敌人坦克
public void hitTank(Shot s,EnemyTank et)
{
//判断该坦克的方向
switch(et.direct)
{
//如果敌人的方向是上或者是下
case 0:
case 2:
if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
{
//击中了
//子弹死亡
s.isLive=false;
//敌人坦克也要死亡
et.isLive=false;
//创建一个炸弹,放入Vector
Bomb b=new Bomb(et.x,et.y);
//放入Vector
bombs.add(b);
}
case 1:
case 3:
if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
{
//击中了
//子弹死亡
s.isLive=false;
//敌人坦克也要死亡
et.isLive=false;
//创建一个炸弹,放入Vector
Bomb b=new Bomb(et.x,et.y);
//放入Vector
bombs.add(b);
} } } //画出坦克函数(扩展)
public void drawTank(int x,int y,Graphics g,int direct,int type)
{
//判断类型
switch (type)
{
case 0:
g.setColor(Color.cyan);break;
case 1:
g.setColor(Color.yellow);break;
}
//判断方向 switch(direct)
{
//向上
case 0:
//画出我的坦克(到时候再封装成一个函数)
//1.画出左面的矩形
//g.drawRect(hero.getX(), hero.getY(), 5, 30);
g.fill3DRect(x,y,5,30,false); //2.画出右边的矩形
g.fill3DRect(x+15,y,5,30,false); //3.画出坦克的中间矩形
g.fill3DRect(x+5, y+5, 10, 20,false);
//画出中间的圆
g.fillOval(x+4, y+10,10,10);
//画出线
g.drawLine(x+9, y+15, x+9, y);
break;
case 1:
//炮筒向右
//画出上面的矩形
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x+30, y+10); break;
case 2:
//向下
g.fill3DRect(x,y,5,30,false);
g.fill3DRect(x+15,y,5,30,false);
g.fill3DRect(x+5, y+5, 10, 20,false);
g.fillOval(x+4, y+10,10,10);
g.drawLine(x+10, y+15, x+10, y+30);
break; case 3:
//向左
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x, y+10);
break;
} } //定义三张图片,三张图片切换组成一颗炸弹
Image image1=null;
Image image2=null;
Image image3=null; //构造函数
public MyPanel()
{
hero=new Hero(100,100); //初始化敌人的坦克
for(int i=0;i<enSize;i++)
{
//创建敌人的坦克对象
EnemyTank et=new EnemyTank((i+1)*50,0);
et.setColor(0);
et.setDirect(2);
//启动敌人的坦克 Thread t=new Thread(et);
t.start();
//给敌人坦克添加一颗子弹
Shot s=new Shot(et.x+10,et.y+30,2);
et.ss.add(s);
Thread t2=new Thread(s);
t2.start();
//加入 ets.add(et);
} image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));
image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg"));
image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg")); } //键按下处理向左,向下,向上,向右
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_UP)
{
// 设置我的坦克的方向
this.hero.setDirect(0);
this.hero.moveUp();
} else if (e.getKeyCode()==KeyEvent.VK_DOWN)
{
this.hero.setDirect(2);
this.hero.moveDown();
} else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
{
this.hero.setDirect(1);
this.hero.moveRight(); }
else if (e.getKeyCode()==KeyEvent.VK_LEFT)
{
this.hero.setDirect(3);
this.hero.moveLeft();
} if (e.getKeyCode()==KeyEvent.VK_J)
{
this.hero.shotEnemy(); }
//必须重新绘制Panel
this.repaint();
}
public void keyReleased(KeyEvent e)
{ }
public void keyTyped(KeyEvent e)
{ } } class Tank
{ //设置坦克的速度
int speed=3;
public int getSpeed()
{
return speed;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
//表示坦克的横坐标
int x=0;
//坦克的纵坐标
int y=0;
int direct=0;
int color; //坦克方向,0表示上,1表示右,2表示下,3表示左
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getDirect()
{
return direct;
} public void setDirect(int direct)
{
this.direct = direct;
}
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;
} } class EnemyTank extends Tank implements Runnable
{
boolean isLive=true; //定义一个向量,可以存放敌人的子弹 Vector<Shot> ss=new Vector<Shot>();
//敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后 public EnemyTank(int x,int y)
{
super(x,y); }
public void run() {
while(true)
{ //移动前进
switch(this.direct)
{
case 0:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(y>=speed)
{
y-=speed;
}
}
break;
case 1:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(x<=400-(speed+30))
{
x+=speed;
}
}
break;
case 2:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(y<=300-(speed+30))
{
y+=speed;
}
}
break;
case 3:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(x>=speed)
{
x-=speed;
} }
break; } //让坦克随机产生一个新的方向
if(Math.random()>0.50)
this.direct=(int)(Math.random()*4); //判断敌人坦克是否死亡
if(this.isLive==false)
{
//让坦克死亡后,退出线程
break;
} } }
} //我的坦克
class Hero extends Tank
{
//子弹
//Shot s=null;
Vector<Shot> ss=new Vector<Shot>();
Shot s=null; public Hero(int x, int y)
{
super(x,y);
}
//坦克向上移动 //坦克的开火的能力和动作
public void shotEnemy()
{
switch(this.direct)
{
case 0:
s=new Shot(x+9,y-1,0);
ss.add(s);
break;
case 1:
s=new Shot(x+30,y+10,1);
ss.add(s);
break;
case 2:
s=new Shot(x+9,y+30,2);
ss.add(s);
break;
case 3:
s=new Shot(x-1,y+9,3); ss.add(s);
ss.add(s);
break;
} Thread t=new Thread(s);
t.start(); } public void moveUp()
{
this.y-=speed;
}
public void moveRight()
{
this.x+=speed;
} public void moveDown()
{
this.y+=speed;
}
public void moveLeft()
{
this.x-=speed;
}
} class Shot implements Runnable
{
int x;
int y;
int direct;
int speed=1;
//是否活着 boolean isLive=true;
public Shot(int x,int y,int direct)
{
this.x=x;
this.y=y;
this.direct=direct;
}
public void run()
{
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} switch(direct)
{
case 0:
//向上
y-=speed;break;
case 1:
x+=speed;break;
case 2:
y+=speed;break;
case 3:
x-=speed;break; } //子弹何时死亡?
//判断该子弹是否碰到边缘
if(x<0||x>400||y<0||y>300)
{
this.isLive=false;
break; } } }
}
class Bomb
{
//定义炸弹的坐标
int x,y;
//炸弹的生命
int life=9;
boolean isLive=true;
public Bomb(int x,int y)
{
this.x=x;
this.y=y;
}
//减少生命值
public void lifeDown()
{
if(life >0) {life--;}
else {this.isLive=false;} } }

Tank大战 version5.0

java练习---->坦克大战5.0

实现功能:
  1.在原有基础啊上进行优化和功能完善;

2.增加闯关功能等;

3.完结版!!!!!

 package TankGame5;

 import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.io.*;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*; public class MyTankGame5 extends JFrame implements ActionListener
{
//声明一个标志
int flag=0;
// 声明一个运行面板
MyPanel mp=null;
//定义一个开始的面板
MyStartPanel msp=null; //做出我需要的菜单
JMenuBar jmb=null;
//开始游戏
JMenu jm1=null;
JMenuItem jmi1=null;
//退出系统
JMenuItem jmi2=null;
JMenuItem jmi3=null;
JMenuItem jmi4=null; public static void main(String[] args)
{
MyTankGame5 mytankgame1=new MyTankGame5();
mytankgame1.setLocationRelativeTo(null);//将JFrame设置在中间
// mytankgame1.setLocation(210,140);//设置JFrame的位置
} public MyTankGame5() //构造
{//初始化菜单栏
jmb=new JMenuBar();
jm1=new JMenu("游戏(G)"); //设置快捷方式
jm1.setMnemonic('G');
jmi1=new JMenuItem("开始新游戏(N)");
jmi2=new JMenuItem("退出游戏(E)");
jmi3=new JMenuItem("存盘退出(C)");
jmi4=new JMenuItem("继续上次游戏(L)"); jmi1.setMnemonic('N');
jmi2.setMnemonic('E');
jmi3.setMnemonic('C');
jmi4.setMnemonic('L'); //对jmi1响应,注册监听,标记消息源
jmi1.addActionListener(this);
jmi1.setActionCommand("new game"); jmi2.addActionListener(this);
jmi2.setActionCommand("exit"); jmi3.addActionListener(this);
jmi3.setActionCommand("save and exit"); jmi4.addActionListener(this);
jmi4.setActionCommand("continue game"); 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.add(msp);
this.setSize(400,300);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
//对用户不同的点击做出不同的处理
// 首先得到command字符串,判断消息源
if(e.getActionCommand().equals("new game"))
{
this.setSize(600,500);
mp=new MyPanel(flag);
//启动mp线程 Thread t1=new Thread(mp); t1.start();
//先删除旧的面板
this.remove(msp); this.add(mp);
//注册监听
this.addKeyListener(mp);
//显示
this.setVisible(true);
}
else if(e.getActionCommand().equals("exit"))
{
//用户退出
//保存击毁敌人数量
Recorder.keepRecording();
System.exit(0);
} else if(e.getActionCommand().equals("save and exit"))
{
Recorder.keepRecAndEnemyTank(mp.ets);
if(this.mp.hero.isLive==true)
{
Recorder.keepRecAndMyTank(this.mp.hero); }
System.exit(0);
}
else if(e.getActionCommand().equals("continue game"))
{
this.setSize(600,500);
flag=1;
mp=new MyPanel(flag);
//启动mp线程 Thread t1=new Thread(mp); t1.start();
//先删除旧的面板
this.remove(msp); this.add(mp);
//注册监听
this.addKeyListener(mp);
//显示
this.setVisible(true);
}
}
} //开始面板起一个提示的作用
class MyStartPanel extends JPanel implements Runnable
{
int times=0;
public void paint(Graphics g)
{
super.paint(g);
g.fillRect(0, 0, 400, 300);
//提示信息
if(times%2==0)
{
g.setColor(Color.yellow);
//开关信息的字体
try{
Font myFont=new Font("华文新魏",Font.BOLD,30);
g.setFont(myFont);
} catch(Exception e){e.printStackTrace();} g.drawString("stage:1", 150, 150);
}
}
public void run()
{
while(true)
{
try {
Thread.sleep(500);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.repaint();
times++;
if(times==1000) times=0;
}
} } class MyPanel extends JPanel implements KeyListener,Runnable
{
//定义我的坦克,成员变量
Hero hero=null; //判断是续上局还是新的游戏
String flag="newGame"; //定义敌人的坦克组 Vector<EnemyTank> ets=new Vector<EnemyTank>();
// 全局变量,声明,敌人坦克数量
static int enSize=5;
public static int getEnSize() {
return enSize;
}
//定义炸弹集合
Vector<Bomb> bombs=new Vector<Bomb>();
// paint 方法被面板适时自动调用
public void paint (Graphics g)
{
super.paint(g);
g.fillRect(0,0,400,300); //画出提示信息
this.showInfo(g); //画出自己的坦克
if(hero.isLive==true)
{
this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
}
//从Vector ss中取出每一颗子弹,并画出,如果有子弹
for(int i=0;i<this.hero.ss.size();i++)
{
Shot myShot=hero.ss.get(i); //画出子弹,只画一颗子弹
if (myShot!=null&&myShot.isLive==true)
{
g.draw3DRect(myShot.x, myShot.y, 1, 1, false); }
if (myShot.isLive==false)
{
//从ss中删除该子弹
hero.ss.remove(myShot); }
} //画出炸弹
for(int i=0;i<bombs.size();i++)
{
// 取出炸弹
Bomb b=bombs.get(i); if(b.life>6)
{
g.drawOval(b.x, b.y, 30, 30);
// g.drawImage(image1, b.x, b.y, 30,30,this);
}
else if(b.life>3)
{
g.drawOval(b.x, b.y, 20, 20);
// g.drawImage(image2, b.x, b.y, 30,30,this); }
else
{
g.drawOval(b.x, b.y, 10, 10);
// g.drawImage(image3, b.x, b.y, 30,30,this);
}
//让b的生命值减小
b.lifeDown();
//如果炸弹的生命值为0,我们就剔除
if(b.life==0) bombs.remove(b); } //画出敌人的坦克
for(int i=0;i<ets.size();i++)
{
EnemyTank et=ets.get(i);
if(et.isLive)
{
this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
//画出敌人的子弹 for(int j=0;j<et.ss.size();j++)
{
//取出子弹
Shot enemyShot=et.ss.get(j);
if(enemyShot.isLive)
{
g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
}
else
{
//如果敌人的坦克死亡就从Vector去掉
et.ss.remove(enemyShot); } }
}
} }
//判断我是否被击中了
public void hitMe()
{
//取出敌人的每一颗子弹 for(int i=0;i<this.ets.size();i++)
{
//取出坦克
EnemyTank et=ets.get(i); //取出每一颗子弹
for (int j=0;j<et.ss.size();j++)
{
//取出子弹
Shot enemyShot=et.ss.get(j);
if(hero.isLive)//&&Recorder.getMyLife()>=1
{
this.hitTank(enemyShot, hero);
//Recorder.setMyLife(Recorder.getMyLife()-1);
} } } } //判断我的子弹是否击中敌人的坦克
public void hitEnemyTank()
{
for(int i=0;i<hero.ss.size();i++)
{
Shot myShot=hero.ss.get(i);
//判断子弹是否有效
if(myShot.isLive)
{
//取出每个坦克,与它判断
for(int j=0;j<ets.size();j++)
{
//取出坦克
EnemyTank et=ets.get(j);
if(et.isLive)
{
this.hitTank(myShot,et); }
} }
} } //写一个函数专门判断子弹是否击中敌人坦克
public void hitTank(Shot s,Tank et)
{
//判断该坦克的方向
switch(et.direct)
{
//如果敌人的方向是上或者是下
case 0:
case 2:
if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
{
//击中了
//子弹死亡
s.isLive=false;
//敌人坦克也要死亡
et.isLive=false;
//减少敌人数量
if (et.getClass()==EnemyTank.class)//反射机制
{
Recorder.reduceEnNum();
//增加我的记录
Recorder.addEnNumRec();
} if (et.getClass()==Hero.class)//反射机制
{ }
//创建一个炸弹,放入Vector
Bomb b=new Bomb(et.x,et.y);
//放入Vector
bombs.add(b);
}
case 1:
case 3:
if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
{
//击中了
//子弹死亡
s.isLive=false;
//敌人坦克也要死亡
et.isLive=false;
//减少敌人数量
if (et.getClass()==EnemyTank.class)//反射机制
{
Recorder.reduceEnNum();
//增加我的记录
Recorder.addEnNumRec();
} if (et.getClass()==Hero.class)//反射机制
{
Recorder.setMyLife(Recorder.getMyLife() - 1);
}
//创建一个炸弹,放入Vector
Bomb b=new Bomb(et.x,et.y);
//放入Vector
bombs.add(b);
} } } //画出坦克函数(扩展)
public void drawTank(int x,int y,Graphics g,int direct,int type)
{
//判断类型
switch (type)
{
case 0:
g.setColor(Color.cyan);break;
case 1:
g.setColor(Color.yellow);break;
}
//判断方向 switch(direct)
{
//向上
case 0:
//画出我的坦克(到时候再封装成一个函数)
//1.画出左面的矩形
//g.drawRect(hero.getX(), hero.getY(), 5, 30);
g.fill3DRect(x,y,5,30,false); //2.画出右边的矩形
g.fill3DRect(x+15,y,5,30,false); //3.画出坦克的中间矩形
g.fill3DRect(x+5, y+5, 10, 20,false);
//画出中间的圆
g.fillOval(x+4, y+10,10,10);
//画出线
g.drawLine(x+9, y+15, x+9, y);
break;
case 1:
//炮筒向右
//画出上面的矩形
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x+30, y+10); break;
case 2:
//向下
g.fill3DRect(x,y,5,30,false);
g.fill3DRect(x+15,y,5,30,false);
g.fill3DRect(x+5, y+5, 10, 20,false);
g.fillOval(x+4, y+10,10,10);
g.drawLine(x+10, y+15, x+10, y+30);
break; case 3:
//向左
g.fill3DRect(x,y,30, 5, false);
g.fill3DRect(x, y+15, 30, 5, false);
g.fill3DRect(x+5, y+5, 20, 10, false);
g.fillOval(x+10, y+5, 10, 10);
g.drawLine(x+15, y+10, x, y+10);
break;
} } public void run()
{
//每个一百毫秒去重画子弹
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} this.hitEnemyTank(); //函数,判断敌人的子弹是否击中我了
this.hitMe(); this.repaint();
//判断是否需要给坦克加入新的子弹
for(int i=0;i<ets.size();i++)
{
EnemyTank et=ets.get(i);
if(et.isLive)
{
if (et.ss.size()<3)
{
//没有子弹了
//添加
Shot s=null;
switch(et.direct)
{
case 0:
s=new Shot(et.x+9,et.y-1,0);
et.ss.add(s);
break;
case 1:
s=new Shot(et.x+30,et.y+10,1);
et.ss.add(s);
break;
case 2:
s=new Shot(et.x+9,et.y+30,2);
et.ss.add(s);
break;
case 3:
s=new Shot(et.x-1,et.y+9,3);
et.ss.add(s);
break;
} //启动子弹线程
Thread t=new Thread(s);
t.start();
}
}
}
}
}
//定义三张图片,三张图片切换组成一颗炸弹
Image image1=null;
Image image2=null;
Image image3=null;
int flagOfContinue;
//构造函数
public MyPanel(int flag)
{ this.flagOfContinue=flag;
//恢复记录
Recorder.getRecording(); if(this.flagOfContinue==0)
{
//如果不是继续上次就直接建一个
hero=new Hero(100,100);
//初始化敌人的坦克
for(int i=0;i<enSize;i++)
{
//创建敌人的坦克对象
EnemyTank et=new EnemyTank((i+1)*60,0);
et.setColor(0);
et.setDirect(2);
//将MyPanel的敌人坦克向量交给该敌人坦克
et.setEts(ets); //启动敌人的坦克 Thread t=new Thread(et);
t.start();
//给敌人坦克添加一颗子弹
Shot s=new Shot(et.x+10,et.y+30,2);
et.ss.add(s);
Thread t2=new Thread(s);
t2.start();
//加入 ets.add(et);
}
}
else if(this.flagOfContinue==1)
{
//如果是继续上次的就读取坐标
Vector<Node> nodes1=new Vector<Node>();
nodes1=Recorder.getNodes(); //初始化敌人的坦克
for(int i=0;i<nodes1.size();i++)
{
if(nodes1.get(i).type==0)
{
//创建敌人的坦克对象
EnemyTank et=new EnemyTank(nodes1.get(i).x,nodes1.get(i).y);
et.setColor(0);
et.setDirect(nodes1.get(i).direct);
//将MyPanel的敌人坦克向量交给该敌人坦克
et.setEts(ets); //启动敌人的坦克 Thread t=new Thread(et);
t.start();
//给敌人坦克添加一颗子弹
Shot s=new Shot(et.x+10,et.y+30,2);
et.ss.add(s);
Thread t2=new Thread(s);
t2.start();
//加入 ets.add(et);
}
else if(nodes1.get(i).type==1)
{
//如果保存有我上次的坦克的信息,就按照信息保存
hero=new Hero(nodes1.get(i).x,nodes1.get(i).y);
hero.setDirect(nodes1.get(i).direct);
}
} } // image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));//文件应该放在src文件夹里面
// image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg"));
// image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg"));
//关于图像我们使用好一点的方法,引入java.io.File;和java.io.IOException;
try
{
image1=ImageIO.read(new File("33.jpg"));//此时文件应该放在工程的根目录里面
image2=ImageIO.read(new File("22.jpg"));
image3=ImageIO.read(new File("11.jpg"));
}
catch (IOException e)
{
e.printStackTrace();
} }
//画出提示信息
public void showInfo(Graphics g)
{
//画出提示信息的坦克 ,该坦克不参加战斗
this.drawTank(80,330,g,0,0);
g.setColor(Color.black);
g.drawString(Recorder.getEnNum()+"",110,350); this.drawTank(150,330,g,0,1);
g.setColor(Color.black);
g.drawString(Recorder.getMyLife()+"",180,350);
//画出玩家的总成绩 g.setColor(Color.black);
try{
Font f=new Font("宋体",Font.BOLD,20);
g.setFont(f);
}catch(Exception e){ e.printStackTrace();}
g.drawString("您的总成绩:",420,40); this.drawTank(420, 60, g, 0, 0); g.setColor(Color.BLACK);
g.drawString(Recorder.getAllEnemy()+"",460,80); } //键按下处理a表示左,s表示向下,w表示向上,d表示向右
public void keyPressed(KeyEvent e)
{
if(hero.isLive)
{
if(e.getKeyCode()==KeyEvent.VK_UP&&hero.getY()>0)
{
// 设置我的坦克的方向
this.hero.setDirect(0);
this.hero.moveUp();
} else if (e.getKeyCode()==KeyEvent.VK_DOWN&&hero.getY()<270)
{
this.hero.setDirect(2);
this.hero.moveDown();
} else if (e.getKeyCode()==KeyEvent.VK_RIGHT&&hero.getX()<370)
{
this.hero.setDirect(1);
this.hero.moveRight(); }
else if (e.getKeyCode()==KeyEvent.VK_LEFT&&hero.getX()>0)
{
this.hero.setDirect(3);
this.hero.moveLeft();
} if (e.getKeyCode()==KeyEvent.VK_SPACE)
{
this.hero.shotEnemy();
} //必须重新绘制Panel
this.repaint();
}
}
public void keyReleased(KeyEvent e)
{ }
public void keyTyped(KeyEvent e)
{ } } //---------------------------------------------------- class Node
{
int x;
int y;
int direct;
int type;
public Node(int x,int y,int direct,int type)
{
this.x=x;
this.y=y;
this.direct=direct;
this.type=type;
} } //记录类
class Recorder
{
public static int getEnNum() {
return enNum;
}
public static void setEnNum(int enNum) {
Recorder.enNum = enNum;
}
public static int getMyLife() {
return myLife;
}
public static void setMyLife(int myLife) {
Recorder.myLife = myLife;
}
//记录每关多少敌人
private static int enNum=MyPanel.getEnSize();
//设置我有多少可以用的人
public static int myLife=3;
//记录总共消灭了多少敌人
private static int allEnNum=0;
//从文件中恢复记录点
static Vector<Node> nodes=new Vector<Node>();
private static FileWriter fw=null;
private static BufferedWriter bw=null;
private static FileReader fr=null;
private static BufferedReader br=null; public static Vector<Node> getNodes()
{
try {
fr=new FileReader("d:\\myRecording.txt");
br=new BufferedReader(fr);
String n=""; n=br.readLine();//读第一行
allEnNum=Integer.parseInt(n);
while((n=br.readLine())!=null)
{
String []xyz=n.split(" ");//按照空格返回数组,新技能
Node node=new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]),Integer.parseInt(xyz[3]));
nodes.add(node);
}
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try {
br.close();
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return nodes;
}
public static void keepRecAndEnemyTank(Vector<EnemyTank> ets)
{
try
{
//创建
fw=new FileWriter("d:\\myRecording.txt");
bw=new BufferedWriter(fw); bw.write(allEnNum+"\r\n"); //保存当前还活着的敌人坐标和方向
for(int i=0;i<ets.size();i++)
{
//取出第一个坦克
EnemyTank et=ets.get(i);
if(et.isLive)
{
//活着的保存
String record=et.x+" "+et.y+" "+et.direct+" "+0;
//写入
bw.write(record+"\r\n");
}
} }
catch (Exception e)
{
e.printStackTrace();
}
finally
{
//关闭流
try {
//谁先开谁后关
bw.close();
fw.close();
} catch (Exception e2) {
}
} } public static void keepRecAndMyTank(Hero hero)
{
try
{
//创建
fw=new FileWriter("d:\\myRecording.txt",true);//追加
bw=new BufferedWriter(fw); //保存当前我的坐标和方向
String record=hero.x+" "+hero.y+" "+hero.direct+" "+1;
//写入
bw.write(record+"\r\n"); } catch (Exception e)
{
e.printStackTrace();
}
finally
{
//关闭流
try
{
//谁先开谁后关
bw.close();
fw.close();
}
catch (Exception e2)
{
e2.printStackTrace();
}
} } //从文件中读取记录
public static void getRecording()
{
try {
fr=new FileReader("d:\\myRecording.txt");
br=new BufferedReader(fr);
String n=br.readLine();
allEnNum=Integer.parseInt(n);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try {
br.close();
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
} }
//把玩家击毁敌人的坦克数量保存到文件中
public static void keepRecording()
{
try
{
//创建
fw=new FileWriter("d:\\myRecording.txt");
bw=new BufferedWriter(fw); bw.write(allEnNum+"\r\n");
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
//关闭流
try {
//谁先开谁后关
bw.close();
fw.close();
} catch (Exception e2) {
}
}
} public static int getAllEnemy() {
return allEnNum;
}
public static void reduceEnNum()
{
enNum--;
} //消灭敌人
public static void addEnNumRec()
{
allEnNum++;
} } class Bomb
{
//定义炸弹的坐标
int x,y;
//炸弹的生命
int life=9;
boolean isLive=true;
public Bomb(int x,int y)
{
this.x=x;
this.y=y;
}
//减少生命值
public void lifeDown()
{
if(life >0) {life--;}
else {this.isLive=false;} }
} class Tank
{ //设置坦克的速度
int speed=3;
public int getSpeed()
{
return speed;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
//表示坦克的横坐标
int x=0;
//坦克的纵坐标
int y=0;
int direct=0;
int color;
boolean isLive=true; //坦克方向,0表示上,1表示右,2表示下,3表示左
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getDirect()
{
return direct;
} public void setDirect(int direct)
{
this.direct = direct;
}
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;
} } class EnemyTank extends Tank implements Runnable
{
//定义一个向量,可以访问到MyPanel上所有敌人的坦克
Vector<EnemyTank> ets=new Vector<EnemyTank>(); //定义一个向量,可以存放敌人的子弹 Vector<Shot> ss=new Vector<Shot>();
//敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后
public EnemyTank(int x,int y)
{
super(x,y);
} //得到MyPanel的敌人坦克向量
public void setEts(Vector<EnemyTank> vv)
{
this.ets=vv; } //判断是否碰到了别人的坦克
public boolean isTouchOtherEnemy()
{
boolean b=false; switch(this.direct)
{
case 0: //我的坦克向上
//取出所有的敌人坦克
for(int i=0;i<ets.size();i++)
{
//取出第一个坦克
EnemyTank et=ets.get(i);
//如果不是自己
if(et!=this)
{
//如果敌人的方向向上或者是向下
if(et.direct==0||et.direct==2)
{
if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
if(this.x+20>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
} } if(et.direct==1||et.direct==3)
{
if(this.x>=et.x&&this.x<=et.x+30&&this.y>=et.y&&this.y<=et.y+20)
{
return true;
}
if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
}
} } break;
case 1:
//坦克向右
//取出所有的敌人坦克
for(int i=0;i<ets.size();i++)
{
//取出第一个坦克
EnemyTank et=ets.get(i);
//如果不是自己
if(et!=this)
{
//如果敌人的方向向上或者是向下
if(et.direct==0||et.direct==2)
{
if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y+20>=et.y&&this.y+20<=et.y+30)
{
return true;
} } if(et.direct==1||et.direct==3)
{
if(this.x+30>=et.x&&this.x+30<=et.x+30&&this.y>=et.y&&this.y<=et.y+20)
{
return true;
}
if(this.x+30>=et.x && this.x+30<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20)
{
return true;
}
}
} } case 2:
//坦克向下
//取出所有的敌人坦克
for(int i=0;i<ets.size();i++)
{
//取出第一个坦克
EnemyTank et=ets.get(i);
//如果不是自己
if(et!=this)
{
//如果敌人的方向向上或者是向下
if(et.direct==0||et.direct==2)
{
if(this.x>=et.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30)
{
return true;
}
if(this.x+20>=et.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30)
{
return true;
} } if(et.direct==1||et.direct==3)
{
if(this.x+20>=et.x&&this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+20)
{
return true;
}
if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+30)
{
return true;
}
}
} }
break;
case 3 :
//坦克向左
//取出所有的敌人坦克
for(int i=0;i<ets.size();i++)
{
//取出第一个坦克
EnemyTank et=ets.get(i);
//如果不是自己
if(et!=this)
{
//如果敌人的方向向上或者是向下
if(et.direct==0||et.direct==2)
{
if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
} } if(et.direct==1||et.direct==3)
{
if(this.x>=et.x&&this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20)
{
return true;
}
if(this.x>=et.x && this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20)
{
return true;
}
}
} }
} return b;
} public void run() {
while(true)
{
switch(this.direct)
{
case 0:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(y>=speed && !this.isTouchOtherEnemy())
{
y-=speed;
}
}
break;
case 1:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(x<=(400-(speed+30))&& !this.isTouchOtherEnemy())
{
x+=speed;
}
}
break;
case 2:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(y<=(300-(speed+30))&& !this.isTouchOtherEnemy())
{
y+=speed;
}
}
break;
case 3:
for(int i=0;i<(int)(100*Math.random());i++)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
if(x>=speed && !this.isTouchOtherEnemy())
{
x-=speed;
} }
break; } //让坦克随机产生一个新的方向
this.direct=(int)(Math.random()*4); //判断敌人坦克是否死亡
if(this.isLive==false)
{
//让坦克死亡后,退出线程
break;
} } }
} //我的坦克
class Hero extends Tank
{
//子弹
//Shot s=null;
Vector<Shot> ss=new Vector<Shot>();
Shot s=null; public Hero(int x, int y)
{
super(x,y);
}
//坦克向上移动 //坦克的开火的能力和动作
public void shotEnemy()
{
switch(this.direct)
{
case 0:
s=new Shot(x+9,y-1,0);
ss.add(s);
break;
case 1:
s=new Shot(x+30,y+10,1);
ss.add(s);
break;
case 2:
s=new Shot(x+9,y+30,2);
ss.add(s);
break;
case 3:
s=new Shot(x-1,y+9,3); ss.add(s);
ss.add(s);
break;
} Thread t=new Thread(s);
t.start(); } public void moveUp()
{
this.y-=speed;
}
public void moveRight()
{
this.x+=speed;
} public void moveDown()
{
this.y+=speed;
}
public void moveLeft()
{
this.x-=speed;
}
} class Shot implements Runnable
{
int x;
int y;
int direct;
int speed=2;
//是否活着 boolean isLive=true;
public Shot(int x,int y,int direct)
{
this.x=x;
this.y=y;
this.direct=direct;
}
public void run()
{
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} switch(direct)
{
case 0:
//向上
y-=speed;break;
case 1:
x+=speed;break;
case 2:
y+=speed;break;
case 3:
x-=speed;break; } //子弹何时死亡?
//判断该子弹是否碰到边缘
if(x<0||x>400||y<0||y>300)
{
this.isLive=false;
break; } } }
}

注:如果大家很多java基础内容不是很清楚,可以观看韩顺平的java学习视频,跟着教程做程序,效果很明显!(●ˇ∀ˇ●)

Java__线程---基础知识全面实战---坦克大战系列为例的更多相关文章

  1. java线程基础知识----线程与锁

    我们上一章已经谈到java线程的基础知识,我们学习了Thread的基础知识,今天我们开始学习java线程和锁. 1. 首先我们应该了解一下Object类的一些性质以其方法,首先我们知道Object类的 ...

  2. java线程基础知识----线程基础知识

    不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...

  3. Windows核心编程 第六章 线程基础知识 (上)

    第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ...

  4. Vue学习之--------消息订阅和发布、基础知识和实战应用(2022/8/24)

    文章目录 1.基础知识 2.代码实例 2.1 main.js 2.2 School.vue 2.3 Student.vue 2.4 App.vue 3.全局事件总线通信改为消息的订阅和发布 3.1 核 ...

  5. 密码基础知识(2)以RSA为例说明加密、解密、签名、验签

    密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...

  6. Java并发之线程管理(线程基础知识)

    因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...

  7. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

  8. java线程基础知识----java daemon线程

    java线程是一个运用很广泛的重点知识,我们很有必要了解java的daemon线程. 1.首先我们必须清楚的认识到java的线程分为两类: 用户线程和daemon线程 A. 用户线程: 用户线程可以简 ...

  9. java并发编程(一)----线程基础知识

    在任何的生产环境中我们都不可逃避并发这个问题,多线程作为并发问题的技术支持让我们不得不去了解.这一块知识就像一个大蛋糕一样等着我们去分享,抱着学习的心态,记录下自己对并发的认识. 1.线程的状态: 线 ...

随机推荐

  1. SQL Server 获取 ActiveDirectory 用户信息

    SQL Server 是可以访问活动目录中的用户信息的. 1. 先用domain administrator建立一个linked server 2. 然后用OpenQuery去查询活动目录   大家可 ...

  2. yum程序下载被占用

    Loaded plugins: fastestmirror, refresh-packagekit, security Existing lock /var/run/yum.pid: another ...

  3. 微信跳转ticket值怎么得到?浏览器跳到微信?哪里有微信跳转接口?跳转功能能用多久?

    目前很多实用微信跳转技术的电商朋友,网站文章头部或者文章中部出现了点击关注微信关注的二维码,用户点击进去直接跳转到微信内打开指定的二维码,识别即可关注,方便省事,比以往的一键复制—粘贴微信号,转化效果 ...

  4. C++进阶:新人易入的那些坑 --1.常量、常指针和指针常量

    声明:以下内容B站/Youtube学习笔记,https://www.youtube.com/user/BoQianTheProgrammer/ Advanced C++. /* why use con ...

  5. asp.net core 下载文件,上传excel文件

    下载文件: 代码: 后端代码: public IActionResult DownloadFile() { var FilePath = @"./files/deparment.xlsx&q ...

  6. numpy地址

    pip安装  http://zhidao.baidu.com/link?url=nkRwDOZ1ALMjRsWHGMR1nLSIyuVycoD4j-mhGDsYptPwDRGYcE8u4_B9VvYk ...

  7. oracle中文乱码问题解决

    中文乱码问题解决:1.查看服务器端编码select userenv('language') from dual;我实际查到的结果为:AMERICAN_AMERICA.ZHS16GBK2.执行语句 se ...

  8. unity网络----简单基础

    网络 TCP:与打电话类似,通知服务到位 UDP:与发短信类似,消息发出即可 IP和端口号是网络两大重要成员 端口号(Port)分为知名端口号[0-1024,不开放)和动态端口号[1024,10000 ...

  9. 整理4种Vue组件通信方式

    整理4种Vue组件通信方式 重点是梳理了前两个,父子组件通信和eventBus通信,我觉得Vue文档里的说明还是有一些简易,我自己第一遍是没看明白. 父子组件的通信 非父子组件的eventBus通信 ...

  10. Android 音视频开发(七): 音视频录制流程总结

    在前面我们学习和使用了AudioRecord.AudioTrack.Camera.MediaExtractor.MediaMuxer API.MediaCodec. 学习和使用了上述的API之后,相信 ...