我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包

本章目的

  • 图形化显示生命值
  • 添加功能方块:血包

一、图形化显示生命值


虽然我们现在在游戏窗口左上角显示了当前的生命值,但是觉得还是将血条显示出来更好一些

我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包_第1张图片

那么具体怎么做呢?使用面向对象思维在坦克类定义一个内部类

class Tank{

    class BloodBar{
        public void  draw(Graphics g){

            //获取默认的颜色Color
            Color c = g.getColor();
            //将当前画笔颜色化为颜色
            g.setColor(Color.RED);
            //画出外层的空心方框
            g.drawRect(x,y-10,Tank.WIDTH,10);
            g.setColor(Color.ORANGE);
            int hp = Tank.WIDTH * liveHp /100;
            g.fillRect(x,y-10,hp,10);
            //将原颜色填充回
            g.setColor(c);
        }
    }
    //省略其他关键性代码........
}

这时我们在绘制坦克的时候呢,将这个类的绘制方法也给绘制出来

class Tank{

    private BloodBar bd = new BloodBar();

    //添加方法完成坦克的绘画
    public void draw(Graphics g) {
    
        //将内部类的血条画出来
        bd.draw(g);
        //省略其他关键性代码........
    }
    //省略其他关键性代码........
}

接下来我们运行游戏窗口,看看这个图形化生命值怎么样?好不好玩?

我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包_第2张图片

步骤总结

图形化显示生命值
  • ✧ 内部类根据生命值绘制
  • ✧ 绘制坦克时绘制图形化

二、添加功能方块:血包


一般当我们的坦克被击中后,会扣除相应的生命值

那么能不能像其他游戏一样,在某一个时间出现一个物品给我补充血量呢?

这时我们添加一个功能方块:血包、完成相应的方法并且按照一定的运动轨迹进行运动

class Blood{

    int x;//血块的x坐标
    int y;//血块的y坐标

    int windth;//血块的宽度
    int height;//血块的高度
}

我们同样需要对于血包这个类,完成相对应的绘制、管理、碰撞等等

class Blood{

    //添加方法完成血块的绘画
    public void draw(Graphics g) {
        //获取默认的颜色Color
        Color c = g.getColor();
        //将当前画笔颜色化为颜色
        g.setColor(Color.MAGENTA);
        g.fillRect(x,y-10,windth,height);
        //将原颜色填充回
        g.setColor(c);
    }
    
    //省略其他关键性代码........
}

在其他游戏中,一般这种功能方块都会飘来飘去的运动,有以下思路

  • 采用坦克的思路每个一段时间更换一个方向
  • 按照固定轨迹移动,并且在一段时间下消失

我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包_第3张图片

我们将移动的坐标轨迹使用二维数组管理

class Blood{

    //将移动的坐标信息使用二维数组保存起来
    private int[][] pos = {
        {350,300},{360,300},{375,275},{400,200},{360,270},{365,290},{340,280}
    };

    int step = 0;

    public Blood() {
        //初始化为第一个坐标
        x = pos[0][0];
        y = pos[0][1];
    }

    private void move(){
        step++;
        if(step == pos.length){
            step = 0;
        }
        x = pos[step][0];
        y = pos[step][1];
        
        windth = height = 15;
    }
    
    //省略其他关键性代码........
}

同时给我们的TankClient添加血块绘制与管理血块移动

public class TankClient extends Frame {
    
    Blood blood =new Blood();
    
    @Override
    public void paint(Graphics g) {
        //省略其他关键性代码........
        //画出血块
        blood.draw(g);
    }
    //省略其他关键性代码........
}
class Blood{

    //添加方法完成血块的绘画
    public void draw(Graphics g) {
        move();
    }
    
    //省略其他关键性代码........
}

这时候我们运行窗口就可以看到这个功能方块血包再移动轨迹了

我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包_第4张图片

那么接下来我们就要思考坦克吃掉它的思路了,说白了就是与它碰撞

class Tank{

    //添加与血包方块碰撞的方法
    public boolean eat(Blood blood){
        //要求:坦克是未消亡的并且坦克与血包的方框碰撞到一块
        if(this.live && this.getRect().intersects(blood.getRect())){
            //让坦克血量充满
            this.setLiveHp(100);
            return true;
        }
        return false;
    }
    //省略其他关键性代码........
}
class Blood{

    //创建血包的坐标空间区域
    public Rectangle getRect(){
        return new Rectangle(x,y,windth,height);
    }
    
    //省略其他关键性代码........
}

TankClient 添加对吃血包的处理

public class TankClient extends Frame {
    
    @Override
    public void paint(Graphics g) {
        //省略其他关键性代码........
        mytank.eat(blood);
    }
    //省略其他关键性代码........
}

当我们的坦克与血包进行碰撞的时候,就会补充血量

我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包_第5张图片

同时我们发现只要我们站在血包的移动轨迹内,就可以一直死不了

我们是不是也需要对血包进行存活状态的处理,若是被吃了则消失

class Blood{

    //区分血包的存活
    private boolean live = true;

    public boolean isLive() {
        return live;
    }

    public void setLive(boolean live) {
        this.live = live;
    }
    //添加方法完成血块的绘画
    public void draw(Graphics g) {
            
        //若消亡则不必绘制出来
        if(!live){return;}

       //省略其他关键性代码........
    }
    //省略其他关键性代码........
}

坦克吃掉血块后,将血块的存活状态改为消亡

class Tank{

    //添加与血包方块碰撞的方法
    public boolean eat(Blood blood){
        //要求:坦克是未消亡的、方块未消亡的,并且坦克与血包的方框碰撞到一块
        if(this.live && blood.isLive() &&  this.getRect().intersects(blood.getRect())){
            //让坦克血量充满
            this.setLiveHp(100);
            //让血包消亡
            blood.setLive(false);
            return true;
        }
        return false;
    }
    //省略其他关键性代码........
}

步骤总结

添加功能方块:血包
  • ✧ 添加Blood类
  • ✧ 添加绘制、移动、移动轨迹坐标、存活等属性方法
  • ✧ 让blood对象固定轨迹移动

参考资料


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

你可能感兴趣的:(我所知道坦克大战(单机版)之图形化显示生命值、添加功能方块:血包)