kotlinでandroidの入門　ブロック崩し2


ボール以外の壁、ブロック、バーのクラスを作り
それぞれ配置（生成）と衝突判定を実装しています

### 壁は

```kabe.kt
class Kabe(val ball : Ball) {
    private var width  : Float = 0F
    private var height : Float = 0F

    // 配置 (画面サイズをもらう)
    fun arrangement( vw : Float, vh : Float) {
        width = vw
        height = vh
    }
    // 衝突判定 戻り true = ぶつかった＆ボール反転させた
    fun chkCollision( ) : Boolean {
        return if (ball.newLeft < 0 ) {
            // 左
            ball.resetNewX(0F )
            true
        } else if ( ball.newRight >= width ) {
            // 右
            ball.resetNewX( width )
            true
        } else if (ball.newTop < 0 ) {
            ball.resetNewY(0F)
            true
        } else if (ball.newBottom >= height ) {
            ball.resetNewY(height)
            true
        } else {
            false
        }
    }
}
```

### ブロックは、
配列を使い複数配置
ぶつかったら消す。

```block.kt
class Block (val ball : Ball ) {
    val take : Int = 3
    val yoko : Int = 5

    private val top : Float = 10F
    private val height : Float = 40F
    private var stepy : Float = height+ 20F

    private var left : Float = 0F
    private var stepx : Float = 0F
    private var width : Float = 0F
    private var blockSt = Array<Boolean>( take * yoko, { true } )


    //
    val blockCount : Int
        get() = blockSt.count { it == true }

    private fun getTakeIndex(idx : Int) : Int {
        return  idx / yoko
    }
    private fun getColumnIndex( idx : Int, line : Int) : Int {
        return  idx - ( line * yoko )
    }
    fun chkBlock( idx : Int ) : Boolean {
        return blockSt[idx]
    }
    fun getRect( idx : Int) : RectFloat {
        var r : RectFloat = RectFloat()
        if ( blockSt[idx] == true) {
            val line = getTakeIndex(idx)
            val column = getColumnIndex(idx, line)
            r.left = left + (column * stepx )
            r.right = r.left + width
            r.top = top + (line * stepy)
            r.bottom =r.top + height
        }
        return r
    }
    fun arrangement( viewWidth : Float, viewHight : Float) {
        stepx = viewWidth / (yoko+1)
        left = stepx / 2
        width = stepx * 0.8F
    }
    fun reset() {
        blockSt = Array<Boolean>( take * yoko, { true } )
    }


    //　衝突判定　それっぽく
    fun chkCollision(): Boolean {
        var r: Boolean = false

        for (l in 0..take - 1) {
            val yt = top + (l * stepy)
            val yb = yt + height
            if (ball.newBottom >= yt && ball.newTop <= yb) {
                for (c in 0..yoko - 1) {
                    if ( true == blockSt[ l*yoko+c]) {
                        val xl = left + (c * stepx)
                        val xr = xl + width
                        if (ball.newRight >= xl && ball.newLeft <= xr) {
                            // ぶつかっている　
                            blockSt[l * yoko + c] = false

                            val ts = Math.abs(yt - ball.bottom)
                            val bs = Math.abs(yb - ball.top)
                            val ls = Math.abs(xl - ball.right)
                            val bl = Math.abs(xr - ball.left)
                            if (ts <= bs && ts <= ls && ts <= bl) {
                                // 上からぶつかったことに
                                ball.resetNewY(yt)
                            } else if (bs <= ts && bs <= ls && bs <= bl) {
                                ball.resetNewY(yb)
                            } else if (ls <= ts && ls <= bs && ls <= bl) {
                                ball.resetNewX(xl)
                            } else {
                                ball.resetNewX(xr)
                            }
                            return true
                        }
                    }
                }
            }
        }
        return false
    }
}

// 有るかも or 本当はここまでいらないと思う
class RectFloat(var left : Float = 0F, var top : Float = 0F, var right : Float = 0F, var bottom : Float = 0F)
```

### バー（ラケットにすればわかりやすかったな）は
ボタンで左右に移動するようにして
衝突は上からのみ判断してます

```Bar.kt
class Bar(val ball : Ball ) {
    // バーの移動状態
    enum class MoveSw {
        move_stop,
        move_left,
        move_right
    }

    // ここでバーの表示状態指定
    private val OffsetY : Float = 100F
    private val h : Float = 20F

    private var vWidth : Float = 0F
    private var x : Float = 0F
    private var y : Float = 0F
    private var moveFlg : MoveSw = MoveSw.move_stop
    private var targetX : Float = 0F

    private var size : Float = 100F
    private var moveSize : Float = 10F

    // バーの座標情報
    val top : Float
        get() = y
    val bottom : Float
        get() = y+h
    val left : Float
        get() = x-size
    val right : Float
        get() = x+size
    val center : Float
        get() = x

    //　配置　（画面の大きさに合わせる)
    fun arrangement( vw : Float, vh : Float) {
        vWidth = vw
        y = vh - OffsetY
    }
    fun reset(barWidih : Float , kizami : Float ) {
        x = vWidth / 2
        size = barWidih
        moveSize = kizami
    }
    fun chkCollision( ) : Boolean {
        var r: Boolean = false
        if ( ball.bottom < y  && ball.newBottom >= y) {
            if ((  ball.right>left || ball.newRight>left ) &&
                    (ball.left < right || ball.newLeft < right))   {
                //　ざっくりとした判定　
                ball.resetNewY( y )
                when(moveFlg) {
                    MoveSw.move_left -> { ball.vectorAcceleX(-0.1F)}
                    MoveSw.move_right -> {ball.vectorAcceleX(0.1F)}
                }
                r = true
            }
        }
        return r
    }
    fun chkLeftRight( px : Int, py :Int) {
        targetX = if ( py > top && py < top+100F ) {
            if ((x + (size / 3)) < px) {
                px.toFloat()
            } else if ((x - (size / 3)) > px ) {
                px.toFloat()
            } else {
                moveFlg = MoveSw.move_stop
                0F
            }
        } else {
            Log.d("out", px.toString()+","+(x.toInt()).toString())
            moveFlg = MoveSw.move_stop
            0F
        }
    }
    fun setMove(LeftRight:MoveSw, goStop : Boolean ) {
        if ( goStop == true) {
            moveFlg = LeftRight
        } else if ( moveFlg == LeftRight ) {
            moveFlg = MoveSw.move_stop
        }
    }
    fun moveTo() {
        moveFlg = if ( 0F != targetX ) {
            if ( (x-(size/3)) >= targetX ) {
                MoveSw.move_left
            } else if ( (x+(size/3)) <= targetX) {
                MoveSw.move_right
            } else {
                targetX = 0F
                MoveSw.move_stop
            }
        } else {
            moveFlg
        }
        x = when(moveFlg) {
            MoveSw.move_left -> {
                if (left < 0F) {
                    size
                } else {
                    x - moveSize
                }
            }
            MoveSw.move_right-> {
                if (right > vWidth) {
                    vWidth - size
                } else {
                    x + moveSize
                }
            }
            else -> { x }
        }
    }
}
```

![blockBreak.png](https://qiita-image-store.s3.amazonaws.com/0/258658/e3bea22b-da6a-6370-5030-43d5da472f7d.png)

こんな感じて
コードは[git](https://github.com/bokufolivora/blockBreak)に置いてます

### おまけ
壁は四方にあるので、下からも跳ね返ります
ゲームとして成り立ってません
（負けの判定作るのが面倒だったんですが）