IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 如何用 Kotlin + 动画 快速实现一款游戏,快速上手 -> 正文阅读

[移动开发]如何用 Kotlin + 动画 快速实现一款游戏,快速上手

前言

前些日子开发过一款小游戏,kotlin快速实现一款小游戏,糖果雨来啦,但由于时间的原因,只开发完成了基础版。如今,我对它进行了升级,新增了进阶版与困难版,分享给大家。

成果展示

现在这款游戏包含三个版本,分别为:

  • 基础版:糖果只会在屏幕最上方生成,然后从上往下掉落。
  • 进阶版:糖果只会在屏幕中间生成,然后向四周发散
  • 困难版:糖果会在屏幕四个角随机生成,然后向大致对角方向发散。
基础版进阶版困难版
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Xt04yYi-1652433709928)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a574077fd89a43618595a4c15b87704a~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image)]

你可以通过点击糖果捕捉器apk 下载地址github进行下载安装apk来体验一下该游戏。

实现细节

这里关于引导动画的实现,糖果的生成、掉落与收集就不再次展开分析了,。

接下里将重点讲解一下进阶版与困难版的实现原理。

进阶版

具体实现主要分为两步:

  1. 动态生成一个View,居中展示。
  2. 生成随机坐标,计算平移距离。
  3. 利用属性动画将View向四周平移出屏幕。
TextView(this).apply {
    //1. 设置为居中
    layoutParams = ConstraintLayout.LayoutParams(tvWidth, tvHeight).apply {
            bottomToBottom = ConstraintSet.PARENT_ID
            topToTop = ConstraintSet.PARENT_ID
            startToStart = ConstraintSet.PARENT_ID
            endToEnd = ConstraintSet.PARENT_ID
        }
    //2. 设置糖果背景
    background = ContextCompat.getDrawable(this@AdvancedActivity, generateRandomCandy())
    //3. 添加到视图
    viewBinding.root.addView(this)
}

动态生成一个TextView,设置其属性让其居中,然后设置糖果的背景,并添加到视图中。

在对其添加属性动画前,我们需要为它确定一个随机坐标。这里我们利用获取到的屏幕宽高来随机生成一个屏幕内坐标。

fun generateRandomX(leftRange: Int = 0, rightRange: Int = getScreenWidth()): Int {
    return (leftRange..rightRange).random()
}

fun generateRandomY(leftRange: Int = 0, rightRange: Int = getScreenHeight()): Int {
    return (leftRange..rightRange).random()
}

我们将屏幕分成四块,生成的随机坐标点随机分布在这四块区域中。

坐标.png

在确定了随机坐标后,接着我们就需要通过这个随机坐标来计算出需平移的距离。

我们以随机坐标点位于左上方区域来举例:

左上.png

我们利用相似三角形来确定需要平移的距离,取两个相同大小的三角形来计算:

  • X轴平移的距离为:halfScreenWidth - x) * -2
  • Y轴平移的距离为:(halfScreenHeight - y) * -2

除了左上区域,剩下的其他三个区域分别为:

右上区域左下区域右下区域

将这四个区域合起来的总的计算方法为:

private fun calculatePosition(x: Int, y: Int): Pair<Int, Int> {
    //利用相似三角形来确定平移距离,现在是取一个相同大小的相似三角形。
    return if (x <= halfScreenWidth) {
        if (y <= halfScreenHeight) {
            //left_top
            Pair((halfScreenWidth - x) * -2, (halfScreenHeight - y) * -2)
        } else {
            //left_bottom
            Pair((halfScreenWidth - x) * -2, (y - halfScreenHeight) * 2)
        }
    } else {
        if (y <= halfScreenHeight) {
            //right_top
            Pair((x - halfScreenWidth) * 2, (halfScreenHeight - y) * -2)
        } else {
            //right_bottom
            Pair(((x - halfScreenWidth) * 2).toInt(), (y - halfScreenHeight) * 2)
        }
    }
}

问题

如上所述,我们利用两个相同的相似三角形来计算平移距离,看起来很美好,但实际调式过程中,发现很多时候糖果无法平移出手机屏幕,因为平移的距离不够。

平移距离不够.png

像这种情况,即使我们用了两个相同的相似三角形来计算平移距离,平移距离还是不够,造成糖果无法平移出手机屏幕。

那怎么办呢?

这里我们采取一个递归算法,来保证我们计算出的平移距离能够支持糖果平移出屏幕。

/**
 * 取一个相同大小的三角形的话,还是有可能平移不出屏幕,应该避免这个情况
 */
private fun checkTransitionXy(transitionXyPair: Pair<Int, Int>): Pair<Int, Int> {
    //递归的终止条件
    if (transitionXyPair.first.absoluteValue > (halfScreenWidth + tvWidth)
        || transitionXyPair.second.absoluteValue > (halfScreenHeight + tvHeight)
    ) {
        return transitionXyPair
    }

    return checkTransitionXy(
        Pair(
            (transitionXyPair.first * 1.1).toInt(),
            (transitionXyPair.second * 1.1).toInt()
        )
    )
}

递归的终止条件就是判断X轴的平移距离或者Y轴的平移距离能够平移出屏幕,不满足该终止条件则将平移距离不停的放大。

介绍完了进阶版的实现原理,接着我们来看看困难版的实现原理。

困难版

相对比基础版与进阶版,困难版的发球点增加到四个,分别位于屏幕的四周。糖果会随机从这四个点生成,然后向大致对角方向发散。

所以同样,我们将屏幕分成四块。

enum class Direction {
    LEFT_TOP,
    RIGHT_TOP,
    LEFT_BOTTOM,
    RIGHT_BOTTOM
}

通过 Direction.values().random()来随机确定糖果的初始坐标位于哪一块区域中,然后通过设置LayoutParams属性来让其位于四个角中。

TextView(this).apply {
    //1.设置糖果背景
    background =
        ContextCompat.getDrawable(this@DifficultActivity, generateRandomCandy())
    //2.确定初始位置
    tv.layoutParams = when (Direction.values().random()) {
        Direction.LEFT_TOP -> {
            ConstraintLayout.LayoutParams(tvWidth, tvHeight).apply {
                startToStart = ConstraintSet.PARENT_ID
                topToTop = ConstraintSet.PARENT_ID
            }
        }
        Direction.LEFT_BOTTOM -> {
            ConstraintLayout.LayoutParams(tvWidth, tvHeight).apply {
                startToStart = ConstraintSet.PARENT_ID
                bottomToBottom = ConstraintSet.PARENT_ID
            }
        }
        Direction.RIGHT_TOP -> {
            ConstraintLayout.LayoutParams(tvWidth, tvHeight).apply {
                endToEnd = ConstraintSet.PARENT_ID
                topToTop = ConstraintSet.PARENT_ID
            }
        }
        Direction.RIGHT_BOTTOM -> {
            ConstraintLayout.LayoutParams(tvWidth, tvHeight).apply {
                endToEnd = ConstraintSet.PARENT_ID
                bottomToBottom = ConstraintSet.PARENT_ID
            }
        }
    }
    //3.添加到视图中
    viewBinding.root.addView(this)
}

接着就是计算平移的距离了。

因为是向对角发散,所以随机坐标是生成在对角区域,也就是左上区域对右下区域,右上区域对左下区域。

我们还是以左上区域来举例:

difficult_左上.png

这里我们简单点直接利用两个相似三角形来计算平移距离:

  • X轴平移距离为:x * 2
  • Y轴平移距离为:y * 2

其它三个区域这边就不展开分析了,总的计算方法为:

/**
 * x, y 是指生成的随机坐标点的坐标
 * 
 * 移动的距离是两个相似三角形相加
 */
private fun calculatePosition(x: Int, y: Int): Pair<Int, Int> {
    
    return if (x > halfScreenWidth) {
        if (y > halfScreenHeight) {
            //right_bottom
            Pair(x * 2, y * 2)
        } else {
            //right_top
            Pair(x * 2, -2 * (screenHeight - y))
        }
    } else {
        if (y > halfScreenHeight) {
            //left_bottom
            Pair(-2 * (screenWidth - x), 2 * y)
        } else {
            //left_top
            Pair(-2 * (screenWidth - x), -2 * (screenHeight - y))
        }
    }
}

因为随机坐标点是在对角,所以两个三角形相加的平移距离就够支持糖果平移出屏幕了,当然你也可以参考进阶版采取递归算法来计算平移距离,那也会更加的精准。

总结

在完成了进阶版与困难版后,糖果捕捉器这款游戏也变得更加完整,当然后续还可以进行更多的升级,比如:让用户来定义糖果的生成速度,定义糖果的掉落速度,后续有时间的话,会对它进行再次升级。

如果你想查看游戏的所有代码,可以点击Github Candy-Catch进行查阅。如果可以,欢迎你给我点个小星星。

你可以通过点击糖果捕捉器apk 下载地址github进行下载安装该apk来进行体验一下该游戏。

到此本篇文章就结束啦,如果你有任何疑问或者不同的想法,欢迎在评论区留言与我一起探讨。

其实分享文章的最大目的正是等待着有人指出我的错误,如果你发现哪里有错误,请毫无保留的指出即可,虚心请教。

另外,如果你觉得文章不错,对你有所帮助,请帮我点个赞,就当鼓励,谢谢~

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-15 11:39:14  更:2022-05-15 11:39:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:24:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码