栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JAVA】-- 专题训练之坦克大战游戏(二)(实现思路+每步代码)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JAVA】-- 专题训练之坦克大战游戏(二)(实现思路+每步代码)

一、增加子弹基础部分

创建子弹类,根据传入的方向来使子弹坐标改变;

坦克类需要设置一个按键J来发射子弹,发射子弹后把方向传给子弹类得到一个子弹m,再给主类中的m;

主类中的m调用子弹类的draw方法,把子弹画出。

创建子弹类:

设置宽高在draw方法中画出子弹,并在此方法中调用move方法使子弹可以移动。

移动的原理是根据传入的方向使x,y加减,加减的值越大子弹速度越快。

如何确定子弹发出的位置和方向:使用构造方法设置参数,在坦克类中调用传参。

import java.awt.*;
public class Missile {
    int x,y;
    public static final int WIDTH = 10;//子弹的宽
    public static final int HEIGHT = 10;//子弹的高
    public static final int XSPEED = 10;//子弹移动速度
    public static final int YSPEED = 10;
    Tank.Direction dir;//子弹方向

    public Missile(int x,int y,Tank.Direction dir){
        super();
        this.x = x;
        this.y = y;
        this.dir = dir;
    }
    public void draw(Graphics g){
        Color c = g.getColor();
        g.setColor(Color.black);
        g.fillOval(x,y,WIDTH,HEIGHT);
        g.setColor(c);
        move();
    }
    private void move() {
        switch (dir) {//判断方向,子弹移动
            case L:
                x -= XSPEED;
                break;
            case LU:
                x -= XSPEED;
                y -= YSPEED;
                break;
            case U:
                y -= XSPEED;
                break;
            case RU:
                x += XSPEED;
                y -= YSPEED;
                break;
            case R:
                x += XSPEED;
                break;
            case RD:
                x += XSPEED;
                y += YSPEED;
                break;
            case D:
                y += XSPEED;
                break;
            case LD:
                x -= XSPEED;
                y += YSPEED;
                break;
            case STOP:
                break;
        }
    }
}
坦克类增加:

坦克类需要主类,将子弹m传入主类,主类中调用。

TankClient tc;
public Tank(int x,int y,TankClient tc){
        this(x,y);
        this.tc = tc;
    }
private Missile fire(){
    int x = this.x+Tank.WIDTH/2-Missile.WIDTH/2;//子弹相对坦克发出的位置
    int y = this.y+Tank.HEIGHT/2-Missile.HEIGHT/2;
    Missile m = new Missile(x,y,dir);
    return m;
}

 在按键抬起方法keyReleased()中增加按键J发射子弹:

            case KeyEvent.VK_J:tc.m = fire();break;//不在按下,在抬手时发出子弹
主类增加:
   Missile m = null;//子弹

paint()方法画出子弹()

m.draw(g);

目前子弹可以在坦克移动时发射一颗,但是静止时子弹停止而且只能发射一颗子弹。

二、发射多颗子弹

只能发射一颗子弹的原因:主类只能接收一个m。

可以使用集合解决此问题,坦克类发射一颗存入集合,主类中在集合中取出。

坦克类增加/修改:

坦克每产生一颗子弹存入集合

fire()方法:

Missile m = new Missile(x,y,dir);
        tc.missiles.add(m);
主类增加/修改

创建一个集合

    List missiles =new ArrayList();//存放子弹的集合

在paint方法中将m.draw(g)替换掉

可以显示子弹的数量。

 g.drawString("子弹数量:"+missiles.size(),10,50);
        for(int i = 0;i 
三、停止时发射子弹 

坦克不能在停止时发射子弹原因:子弹方向和坦克的移动方向是一个,坦克在停止时发射子弹,子弹也是停止的。

需要用另外一个变量来表示子弹的方向。

坦克类增加/修改
    private Direction ptDir = Direction.D;//子弹发射方向

move()方法增加

if(this.dir != Direction.STOP){//排除坦克停止时的情况
            this.ptDir = this.dir;//使子弹发射的方向为其余八个方向
        }
四、增加炮筒

由于坦克只有一个椭圆是非常单调的且无法判断坦克的方向,可以在坦克上增加一个炮筒。

坦克类增加/修改

可以根据子弹的方向来画炮筒的方向

在draw方法中增加

switch (ptDir){//根据子弹方向来画炮筒
            case L:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x,y+Tank.HEIGHT/2);break;//x,y在坦克矩形的左上角
            case LU:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x,y);break;
            case U:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH/2,y);break;
            case RU:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH,y);break;
            case R:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH,y+Tank.HEIGHT/2);break;
            case RD:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH,y+Tank.HEIGHT);break;
            case D:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x+Tank.WIDTH/2,y+Tank.HEIGHT);break;
            case LD:g.drawLine(x+Tank.WIDTH/2,y+Tank.HEIGHT/2,x,y+Tank.HEIGHT);break;
        }
五、子弹越界消失

子弹在发出后,是不会消失的。

需要解决子弹离开窗口后在集合移出的问题。

子弹类增加/删除

子弹类需要接收tc的子弹集合

    private boolean live = true;//子弹的状态
    private TankClient tc;
 public Missile(int x,int y,Tank.Direction dir,TankClient tc){
        this(x,y,dir);
        this.tc =tc;
    }

draw()方法增加:

如果子弹live状态为false,则在子弹集合中移出

if(!live){
            tc.missiles.remove(this);
            return;
        }

move()方法增加:

判断子弹位置,如果离开窗口,则改变live状态为false。

//子弹越界
        if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT){
            live = false;
        }
坦克类增加/修改:

坦克类需要将tc的子弹集合传给子弹类,然后子弹类再删除。

fire()

Missile m = new Missile(x,y,ptDir,tc);
六、阻止坦克越界 坦克类增加/修改

坦克在将要出界时,改变坦克坐标,回到出界前。

move()方法增加

        //阻止坦克越界
        if(x<0) x = 0;
        if(y<30) y = 30;
        if(x+Tank.WIDTH>TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH-Tank.WIDTH;
        if(x+Tank.HEIGHT>TankClient.GAME_HEIGHT) x = TankClient.GAME_HEIGHT-Tank.HEIGHT;

至此,坦克大战界面:(改了一下界面背景)

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/980806.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号