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

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

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

今日は『効果音』です

import android.content.Context
import android.content.Intent
import android.media.SoundPool
import android.media.AudioAttributes
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 } }   //ブロックの表示/非表示のフラグ
internal lateinit var soundPool: SoundPool   //サウンドプール

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()
    private var hit = 0   //ボールがあたった音

    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 } }
        //効果音作成
        val audioAttributes = AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
            .build()
        soundPool = SoundPool.Builder()
            .setAudioAttributes(audioAttributes)
            .setMaxStreams(2)
            .build()
        hit = soundPool.load(this, R.raw.hit, 1)
    }

    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)

        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){   //右方向へ
            var random = (8..15).random()/10
            ballx = ballx+(ballSpeed*random).toFloat()+abs(dis/8)
        }else{                //左方向へ
            var 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)
            soundPool.play(hit, 1.0f, 1.0f, 1, 0, 1.0f)
            flag_UpDown = false  //上方向へ
        }else if(bally > frameHeight){ //下壁より下へ->ゲーム終了
            ball.y = (frameHeight+ballHeight).toFloat()
            ball.x = ballx
            timer.cancel()
            //結果画面へ
            val intent = Intent(this,ResultActivity::class.java)
            intent.putExtra("SCORE",score)
            intent.putExtra("BLOCKCOUNT",bcount)
            startActivity(intent)
            finish()
        }else if(bally < 0){  //上壁
            soundPool.play(hit, 1.0f, 1.0f, 1, 0, 1.0f)
            flag_UpDown = true  //下方向へ

        }else if(ballx > frameWidth-ballWidth){  //右壁
            soundPool.play(hit, 1.0f, 1.0f, 1, 0, 1.0f)
            flag_RightLeft = false  //左方向へ
        }else if(ballx < 0){  //左壁
            soundPool.play(hit, 1.0f, 1.0f, 1, 0, 1.0f)
            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++
                            soundPool.play(hit, 1.0f, 1.0f, 1, 0, 1.0f)
                            flag_UpDown = true  //下方向へ
                            if(bcount == tate*yoko){  //GAME CLEAR
                                timer.cancel()
                                //結果画面(GAME CLEAR)
                                val intent = Intent(this,ResultActivity::class.java)
                                intent.putExtra("SCORE",score)
                                intent.putExtra("BLOCKCOUNT",bcount)
                                startActivity(intent)
                                finish()
                            }
                        }
                    }
                }
            }
        }
        if(barx > frameWidth-barWidht){
            barx = (frameWidth-barWidht).toFloat()
        }
        if(barx < 0){
            barx = 0F
        }
        bar.setX(barx)
    }
}

SoundPoolを設定して音源をロードしボールが当たったら再生します

(再生できなくなっていたので2024.2.5に修正しました)
【注意】音でます
これで完成です