Scratch游戏《2048》实战(六)

今天,我们来给我们Scratch版的《2048》游戏进行最后的整合。

之前的五节课,我们将游戏的各个小功能模块依次制作了出来,抛开一些逻辑细节问题我们没有探讨外,大体已经实现了大部分功能,这次,我们把它们整合起来,看看还有哪些新的内容需要考虑。

第一点,我们在设计上下左右移动的时候,要考虑一个添加到待处理元素这个列表中的顺序,因为我们可以想到的向左和向右一定处理起来是两个相反的方向,向上和向下也是同样的道理。

第二点,我们需要考虑一下游戏无法进行下去时的判定,什么样的情况下,游戏就无法继续进行下去了呢?显然,是棋盘上所有的位置都有棋子,并且所有的棋子周围都没有和它自己相同的棋子,也就代表接下来,无法继续再进行任意一个方向的移动,那么这个时候,就需要弹出一个游戏失败的提示了。

最后,我们在合适的位置添加一个得分统计的操作。

这次《2048》的小游戏制作就全部完成了,在编写最后这篇文章的时候,我们的视频教程已经先行登录我们的网站了,大家可以在下面的页面中查看学习。

点击这里

这次的课程就到这里结束了,更多的课程教学,请持续关注本网站。
也欢迎您添加我的微信,跟我一起讨论编程。

微信扫描二维码添加我的微信

Scratch游戏《2048》实战(五)

今天,我们接着上次留给大家的作业继续。

我们要用【待处理元素】列表中的内容替换掉【元素布局】列表中对应行的4个元素,可我们发现当我们使用一个4次循环将内容替换掉以后,实际的前端显示并不是右对齐,而看起来像是左对齐的,这是因为我们在处理【待处理元素】最后,使用的是将0加入到列表末尾的方法,所以导致我们在替换【元素布局】对应的内容时,使得0到了一行的右端,所以整体看起来像是按了左键该有的效果。
那么我们怎么来解决这个问题呢?我们这里考虑两个思路,第一个,在处理【待处理元素】的最后,我们将0加到头部,这样就可以在替换【元素布局】时有正确的效果了;第二个,在替换【元素布局】时,我们从【待处理元素】中倒着取出元素去替换,这样的效果就会正确了。

实际上这两个效果的最终效果是一致的,我们这里暂时选取第二个方案来执行。

选取思路二,倒着替换【数据布局】中的元素

这样我们的右移操作就基本上形成一个大体框架了。
参照右移的代码,我们尝试把左移、上移、下移补全,并增加对应的按键响应,我们游戏的整体框架就初见端倪了。

下节课我们将继续完善游戏的其他细节,使游戏变得更加完善。
下课~

Scratch游戏《2048》实战(四)

上节课最后,我们把制作右移操作积木块的任务当成了作业布置下去,大家做的如何呢?下面我们先简单看一下老师这边的实现情况。

我们再稍微往细致思考一下,还记得上节课分析出来的三个步骤吗?
①删除同行的所有0;②检查相邻元素是否相同,如果相同就去掉一个然后留下的+1;③补“0”使得该行总数为4。
我们依次来看。

第①个,删除同行的所有“0”。
删除所有的“0”,这个好实现,但是“同行”应该怎么操作呢?
第一行是列表【数据布局】中的第1、2、3、4个元素,第二行就是第5、6、7、8个元素,第三行是第9、10、11、12,最后一行是第13、14、15、16,那么我们发现了什么样的规律吗?是否有一个通用的公式可以代表每行的四个元素的下标呢?大家自己思考一下,我把答案用白色的文字写在这里:在下面~
(行号 -1)×4+列号

这样的公式第一行第三个元素的序号是3,我们把行号=1,列号=3代入计算,得到的结果为3,这当然没问题了;换一个试试,比如第三行的第二个元素的序号是10,将行号=3,列号=2代入计算,得到的结果确实是10。由此可见,我们使用了一个通用的公式完成了【数据布局】中的元素序号和行列坐标关系的转换,这样对于我们下面的工作又做好了铺垫。

我们第①步要做的是删除每行所有的“0”,那么我们自然不能在【数据布局】这个大的列表中进行删除,因为这样会影响到这个列表的排列顺序,所以我们选择一个比较稳妥的方法,将每行的元素取出到一个临时列表变量【待处理元素】中,每次放一行共4个元素,然后我们开始在这个小的列表里进行处理。

既然要放到这个小列表里,那么我们首先要保证这个小列表里是空的,即便它本来是空的,我们也应该在开始时进行一个初始化,删除掉它当中的所有元素。然后我们就可以依次放入第一行的内容了,用我们刚才得出的公式,嵌入到一个4次循环中,每次取出一个,放入到【待处理元素】中。我们发现这个公式里要考虑两个变量——行号和列号,所以我们需要两个临时的变量来用于计算。

这里要注意添加到小列表时的顺序
这里使用的是在“第1项前插入”,为什么呢?

对应行的内容我们取到了,“0”我们也去掉了。
那么下面我们执行第②步:检查相邻元素是否相同,如果相同就去掉一个然后留下的+1。
这一步操作,实际上,我们要进行3次比较,分别比较第一列和第二列、第二列和第三列、以及第三列和第四列,如果有相同的,我们就删掉一个,然后留下的+1。

使用一个临时变量,完成了一行的4个元素的比较

好了,下面剩下最后一步了,第③步,补“0”使得该行总数为4。

为了完成这最后一步的要求,我们要先把【待处理元素】这个列表中补齐4个元素,这个简单。

用0补齐

最后,我们按照顺序,用【待处理元素】列表中的元素,替换【数据布局】里对应行的元素,之后就完成咯。

这部分内容留给大家做本次内容的作业吧!

Scratch游戏《2048》实战(三)

上节课我们成功构建了后台数据和前台显示部分的关联,同时还做好了空白位置新增加一个数字2的功能。那么接下来就到了游戏的核心部分,通过方向键来对棋盘上的数字进行移动的部分了。

在这个状态下,按下右键

我们还是以这个图为例来进行分析。
当我们按下方向键右时,棋盘上的所有棋子首先全部右移,先来看数据层面是如何移动的。

(后两张图里我将0设置了隐藏不显示,这里我就不再补充了,大家明白就好)

再图①的情况下按下右键,然后我们发现这里经历了两个过程,首先是由①到②的这个步骤:在这个过程中,所有的棋子都靠到了自己所在行的最右边,也可以换一个思路来理解,就是把之前所有的“0”删除,然后又全部补充在了现有序列的左边,比如第一行由“1010”,变成了“0011”(请仔细思考)。接下来第二个过程,由②到③的步骤:将相邻的元素从最右边开始向左比较,如果有相同的元素,那么我们去掉一个,然后把留下的元素+1,所以第一行的“0011”就变成了“0002”(结合刚才的思考,“0”是不是在这里添加更合适呢?)

这里会有同学提出异议了,之前的文章里指出的游戏规则里说的是,相邻的两个相同的元素应该在移动过程结束后相加呀,1=1=2,这里怎么说是+1呢?
这个问题,我们带着它继续往下看下面这张图,可能就会明白了。

对比上面的后台数据图,是不是

我们从后台数据转化成前台显示后,我们发现,这个相加的规则是针对前台显示而言的,而对于后台的数据来说,显示部分的相加,恰好就等价于数据部分的+1。

既然我们已经分析出了右移时的三个步骤,分别是:①删除同行的所有0;②检查相邻元素是否相同,如果相同就去掉一个然后留下的+1;③补“0”使得该行总数为4。当然,这三个步骤要重复4次(为什么?)。

那么,我们这堂课的作业就是将右移操作转换成代码。

Scratch游戏《2048》实战(二)

上一回,我们已经成功把问题的重点就挪到了用来存储棋盘数据的列表变量上,那么这次我们就先从这个列表的结构说起,看看它里面应该如何合理的构建这个存放数据的列表,才能帮我们实现游戏的效果。

内部数据 → 显示画面

还记得这张图吧,左边的部分就是我们游戏后台的内部数据,我们将其存储在一个列表变量中,起名为“数据布局”,比如图中的数据,我们把它存入列表以后,列表应该是这样的:

数据布局

那如何让16个克隆的角色获取到自己对应的那个位置的值呢?
首先,我们这里要使用一种特殊的变量——局部变量(角色专用变量)。这种变量只可能被某个角色使用,其他角色是无法看到代码区里又这个变量的,同时,如果一个拥有局部变量的角色执行了克隆命令,那么每个克隆体之间的局部变量又是互不干涉的,他们的初始值与角色本体的局部变量值相同,但之后两个变量就互不相干了,克隆体中的变量值发生变化,对角色本体的变量没有影响。

这里,我们使用一个局部变量来给每个克隆体编号,我们给这个变量起名叫“角色ID”,ID变量初始值为1,每克隆一个克隆体,这个变量的值+1,所以这样下来,第一个克隆体的ID变量值为1,第二个克隆体的ID变量值为2,以此类推,第16个为16,而克隆全部结束后,本体的ID变量值为17,不过这个已经无关紧要了。

下面就是要让克隆体盯紧列表变量“数据布局”中自己所需要关注的那个变量的值了,我们发现,它们的ID变量这时候就起作用了,使用【数据布局】中第【角色ID】个元素,就可以轻松的获取到每个克隆体对应的数据值,我们使用一个死循环,让克隆体一直关注这个值,等于0时隐藏起来,一旦大于0,我们就把造型编号根据这个值进行一个改变,这样每个用于显示的克隆体就与数据部分一一对应起来了。

想想看这样的代码有什么好处

接下来,我们还要找到一个合适的方法来在空白的位置添加一个新的“2”,在Scratch3中,我们借助列表变量中特有的方法“【数据布局】中的第一个(0)”,就可以轻松找到列表中的第一个0。但我们现在需要的不是第一个,而是所有,我们要收集整个列表中所有的“0”元素的位置,然后从中随机挑一个出来,还好我们的列表并不大,只有16个元素,我们可以用一个16次的循环,挨个查看列表中的每个元素是否为0,如果是,那么就把序号保存到另一个列表变量——“可能零位”中。这里,我们需要一个临时变量,用来做序号,从1开始一直到16,方便我们收集。当这个循环结束时,我们就会在“可能零位”这个列表中收集到一些数据,其中包含所有目前棋盘中还空着的位置,然后,我们使用随机方法,取出【可能零位】中的第【(1)到【【可能零位】的项目数】的随机数】项作为一个目标位置,然后将【数据布局】中对应的位置,设置为1。如此我们就完成了在棋盘空白位置添加一个“2”的这个操作了。另外,我们很容易想到,这部分代码是要频繁调用的,所以我们可以给它封装成一个单独的自定义积木块来方便我们后面的使用,当然在封装的时候,我们也要考虑一些局部的初始化过程。

请大家仔细想想,这段代码还有可以优化的地方吗?

Scratch游戏《2048》实战(一)

今天开始,我们来对前几日说的游戏《2048》,来进行一个系统的分析,对制作过程进行一个比较详细的说明,后期也会有视频教程放出,大家有兴趣的朋友们可以跟着一起来做做看。

作为游戏制作的第一篇内容,我们首先就要对游戏进行一个分析,有了分析思考的过程,才可以在制作的过程中有的放矢。

首先,《2048》这个游戏的规则大致是这样的,玩家需要控制所有方块向同一个方向运动,两个相同数字方块撞在一起之后合并成为他们的和,每次操作之后会随机生成一个2,最终得到一个“2048”的方块就算胜利了。

那么我们在构建这个游戏系统的时候,就需要先想好游戏的主框架,包括核心算法的主思路、主要的变量、主要的角色等等。由于是在Scratch中进行开发,所以我们在设定核心算法时要考虑到Scratch本身的特点和局限性,下面我们来具体分析。

游戏中存在一个4*4的棋盘,而后面反复出现的棋子很容易使我们联想到要使用到的是“克隆”功能。在这里,我使用一个相对比较容易理解的思路来进行构想,假如4*4的棋盘里每个位置都有一个克隆角色,而每个位置在数据存储中都有一个数字与之对应,0代表不显示,1代表显示2,2代表显示4,以此类推,11代表显示2048。反应比较快的朋友可能已经看出来,除了0以外,这刚好是2的整数次幂的规律所在。而且,用来代表的那个数字是从1到11,刚好可以与角色的造型功能相结合,实现起来也比较容易。

内部数据 → 前景显示

好了,经过上面的分析,我们发现,游戏的显示部分,通过16个克隆体和一个用来存储棋盘数据的列表变量就可以完美的解决。那么问题的重点就挪到了用来存储棋盘数据的列表变量上,它里面应该如何存储,它又该如何根据玩家的按键发生变化成为了我们接下来要思考的核心问题。

Scratch讨论之《2048》

电脑没有拿回家,发现今天还没更新,只好用手机来码字了。

今天主要在Scratch群里讨论了游戏《2048》的一些问题,我这里也写出我的思路来,大家可以一起讨论。

在这个题目刚出现的时候,我第一时间想到的是利用角色的克隆体进行上下左右的移动,但是在实践时发现,在处理移动动作时,要提前判断目标位置是否有其他的数字块,而这就存在一个判断时机的问题,如果目标位置本来有数字块,在当前数字块判断的时候还在,但稍后它移走了,这就造成当前数字块错过了移动时机,从而产生逻辑错误。

当然,想要解决这个问题也是有方法的,针对不同的移动指令,从需要移动的末端开始倒着进行移动指令的执行,这样就可以解决掉移动时机的问题,但是这样做会产生一个不确定因素,就是部分性能不好的电脑在执行这里会出现卡顿,导致数字块移动的过程被过分的放慢,体验很不好。

所以我更换了一套思路,使用16个数字块克隆体,充当一个“LED灯珠”角色,当数据部分需要对应位置的数字块呈现数字的时候,克隆体直接切换为对应造型并显示,这样数据部分的运算封装到一个不显示过程的自定义积木中,这样数据部分的运算相当快,然后16个克隆体只要根据数据分配,实时切换造型就好了。

用Scratch来制作“逢七过”游戏(基础篇)

各位同学好,我们又见面了。今天给大家带来的是用Scratch制作一款“逢七过”的演示小游戏,通过制作游戏的过程,我们继续巩固Scratch中判断和循环的用法,同时对数学知识中的除法、余数等运算进行一个加深的理解。

  首先,先来简单的介绍一下我们提到的“逢七过”这个游戏。
  这个游戏的规则很简单,就是大家围成一个圈,然后由老师指定一名同学开始从1报数,在大家报数的过程中,凡是数字能被7整除的,同学们在报到这个数字时,都必须用一声“喵”来代替,之后后面的同学继续报数,那么游戏开始时报数会是这个样子的:1、2、3、4、5、6、喵、8、9、10、11、12、13、喵、15、16……随着游戏的进行,游戏的难度也会慢慢的提升,我们目前先从最基础的规则开始制作。

  我们来思考一下这个游戏要怎么进行,我们首先想到如果想要有一个不停增加的数字,我们要运用到“变量”模块;同时为了让它不停的增加,还需要用到“控制”模块中的“循环”功能;此外,在判断数字是否能被7整除时,还需要用到“控制”模块中的“如果…那么…否则”功能;最后,如果要让角色说出这个数字,还需要用到“”模块中的“说…”功能。
  我们先画个简单的流程图来说明一下。参看“流程图(1)”。

流程图(1)

  下面,我们来看Scratch积木代码。

  嗯,这个程序很容易就做好了,点击绿旗运行,没问题,角色如我们所设计的那样“1、2、3、4、5、6、喵、8、9、10、11、12、13、喵、15……”,开始依次报数了。成功!
  下面,我们来增加难度。
  在报数的过程中,如果数字中的某一位包含了“7”,就需要用“喵喵”来代替,比如“13、喵、15、16、喵喵、18……”。
  好了,我们来想想在程序中该如何实现吧。参看“流程图(2)”。

流程图(2)

  下面,问题来了,如何来判断这个数字中含有7呢?Scratch中为我们提供了一种很便捷的方法,这个积木位于“运算”功能区中,这个方法允许代入一个字符串类的参数,如果不是字符串的话,也会使其变化为字符串,然后判断这个字符串中是否有我们要求的字符。
  这里要注意,当我们在做多个条件的判断时,一定要分清楚几个条件彼此之间的关系。比如本题目中的判断条件就是只能满足一种情况,角色要不说“喵”,要不说“喵喵”,要不说出数字,在角色准备说出一个数字的时候,仅能说出这三种情况中的某一种,而不会同时出现两种的情况。这样的判断,我们需要使用到嵌套结构来实现,我们要使判断只能出现一种结果。具体可参看下图。

  下面,我们再来增加一次难度。
  在报数的过程中,如果数字中各个位置的数字的和为“7”,就需要用“喵喵喵”来代替,比如“13、喵、15、喵喵喵、喵喵、18……”。
  这次在程序中该如何实现呢,让我们慢慢来分析。
  流程图与之前的差不多,只不过是加入了第三个判断,用来判断数字各个位置的和是否为“7”。这次我们要用到“自制积木”这个功能。
  我们通过“自制积木”功能,将当前数字通过参数传递进自制积木的内部,让内部的程序来执行完结果,然后回到外部程序中,继续我们的判断。下面我们来看一下代码。

  这里,我们对于“各位求和”这个功能做了两种不同的积木块程序。

方法一

  方法一中,我们使用余数的方法,反复“切”下数字的个位,让它们相加,然后再设法将新数字的个位“切”下,继续相加,如此反复便可以得到整个数字各个位置的和。
  在这里我们用到了——向下取整这个功能。对数字除以10的结果进行向下取整,也就相当于把数字的个位直接切除,比如(向下取整 )123÷10,得到的结果就是12。当然如果这个方法不好理解的话,我们可以看下一种方法。

方法二

  方法二使用了Scratch中提供的字符串处理方法,直接逐位取出数字中的各个位置的数字,然后相加即可。

  至此,我们完成了“逢七过”游戏的三种游戏难度的Scratch方法移植,赶快点击小绿旗,让Scratch的小猫试着给我们演示一下这个游戏吧!  

  好了,这次带来的趣味小编程就到这里了,大家有任何的想法可加我的微信(下方二维码)、微博@亿万星辰桃桃爸,跟我一同讨论少儿编程,进入编程这五彩斑斓的世界,我们下期再见。

用Scratch来解决奥数问题之“韩信点兵”(基础篇)

从今天起,我们将每隔一段时间安排一次用Scratch来解决奥数问题的栏目。在这个栏目里,我们将通过Scratch编程来帮助我们理解奥数问题中的核心所在——解题逻辑。

  下面,我们先来看看题目。

  题目出自我国古代一道流传于民间的趣味算术题——“韩信点兵”。大致的故事是,楚汉争霸,韩信率领了1500名将士和敌人交战。大战过后,虽然汉军获胜,但死伤也有近五百人,剩下的大概刚有一千人出头,回营之后,韩信想要清点一下剩余的将士。

  只见韩信命令士兵3人站一排,最后一排多出2人;5人站一排,最后一排多出3人;命令士兵7人一排,最后多出2人。

  紧接着,韩信向将士们宣布了剩余的汉军人数是1073人。大家都觉得韩信点兵如此绝妙,纷纷觉得韩信是“神仙下凡”、“神机妙算”。

  下面,各位同学们,你们能像韩信一样“神机妙算”吗?

  我们先用数学的方法来试着解答一下。

  不过首先,我们先把题目的重点重新归纳一下,然后把题目换个说法。
  一个数字除以3余2,除以5余3,除以7余2,请找到满足上述要求的,大于1000的最小的数。

  首先,我们要明白这类题目所考核的知识点是公倍数的概念,要同时满足三个要求,意味着我们要在调整其中某一个条件的时候不能影响另外两个条件,所以我们根据第一个条件“除以3余2”,找到5和7的公倍数中满足此条件的,很容易,我们发现5×7=35,35÷3=11……2,35正是满足这个要求的数字;再来看第二个条件“除以5余3”,我们同样找到3和7的公倍数中满足此条件的,这也很容易3×7=21,21÷5=4……1,于是我们能得到,21×3=63,63÷5=12……3,63就是满足第二个条件的数字;同理,我们按照第三个条件,用相同的方法,可以得到30÷7=4……2,30是满足第三个条件的数字。
  我们把三个结果相加,发现35+63+30=128,这个结果除以3余2,除以5余3,除以7余2,正好满足了题目前半部分的要求,但它并不是大于1000的。究竟如何找到满足题目后半部分要求的答案呢?显然,我们要在目前已经得出的结果上加上一个数字,但加多少合适呢?我们需要加上一个不会影响当前余数变化的数字,也就是要加上一个能同时被3、5、7同时整除的数字,这难不倒我们,3、5、7的最小公倍数是3×5×7=105,我们用之前的结果128反复加上多次105,最终便会得到我们所要的结果。(如下表)

加上最小公倍数105的次数最终结果
1233
2338
3443
4548
5653
6758
7863
8968
91073

这样,我们得到了正确的答案,1073。

如何用数学的方法来解答这道题目说完了,不免有些繁琐复杂,下面我们用编程的方法来试着解答一下。

  我们先来看一下这位同学是如何解答的。

  我们来看这位同学的答案。
  在这段代码里,这位同学在程序开始时,首先对他所用到的变量和列表进行了初始化,这样确保每次启动程序时,变量和列表都是处于“空”的状态,之后使用了循环、判断来重复的对“兵士数量”进行判断,看是否满足题目的要求,当满足题目要求时将答案存储到一个列表中,并在最后全部计算完毕后显示这个列表。

  之后的讨论,有同学指出了代码中可以改进的地方:我们需要的答案是超过1000的最小的那个“兵士数量”,也就是大于1000的第一个答案,那么没有必要设置一个列表来记录那么多的答案,我们只需要从1000开始找,找到的第一个答案就是最终的答案了。
  对于这点,我们通过讨论获得大家一致赞同,之后我们修改了部分代码。

  对于本次的题目而言,这样的答案可以说非常完美的找到了题目的答案,但编程的乐趣就是不断的升级,对于目前的答案其实还有很多地方能够继续深挖,在保证运算结果的前提下提升代码在运算时的效率,具体该怎么做,我们会在后续的“深入篇”中继续讲解。

  好了,这次带来的趣味小编程就到这里了,大家有任何的想法可加我的微信(下方二维码)、微博@亿万星辰桃桃爸,跟我一同讨论少儿编程,进入编程这五彩斑斓的世界,我们下期再见。

千呼万唤始出来 Scratch3.0 初体验

  近期,Scratch官方麻省理工学院终于发布了Scratch的3.0版本,实际上3.0的测试版早就出现在了网络上,之前我们也有过各种接触,这次作为3.0版本的正式出道,我们也重新做一次系统的介绍。

一、内核更新

  MIT和Google合作共同打造的以Blocky为核心的Scrach 3.0,采用了HTML5的页面技术,通过HTML5的良好跨平台性,Scratch3.0可以在 iOS&Android手机平板及PC上无差别使用。

二、界面变动

Scratch3.0主界面

  Scratch3.0界面更新,将舞台区移到右边,编程序放在中间,更加方便编程者编程程序;积木区不再严格分区,可以通过滑动鼠标来选择区块,减少点击率,增加了用户的体验度。

三、丰富多彩的扩展

Scratch3.0中丰富的扩展插件

  Scratch3.0整合并添加了插件模块,例如文字朗读模块,可以让角色真正的“说话”;翻译功能可以翻译多种语言;扩展了Makey Makey插件,把创意有趣味性的硬件加进来;乐高EV3在新版本中可以使用,增加了应用场景。

四、更好的中文支持

终于可以打中文了

  在2.0版本中,最让人崩溃的是没有办法输入中文,并且文字框不可以二次选中。更新的3.0版本中优化了这个功能,可以在编辑的文字框中输入中文,并且写过的文字框可以继续复选。大大方便了编辑效率。

  不过新的版本也带来了新的问题。

  首先,按钮变大了,但是上面的字实在是太小了……(眼睛遭受了很大的伤害……);第二个就是程序目前还不是很稳定,经常就会莫名其妙的崩溃,给积木块打上注释侯,注释会满屏幕的乱跑,也是很崩溃了……

  总的说来,新版本的Scratch带给我们的惊喜还是很大的,我们也将从Scratch3.0的基础开始,为大家逐步介绍编程的乐趣。