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

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

【Android Studio】もぐらたたき 3回目

今日は『もぐらをランダムに出没させる』です

import android.graphics.*
import android.os.Bundle
import android.os.Handler
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.appcompat.app.AppCompatActivity
import java.util.*
import java.util.concurrent.ThreadLocalRandom

//モグラフラグ  0:モグラ穴 1:モグラ出没 2:モグラパンチ 3:モグラ空振り
var flag =Array(5) { IntArray(4) { 0 } }

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

        //MainActivity  Viewの取得
        val surfaceview: SurfaceView = findViewById(R.id.surfaceView)
        // MySurfaceViewのインスタンスを生成
        MySurfaceView(this, surfaceview)

        moleStart()
    }

    fun moleStart() {
        val hl = Handler()
        var r = Runnable { }
        //モグラ出没
        r = Runnable {
            val dspTime = ThreadLocalRandom.current().nextLong(500, 1000)
            val tateNum = Random().nextInt(5)
            val yokoNum = Random().nextInt(4)
            flag[tateNum][yokoNum] = 1
            Handler().postDelayed(
                {
                    if (flag[tateNum][yokoNum] !=0) {
                        flag[tateNum][yokoNum] = 0
                    }
                }, dspTime
            )
            hl.postDelayed(r, 300)
        }
        hl.post(r)
    }
}

class MySurfaceView: SurfaceView, SurfaceHolder.Callback {
    var surfaceHolder: SurfaceHolder? = null
    var paint = Paint()
    var canvas = Canvas()
    val mogurawidth = 260   //モグラの幅
    val moguraheigh = 250   //モグラの高さ
    val tstart = 400f   //表示開始のy座標
    val ypich = 270f    //横幅のピッチ
    val tpich = 250f    //高さのピッチ
    //モグラ穴のビットマップ
    val mogurahole = Bitmap.createScaledBitmap(
        BitmapFactory.decodeResource(resources, R.drawable.mogurahole),
        mogurawidth, mogurawidth, true
    )
    //モグラが出没しているビットマップ
    val mogura = Bitmap.createScaledBitmap(
        BitmapFactory.decodeResource(resources, R.drawable.mogura),
        mogurawidth, moguraheigh, true
    )

    constructor(context: MainActivity, surfaceView: SurfaceView) : super(context) {
        surfaceHolder = surfaceView.holder
        // 背景を透過させ、一番上に表示
        surfaceHolder!!.setFormat(PixelFormat.TRANSPARENT)
        surfaceView.setZOrderOnTop(true)
        // コールバック
        surfaceHolder!!.addCallback(this)
    }

    override fun surfaceCreated(p0: SurfaceHolder) {
        // ロックしてキャンバスを取得
        canvas = surfaceHolder!!.lockCanvas()
        for (i in 0..4) {
            for (j in 0..3) {
                canvas.drawBitmap(mogurahole, ypich * j, tstart + tpich * i, paint)
            }
        }
        // ロックを解除
        surfaceHolder!!.unlockCanvasAndPost(canvas)
    }

    override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {
        moguradraw()
    }

    override fun surfaceDestroyed(p0: SurfaceHolder) {

    }

    fun moguradraw() {
        canvas = Canvas()
        var runnable = Runnable {  }
        val handler = Handler()
        runnable = Runnable {
            Handler().postDelayed(
                {
                    // ロックしてキャンバスを取得
                    canvas = surfaceHolder!!.lockCanvas()
                    // キャンバスのクリア
                    canvas.drawColor(0, PorterDuff.Mode.CLEAR)
                    // 描画
                    for (i in 0..4) {
                        for (j in 0..3) {
                            if(flag[i][j]==1)   //モグラ
                                canvas.drawBitmap(mogura, ypich * j, tstart + tpich * i, paint)
                            else   //モグラ穴
                                canvas.drawBitmap(mogurahole, ypich * j, tstart + tpich * i, paint)
                        }
                    }
                    // ロックを解除
                    surfaceHolder!!.unlockCanvasAndPost(canvas)
                }, 0 )
            handler.postDelayed(runnable,50)
        }
        handler.post(runnable)
    }
}


(再生できなくなっていたので2024.2.5に修正しました)
もぐらがランダムに出没するようになりました
SurfaceViewは最初戸惑いますね(汗)
SurfaceHolder.Callbackには

override fun surfaceCreated(p0: SurfaceHolder) {}
override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {}
override fun surfaceDestroyed(p0: SurfaceHolder) {}

この3つのメソッドを実装しなければなりません
それぞれ呼ばれるタイミングはSurfaceが作られた時 変化があった時 破棄された時です
ある程度パターンが決まっているので初めはコピペでとりあえずやってみるのがいいと思います