Android 数独游戏开发,强逻辑的梳理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Utzw0p0985/article/details/93679295

本文阅读大约六分钟


Hi 大家好,欢迎大家关注我的星球【Hi Android】

 

本篇带来的是Android的一个小游戏:数独,虽然是个小游戏,但是也把老刘给算晕了,其实在Android中,有一小部分简单的小游戏是可以通过自定义View来完成的,所以今天我们也来实现一下吧,先给大家看一下预览: 

      640?wx_fmt=png      

 从预览总我们可以看到如下的一些功能:

 

1.引导页,延迟1.5s后进入主页

2.主页上方有一个游戏规则的按钮点击可以跳转到游戏规则

3.主页上方有一个设置的按钮点击可以跳转到游戏设置

4.游戏上方有一个计时器

5.游戏中央是一个自定义的棋盘,并且数字是七彩的

6.游戏下方是1-9的数字按钮

7.设置中有多彩文字和智能提示的开关

 

大致的一些功能,当然你也可以增加一些其他的功能,这里因为项目比较繁琐,所以我会尽量沿着核心思路去讲解,其他的小UI什么的各位自己去处理一下,有兴趣可以在文章末尾下载源码。

 

好了,我们正文开始吧。


一.绘制九宫格

其实绘制九宫格和小九宫格相对来说是比较简单的,我创建了一个GameView,由于是九宫格,所以横竖都是9,那么我们可以将View的高宽都除以9得到的高宽就是每一个方块的高宽了

       640?wx_fmt=png在onSizeChanged中计算出了方块的大小之后,绘制九宫格就变得极其简单了,在GameView的onDraw中,我们可以通过drawLine来绘制交叉的线条

640?wx_fmt=jpeg      

可以看到,这个MAX_VALUES = 9,我们通过循环遍历调用canvasLine绘制横竖的线条,这样就实现九宫格了


       640?wx_fmt=png  

    

for循环中的3是为了加深小九宫格的颜色,调用之后的效果如下:


       640?wx_fmt=png      


这样,我们的一个基础棋盘就完成了,那么我们来看下canvasLine里到底做了什么

       640?wx_fmt=jpeg      

正常的写法只要第一个drawLine和第三个即可,我这里在高宽上都+1是为了有一个视觉的加深效果,到这里九宫格就完成了,那么接下来,我们要做的事情是什么呢?那就是绘制绘制数字了


二.绘制数字

绘制数字和绘制九宫格的写法是基本类似的,只是坐标比较难计算,我们来看下绘制数字的代码

       640?wx_fmt=jpeg      

在这段代码中,我们需要关心mGame这个对象和canvasNumberText这个函数

 

Game对象就是我们的数独逻辑计算类,我们所有关于数独计算都会在里面实现,先来看下canvasNumberText函数


       640?wx_fmt=jpeg      

这个函数有必要仔细的说明一下,首先是这个画笔的文本大小,这里我设置了方块高度的0.75f,再结合文字绘制居中效果,那么视觉会舒服很多,各位也可以对此稍微进行修改,然后是FontMetrics,这是绘制文本测量类,关于FontMetrics我建议大家去查阅一下相关的资料,实际上只是对字符以及基准线的一个绘测,我们就是通过基准线的界定来实现绘制文本几种的,并且这里有一个sp的保存,是为了之后设置中是否使用多彩文字,多彩文字的实现很简单,主要是在canvasNumberColor这个函数中,你定义九个颜色就好了


       640?wx_fmt=jpeg      

我们可以先运行一下看看效果

 

       640?wx_fmt=png      

当然,我们还有Game类没有讲


三.Game逻辑类

Game类我要仔细的讲解,首先我定义了一个字符

 

//默认显示

private final String mDefData = "3600000000004230800000004200070460003820000014500013020001900000007048300000000045";

 

这个字符一共81个字节,对应的就是九宫格的81个小方块,其中0为未输入,一般的数独游戏都是按照规则随机的,但是我并不是很懂这个规则,所以只能写死了,接着我再定义一个二维数组来建立九宫格查询的索引列表

 

//装载数独

private int sudo[] = new int[9 * 9];

 

所以我们就可以实现如下的三个方法

 

      640?wx_fmt=jpeg      

 这三个方法,首先是parsingStringChat,就是解析默认字符串到我定义的sudo索引数组中,这样我们就可以通过getCardNumber来索引到对应的字符了,这里的算法是 纵列 * 9 + 横列,打个比方,第三行的第六个,那么就是3 * 9 + 6 得出来的下标再去sudo中索引,就可以拿到对应的数字了,而getCardString这个方法只是为了方便文字的绘制,而去将0转换成空的一个方法,到了这里,基本的UI就完成了,我们接下来就要实现它的点击逻辑了


四.点击逻辑

我们的点击逻辑思路很简答, 你点击后这个方块红色包裹,然后输入数字,即可,这里掺杂了一个只能提示的功能,所以变得复杂起来了,我们一步步来,首先,来看下这个触摸事件的代码


       640?wx_fmt=jpeg这段代码比较长,我们一个个来解释一下,首先是过滤事件,如果不是ACTION_DOWN,那么就按照系统事件下发就好了,如果是ACTION_DOWN,那么通过getXY再除以方块的高宽,就可以得到选择的方块的横纵位置了,然后是获取当前方块上的数字,这里我没有用到,继续往下看,绘制一个红色边框,因为有了他的X,Y,所以绘制起来比较简单

 

       640?wx_fmt=png      

 

这里是否智能提示,如果打开了智能提示,那么我会将这个方块的已显示的数字数组通过接口传递出去,在主页面做逻辑处理,那么怎么计算已显示的数字数组呢?,这里还需要用到我们的Game对象

 

我定义了一个三维数组

 

//存储每个单元格已经不可用数据 x y data

private int userNo[][][] = new int[9][9][];

 

通过他,我可以传递x,y后获取到他所显示过的数组集合,也就是Game中的parsingAllUserNoNumber函数

       640?wx_fmt=jpeg      

 parsingAllUserNoNumber就是遍历一遍所有的方块,最终的实现还是在parsingUserNoNumber中,我们来看下逻辑,首先定义一个长度为9的数组z,然后通过遍历横纵获取已显示的数字存储在z中,并且我们还需要计算小九宫格也不能有重复的,最终将0去除,得到的就是我们所传递方块的x,y的已显示数组,那么我们智能提示,就需要将这些给去除

 

我们在主页定义了九个按钮,这里我为了方便管理,直接定义了一个数组

 

private Button mView[] = new Button[9];

 

然后进行初始化

      640?wx_fmt=jpeg      

 这里初始化后设置点击事件,我只要点击某一个按钮,就将对应的数字通过setNumberText传递给GameView绘制,并且设置了一遍全部显示,因为有可能因为智能提示导致有些按钮不显示

 

我们回到GameView中关于setNumberText函数

       640?wx_fmt=jpeg      

 

这里其实最终调用的还是Game对象中的refreshSudo,我们并不需要直接去绘制文本,只需要将我刚才定义的sudo数组对应坐标的字符修改后刷新View即可,这里还有一个内容就是检查游戏结束,我们每次输入文字都会检查一遍游戏的逻辑是否对应上了,然后游戏是否结束,不过这个逻辑比较复杂,我暂时还没有去实现,大家理解下思路即可,继续来看refreshSudo

       640?wx_fmt=jpeg      

这里就是将sudo更新一下并且重新计算显示数字的数组

 

到这里我们的基本逻辑就完成了,实际上最终比较核心的内容就是GameView和Game,其中GameView还比较简单,只是逻辑的中转,我们来看一下全部的Game代码;


五.Game

       640?wx_fmt=jpeg      

 主要还是逻辑和思路,for循环太多,脑瓜子嗡嗡的叫呀,我们来看下最终的Gif预览吧

 

       640?wx_fmt=gif      

 

好的,有兴趣可以加入我的知识星球【Hi Android】 或者点击阅读原文加入

 

Android Developer 交流群:417046685 现在无限制加入,抓紧哦

 

源码下载可阅读原文在星球中 或者 加入QQ群

 

我们下期再见!

 



猜你喜欢

转载自blog.csdn.net/Utzw0p0985/article/details/93679295