ボール以外の壁、ブロック、バーのクラスを作り
それぞれ配置(生成)と衝突判定を実装しています
壁は
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 }
}
}
}
こんな感じて
コードはgitに置いてます
おまけ
壁は四方にあるので、下からも跳ね返ります
ゲームとして成り立ってません
(負けの判定作るのが面倒だったんですが)