kotlin 仿黑客帝国代码雨

kotlin 仿黑客帝国代码雨


我们看代码之前先看一下效果这个是我做的一个效果,可能没有100%还原,但是也有80%的相似度,主要是看一下实现的逻辑
如果不懂kotlin的,建议用gpt去翻译成你所熟悉的语言,我想大多数程序员都还是想自己去搞一些比较炫酷的操作的,接下来大家就看一下代码

在这里插入图片描述

package com.ghn.cocknovel

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import kotlin.random.Random

/**
 * @author 浩楠
 *
 * @date 2024/6/1-16:43.
 *
 *      _              _           _     _   ____  _             _ _
 *     / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 *    / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 *   / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 *  /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 * @Description: TODO 实现矩阵雨效果
 */
class MatrixEffectView(context: Context, attrs: AttributeSet) : View(context, attrs) {
    // 画笔对象,用于绘制字符
    private val paint = Paint().apply {
        textSize = FONT_SIZE.toFloat()
        isAntiAlias = true
    }

    // 背景画笔对象,用于绘制背景
    private val bgPaint = Paint().apply {
        color = Color.argb(150, 0, 0, 0)
    }

    // 列数
    private var columns: Int = 0

    // 存储每列字符下落的位置
    private lateinit var drops: FloatArray

    // 字符矩阵
    private lateinit var matrix: Array<CharArray>

    // 可见性矩阵
    private lateinit var visibilities: Array<FloatArray>

    init {
        // 设置背景颜色为黑色
        setBackgroundColor(Color.BLACK)
    }

    // 当视图大小改变时调用此方法
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // 计算列数
        columns = w / (FONT_SIZE + COLUMN_SPACING)
        // 初始化各数组
        drops = FloatArray(columns) { -Random.nextFloat() * h / FONT_SIZE }
        matrix = Array(columns) { CharArray(h / FONT_SIZE) { getRandomChar() } }
        visibilities = Array(columns) { FloatArray(h / FONT_SIZE) { 0f } }
    }

    // 绘制方法
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 绘制背景
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), bgPaint)

        // 遍历每列
        drops.forEachIndexed { i, drop ->
            val x = i * (FONT_SIZE + COLUMN_SPACING)

            // 遍历每列中的每个字符
            matrix[i].forEachIndexed { j, char ->
                val y = (j + drop) * FONT_SIZE

                // 绘制字符
                if (y >= 0 && y < height) {
                    paint.color = getGradientColor(j, matrix[i].size, visibilities[i][j])
                    canvas.drawText(char.toString(), x.toFloat(), y.toFloat(), paint)
                }

                // 增加字符的可见性,使其逐渐显示出来
                if (visibilities[i][j] < 1f && y >= 0 && y < height) {
                    visibilities[i][j] += 0.05f
                }
            }

            // 更新下落位置
            drops[i] += DROP_SPEED
            // 如果字符下落超出屏幕,重置位置和字符
            if (drops[i] * FONT_SIZE > height) {
                resetColumn(i, height)
            }
        }
        // 延迟刷新
        postInvalidateDelayed(50)
    }

    // 获取随机字符
    private fun getRandomChar() = MESSAGE.random()

    // 获取渐变颜色
    private fun getGradientColor(position: Int, length: Int, visibility: Float): Int {
        val factor = position.toFloat() / length
        val greenValue = (150 + (255 - 150) * factor).toInt()
        val alphaValue = (255 * visibility).toInt()
        return Color.argb(alphaValue, 0, greenValue, 0)
    }

    // 重置列数据
    private fun resetColumn(i: Int, height: Int) {
        drops[i] = -Random.nextInt(height / FONT_SIZE).toFloat()
        matrix[i] = CharArray(height / FONT_SIZE) { getRandomChar() }
        visibilities[i] = FloatArray(height / FONT_SIZE) { 0f }
    }

    // 常量定义
    companion object {
        private const val FONT_SIZE = 26 // 字体大小
        private const val COLUMN_SPACING = 10 // 列间距
        private const val DROP_SPEED = 0.5f // 下落速度
        private const val MESSAGE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // 字符集
    }
}


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值