利用Java语言中的集合、Swing、线程等知识点编写一个坦克大战游戏。
(1) 画出敌我坦克的原理:
在坦克类里面有一个布尔类型变量good。用于判断坦克的阵营,在创建坦克对象时在Tank类的构造方法中传入good的值。在画坦克的时候判断good的值,区分敌我坦克的颜色;
(2) 坦克运动的原理:
在坦克类里写入了监听键盘摁键的响应事件,对监听到的上下左右键进行记录,并合成坦克移动的八个方向的变量。之后对应每个方向的不同对坦克坐标x,y的值做响应的更改实现我方坦克的移动。而敌方坦克则自动移动,通过随机数对敌方坦克移动方向的随机,并且随机出每次移动的次数。两个随机值相结合即实现了敌方坦克的移动。
(3) 坦克发射子弹的原理:
通过键盘监听,检测到发射子弹命令后将主类的子弹类集合中添加一个子弹类。将炮筒的方向以及坦克的位置以及坦克的阵营传入给子弹类,在主类paint画方法中一直循环子弹类集合,如果集合内有子弹,就画出来。这样就实现了发射子弹。
(4) 坦克、子弹、墙的碰撞原理:
在坦克类子弹类墙类中分别getRect方法获取自身的范围,然后在每次画坦克、子弹时都会进行相应的碰撞检测(在坦克类里有与墙和出自己外的坦克相撞的处理方法、在子弹类里有与墙和坦克相碰撞的处理方法。),如果自身与不该碰撞的物体的范围相重合,则代表两物体相撞。
(5)坦克加血的原理:
在血块类中有血块与我方坦克相碰撞的处理方法,如果血块范围与坦克范围重合则血块类死亡,并且坦克类的血量回复置满。
(6)坦克复活的原理:
通过键盘监听,检测到我方坦克复活命令后,如果我方坦克处于死亡状态,则将我方坦克存货状态改为活着并且将我方坦克血量回置满血。

 编程思想:

坦克大战的编程思想在主类开启一个线程,没50毫秒循环一次画方法(绘制整个界面内的所有东西)。画的东西有敌我坦克(颜色区分)、子弹、墙、血块、爆炸。所以总共写出了几个类:Tank坦克类、Missile子弹类、Wall墙类、Blood血块类、TankClient主类。在每一个类中均写有画方法实现本类属性的绘制功能。在主类中有键盘监听事件调用这Tank类的键盘监听事件。通过键盘监听判断出对Tank做出相应的移动,而敌方Tank则是随机运动。并且每次刷新都有调用各类的碰撞方法,判断一些不该碰撞的对象的情况时做出处理。而每个对象的创建例如子弹这些是在触发产生之后将新建子弹类加入一个子弹类集合之中,在绘制的时候判断集合中的数量进行绘制,出界或者打死坦克则在集合中删除。其他类也均相似,不在细说。
代码中每步都注释有相应的解释。

TankClient.java

 import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List; import javax.swing.JFrame; public class TankClient extends JFrame{
/**
* @param args
*/
Image OffScrennImage = null; //双缓冲内存图片存储
/*游戏大小*/
public static final int GAME_WIDTH = 800; //界面宽
public static final int GAME_HEIGTH = 600; //界面高 Tank myTank = new Tank(500,400,true,Color.red,Tank.Direction.STOP, this);//我方坦克类
List<Missile> missiles = new ArrayList<Missile>();//子弹的集合
List<Explode> explode = new ArrayList<Explode>();//爆炸集合
List<Tank> tanks = new ArrayList<Tank>(); //坦克集合
Wall wall1 = new Wall(150,200,20,300,this); //墙1
Wall wall2 = new Wall(250,500,300,20,this); //墙2
Wall wall3 = new Wall(650,200,20,300,this); //墙2
Wall wall4 = new Wall(250,300,300,20,this); //墙2
Wall wb = new Wall(750,550,40,40,this); //墙2
Blood b = new Blood(); //血类 public static void main(String[] args) {
// TODO Auto-generated method stub
TankClient tc=new TankClient();
tc.lauchFrame();
} private void lauchFrame() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++){
tanks.add(new Tank(50+40*(i+1), 50, false,Color.blue,Tank.Direction.D, this));
}
this.setLocation(100, 100); //窗口初始坐标点
this.setSize(GAME_WIDTH, GAME_HEIGTH); //窗口初始大小
this.setTitle("TankWar"); //窗口名称
/*窗口监听*/
this.addWindowListener(new WindowAdapter() {
@Override
/*点退出叉之后运行*/
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
System.exit(0); //退出
}
});
this.addKeyListener(new KeyMoniton()); //设置键盘监听
this.setVisible(true); //设置窗口显现
this.setResizable(false); //设置窗口不可改变大小
this.getContentPane().setBackground(Color.green); //设置窗口前景色为绿色
new Thread(new PaintThread()).start(); //开始运行PaintThread类run
} @Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
//Graphics为画笔类
super.paint(g);
myTank.draw(g);
wall1.draw(g);
wall2.draw(g);
wall3.draw(g);
wall4.draw(g);
wb.draw(g);
b.draw(g);
myTank.eatBlood(b);
myTank.hitWall(wall1);
myTank.hitWall(wall2);
myTank.hitWall(wall3);
myTank.hitWall(wall4);
/*循环子弹集合*/
for (int i = 0; i < missiles.size(); i++){
Missile m = missiles.get(i); //获取当前子弹
m.hitTanks(tanks); //自己子弹打死敌方坦克
m.hitWall(wall1); //子弹与墙
m.hitWall(wall2);
m.hitWall(wall3);
m.hitWall(wall4);
m.hitTank(myTank);//敌人子弹打击自己的坦克
m.draw(g); //画子弹
}
for (int i = 0; i < explode.size(); i++){
explode.get(i).draw(g); //画爆炸
}
for (int i = 0; i < tanks.size(); i++){
Tank t = tanks.get(i);
t.draw(g); //画敌方坦克
t.hitTanks(tanks);
t.hitWall(wall1); //坦克与墙
t.hitWall(wall2);
t.hitWall(wall3);
t.hitWall(wall4);
}
//g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString("missiles count:"+missiles.size(), 10, 50);//显示
g.drawString("explode count:"+explode.size(), 10, 80);//显示
g.drawString("tanks count:"+tanks.size(),10, 110);
g.drawString("myTank Life:"+myTank.getLife(), 10, 130);
g.drawString("回血:", 750, 540);
g.drawString("方向键移动方向;E:释放移动血快", 10, 590);
g.drawString("z:发射东风-31;a:发射东风-41;", 10, 570);
g.drawString("F2:复活;F3:敌方复活(对多20)", 10, 550);
g.drawString("R:位置还原;Q:血量加满", 10, 530);
} @Override
/*repaint-〉update->paint*/
public void update(Graphics g) {
// TODO Auto-generated method stub
super.update(g);
if(OffScrennImage == null)
OffScrennImage = this.createImage(GAME_WIDTH, GAME_HEIGTH);
Graphics goffscrenn = OffScrennImage.getGraphics(); //设置一个内存画笔颜色为前景图片颜色
Color c = goffscrenn.getColor(); //还是先保存前景颜色
goffscrenn.setColor(Color.green); //设置内存画笔颜色为绿色
goffscrenn.fillRect(0, 0, GAME_WIDTH, GAME_HEIGTH); //画成图片,大小为游戏大小
goffscrenn.setColor(c); //还原颜色
g.drawImage(OffScrennImage, 0, 0, null); //在界面画出保存的图片
paint(goffscrenn); //把内存画笔调用给paint
} private class PaintThread implements Runnable{ @Override
public void run() {
// TODO Auto-generated method stub
while(true){
repaint(); //运行顺序repaint->update->paint
try{
Thread.sleep(50); //每隔50毫秒刷新画面一次
}catch(Exception e){
e.printStackTrace();
}
}
} }
/*键盘响应*/
private class KeyMoniton extends KeyAdapter{ /*摁下键盘响应*/
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
super.keyPressed(e);
myTank.KeyPressed(e);
}
/*抬起键盘响应*/
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
super.keyReleased(e);
myTank.keyReleased(e);
} }
}

Tank.java

 import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random; import javax.swing.ImageIcon; public class Tank {
/*坦克本身数据*/
int x, y;//坦克坐标
private int oldX, oldY; //坦克上一步坐标
public static final int Whith = 30; //坦克宽
public static final int Higth = 30; //坦克高
public static final int XSPEED = 5; //横向移动速度
public static final int YSPEED = 5; //纵向移动速度
private Color color; //坦克颜色
private boolean bL=false, bU=false, bR=false, bD=false; //四个方向控制值
enum Direction {L, LU, U, RU, R, RD, D, LD, STOP}; //由四个方向值合成八个方向的移动
private Direction dir = Direction.STOP; //出场方向
private Direction ptDir = Direction.D; //炮筒初始方向
private boolean good; //判断坦克的阵营
private boolean live = true; //判断坦克是否存活
private static Random r = new Random();//设置一个随机值变量
private static int step = r.nextInt(12)+3; //敌方坦克随机移动步骤3-14步
private int Life = 100; //血量
private BloodBar bb = new BloodBar(); //血块类 // ImageIcon icon = new ImageIcon("res\\myTank.jpg");
// ImageIcon icon2 = new ImageIcon("res\\enemyTank.jpg");
// Image image = icon.getImage();
// Image image2 = icon2.getImage(); private TankClient tc; //主类权限 public Tank(int x, int y, boolean good, Color color) {
super();
this.x = x;
this.y = y;
this.color = color;
this.good = good;
}
public Tank(int x, int y, boolean good,Color color,Direction dir,TankClient tc){
this(x,y,good,color);
this.dir = dir;
this.tc = tc;
}
/*获取坦克生命值*/
public int getLife() {
return Life;
}
/*设置坦克生命值*/
public void setLife(int Life) {
this.Life = Life;
} /*获取坦克阵营*/
public boolean isGood() {
return good;
}
/*设置坦克阵营*/
public void setGood(boolean good) {
this.good = good;
}
/*获取坦克存活状态*/
public boolean isLive() {
return live;
}
/*设置坦克存活状态*/
public void setLive(boolean live) {
this.live = live;
}
/*画坦克*/
public void draw(Graphics g){
if(!live){
if(!good){
tc.tanks.remove(this); //敌方坦克死亡时在集合中删除
//tc.tanks.add(new Tank(r.nextInt(700),r.nextInt(500),false,Color.blue,Direction.D,this.tc));
}
return;
}
/*先保存之前的画笔颜色,画完之后再还原画笔颜色*/
Color c = g.getColor(); //获取当前画笔颜色
g.setColor(color); //设置画笔颜色为红色
/*画坦克*/
g.fillOval(x, y, Whith, Higth);
/*两种方法绘制敌我坦克,运用之前加入的图片或者颜色区分*/
// if(good)
// g.drawImage(image, x, y,Whith,Higth,null);
// else
// g.drawImage(image2, x, y, Whith, Higth, null);
if(good)
bb.draw(g); //我方坦克画血条
g.setColor(Color.black);
/*通过炮筒方向画出炮筒*/
switch(ptDir){
case L:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y+Tank.Higth/2);
break;
case LU:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y);
break;
case U:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith/2, y);
break;
case RU:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y);
break;
case R:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y+Tank.Higth/2);
break;
case RD:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y+Tank.Higth);
break;
case D:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith/2, y+Tank.Higth);
break;
case LD:
g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y+Tank.Higth);
break;
}
g.setColor(c); //还原画笔颜色
move();//移动
} /*键盘监听;摁键*/
public void KeyPressed(KeyEvent e){
int key = e.getKeyCode(); //将键盘监听到的摁键以整数保存
/*键盘移动坦克*/
switch(key){
/*移动摁键*/
case KeyEvent.VK_UP:
bU=true;
break;
case KeyEvent.VK_DOWN:
bD=true;
break;
case KeyEvent.VK_RIGHT:
bR=true;
break;
case KeyEvent.VK_LEFT:
bL=true;
break;
}
locateDirection();
} /*键盘监听;抬起键*/
public void keyReleased(KeyEvent e){
int key = e.getKeyCode(); //将键盘监听到的摁键以整数保存
/*键盘移动坦克*/
switch(key){
case KeyEvent.VK_UP:
bU=false;
break;
case KeyEvent.VK_DOWN:
bD=false;
break;
case KeyEvent.VK_RIGHT:
bR=false;
break;
case KeyEvent.VK_LEFT:
bL=false;
break;
case KeyEvent.VK_Z: //单发子弹
if(live)
fire();
break;
case KeyEvent.VK_F2: //我方复活
if(!this.live){
this.live=true;
this.setLife(100);
}
break;
case KeyEvent.VK_F3: //敌方复活
fuhuo();
break;
case KeyEvent.VK_A: //无敌导弹
superFire();
break;
case KeyEvent.VK_Q: //回血
if(this.live)
this.Life = 100;
break;
case KeyEvent.VK_E: //释放血块
tc.b.fh();
break;
/*还原位置键*/
case KeyEvent.VK_R:
x = 50;
y = 50;
break;
}
locateDirection(); //合成方向
}
/*合成移动方向*/
void locateDirection(){
if(bL&&!bU&&!bR&&!bD) dir=Direction.L;
else if(bL&&bU&&!bR&&!bD) dir=Direction.LU;
else if(!bL&&bU&&!bR&&!bD) dir=Direction.U;
else if(!bL&&bU&&bR&&!bD) dir=Direction.RU;
else if(!bL&&!bU&&bR&&!bD) dir=Direction.R;
else if(!bL&&!bU&&bR&&bD) dir=Direction.RD;
else if(!bL&&!bU&&!bR&&bD) dir=Direction.D;
else if(bL&&!bU&&!bR&&bD) dir=Direction.LD;
else if(!bL&&!bU&&!bR&&!bD) dir=Direction.STOP;
} void move(){ //移动
/*记录上一步的位置*/
oldX = x;
oldY = y;
switch(dir){
case L:
x-=XSPEED;
break;
case LU:
x-=XSPEED;
y-=YSPEED;
break;
case U:
y-=YSPEED;
break;
case RU:
x+=XSPEED;
y-=YSPEED;
break;
case R:
x+=XSPEED;
break;
case RD:
x+=XSPEED;
y+=YSPEED;
break;
case D:
y+=YSPEED;
break;
case LD:
x-=XSPEED;
y+=YSPEED;
break;
case STOP:
break;
}
/*判断坦克移动越界情况(游戏边界)*/
if(x < 5) x = 5;
if(y < 25) y = 25;
if(x+Whith > tc.GAME_WIDTH-5) x = tc.GAME_WIDTH-Whith-5;
if(y+Higth > tc.GAME_HEIGTH-5) y = tc.GAME_HEIGTH-Higth-5; if(dir != Direction.STOP) //如果坦克不静止就改变炮筒方向
ptDir = dir; /*敌方坦克自动移动*/
if(!good){
Direction[] dirs = Direction.values(); //将方向变量设为数组
if(step == 0){
step = r.nextInt(12)+3; //随机移动步骤
int randomNumber = r.nextInt(dirs.length); //随机移动方向
dir = dirs[randomNumber];
}
step--;
if(r.nextInt(40)>30) this.fire(); //随机是否发射炮弹
}
}
/*敌方坦克复活*/
public void fuhuo(){
if(tc.tanks.size() < 20)
while(true){
int x = r.nextInt(700);
int y = r.nextInt(500);
Tank t = new Tank(x,y,false,Color.blue,Direction.D,tc);
/*如果坦克与墙重合则重新随机位置直到不重合为止才将新坦克加入集合*/
if(t.getRect().intersects(tc.wall1.getRect())||t.getRect().intersects(tc.wall2.getRect())
||t.getRect().intersects(tc.wall3.getRect())
||t.getRect().intersects(tc.wall4.getRect())){
continue;
}
else{
tc.tanks.add(t);
break;
}
}
}
/*子弹发射*/
public void fire(){
int x = this.x + Whith/2 - Missile.Whith/2; //控制子弹方向为坦克中间
int y = this.y + Higth/2 - Missile.Higth/2;
tc.missiles.add(new Missile(ptDir,color,x,y,good,tc)); //创建新的子弹类加入到子弹集合中
}
/*碰撞;获取坦克的范围*/
public Rectangle getRect(){
return new Rectangle(x,y,Whith,Higth);
}
/*回执上一步位置*/
private void stay(){
x = oldX;
y = oldY;
}
/*如果撞墙,调用stay方法,返回上一步位置*/
public boolean hitWall(Wall w){
if(this.live&&this.getRect().intersects(w.getRect())){
this.stay();
return true;
}
return false;
}
/*坦克互相撞击事件*/
public boolean hitTanks(List<Tank> tanks){
for(int i=0;i<tanks.size();i++){
Tank t=tanks.get(i);
if(this!=t){//自己与自己不可相撞
/*如果相撞返回上一步位置*/
if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){
this.stay();
t.stay();
return true;
}
}
}
return false;
}
/*带开火方向的发射函数*/
public Missile fire(Direction dir){
if(!live) return null;
int x=this.x+Whith/2-Missile.Whith/2;
int y=this.y+Higth/2-Missile.Higth/2;
Missile m=new Missile(dir,color,x, y,good, this.tc);
tc.missiles.add(m);
return m;
}
/*超级射击导弹*/
private void superFire(){
Direction[] dirs=Direction.values();
for(int i=0;i<8;i++){
fire(dirs[i]);//循环调用八个方向
}
}
/*新增血块类*/
private class BloodBar{
/*画血条*/
public void draw(Graphics g){
Color c=g.getColor();
g.setColor(Color.red);
g.drawRect(x, y-10, Whith, 10);
int w=Whith*Life/100;
g.fillRect(x, y-10, w, 10);
g.setColor(c);
}
}
/*吃血方法*/
public boolean eatBlood(Blood b){
if(this.live&&b.isLive()&&this.isGood()&&this.getRect().intersects(b.getRect())){
this.setLife(100);
b.setLive(false);
return true;
}
if(this.getRect().intersects(tc.wb.getRect()))
this.Life = 100;
return false;
}
}

Missile.java

 import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.List; public class Missile {
/*子弹本身数据*/
Tank.Direction dir; //子弹方向
Color c; //子弹颜色
int x,y; //子弹位置
public static final int XSPEED = 15; //横向移动速度
public static final int YSPEED = 15; //纵向移动速度
public static final int Whith = 10; //子弹宽
public static final int Higth = 10; //子弹高
private boolean live = true; //判断子弹的存活
private boolean good; //判断子弹和阵营 private TankClient tc;//主类权限 public Missile(Tank.Direction dir,Color c, int x, int y) {
super();
this.dir = dir;
this.x = x;
this.y = y;
this.c = c;
}
public Missile(Tank.Direction dir,Color c, int x, int y,boolean good,TankClient tc){
this(dir,c,x,y);
this.good = good;
this.tc = tc;
} /*获取子弹的存活*/
public boolean isLive() {
return live;
}
/*设置子弹的存活*/
public void setLive(boolean live) {
this.live = live;
}
public void draw(Graphics g){
/*如果子弹死亡状态将这个子弹在子弹集合中删除*/
if(!live){
tc.missiles.remove(this); //集合中删除
return;
}
/*先保存之前的画笔颜色,画完之后再还原画笔颜色*/
Color d = g.getColor(); //获取当前画笔颜色
g.setColor(c); //设置画笔颜色为红色
/*画子弹*/
g.fillOval(x, y, Whith, Higth); g.setColor(d); //还原画笔颜色
move(); //移动
} public void move(){
/*判断移动方向移动坦克位置*/
switch(dir){
case L:
x-=XSPEED;
break;
case LU:
x-=XSPEED;
y-=YSPEED;
break;
case U:
y-=YSPEED;
break;
case RU:
x+=XSPEED;
y-=YSPEED;
break;
case R:
x+=XSPEED;
break;
case RD:
x+=XSPEED;
y+=YSPEED;
break;
case D:
y+=YSPEED;
break;
case LD:
x-=XSPEED;
y+=YSPEED;
break;
case STOP:
break;
}
/*判断子弹的越界情况;出界则子弹死亡,在子弹集合中删去*/
if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGTH)
live = false;
}
/*碰撞;获取子弹的范围*/
public Rectangle getRect(){
return new Rectangle(x,y,Whith,Higth);
}
/*子弹与坦克碰撞过程*/
public boolean hitTank(Tank t){
/*如果子弹与坦克在同一范围则子弹和坦克同时死亡;且子弹只能杀死对方坦克*/
if(this.live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()){
if(t.isGood()){ //好坦克
/*我方坦克子弹射中会减少生命值,生命值0的时候会死亡*/
t.setLife(t.getLife()-20);
if(t.getLife()<=0)
t.setLive(false);
}else{ //坏坦克
t.setLive(false);//死亡
}
this.live=false;//子弹死亡
tc.explode.add(new Explode(x, y, tc));//新建爆炸加入集合
return true;
}
return false;
}
/*循环坦克集合分别进行判断子弹碰撞*/
public boolean hitTanks(List<Tank> tanks){
for (int i = 0; i < tanks.size(); i++){
if(hitTank(tanks.get(i)))
return true;
}
return false;
}
/*子弹与墙的碰撞过程*/
public boolean hitWall(Wall w){
/*如果子弹与墙的范围重合子弹死亡*/
if(this.live&&this.getRect().intersects(w.getRect())){
this.live=false; //子弹死亡
return true;
}
return false;
}
}

Wall.java

 import java.awt.Graphics;
import java.awt.Rectangle; public class Wall {
/*墙数据*/
int x,y,w,h; //位置和宽高
private TankClient tc; //主类权限 public Wall(int x, int y, int w, int h, TankClient tc) {
super();
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.tc = tc;
}
/*获取墙的范围*/
public Rectangle getRect(){
return new Rectangle(x,y,w,h);
}
/*画墙*/
public void draw(Graphics g){
g.fillRect(x, y, w, h);
}
}

Explode.java

import java.awt.Color;
import java.awt.Graphics; public class Explode {
/*坦克爆炸属性*/
int x,y; //爆炸位置
private boolean live = true; //爆炸是否存在
int step = 0; //爆炸时间控制
int [] diameter = new int[] {4, 7, 12, 18, 26, 32, 49, 56, 65, 77, 80, 50, 40, 30, 14, 6};//爆炸范围 private TankClient tc; //主类权限
public Explode(int x, int y, TankClient tc) {
super();
this.x = x;
this.y = y;
this.tc = tc;
} /*画爆炸*/
public void draw(Graphics g){
if(!live) return; //如果爆炸死亡状态不画结束
/*如果爆炸时间结束爆炸不存在并在集合中删除*/
if(step == diameter.length){
live = false; //爆炸死亡
step = 0; //步骤时间归0
tc.explode.remove(this); //集合中删除
return;
}
/*画爆炸*/
Color c = g.getColor();
g.setColor(Color.orange);
g.fillOval(x, y, diameter[step], diameter[step]);
g.setColor(c); step++;
} }

Blood.java

 import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random; public class Blood {
/*血块数据*/
int x, y, w, h;//血块位置和大小
private TankClient tc; //主类权限
private boolean live=true;//血块的存活
private static Random r = new Random();//设置一个随机值变量
/*获取血块的存活状态*/
public boolean isLive() {
return live;
}
/*设置血块的存活状态*/
public void setLive(boolean live) {
this.live = live;
}
/*血块位置初值随机一个数值*/
public Blood(){
x=r.nextInt(600)+100;
y=r.nextInt(400)+100;
w=h=15;
}
/*画血块*/
public void draw(Graphics g){
if(!live) return;
Color c=g.getColor();
g.setColor(Color.magenta);
g.fillRect(x, y, w, h);
g.setColor(c);
}
/*释放血块*/
public void fh(){
if(!live){
x = r.nextInt(600)+100;
y = r.nextInt(400)+100;
live = true;
}
}
/*获取血块范围*/
public Rectangle getRect(){
return new Rectangle(x, y, w, h);
}
}

Java-坦克大战的更多相关文章

  1. Java坦克大战(四)

    这是我的坦克游戏大战的最后一版,里面添加很多新的功能.这个坦克大战的有很多不足之处,但是对于初学者来说依然是一个很好的练习项目,从中我们可以学习Java基础知识,将知识与项目结合,学习面向对象编程思想 ...

  2. Java坦克大战(三)

    关于这个坦克大战的项目是在学习Java基础的时候,拿来练习的最近看到这些代码,感觉很亲切,就把他们都复制下来,编辑成博客.回首看去,Java基础的学习确实应该建立在找项目练习上,这样才能将学到的基础知 ...

  3. Java坦克大战(二)

    本文紧接上一篇讲解坦克大战这个项目,因为当初在学习的时候,是以这个案例逐步学习Java基础的,过程是先讲知识点,再将知识点逐步的融入到项目中,即给坦克添加新的功能.之前的Demo练习,想都记录下来.这 ...

  4. Java坦克大战(一)

    接下来的几篇博客,想记录一下通过学习坦克大战项目来循序渐进的学习Java基础.主要是为了巩固基础知识,当然学习编程重要的还是多敲,问题通常是在敲代码的过程中发现的,积累也是在敲代码中寻求的经验.这个坦 ...

  5. Java坦克大战 (七) 之图片版

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  6. Java坦克大战 (六) 之增加可玩性

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  7. Java坦克大战 (五) 之产生敌方坦克和爆炸效果

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  8. Java坦克大战 (四) 之子弹的产生

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  9. Java坦克大战 (三) 之可完全控制坦克朝八个方向运动

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  10. Java坦克大战 (二) 之画一个能动的圆圈代表坦克

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

随机推荐

  1. 一、oracle数据库成功安装步骤 (11gR2)

    下载安装包 从Oracle官方网站下载数据库软件安装包:http://www.oracle.com/technetwork/cn/database/enterprise-edition/downloa ...

  2. C#异常处理性能测试

    异常处理性能测试 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq ...

  3. RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-29(提供下载)

    本次主要更新内容: 1.增加对Oracle表创建语句的查看. 2.新增对MySql的代码生成支持. 3.全面重构对多线程的支持,改变以前会无故退出的现象. RDIFramework.NET代码生成器V ...

  4. kali driftnet

    语法 : driftnet   [options]   [filter code] 主要参数: -b               捕获到新的图片时发出嘟嘟声 -i  interface     选择监 ...

  5. 【Python + Selenium】Mock Testing 是啥?一个so上的高票答案。

    There are many kinds of testing which really made me confused. To be honest, I've never heard of som ...

  6. echarts 用marlkline画线 同时配置中含有datazoom,怎么设置markline

    由于项目需要设置边界值即用markline 画标线,通过echarts文档可以查看到(如下) 1.通过坐标点(xAxis和yAxis的设置) 通过网上搜索许多markline的配置都是通过下面来设置的 ...

  7. Python爬虫爬取糗事百科段子内容

    参照网上的教程再做修改,抓取糗事百科段子(去除图片),详情见下面源码: #coding=utf-8#!/usr/bin/pythonimport urllibimport urllib2import ...

  8. was not declared in this scope

    “was not declared in this scope”是一个错误信息,在编译的时候会遇到.其含义为标识符在其出现的地方是未被定义的. 出现该错误的时候,会同时把未定义的变量名显示出来.比如如 ...

  9. 邓博泽 java最全的DateUtil工具类

    package com.kld.yijie.web.util; import org.slf4j.Logger;import org.slf4j.LoggerFactory; import java. ...

  10. 什么情况下会用到try-catch

    本文不区分语言,只为记录一次有收获的面试. 面试官:什么情况下用到try-catch?程序员:代码执行预料不到的情况,我会使用try-catch.面试官:什么是预料不到的情况呢?程序员:比如我要计算a ...