kotlin版本的围住神经猫

作者看到围住神经猫游戏,结合极客学院教学视频,用Kotlin实现该游戏。作者未过多阐述游戏原理,认为网上已有很多相关内容,直接贴出核心代码,还称赞Kotlin十分简洁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     最近看见了围住神经猫这个游戏,刚好极客学院又有这个游戏的教学视频,就准备跟着视频撸一遍,但是干撸不过瘾,所以打算用kotlin撸了一遍,游戏的原理我就不做过多赘述了,网上已经一搜一大把了。直接贴出代码了

package com.yking.catchcrazycat

import android.content.Context
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.Log
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import android.widget.Toast
import java.util.*
import kotlin.collections.HashMap

/**
 * Created by  on 2018/8/28.YaoKai
 */
class PlayGround constructor(
        context: Context
) : SurfaceView(context), SurfaceHolder.Callback, View.OnTouchListener {


    companion object {
        private const val COL: Int = 10
        private const val ROW: Int = 10
        private const val BLOCKS: Int = 15//初始障碍物个数
        private var WIDTH: Int = 40//每个圆圈的默认宽度
    }

    private var martix = Array(COL) { arrayOfNulls<Dot>(ROW) }
    private var cat: Dot? = null

    init {
        holder.addCallback(this)
        //加载数据源
        for ((i, arrayRow) in martix.withIndex()) {
            for (j in 0..(COL - 1)) {
                arrayRow[j] = Dot(j, i)
            }
        }
        setOnTouchListener(this)
        initGame()
    }

    /**
     * 初始化游戏
     */
    private fun initGame() {
        for (arrayRow in martix) for (dot in arrayRow) dot?.let {
            it.status = Dot.STATUS_OFF
        }
        cat = Dot(4, 5)
        getDot(4, 5)?.status = Dot.STATUS_IN
        for (i in 1..BLOCKS) {
            val x: Int = ((Math.random() * 1000) % COL).toInt()
            val y: Int = ((Math.random() * 1000) % ROW).toInt()
            if (getDot(x, y)?.status == Dot.STATUS_OFF) {
                getDot(x, y)?.status = Dot.STATUS_ON
                Log.e("BLOCKS", "x:$x y:$y")
            }
        }
    }

    private fun getDot(i: Int, i1: Int): Dot? {
        return martix[i1][i]
    }

    /**
     * 判断是否为边界
     */
    private fun isAtEdge(dot: Dot): Boolean {
        if (dot.x * dot.y == 0 || dot.x + 1 == COL || dot.y + 1 == ROW) {
            return true
        }
        return false
    }

    /**
     * 获取相邻点位
     */
    private fun getNeighbor(dot: Dot, dir: Int): Dot? {
        when (dir) {
            1 -> {
                return getDot(dot.x - 1, dot.y)
            }
            2 -> {
                return if (dot.y % 2 == 0) {
                    getDot(dot.x - 1, dot.y - 1)
                } else {
                    getDot(dot.x, dot.y - 1)
                }
            }
            3 -> {
                return if (dot.y % 2 == 0) {
                    getDot(dot.x, dot.y - 1)
                } else {
                    getDot(dot.x + 1, dot.y - 1)
                }
            }
            4 -> {
                return getDot(dot.x + 1, dot.y)
            }
            5 -> {
                return if (dot.y % 2 == 0) {
                    getDot(dot.x, dot.y + 1)
                } else {
                    getDot(dot.x + 1, dot.y + 1)
                }
            }
            6 -> {
                return if (dot.y % 2 == 0) {
                    getDot(dot.x - 1, dot.y + 1)
                } else {
                    getDot(dot.x, dot.y + 1)
                }
            }
        }
        return null
    }

    /**
     * 获取距离
     */
    private fun getDistance(dot: Dot, dir: Int): Int {
        var distance = 0
        var ori: Dot = dot
        var next: Dot?
        if (isAtEdge(dot)) {
            return 1
        }
        while (true) {
            next = getNeighbor(ori, dir)
            if (next!!.status == Dot.STATUS_ON) {
                return -distance
            }
            if (isAtEdge(next)) {
                distance++
                return distance
            }
            distance++
            ori = next
        }
    }

    /**
     * 移动点位到新点
     */
    private fun moveTo(dot: Dot) {
        getDot(cat!!.x, cat!!.y)!!.status = Dot.STATUS_OFF
        dot.status = Dot.STATUS_IN
        cat!!.x = dot.x
        cat!!.y = dot.y
    }

    /**
     * 移动方法
     */
    private fun move() {
        if (isAtEdge(cat!!)) {
            lose()
            return
        }
        val avaliable = Vector<Dot>()
        val positive = Vector<Dot>()
        val al = HashMap<Dot, Int>()
        for (i in 1..6) {
            val neighbor = getNeighbor(cat!!, i)
            if (neighbor!!.status == Dot.STATUS_OFF) {
                avaliable.add(neighbor)
                al.put(neighbor, i)
                if (getDistance(neighbor, i) > 0) {
                    positive.add(neighbor)
                }
            }
        }
        when {
            avaliable.size == 0 -> win()
            avaliable.size == 1 -> moveTo(avaliable[0])
            else -> {
                var best: Dot? = null
                if (positive.size == 0) {
                    var max = 0
                    (0 until avaliable.size).forEach { i ->
                        val distance = getDistance(cat!!, al[avaliable[i]]!!)
                        if (distance < max) {
                            max = distance
                            best = avaliable[i]
                        }
                    }
                } else {
                    var min = 999
                    for (i in 0 until positive.size) {
                        val distance = getDistance(positive[i], al[positive[i]]!!)
                        if (distance < min) {
                            min = distance
                            best = positive[i]
                        }
                    }
                }
                moveTo(best!!)
            }
        }
    }

    private fun lose() {
        Toast.makeText(context, "Lose", Toast.LENGTH_SHORT).show()
    }

    private fun win() {
        Toast.makeText(context, "You Win!", Toast.LENGTH_SHORT).show()
    }

    override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
        WIDTH = width / (COL + 1)
        reDraw()
    }

    override fun surfaceDestroyed(holder: SurfaceHolder?) {
    }

    override fun surfaceCreated(holder: SurfaceHolder?) {
        reDraw()
    }

    private fun reDraw() {
        val canvas = holder.lockCanvas()
        canvas.drawColor(Color.LTGRAY)
        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
        for (i in 0 until ROW) {
            var offset = 0
            if (i % 2 != 0) {
                offset = WIDTH / 2
            }
            for (j in 0 until COL) {
                val dot = getDot(j, i)
                when (dot!!.status) {
                    Dot.STATUS_ON -> {
                        paint.color = 0xFFFFAA00.toInt()
                    }
                    Dot.STATUS_OFF -> {
                        paint.color = 0xFFEEEEEE.toInt()
                    }
                    Dot.STATUS_IN -> {
                        paint.color = 0xFFFF0000.toInt()
                    }
                }
                canvas.drawOval(RectF(
                        (dot.x * WIDTH + offset).toFloat(),
                        (dot.y * WIDTH).toFloat(),
                        ((dot.x + 1) * WIDTH + offset).toFloat(),
                        ((dot.y + 1) * WIDTH).toFloat()
                ), paint)
            }
        }
        holder.unlockCanvasAndPost(canvas)
    }

    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        if (event!!.action == MotionEvent.ACTION_UP) {
            val x: Int
            val y: Int = (event.y / WIDTH).toInt()
            x = if (y % 2 == 0) {
                (event.x / WIDTH).toInt()
            } else {
                ((event.x - WIDTH / 2) / WIDTH).toInt()
            }
            when {
                x > COL + 1 || y > ROW + 1 -> initGame()
                getDot(x, y)!!.status == Dot.STATUS_OFF -> {
                    getDot(x, y)!!.status = Dot.STATUS_ON
                    move()
                }
            }
            reDraw()
        }
        return true
    }
}

这是游戏的核心代码,不得不说kotlin真的是十分简洁啊

这是源码

原谅我如此懒惰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值