日々是好日~every day is a good day~

日常の中の非日常の備忘録

【Android Studio】ブロックくずし 6回目

今日は『ボールの跳ね返るスピードに変化をつける』と『スコアの表示』です

import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.util.DisplayMetrics
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.util.*
import kotlin.math.abs

var SCREEN_HEIGHT = 0   //画面の高さ
var SCREEN_WIDTH = 0   //画面の幅
val tate: Int = 8   //ブロックの縦の数
val yoko: Int = 5   //ブロックの横の数
var flag_Block = Array(tate) { BooleanArray(yoko) { true } }   //ブロックの表示/非表示のフラグ

open class MainActivity : AppCompatActivity() {
    private var ballx:Float = 0F   //ボールのx座標
    private var bally:Float = 0F   //ボールのy座標
    private var frameHeight = 0   //枠の高さ
    private var frameWidth = 0   //枠の幅
    private var ballHeight = 0   //ボールの高さ
    private var ballWidth =0   //ボールの幅
    private var barx = 0F   //バーのx座標
    private var barWidht = 0   //バーの幅
    private var barHeight = 0   //バーの高さ
    private val ballSpeed = 10   //ボールのスピード
    private var bcount = 0   //消したブロックの数
    private var score = 0   //スコア
    private var flag_UpDown:Boolean = true   //上下フラグ(true:下 false:上)
    private var flag_RightLeft:Boolean = true   //左右フラグ(true:右 false:左)
    private var flag_Start = false   //スタートフラグ
    private var timer = Timer()
    private val handler = Handler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //スクリーンサイズの取得
        val vm: WindowManager = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val display = vm.defaultDisplay
        val metric = DisplayMetrics()
        display.getMetrics(metric)
        SCREEN_WIDTH = metric.widthPixels
        SCREEN_HEIGHT = metric.heightPixels
        //ブロックをすべて表示
        flag_Block = Array(tate) { BooleanArray(yoko) { true } }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val startLabel:TextView = findViewById(R.id.startLabel)
        val bar:ImageView = findViewById(R.id.bar)
        val ball:ImageView = findViewById(R.id.ball)
        val tvScore:TextView = findViewById(R.id.tvScore)
        var random = (0..9).random()

        if(flag_Start == false){
            flag_Start = true
            barx = bar.x
            ballx = ball.x
            bally = ball.y

            startLabel.setVisibility(View.GONE)

            if(random<5){flag_RightLeft=false}  //最初のボールの方向
            //タッチでスタート、タイマー処理が始まる
            timer.schedule(object : TimerTask() {
                override fun run() {
                    handler.post {
                        ballMove()
                        tvScore.setText("Score : "+score.toString())
                    }
                }
            }, 0, 20)
        }else{   //バーを動かす
            if(event?.getAction() == MotionEvent.ACTION_MOVE) {
                barx = event.x
            }
            else{
                barx = barx
            }
            bar.setX(barx)
        }
        return true
    }

    var dis =0F   //ボールの中心がバーの中心からどれだけずれているか
    fun ballMove(){
        val ball:ImageView = findViewById(R.id.ball)
        val frame: FrameLayout = findViewById(R.id.frame)
        val bar:ImageView = findViewById(R.id.bar)
        var random = 0

        frameHeight = frame.getHeight()
        frameWidth = frame.getWidth()
        ballHeight = ball.getHeight()
        ballWidth = ball.getWidth()
        barWidht = bar.getWidth()
        barHeight = bar.getHeight()
        //ボールの移動
        if(flag_UpDown){  //下方向へ
            bally += ballSpeed
        }else {           //上方向へ
            bally -= ballSpeed
        }
        if(flag_RightLeft){   //右方向へ
            random = (8..15).random()/10
            ballx = ballx+(ballSpeed*random).toFloat()+abs(dis/8)
        }else{                //左方向へ
            random = (8..15).random()/10
            ballx = ballx-(ballSpeed*random).toFloat()-abs(dis/8)
        }
        ball.setY(bally)
        ball.setX(ballx)
        //壁・barへの衝突
        if((ball.y+ballHeight > bar.y) &&     //bar
            (ball.y+ballHeight < bar.y+barHeight) &&
            (bar.x < ball.x+ballWidth) &&
            (ball.x < bar.x+barWidht)) {
            dis = (bar.x+barWidht/2) - (ball.x+ballWidth/2)
            flag_UpDown = false  //上方向へ
        }else if(bally > frameHeight){ //下壁より下へ->ゲーム終了
            ball.y = (frameHeight+ballHeight).toFloat()
            ball.x = ballx
            timer.cancel()
        }else if(bally < 0){  //上壁
            flag_UpDown = true  //下方向へ

        }else if(ballx > frameWidth-ballWidth){  //右壁
            flag_RightLeft = false  //左方向へ
        }else if(ballx < 0){  //左壁
            flag_RightLeft = true  //右方向へ
        }else{  //ブロック
            for (i in 0..tate - 1) {
                if(ball.y < startY+recHeight+recHeight*i +recPich*i){
                    for(j in 0..yoko-1) {
                        if((startX+recWidth*j+recPich*j-ballWidth*3/4 < ball.x) &&
                            (ball.x <startX+recWidth+recWidth*j+recPich*j-ballWidth*1/4) &&
                            (flag_Block[i][j])){
                            flag_Block[i][j]=false
                            if(i%2 == 0){
                                score = score + (tate-i)*10/2    //偶数段
                            }else {
                                score = score + (tate-i+1)*10/2  //奇数段
                            }
                            bcount++
                            flag_UpDown = true  //下方向へ
                            if(bcount == tate*yoko){  //GAME CLEAR
                                timer.cancel()
                            }
                        }
                    }
                }
            }
        }
        if(barx > frameWidth-barWidht){
            barx = (frameWidth-barWidht).toFloat()
        }
        if(barx < 0){
            barx = 0F
        }
        bar.setX(barx)
    }
}


(再生できなくなっていたので2024.2.5に修正しました)
左右への移動の時ランダムに0.8倍から1.5倍スピードに変化をつけて
さらにボールがバーのどの位置に当たったかによっても変化をつけました
スコアは青が10点 緑が20点 黄が30点 赤が40点です