乐趣区

关于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;
    }
    
    // 省略其余关键性代码.......
}

参考资料


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

退出移动版