万物皆可消——kotlin开发可自定义内容的消消乐

1,680 阅读3分钟

“我正在参加掘金社区游戏创意投稿大赛个人赛,详情请看:游戏创意投稿大赛

  • 开局一张图
    • 目前实现暂时只能开始游戏,数据库已加入,但逻辑还在开发中,目前数据为固定内容。

微信图片_20220423163825.png

  • 体验地址:安卓手机可用百度网盘扫码下载

微信图片_20220423165049.png

一、创意灵感

  • 上个月在找工作之余,抽空学习了一下前端的知识,老朋友都知道我是做移动端的。
    • ① 前端的标签比较多嘛,所以我就想着做一个消消乐,将标签以及它对应的功能录入到手机中,这样方便查看,把他们打乱顺序,选中标签及标签所对应的含义,即可消除两个方块。
    • ② 第一步的功能实现之后,发现只能是我自己用代码编写想要学习的内容,这样局限性比较大,我自己也需要重新改代码,才能录入数据。
    • ③ 所以我添加了数据库功能,支持用户录入信息,也就是最终版的万物皆可消——任何匹配的东西都可以录入。

二、思路分析

  • 支持展示以及消除——RecyclerView符合
    • 首先我们定义一个Bean里面存放标签,是否选中,以及id,标签对应的含义的id需要相同。
    • 在建一个Bean,用于存放点击的第一个按钮和第二个按钮,用于匹配id。
    • 如果id相同则消除两个按钮,反之重置选中状态为未选中。
  • 支持自定义内容——Room数据库符合(目前只做了增加)
  • 界面设计(安卓屏幕多尺寸适配)——ConstraintLayout符合
  • 开始撸码

三、AC 代码:

  • 首先是游戏首页:

微信图片_20220423155001.jpg * 采用自定义TextView显示不一样的字体,可查看之前文章介绍ConstraintLayout+ViewPager2打造《摇一摇新年幸运签》App

  • 圆角加渐变按钮采用shape实现代码如下
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">

   <corners
       android:bottomLeftRadius="50dp"
       android:topRightRadius="50dp" />
   <gradient
       android:angle="90"
       android:startColor="#F0e675"
       android:endColor="#ed8f60"/>
</shape>
  • 开始按钮选择从中心到外边渐变也是shape实现,代码如下
<?xml version="1.0" encoding="utf-8"?>
<!-- 圆形边框 + 填充 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >
    <stroke
        android:width="13dp"
        android:color="#22E44444" />
    <gradient
        android:endColor="@color/oriange"
        android:startColor="@color/red"
        android:gradientRadius="100%"
        android:type="radial" />

</shape>
  • 点击开始游戏,进入消消乐环节:

微信图片_20220423154952.jpg

微信图片_20220423155009.jpg

  • 从图中可以看出,首次点击,我们会将选中的按钮,变色
    • 实现思路是在点击的时候改变我们的model中的字段,同时调用notifyDataSetChanged,在onBindViewHolder中去改变颜色即可,代码如下
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
   val itemMatch = mItemMatchList[position]
   holder.textView.text = itemMatch.wordString
   if(itemMatch.isChosen){
       holder.cardView.setCardBackgroundColor(MyApplication.context.resources.getColor(R.color.colorLightBlue))
       holder.textView.setTextColor(MyApplication.context.resources.getColor(R.color.colorBgWhite))
   }else{
       holder.cardView.setCardBackgroundColor(MyApplication.context.resources.getColor(R.color.colorLightWhite))
       holder.textView.setTextColor(MyApplication.context.resources.getColor(R.color.colorLightBlack))

   }
}
  • 当选中第二个按钮时,如果答案正确,则消除两个按钮,主要逻辑在onCreateViewHolder中,代码如下:
    • 主要逻辑就是,添加选中的按钮临时的集合中
    • 如果是第一个直接添加
    • 第二个需要做一下判断
    • 如果ID相同,表示正确,调用notifyItemRemovednotifyItemChanged
    • 不同则重置选中状态,并清空判断用的临时集合
holder.view.setOnClickListener(View.OnClickListener {
    val position: Int = holder.adapterPosition
    val itemMatch = mItemMatchList[position]
    if (idAnalyseList.isEmpty()) {
        idAnalyseList.add(IdAnalyse(itemMatch.ids, position))
        itemMatch.isChosen = true
        notifyDataSetChanged()
    } else if (idAnalyseList.size == 1) {
        if (idAnalyseList[0].wordId === itemMatch.ids && idAnalyseList[0].position !== position) {
            idAnalyseList.add(IdAnalyse(itemMatch.ids, position))
            val itemMatches: MutableList<ItemMatch> = java.util.ArrayList()
            itemMatches.add(mItemMatchList[idAnalyseList[0].position])
            itemMatches.add(mItemMatchList[position])
            mItemMatchList.removeAll(itemMatches)
            notifyItemRemoved(position)
            notifyItemChanged(position, mItemMatchList.size)
            if (idAnalyseList[0].position === 0) {
                notifyItemRemoved(0)
                notifyItemChanged(0, mItemMatchList.size)
            } else {
                notifyItemRemoved(idAnalyseList[0].position - 1)
                notifyItemChanged(idAnalyseList[0].position - 1, mItemMatchList.size)
            }
            notifyItemChanged(0, mItemMatchList.size)
            idAnalyseList.clear()

            if (mItemMatchList.isEmpty()) {

            }
        } else {
            val itemMatch1 = mItemMatchList[idAnalyseList[0].position]
            itemMatch1.isChosen = false
            val itemMatch2 = mItemMatchList[position]
            itemMatch2.isChosen = false
            notifyDataSetChanged()
            idAnalyseList.clear()
        }
    }
})

四、总结:

  • 好了,代码撸完,我们总结一下
    • 用shape和自定义view,实现了首页的渐变色以及文字样式

    • ConstraintLayout减少布局层级并实现屏幕适配

    • RecyclerView删除条目和刷新条目的api使用

其实还是蛮简单的,创作不易,对你有一些启发的话还请点赞关注,走一波哈!