关于java:我所知道坦克大战单机版之-让子弹飞让坦克控制子弹开炮

本篇文章目标


  • 让子弹飞
  • 让坦克管制子弹来发射

咱们后面实现了让坦克动起来,这次咱们须要让坦克进行开出炮弹的成果

一、让子弹飞


让子弹开炮,其实也就子弹,当咱们发射的时候,其实也相当于是一个圆在不听的动

class Missle{

    int x;//子弹的x坐标
    int y;//子弹的y坐标

    Tank.Direction dir;//方向枚举

    public Missle(int x, int y, Tank.Direction dir) {
        this.x = x;
        this.y = y;
        this.dir = dir;
    }
}

同时当咱们坦克按下发射键的时候发射子弹,那么就须要将这个子弹画进去

class Missle{

    //省略其余关键性代码.......
    
    //增加办法实现子弹的绘画
    public void draw(Graphics g) {
        //获取默认的色彩Color
        Color c = g.getColor();
        //将子弹色彩为红色
        g.setColor(Color.black);
        //画一个子弹的大小
        g.fillOval(x, y, 10, 10);
        //将原色彩填充回
        g.setColor(c);   
    }
}

以及当咱们发射子弹的时候,子弹是依据坦克的方向进行发射挪动,那么也须要move办法

class Missle{

    //省略其余关键性代码.......
    
    //每次挪动x坐标的步骤间隔
    public static final int XSPEED = 10;

    //每次挪动y坐标的步骤间隔
    public static final int YSPEED = 10;
    
    //增加办法实现子弹的绘画
    public void draw(Graphics g) {
        
        //省略其余关键性代码.......
        //让坦克动起来
        move();
    }
    
    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;
        }
    }
}

那么咱们这时依据思路new一个子弹进去,让它飞起来

public class TankClient extends Frame {
    
    //省略其余关键性代码.......
    
    //创立子弹对象
    Missle missle = new Missle(50,50, Tank.Direction.R);
    
    @Override
    public void paint(Graphics g) {
        //画出坦克....
        mytank.draw(g);
        //画出子弹....
        missle.draw(g);
    }
}

步骤思路总结

  • ✧增加Missile类
  • ✧增加x,y,dir等属性以及常量
  • ✧增加构造方法,draw办法等必要办法
  • ✧依据不同方向,进行不同的静止
  • ✧在TankClient中模仿一颗子弹
  • ✧new 一颗子弹进去并让他动起来

二、让坦克开炮

刚刚咱们胜利让子弹在界面上飞起来了,然而它是不听指挥的

那么咱们如何实现当咱们按下某个键的时候,依据坦克方向发射子弹呢?

第一步:坦克增加发射步骤的办法

public class Tank {
    
    //省略其余关键性代码.......
    
    //坦克发射子弹.....
    public Missle fire(){
        //依据坦克的坐标地位、方向、传给子弹
        Missle missle =new Missle(x,y,dir);
        return missle;
    }
}

第二步:增加Client关联坦克的发射子弹

之前咱们的子弹是固定的,当初咱们的子弹应该是由坦克来创立发射的

所以咱们这里的坦克须要获取到Client,并将创立的子弹传递绘画进去

public class Tank {
    
    TankClient tc;
    
    public Tank(int x, int y, TankClient tc) {
        this(x,y);
        this.tc = tc;
    }
    
    //省略其余关键性代码.......
}

并且要由咱们的坦克按下Ctrl键,创立子弹时咱们从才进行绘画

public class TankClient extends Frame {
    
    //省略其余关键性代码.......
    Tank mytank = new Tank(50,50,this);
    
    //创立子弹对象
    Missle missle = null;
    
    @Override
    public void paint(Graphics g) {
        //画出坦克....
        mytank.draw(g);
        //画出子弹....
        if(missle != null){missle.draw(g)}
    }
}

第三步:增加坦克键盘按下Ctrl处理事件

public class Tank {
    
    //省略其余关键性代码.......
    //坦克键盘按下监听器
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        switch (key) {
            case KeyEvent.VK_CONTROL:
                tc.missle = fire();
                break;
            case KeyEvent.VK_LEFT:
                BL = true;
                break;
            case KeyEvent.VK_UP:
                BU = true;
                break;
            case KeyEvent.VK_RIGHT:
                BR = true;
                break;
            case KeyEvent.VK_DOWN:
                BD = true;
                break;
        }
        locateDirection();
    }
}

这下咱们的子弹能够由坦克按下Ctrl键进行发射进去了

步骤思路总结

  • ✧减少对Ctrl键的按键解决
  • ✧依据坦克发射子弹的思路,创立办法fire,其返回值为Missle
  • ✧增加构造方法,draw办法等必要办法
  • ✧依据不同方向,进行不同的静止
  • ✧在TankClient中模仿一颗子弹
  • ✧new 一颗子弹进去并让他动起来

然而有没有发现咱们的子弹是由坦克的坐标左上角x,y的地位登程的

那么能不能由坦克的正中间登程呢?

三、优化坦克管制子弹开炮


将子弹、坦克的高度、宽度都设置为成员变量,给予固定

public class Tank {
    
    //坦克的宽度
    public static final int WIDTH = 30;
    //坦克的高度
    public static final int HEIGHT = 30;
    
    //增加办法实现坦克的绘画
    public void draw(Graphics g) {
        //省略其余关键性代码.......
        g.fillOval(x, y, WIDTH, HEIGHT);
    }
    //省略其余关键性代码.......
}
class Missle{

    //子弹的宽度
    public static final int WIDTH = 10;
    //子弹的高度
    public static final int HEIGHT = 10;
    
    //增加办法实现坦克的绘画
    public void draw(Graphics g) {
        //省略其余关键性代码.......
        g.fillOval(x, y, WIDTH, HEIGHT);
    }
    //省略其余关键性代码.......
}

批改坦克的fire办法,从新定位子弹的起始地位

public class Tank {
    
    //坦克发射子弹.....
    public Missle fire(){
        //依据坦克的坐标地位、方向、传给子弹
        int x = (this.x + WIDTH / 2) - Missle.WIDTH/2;
        int y = (this.y + HEIGHT / 2) - Missle.HEIGHT/2;
        Missle missle =new Missle(x,y,dir);
        return missle;
    }
    
    //省略其余关键性代码.......
}

参考资料


尚学堂:坦克大战(马士兵老师)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理