【Kotlin】坦克大战9:大本营绘制

文章目录

  • 大本营绘制
  • 大本营特性
  • 显示爆炸物
  • 细节处理
  • 子弹对消灭

大本营绘制

大本营的位置如图所示:
【Kotlin】坦克大战9:大本营绘制_第1张图片
中间有一只老鹰的图标,左,上,右都有砖墙
【Kotlin】坦克大战9:大本营绘制_第2张图片
新建Camp

/**
 * 大本营
 */
class Camp(override val x: Int, override val y: Int) : View {

    override val width: Int = Config.block * 2
    override val height: Int = Config.block + 32

    override fun draw() {
        //绘制外围砖块
        Painter.drawImage("img/steel_small.gif", x, y)
        Painter.drawImage("img/steel_small.gif", x + 32, y)
        Painter.drawImage("img/steel_small.gif", x + 64, y)
        Painter.drawImage("img/steel_small.gif", x + 96, y)

        Painter.drawImage("img/steel_small.gif", x, y + 32)
        Painter.drawImage("img/steel_small.gif", x, y + 64)

        Painter.drawImage("img/steel_small.gif", x + 96, y + 32)
        Painter.drawImage("img/steel_small.gif", x + 96, y + 64)

        Painter.drawImage("img/camp.gif", x + 32, y + 32)
    }
}

GameWindow中绘制

class GameWindow :
    Window(title = "坦克大战", icon = "img/kotlin.jpg", width = Config.gameWidth, height = Config.gameHeight) {
    ......
    override fun onCreate() {
        ......
        //添加我方坦克
        tank = Tank(Config.block * 10, Config.block * 12)
        views.add(tank)

        //添加大本营
        views.add(Camp(Config.gameWidth/2 - Config.block,Config.gameHeight - 96))

    }
	......
}

运行

大本营特性

运行刚才的程序,我们的坦克能直接穿过大本营,所以我们应给大本营增加一些特性,大本营应该具备阻挡功能,接受攻击的功能

/**
 * 大本营
 * 具备阻挡功能
 * 具备接受攻击的功能
 */
class Camp(override var x: Int, override var y: Int) : View, Blockable, Sufferable {
    override var width: Int = Config.block * 2
    override var height: Int = Config.block + 32

    override var blood: Int = 12

    override fun draw() {
        //血量不同,绘制不同
        //血量开始时,铁墙
        //血量低于6个时,砖墙
        //血量低于3个时,没有墙
        if (blood < 3) {
            width = Config.block
            height = Config.block
            x = (Config.gameWidth - Config.block)/2
            y = Config.gameHeight - Config.block
            Painter.drawImage("img/camp.gif", x, y)
        } else if (blood < 6) {
            //绘制外围砖块
            Painter.drawImage("img/wall_small.gif", x, y)
            Painter.drawImage("img/wall_small.gif", x + 32, y)
            Painter.drawImage("img/wall_small.gif", x + 64, y)
            Painter.drawImage("img/wall_small.gif", x + 96, y)

            Painter.drawImage("img/wall_small.gif", x, y + 32)
            Painter.drawImage("img/wall_small.gif", x, y + 64)

            Painter.drawImage("img/wall_small.gif", x + 96, y + 32)
            Painter.drawImage("img/wall_small.gif", x + 96, y + 64)

            Painter.drawImage("img/camp.gif", x + 32, y + 32)
        } else {
            //绘制外围砖块
            Painter.drawImage("img/steel_small.gif", x, y)
            Painter.drawImage("img/steel_small.gif", x + 32, y)
            Painter.drawImage("img/steel_small.gif", x + 64, y)
            Painter.drawImage("img/steel_small.gif", x + 96, y)

            Painter.drawImage("img/steel_small.gif", x, y + 32)
            Painter.drawImage("img/steel_small.gif", x, y + 64)

            Painter.drawImage("img/steel_small.gif", x + 96, y + 32)
            Painter.drawImage("img/steel_small.gif", x + 96, y + 64)

            Painter.drawImage("img/camp.gif", x + 32, y + 32)
        }
    }

    override fun notifySuffer(attackable: Attackable): Array<View>? {
        //被打时
        blood -= attackable.attackPower
        return null
    }
}

看以上代码,在onDraw时,攻击大本营后,随着血量变少,大本营由铁墙变为砖墙,最后消失。消失后,应对大本营大小进行处理

显示爆炸物

绘制的爆炸物大致如下
【Kotlin】坦克大战9:大本营绘制_第3张图片
修改Camp中以下方法

override fun notifySuffer(attackable: Attackable): Array<View>? {
        //被打时
        blood -= attackable.attackPower
        if(blood == 3 || blood == 6){
            val x = x -32
            val y = y -32
            return arrayOf(Blast(x,y),
                Blast(x+32,y),
                Blast(x+Config.block,y),
                Blast(x+Config.block+32,y),
                Blast(x+Config.block*2,y),

                Blast(x,y+32),
                Blast(x,y+Config.block),
                Blast(x,y+Config.block +32),

                Blast(x+Config.block*2,y+32),
                Blast(x+Config.block*2,y+Config.block),
                Blast(x+Config.block*2,y+Config.block+32)
            )
        }
        return null
    }

运行:
【Kotlin】坦克大战9:大本营绘制_第4张图片

细节处理

1、绘制爆炸物时,当铁墙爆炸后,还是显示铁墙,需要再打一下才能变成砖墙

这里在绘制时改为

 override fun draw() {
        if (blood <= 3) {
            ......
        } else if (blood <= 6) {
            ......
        } else {
            ......
        }
    }

2、子弹能穿过铁墙

class Steel(override val x: Int, override val y: Int) :Blockable,Sufferable{
    override var blood: Int = 1

    ......

    override fun notifySuffer(attackable: Attackable): Array<View>? {
        return null
    }
}

子弹对消灭

class Bullet(override var owner: View,override val currentDirection: Direction, create: (width: Int, height: Int) -> Pair<Int, Int>
) : AutoMoveable,Destroyable,Attackable,Sufferable {
    ......

    override var blood: Int = 1
    ......
    override fun notifySuffer(attackable: Attackable): Array<View>? {
        return arrayOf(Blast(x,y))
    }
}

GameWindow中

override fun onRefresh() {
        ......
        //检测有攻击能力和被攻击能力的物体间是否发生了碰撞
        //1)过滤具备攻击能力的
        views.filter { it is Attackable }.forEach{attack->
            attack as Attackable
            //2)具备受攻击能力的(攻击方的源,不可以是发射方)
            //攻击方如果也是受攻击方,不可以打自己
            views.filter { (it is Sufferable) and (attack.owner != it) and (attack != it) }.forEach sufferTag@ {suffer->
                ......
                }
            }
        }
		......
    }

首先让Bullet获得Sufferable的特性,给一个血量,在遭到攻击后返回爆照效果

GameWindow的逻辑判断那里,攻击方如果也是受攻击方,不可以打自己,否则每次发出一颗子弹,都会爆炸

你可能感兴趣的:(Kotlin从零到一无所有)