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

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

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

今日は『ゲームスタートと終了』です

import android.graphics.*
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.widget.ImageButton
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.util.*
import java.util.concurrent.ThreadLocalRandom

//モグラフラグ  0:モグラ穴 1:モグラ出没 2:モグラパンチ 3:モグラ空振り
var flag =Array(5) { IntArray(4) { 0 } }
var flgend = false   //ゲーム終了フラグ
var score:Int =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のインスタンスを生成
        val mysurfaceview = MySurfaceView(this, surfaceview)
        surfaceview.setOnTouchListener { v, event ->
            mysurfaceview.onTouch(event)
        }

        val startTime: Long = 30000   //ゲームのプレイ時間
        val btnStart: ImageButton = findViewById(R.id.ImgbtStart)
        var tvScore: TextView = findViewById(R.id.tvScore)
        var tvTimer: TextView = findViewById(R.id.tvTimer)
        tvTimer.text = "${startTime / 1000}" //開始時間を秒で表示

        //カウントダウンタイマーのオブジェクトを用意
        val timer = object : CountDownTimer(startTime, 1000) {
            //途中経過・残り時間
            override fun onTick(p0: Long) {
                //残り時間を表示
                tvTimer.text = "${p0 / 1000}" //秒単位
            }
            //終了設定
            override fun onFinish() {
                flgend = true
            }
        }

        //スタートボタンタップ
        btnStart.setOnClickListener {
            tvScore.text = score.toString()
            btnStart.isEnabled = false
            btnStart.setBackgroundResource(R.drawable.btninvalid)
            timer.start()
            moleStart()
        }
    }

    fun moleStart() {
        var tvScore: TextView = findViewById(R.id.tvScore)
        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
            )
            tvScore.text = score.toString()
            hl.postDelayed(r, 300)
            if (flgend) hl.removeCallbacks(r)
        }
        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
    )
    //モグラを空振りしているビットマップ
    val mogura0 = Bitmap.createScaledBitmap(
        BitmapFactory.decodeResource(resources, R.drawable.moguraswing),
        mogurawidth, mogurawidth, true
    )
    //モグラをパンチしているビットマップ
    val mogura1 = Bitmap.createScaledBitmap(
        BitmapFactory.decodeResource(resources, R.drawable.mogurahit),
        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) {

    }
    var tate=0
    var yoko=0
    // 画面をタッチしたときにアクションごとに関数を呼び出す
    fun onTouch(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> touchDown(event.x, event.y)
            MotionEvent.ACTION_UP -> tochUp()
        }
        return true
    }
    //どのモグラをクリックしたか
    fun touchDown(x:Float,y:Float){
        for (i in 0..4) {
            if((tstart+tpich*i)<y && y<(tstart+tpich*i+moguraheigh)){
                tate=i
                break
            }
        }
        for (j in 0..3) {
            if((ypich*j)<x && x<(ypich*j+mogurawidth)){
                yoko=j
                break
            }
        }
        if(flag[tate][yoko]==1) {
            flag[tate][yoko]=2
            score++
        }
        else {
            flag[tate][yoko]=3
        }
    }

    fun tochUp(){
        flag[tate][yoko] = 0
    }

    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 if(flag[i][j]==2)   //モグラパンチ
                                canvas.drawBitmap(mogura1, ypich * j, tstart + tpich * i, paint)
                            else if(flag[i][j]==3)   //モグラ空振り
                                canvas.drawBitmap(mogura0, ypich * j, tstart + tpich * i, paint)
                            else   //モグラ穴
                                canvas.drawBitmap(mogurahole, ypich * j, tstart + tpich * i, paint)
                        }
                    }

                    // ロックを解除
                    surfaceHolder!!.unlockCanvasAndPost(canvas)
                }, 0 )
            handler.postDelayed(runnable,50)
            if (flgend) {
                handler.removeCallbacks(runnable)
            }
        }
        handler.post(runnable)
    }
}


(再生できなくなっていたので2024.2.5に修正しました)
スタートボタンを押すとゲームが始まり タイマーが0になると終了です
ゲームらしくなってきました
次回は結果画面を作成します

  翻译: