坦克大战总结

新手请见谅!不足之处,多多指教!谢谢。

坦克大战总结

0.1版本

实现功能:

设计出一个框架出来

 

0.2版本

实现功能:

1、添加关闭比窗口事件处理。

this.addWindowListener(new WindowAdapter ()

{

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

2、不允许窗口的大小改动。

this.setResizable(false);

掌握:

1、匿名类的用法

2、匿名类的应用场合(类短小,不涉及将来的扩张,不涉及重要的业务逻辑)

3、通过eclipse 重写父类方法

右键-----source----overWrite.

 

 

0.3版本

功能:    画出代表坦克的实心圆。

掌握:    如何重写paint 方法。

public void paint(Graphics g) {

Color c = g.getColor();

g.setColor(Color.red);

g.fillOval(50,50, 30, 30);

g.setColor(c);

}

注意:不要改变原来的前景色。.

 

 

0.4版本

功能:

让坦克动起来

步骤:

1、将位置改变为变量。

int x = 50,y = 50; g.fillOval(xy, 30, 30);

2、启动线程不断重画。

private class PaintThread implements Runnable

{

public void run() {

while(true)

{

repaint();

try {

Thread.sleep(50);

catch (InterruptedException e) {

e.printStackTrace();

}

}

}

 

}

3、为什么使用线程重画而不是没按下一个键进行一次重画。

线程重画更均匀,更能控制重画的速度。

按键重画不能解决子弹自动飞行的问题。

 

0.41版本

功能:使用双缓冲消除闪烁现象。

原因:刷新重画频率太快,paint 方法还完成。

解决办法:  将所有东西画在虚拟图片上一次性现实出来。

 

因为调用paint方法之前会调用updata()方法,现在在update()方法中将重画的图先画在一张图上

public void update(Graphics g) {

if(offgreenImage == null)//offgreenImage 在类中定义了。

{

offgreenImage = this.createImage(800, 600);

}

 Graphics offScreen = offgreenImage.getGraphics();//得到图片的画笔

 Color c = offScreen.getColor();

  offScreen.setColor(Color.GREEN);

  offScreen.fillRect(0, 0, 800, 600);

  paint(offScreen);

 g.drawImage(offgreenImage, 0, 0, null);

}

 

 

0.5版本

功能:   代码重构

将以后可能需要多处改变的变量定义为常量

本例中是:Frame 的宽度和高度。常量名一般大写。

注意:常量一般是 public static final 的。

0.6版本

功能:  让坦克听从指挥

1、添加键盘监听器类 KeyMonitor

private class KeyMonitor extends KeyAdapter {

public void keyPressed(KeyEvent e) {

int key = e.getKeyCode();

switch (key) {

case KeyEvent.VK_LEFT:

x -= 5;   break;

case KeyEvent.VK_RIGHT:

x += 5;    break;

case KeyEvent.VK_UP:

y -= 5;    break;

case KeyEvent.VK_DOWN:

y += 5;    break;

}

}

}

2、TankWar 添加键盘监听器类

 

luanchFrame中添加this.addKeyListener(new KeyMonitor());

3、针对不同的键改变坦克的位置,与重画线程结合产生不同方向的运动。

 

注意:

Switch case 语句中break 的运用。

 

 

版本0.7

功能: 将坦克单独包装成类。

步骤:

1、建立Tank

2、Tank类添加成员变量 x,y

3、添加draw方法,是Tank类自己控制自己的画法

4、添加Tank类处理按键的方法

5、根据Tank类修改TankWar类。

 

版本0.8

功能:让坦克朝8个方向行走

步骤:

1、添加记录按键状态的布尔量

private boolean bL = false,bU = false,bR = false,bD = false;

2、添加代表方向的量(使用枚举)

enum Direction  {L,LU,U,RU,R,RD,D,LD,STOP};

Direction dir = Direction.STOP;

3、根据状态确定坦克的方向

void locaDirection()

{

if(bL && !bU && !bR && !bDdir = Direction.L;

else if(bL && bU && !bR && !bDdir = Direction.LU;

else if(!bL && bU && !bR && !bDdir = Direction.U;

else if(!bL && bU && bR && !bDdir = Direction.RU;

else if(!bL && !bU && bR && !bDdir = Direction.R;

else if(!bL && !bU && bR && bDdir = Direction.RD;

else if(!bL && !bU && !bR && bDdir = Direction.D;

else if(bL && !bU && !bR && bDdir = Direction.L;

else if(!bL && !bU && !bR && !bDdir = Direction.STOP;

}

4、根据方向进行下一步的移动(move方法)

5、pressed()方法中调用locaDurection()方法。

public void pressed(KeyEvent e)

{

int key = e.getKeyCode();

switch (key) {

case KeyEvent.VK_LEFT:

bL = true;break;

case KeyEvent.VK_RIGHT:

bR = true;break;

case KeyEvent.VK_UP:

bU = true;break;

case KeyEvent.VK_DOWN:

bD = true;break;

}

locaDirection();

}

 

版本0.9

功能:修正0.8版本

问题:0.8版本中按下一个键后键就永远变成了true

解决: 处理按键抬起的消息

1、TankWar中的KeyMoniter中增加按键抬起消息响应。

 

public void keyReleased(KeyEvent e) {

myTank.released(e);}

2、Tank中增加代码

public void released(KeyEvent e) {

int key = e.getKeyCode();

switch (key) {

case KeyEvent.VK_LEFT:

bL = false;break;

case KeyEvent.VK_RIGHT:

bR = false;break;

case KeyEvent.VK_UP:

bU = false;break;

case KeyEvent.VK_DOWN:

bD = false;break;

}

locaDirection();

}

 

版本1.0

功能:添加子弹类

步骤:

1、添加Missile 

2、添加x,y,dir等属性及常量

3、添加构造方法,draw方法

4、更具不同方向,进行不同运动

 

 

版本1.1

功能:根据主坦克的方向和位置,打出子弹

步骤:

1、增加对CTRL键的按键处理

2、根据“坦克打出依法子弹”这句话确定Tank中的fire,其返回值是Missile

3、根据Tank方向和位置设定子弹的方向和位置并画出来,然后返回。

 

 

版本1.2

功能:为了解决坦克停下也能打出炮弹的问题-----画出炮筒

步骤

1、Tank 类增加新的属性 ptDir

2、每次move后根据Tank新的方向确定炮筒的方向

3、将炮筒用直线的形式画出来(在draw方法中中画出来)

 

 

版本1.3

功能:打出多发炮弹

步骤:

1、使用容器装炮弹

List<Missile> missiles = new ArrayList<Missile>();

2、每当抬起Ctrl键就往容器中添加新的炮弹

case KeyEvent.VK_CONTROL:

 fire();

break;

3、逐一画出每一发炮弹

paint中使用

for(int i = 0;i<missiles.size();i++)

{

Missile m = missiles.get(i);

m.draw(g);

4、}

追:泛型的使用

TankWar1的示例传递到tank

 

版本1.4

功能:解决炮弹不消亡的问题

解决坦克出界的问题

if(x<0)  x = 0;

if(y<30) y = 30;

if(x+Tank.WIDTH > TankWar1.GAME_WIDTHx =  TankWar1.GAME_WIDTH - Tank.WIDTH;

if(y + Tank.HEIGHT > TankWar1.GAME_HEIGHTy = TankWar1.GAME_HEIGHT - Tank.HEIGHT;

 

步骤:

1、加入控制炮弹生死的量live (Missile类中加入)

2、当炮弹已经死去就不需要对其进行重画

3、当炮弹飞出边界就死亡

if(x < 0 || y < 0 || x > TankWar1.GAME_WIDTH || y > TankWar1.GAME_HEIGHT )

{

live  = false;

this.tc.missiles.remove(this);

}

4、但炮弹死亡就从容器中擦出

5、Missile类中添加新的构造函数 加入对TankWar1的引用

public Missile(int x,int y,Tank.Direction dir,TankWar1 tc)

{

this(x,y,dir);

this.tc = tc;

}

6、当炮弹new 出来时在fire()方法中

Missile m = new Missile(x,y,ptDir,this.tc);

 

 

版本1.41

功能:Debug的使用

1、一步一步跟踪代码

2、为代码设置断点

3、Step into 和 step over 的概念

4、学会在运行过程中观测变量的值。

 

 

版本1.5

功能:画出一量敌人的坦克

步骤:

1、加入区别敌我的量

2、根据敌我的不同设置不同的颜色

3、更新Tank的构造函数,加入good

4、TankWar1中画出敌人的坦克并画出。

 

版本1.6

功能:将敌人坦克击毙

分析:一颗子弹击中敌人坦克

步骤:

1、Missile中加入hitTankTank)方法,返回布尔类型

public boolean hitTank(Tank t)

{

if(this.getRect().intersects(t.getRect()) && t.isLive())

{

t.setLive(false);

this.live = false;

return true;

}

return false;

}

2、碰撞检测的辅助类Rectangle

public Rectangle getRect()

{

return new Rectangle(x,y,WIDTH,HEIGHT);

}

 

3、TankMissile都加入getRect方法

4、当击中敌人坦克时,坦克被打死,子弹也死去

即把坦克和子弹的live 都设置为false

5、增加控制Tank生死的量live

6、如果死去就不画了

7、修改当子弹出界后把子弹的live设置为false,并不把它擦出

8、当画出子弹时先判断一下子弹是否还活着

if(!live)

{this.tc.missiles.remove(this);

return;}

版本1.7

功能: 加入爆炸

步骤:

1、添加爆炸类

2、用不同直径的圆模拟爆炸

3、加入live 判断爆炸的生死,死了就不要画了

4、加入位置属性

5、加入draw方法

 

爆炸应该位于集合类中

1、TankWar1加入集合

List<Explode> explodes = new ArrayList<Explode>();

2、将集合中的爆炸逐一画出(如果死去就去除)(模仿子弹画法)

for(int i=0;i<explodes.size();i++)

{

Explode e = explodes.get(i);

e.draw(g);

}

击毙一辆坦克时产生爆炸(在hitTank中添加)

Explode e = new Explode(x,y,tc);

tc.explodes.add(e);

 

 

版本1.8

功能:添加多辆坦克

步骤:

1、用容器来装敌人的Tank

List<Tank> tanks = new ArrayList<Tank>();

2、向容器中装入多辆敌人的Tank

for(int i = 0;i<tanks.size();i++)

{

Tank t = tanks.get(i);

t.draw(g);

}

3、画出敌人的坦克

4、运行,不能打掉

5、添加hitTanks方法,打一系列的坦克

public boolean hittanks(List<Tank> tanks)

{

for(int i = 0;i<tanks.size();i++){

if(hitTank(tanks.get(i)))

{

return true;}}

return false;}

6、TankWar中每一发子弹都可以打tanks

7、每次击毙一辆坦克要从容器中去除

if(!live)

{if(!good)

{

tc.tanks.remove(this);

}

return;}

 

 

 

版本1.9

功能:让敌军的坦克更加智能

步骤:

1、让敌军的坦克动起来

构造函数中可以指定方向

New 敌军坦克的时候指定敌军坦克的方向

2、让敌军的坦克向随机的方向移动

坦克静态的,添加随机数产生器 java.util.Random

private static Random r = new Random(); 

Move完成后,如果是敌军坦克,随机设定一个数来指定坦克的下一个方向

enum转化为相应的整形数组

Direction[] dirs = Direction.values();

Direction.values()

3、让敌军坦克向随机方向移动随机的步骤

添加变量,记录随机步骤

if(step == 0)

{step = r.nextInt(12)+4;

int rn = r.nextInt(dirs.length);

dir = dirs[rn];

}

当变量等于0时,改变方向,否则只是随机步骤递减

4、让敌军坦克发射炮弹

本军炮弹不打本军炮弹

炮弹根据好坏添加变量good,根据好坏画出不同的颜色

修改炮弹的构造方法

修改坦克的fire()方法

如果坦克死了的话就不可以打出子弹了

if(!live)

return null;

修改hitTank方法,好不能打好,坏不能打坏

this.good!=t.isGood()

5、敌军炮火不可以太猛烈

用随机数解决

if(r.nextInt(20)>16)

{

this.fire();

}

 

版本2.0

功能:添加两堵墙

步骤:

1、建立Wall类,建立Wall对象,画出来

2、让每一颗子弹打击每一堵墙

hitWall()方法。

public boolean hitWall(Obstancle ob)

{

if(live && this.getRect().intersects(ob.getRect()))

{

live = false;

return true;

}

return false;}

注意:子弹速度不可以太快,否则容易穿过墙

3、让坦克不能穿过墙

记录上一次的位置oldX,oldY

修改构造函数

每次move之前记录上一次位置

添加stay()方法

public void stay()

{

x = oldX;

y = oldY;

}

记录移动前的位置

当撞到时回到移动前的位置

当撞到的时候stay

 

 

版本2.1

功能:坦克不能互相穿越

步骤:当坦克撞到坦克时stay Tank类中增加jittanks()方法

public boolean hitTanks(java.util.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;

}

 

 

版本2.2

功能:增加超级炮弹

代码:

增加一个fire(Direction dir)方法。

按方向来打出炮弹

public void superfire()

{

Direction [] dirs = Direction.values();

for(int i = 0;i<8;i++)

{

fire(dirs[i]);

}

 }

 

版本2.3

功能:给我方坦克增加生命值

给坦克增加life 变量 初始值为100

hitTank中改变代码

if(t.isGood())

{

t.setLife(t.getLife()-20);

if(t.getLife()<=0)

t.setLive(false);

}

else

t.setLive(false);

 

版本2.4

功能:图形化表示主坦克的生命值

步骤:

根据不同的life值进行不同的显示

给坦克类增加一个内部类

private class bloodBar

{

public void draw(Graphics g)

{

Color c = g.getColor();

g.setColor(Color.lightGray);

g.drawRect(xy-10,WIDTHHEIGHT);

int w = WIDTH * life/100;

g.fillRect(xy-10, w, 10);

g.setColor(c);

}

}

 

版本2.5

功能:添加血块

添加Blood

添加必要的方法

blood对象固定轨迹运动,并在一定时间后消失

 

版本2.6

敌人死光了重新加入

我军死掉了按F12开始

原文地址:https://www.cnblogs.com/LLeiFeng/p/2828600.html