【Kotlin】坦克大战8:敌方坦克发射

敌方坦克发射

创建AutoShot

/**
 * 自动射击的能力
 */
interface AutoShot {
    //自动射击的功能
    fun autoShot(): View?
}

Enemy实现这个接口,重写autoShot方法(Tank中有相同代码,抄一抄)

class Enemy(override var x: Int, override var y: Int) :Moveable, AutoMoveable,Blockable,AutoShot {
    ......
    override fun autoShot(): View? {
        return Bullet(currentDirection, { bulletWidth, bulletHeight ->
            var tankX = x
            var tankY = y
            var tankWidth = width
            var tankHeight = height

            var bulletX = 0
            var bulletY = 0

            //计算子弹真实的坐标
            //如果坦克向上:bulletX = tankX+(tankWidth-bulletWidth)/2
            //bulletY = tankY - bulletHeight/2
            when (currentDirection) {
                Direction.up -> {
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY - bulletHeight / 2
                }
                Direction.down -> {
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY + tankHeight - bulletHeight / 2
                }
                Direction.left -> {
                    bulletX = tankX - bulletWidth / 2
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }
                Direction.right -> {
                    bulletX = tankX + (tankWidth - bulletWidth / 2)
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }
            }

            Pair(bulletX, bulletY)
        })
    }
}

GameWindow中onRefresh中增加

		//检测自动射击
        views.filter { it is AutoShot }.forEach{
            it as AutoShot
            var shot:View? = it.autoShot()
            shot?.let {
                views.add(shot)
            }
        }

现在运行程序,敌方坦克发射速度很快,现在增加时间控制

class Enemy(override var x: Int, override var y: Int) :Moveable, AutoMoveable,Blockable,AutoShot {
    ......
    //上次射击时间
    private var lastShotTime = 0L
    //射击频率
    private var shotFrequency = 800

    private var lastMoveTime = 0L
    private var moveFrequency = 50

  override fun autoMove() {
        //频率检查
        var current = System.currentTimeMillis()
        if(current - lastMoveTime < moveFrequency) return
        lastMoveTime = current
  
        if(currentDirection == badDirection){
            //要往错误方向走,不允许
            //改变自己方向
            currentDirection = rdmDirection(badDirection)
        }
        //坦克的坐标移动
        //根据方向改变坐标
        when (currentDirection) {
            Direction.up -> y -= speed
            Direction.down -> y += speed
            Direction.left -> x -= speed
            Direction.right -> x += speed
        }

        //越界判断
        if (x < 0) x = 0
        if (x > Config.gameWidth - width) {
            x = Config.gameWidth - width
        }
        if (y < 0) y = 0
        if (y > Config.gameHeight - height) {
            y = Config.gameHeight - height
        }
    }
    
    ......

    override fun autoShot(): View? {
        var current = System.currentTimeMillis()
        if(current - lastShotTime < shotFrequency) return null
        lastShotTime = current
		......
    }
}

双方坦克互相伤害

修改Tank

class Tank(override var x: Int, override var y: Int) : Moveable,Blockable,Sufferable {
    ......
    override var blood: Int = 20
    override fun notifySuffer(attackable: Attackable): Array<View>? {
        blood -= attackable.attackPower
        return arrayOf(Blast(x,y))
    }
    ......
}

修改敌方坦克

class Enemy(override var x: Int, override var y: Int) :Moveable, AutoMoveable,Blockable,AutoShot,Sufferable {
    ......
    override var blood: Int = 2
    ......
    override fun notifySuffer(attackable: Attackable): Array<View>? {
        blood -= attackable.attackPower
        return arrayOf(Blast(x,y))
    }
}

现在运行会发现,各种爆炸,原因是,子弹击中自己后,爆炸了,现在Attackable加一个所有者的属性

interface Attackable : View {
    //所有者
    var owner:View
    ......
}

Bullet报错了,修改

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

Tank,Enemy中的autoShot方法修改为

override fun autoShot(): View? {
        ......
        return Bullet(this,currentDirection, { bulletWidth, bulletHeight ->
            ......
        })
    }

GameWindow的onRefresh中,让攻击方和发射方不相同

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

敌方坦克销毁

class Enemy(override var x: Int, override var y: Int) :Moveable, AutoMoveable,Blockable,AutoShot,Sufferable,Destroyable {
    ......
    override fun isDestroyed(): Boolean = blood<=0
}

现在运行程序,敌方坦克互相伤害,然后不战而胜…

但这样确实缺少了游戏乐趣,我们让敌方坦克不能相互伤害,修改Enemy

class Enemy(override var x: Int, override var y: Int) :Moveable, AutoMoveable,Blockable,AutoShot,Sufferable,Destroyable {
    ......
    override fun notifySuffer(attackable: Attackable): Array<View>? {

        //如果攻击方是敌方,挨打不掉血
        if(attackable.owner is Enemy) return null

        blood -= attackable.attackPower
        return arrayOf(Blast(x,y))
    }

  	......

}
发布了640 篇原创文章 · 获赞 143 · 访问量 54万+

猜你喜欢

转载自blog.csdn.net/u010356768/article/details/103584474
今日推荐