2048

作者: _浅梦丶 | 来源:发表于2018-09-17 13:03 被阅读0次

    近期打算做一些小游戏 先发布在电脑端,在尝试移植到手机上,熟悉一下流程各方面.先拿之前很火的2048练手,暂时写了一部分,先记录一下.暂时没有什么高深的东西.都是一些很基础的实现,操作,甚至优化不好的操作,只是一个自己个人实现某项目思维过程的记录,分享讨论,希望有兴读下去的前辈评论指点一下;

    2048除了UI上的同步,比如分数的统计,最高分的记录,重新开始新的游戏按钮,胜利失败判定提示等就是游戏区域的操作;

    游戏区操作:

    1.实现能够判定鼠标滑动的方向

    思路:计算鼠标滑动方向,在标准方向没有偏移时很容易,获取鼠标在某一刻按下鼠标和抬起鼠标时的坐标,即可获取鼠标滑动的向量.如果只是标准方向,只需判断两点坐标的纵坐标差值和横坐标差值的正负即可判断是那个方向.但是在实际操作时,滑动方向难免有误差,所以理论上要通过滑动时向量在x,y坐标系的角度,即tan,来共同判断滑动时,具体向量倾向于那个方向.

    模拟图

    如模拟图所示,假设在我们滑动时给我们滑动的这个向量加一个坐标系.yerp表示终止点和起始点的纵坐标差值,xlerp表示横坐标的差值.在向量与x轴夹角小于45度(即ylerp/xlerp<1)时,我们将此次向量的方向判定为倾向于x轴正方向,即向右滑.在比值大于1时,我们判定倾向于y轴正方向,即向上滑

    具体实现:在鼠标操作脚本里,Update方法里检测,如果按下鼠标,则记录鼠标按下那一刻的初始坐标,同样,在鼠标抬起时,记录鼠标的抬起坐标.

    记录鼠标抬起放下坐标

    计算出按下抬起位置的坐标在X,Y轴方向的差值,后面在判定鼠标滑动方向时需要用到.

    接下来是滑动方向的几种情况,一种思路是这样:

    纵方向滑动:当向上滑,即ylerp>0时,不管是左上还是右上,只要比值大于1,就说明是倾向于y轴正方向,同理,向下滑时比值大于1倾向于y轴负方向;

    横方向滑动:当向左滑,即xlerp<0时,不管是左上还是左下,只要比值小于1,就说明是倾向于x轴负方向,同理,向右滑时比值大于1倾向于x轴正方向;

    判定向量倾向方向

    通过这样可以得到向量滑动的direction,并记录下来,给于其他脚本调用.

    2.实现游戏区格子里的值能够根据鼠标移动方向做出对应操作

    思路:我们以向上滑动来举例说明实现思路,如果是向上滑动,就从每一列的每一行开始遍历格子,从第一列第二行(第一行可跳过)-第四行进行操作.

            首先先判断自身是否为空,是空则跳过.如果不为空,就判断前一行是否为空,是空则继续判断再前一行,直到第一行为止.如果判断到不为空,说明这个不为空的格子前面都有值,我们需要后续操作,判断合并值或者换位.如果判断到第一行都为空,则进行换位即可.

    向上滑动时操作方法

    假设我们的操作池是一个二维数组,i表示行号,j表示列号.从第一列开始遍历第二行到第四行,不为空则执行操作方法

    方法截图A 方法截图B

    方法需要传入三个参数,分别表示行,列,特殊操作,以我们向上滑动来说,特殊操作就是需要i-1,所以我们传入三个参数,i,j,i-1.

    方法首先判断特殊参数arrow-1是否>=1,意思是判断我们要进行判断的下一行或者下一列是否已经是第一行或者第一列了,防止越界.如果不越界,先获取我们此时正在判断的本身格子的值,因为方法入口前已经判断过他不为空才进入方法,所以值肯定不为空.再获取向上一个格子的值(arrow)行,如果是空,则记录此次空格子的行和列,然后递归再传入(arrow-1)作为再一个格,直到判断为全空,进行互换.在判断过程中找到了非空,则判断能否相加,不能就找到最后一个为空的(之前记录的last)同步

    依次修改对应的下,左,右.

    下,左,右 下操作 左操作 右操作

    如此,游戏区的操作算法就实现了.后续需要加不同值颜色不同,增加一个滑动限制(没有能够向某方向移动的格子不能向此方向滑动)

    由于时间有限,先写到这里,后续做出完整版续写.

    //2018.10.5续写


    3.颜色改变

    思路:由于我们最初关于格子操作时所采取的思路是换值,而不是替换整个格子,所以我们需要在每次操作结束时,生成新的格子时候给予对应颜色,在加值,换位时,替换对应的颜色.写了一个方法,传进来这个单元格的值,哪个单元格,修改其颜色

    匹配颜色方法 初始颜色预设,方便后期修改

    4.滑动限制

    整体滑动限制,首先在操作区做对应判断操作完成之前,是无法滑动的,其实内置0.5S的延迟协程,其次是在对某个方向滑动时,这个方向没有任何格子做出改变时,是不生成新值的,也就相当于无效操作

    思路:在滑动判断脚本里,加入一个bool值,滑动结束后开始限制,然后操作区根据这个值判断是否进行操作,操作是否完成,或者有效,然后重置bool值,给与再次滑动的能力.

    是否开始检测鼠标滑动 是否能执行操作

    每次滑动结束后,bool值修改,然后进行分析判断,让操作区格子去判断寻找有没有需要作出相应操作的格子.

    判断分析或者进行操作的介绍在第二部分已经介绍过了,这里介绍一下如果判断在某一方向上进行空操作的一种思路:

    我们在一个二维for结构里依次遍历某一行或者某一列时,如果还是像前几部一样拿向上操作来举例.我们在每一个格子判断前面为空,有值这类操作之前加一个标志统计,初始化为0,每一个格子进行操作之前就+1,如果没找到空格子,前面格子值也不相等,标志位再减1,这样我们最后就可以得到有几个格子在向上滑动时,做出了操作,如果最后是0,说明是无效操作,就不生成新的值.

    向上举例,每一个格子,操作之前统计加1 在我们之前介绍的判断方法基础上,在没找到空,也没有相等的情况下,统计值-1

    如此,我们在操作完之后生成新的值并重置可以操作bool值之前加一个判断,是否有效

    判断是否需要生成新的值

    5.分数部分

    在此,我们完成每一步分数的统计,加分显示,最高分的判断,和最高分的数据持久化

    思路:分数统计,比较简单,找到显示分数的txt,在每一步可以满足加分合并的时候,进行加分,同步

    加分显示,做出一个显示一会消失的效果,这里采取更改位置到视野之外,减少激活非激活次数,提高性能

    数据持久化,在分数已经超越最高分时,将值存到本地目录的txt下,在每次游戏开始时读取最大值

    加分部分

    首先同步积分,socre+=2倍当前格子;

    其次判断最大分,如果每次加分之后,此次游戏积分大于最高分,则改变最高分数据,并用file.writealltext(路径,传入数据,格式)存入本地路径下的记录最高的txt中,同样在start里用readalltext读取值.

    加分显示,修改加分提示浮现框的值,然后修改位置到应该出现的位置,并且在每次操作结束时回归到视野外

    6.游戏胜利和失败判断和效果

    思路:游戏胜利:在每次在碰到同样格子进行加分操作时判断,满足1024+1024则在同步完格子,颜色,分数之后浮现游戏胜利panel,半透明,并且关闭滑动的功能

           游戏失败:这里留存一个思路,我暂时没有想到一个损耗又小又简单的算法,后续想好了再来填坑

    加分操作后判断

    如果是1024+1024,游戏结束bool标志位开启,关闭滑动,winpanle激活,同时主线操作那里也会判断,游戏关闭,不进行生成

    game end联同判断

    7.游戏重新开始按钮

    思路:button监听事件:win/lose panel的关闭,操作区每一个格子的值,颜色的重置,当前积分的重置,重新开始生成俩个新的值,然后开启鼠标滑动能力

    监听方法

    总结:在国庆假期抽空写完了这个2048,至此基本算作完成了这个游戏的制作,差一步游戏失败的判断和实现.写这个收获还是有的,虽然浪费了点时间,研究了一下数据持久化的几个方法,和playprebs的注册表生成(所以没有采用这个).以为关于注重优化和代码质量的思考(一直用transform寻找做操作是不是浪费资源..),希望有大牛有幸看到能给与一些不同的思路,优化方面的指点.

    相关文章

      网友评论

          本文标题:2048

          本文链接:https://www.haomeiwen.com/subject/nzcknftx.html