今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过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. Codeforces 1144F Graph Without Long Directed Paths (DFS染色+构造)

    <题目链接> 题目大意:给定一个无向图,该无向图不含自环,且无重边.现在要你将这个无向图定向,使得不存在任何一条路径长度大于等于2.然后根输入边的顺序,输出构造的有向图.如果构造的边与输入 ...

  2. 2013年省赛I题 Thrall’s Dream

    2013年省赛I题判断单向联通,用bfs剪枝:从小到大跑,如果遇到之前跑过的点(也就是编号小于当前点的点),就o(n)传递关系. bfs #include<iostream> #inclu ...

  3. JTAG各类接口针脚定义及含义

    注:转自 揽月阁 JTAG有10pin的.14pin的和20pin的,尽管引脚数和引脚的排列顺序不同,但是其中有一些引脚是一样的,各个引脚的定义如下. 一.引脚定义 Test Clock Input ...

  4. 七牛云音频转码准备工作之如何创建音视频处理私有队列pipeline

    如何创建音视频处理私有队列 最近更新时间:2017-08-28 15:54:45 在七牛进行音视频处理,推荐使用私有队列(pipeline). 创建私有队列方法如下: 第一步 登录七牛开发者平台 ht ...

  5. pom string

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  6. vue-cli跳转到新页面的顶部

    我这里有两种方法都是可以用的 1,利用vue-router的默认模式hash,可以记录上一页的位置,如果需要点话,如果没有记录,在进入新页面的时候是返回到新页面的最顶部的 scrollBehavior ...

  7. [LeetCode] Mirror Reflection 镜面反射

    There is a special square room with mirrors on each of the four walls.  Except for the southwest cor ...

  8. 4.再来看看逆向——OD的简介

    目录 1.前言 2.一些设置和配置 3.开始了解OD 代码窗口 数据窗口 小端序问题 前言 前3节主要写了恶意代码用到的手段,接下来先写一下关于逆向调试的一些内容.毕竟逆向比较难理解一点. 一些配置和 ...

  9. python从入门到实践-7章用户输入和while循环

    #!/user/bin/env python# -*- coding:utf-8 -*- # input() 可以让程序暂停工作# int(input('please input something: ...

  10. mongodb怎么创建数据库和配置用户

    mongodb怎么创建数据库和配置用户,远程连接是不够的,还要上去操作和放数据的. 系统:centos 5.x 环境:mongodb 1.安装mongodb 这步就不说了,大家自己去看Centos安装 ...