张飞 清华大学终身学习实验室 课程设计主管 aleX 老师又有《想·法》要讲了。两周前的第一讲反应还不错,接近500浏览量。 作为一个开头,我已经很知足了。 不过我也知道,真正能跟着教程一步步做完的人,一定是少之又少。 也不怪你们,一课的内容确实挺多。 我的一课够别的各种群、公众号里讲十几课的。 这第二讲又是一堆干货。 内容本来就多,Alex 老师又一点点掰开了揉碎了讲透了,真的老长了。 这不是过年嘛,还不整几个硬菜!😁 你准备好了吗? 咱们可开始了。 第 二 讲|重 力 与 跳 跃 上一讲,咱们研究了如何用键盘控制角色的上下左右移动。 但在一个平台类游戏里,只是来回跑显然是不够的。我们还要让角色跳起来! (啥叫平台类的游戏?麻烦参看上一讲) 今天我们就来研究研究跳跃的问题——小跳,大跳,二段跳,各种跳,要跳出花来。 而“跳跃”的前提是要有一个“重力”的概念的,不然你一蹦就上天了,落不下来了,这游戏也没法玩了。 所以,这一讲主要包含如下几个大部分: 表现重力 2 跳跃! 3 二段跳 4 控制高度的跳跃 ❶ 先来点重力 在 Scratch 的舞台上,本是没有重力概念的。如果我们不编程,角色可以停留在任何位置。当我们想模拟现实世界时,第一件事儿,可能就是把重力加进去:让角色只能停留在舞台的底部;其他任何高度,都会落下来。落还不能匀速,还要落得越来越快,就像真实世界的下落过程一样。 有些学过自由落体知识的孩子要说了: 我知道!下落高度 h = ½ gt² 按照这个公式来做就可以了! 嗯嗯,完全可以,不过没有必要。一是增加编程的难度,二是按照真实世界完全精准模拟,有时候反而会丧失游戏的乐趣。我们首先要追求“好玩”,其次要“看起来真实”就可以了。 具体怎么做?一起来捋捋编程思路: 角色要往下落?那么就是让它的 Y 轴坐标值越来越小就好了; 落到底边不动了?那我们要规定一个 Y 值的最小值,Y 的所有变化都不能小于这个最小值,就 OK。 落得越来越快?这就需要动用变量了。我们设定一个变量“Y 速度”,让它在循环里不断变大,(加上负号,就是在 Y 轴的向下的方向上不断变大),再将它的值在循环里不断的付给 Y 坐标的增加。 那这里有一个问题了:我怎么知道 Y 值的最小值应该是多少呢?是 -180 吗? 这个简单,你把角色拖到舞台底边,在看一下运动 → “移到 X Y”模块的数字,就知道它当前的位置了。Y 的值就应该是它的最小值。 我们看程序: 第一部分初始化,确定变量初始值、大小和初始位置。 第二部分,在大循环里,首先判断角色的 Y 轴坐标是否大于 -165,就是判断角色是不是在“空中”。如果是,就把变量“Y 速度”减2,把角色的 Y 坐标向下移动“Y 速度”值;如果不是,说明角色已经“着地”了,就把 Y 坐标值锁定在 -165,角色就会贴在地面上。 我们可以具体推演一下: 刚点击小绿旗,还没往下掉的时候,角色的 Y 坐标值为150,“Y 速度”值为0; 第一次循环,角色还在空中嘛,“Y 速度”值 = -2,Y 坐标向下移动 2; 第二次循环,“Y 速度”值 = -2-2 = -4,Y 坐标向下移动 4; 第三次循环,“Y 速度”值 = -6,Y 坐标向下移动 6; 第四次,-8,向下移动 8…… 看出来了吗?每次循环,向下移动的距离更多,这样看起来就是越来越快的了。 看一下实际执行结果: 就是酱紫。是不是还挺像自由落体的。自己再配个音:“啊~~~~~Pià~!” 不过还是有点不对。仔细看落地前的瞬间:居然砸到地面以下去了!为什么会有地面被“击穿”的现象呢? 仔细看上面那张 gif 图,在角色着地前,“Y 速度”值已经涨到 -36 。角色在最后一次向下移动时,移动了36步之多;而最后一次移动前,角色和地面之间的距离也许已经很小,不到36步,所以角色就移动到了地面以下了。 想要看清这个过程,你可以在上面的循环里,加一个等待0.5秒,下落过程就会一帧一帧展现给你看,你就明白了。 那怎样才能不“击穿”地面呢? ❷ 无击穿的下落 思路其实也简单:就是多加一个判断条件。除了判断角色是不是在空中(Y 坐标 > -165),还要判断角色和地面之间的距离是否小于变量“Y 速度”的值(-165 - y 坐标 < y="" 速度)。如果“y="" 速度”比角色到地面的距离还大,说明马上要“击穿”了,我们就不让角色继续按照“y="" 速度”值移动了,而是直接移动到="" -165=""> ![]() ![]() 大家注意到没有,最终“Y 速度”定格在了 -34,比刚才少加了一次。最后会“击穿”的那一次被判断条件排除了。这个落地就很好了。✌️ OK,学会了表现重力的基本方法,我们可以考虑在游戏里如何运用了。 在众多平台类游戏里,角色都是在一个平台上奔跑跳跃的。 咱们现在就把这个平台给加进去。 ❸ 单层平台上的下落 平台呢,有好看的做法,也有省事儿的做法。 省事儿是 Alex 老师的风格吗?不能!! 一定要好看!颜值就是正义!😂 好看的怎么做?其实也挺省事儿的。😂 我们就稍微详细的说一下。 ① 先在网上找张砖块的方块图。可以搜索“砖块 贴图”。大家无论搜索什么,一定要用对关键词。我找到的是下面这张,卡通一点的风格,比较符合游戏的感觉。 ![]() ② 用绘制的方式新建一个角色,在造型中导入方块图; ![]() ③ 点击右下角切换成矢量编辑的模式,把导入的方块图调整到合适大小后,复制多个方块图,摆成一排,一个像样的平台就 OK 了!最后要记得点击右上角的“设置造型中心”的十字按钮,把造型中心设定在平台的正中心啊。 ![]() ![]() 我把这个平台的角色命名为“墙头”。把墙头在舞台上摆好合适的位置,重新摆放一下摔猫,获得合适的下落高度,就用刚才没有“击穿”效果的代码来改,具体的代码就不贴了,效果是酱紫: ![]() 看着还不错。不过这里有一个问题:稍微好玩一点的游戏,平台就不会是一层,而是有好几层,摔猫要从一个高度的墙头跳到另一个高度的墙头,这种靠坐标定位的的做法,就不好用了。我们就要用“碰到 ?”侦测模块了。 ❹ 双层平台上的下落 首先你得先整出一个双层平台出来。还是用刚才的墙头,在造型里修改,摆一个双层平台,让摔猫可以从上面一层摔到下面一层。 ![]() 然后我们把摔猫放在第一层。为了能控制它移动、落到第二层,我们还要给它加上左右移动的代码。这部分上一讲已经说得很透了,这里就不展开了,直接上代码。 ![]() 刚才说了,控制下落的代码,因为有多层高度,我们不能用坐标定位下落位置了,而要换成侦测是否碰到某个角色的模块。即我们判断摔猫是不是碰到了平台?如果没碰到,说明还在空中的下落状态,我们让变量“Y 速度”不断增大(负的);如果碰到了,说明落在平台上了,我们就把变量“Y 速度”锁定为 0 。来看代码。 ![]() 效果呢,是酱紫: ![]() 摔猫趴在上层的平台没动,因为他碰到了平台,“Y 速度”为 0 ,Y 坐标值就没有任何变化。 控制它滑出上层平台,它没碰到平台了,“Y 速度”就开始负方向增加,就开始越落越快。碰到下层平台的时候,“Y 速度”又变为 0 了,又趴着不动啦。不过还是可以来回滑动。咕叽咕叽,咕叽咕叽。😁 (要是有童鞋的摔猫转向的时候头朝下,不知道怎么解决,你就自己也头朝下好好反思一下,再去看看第一讲) 不对啊 Alex 老师,你这个例子里没有用防击穿的方法啊,怎么落下来这么完美呢? ![]() ![]() 嗯嗯,确实,用碰到角色的侦测方式,确实容易出现击穿地面的现象,但我们可以通过精确摆放调整平台高度的方法,让角色的最后一次移动正好落在平台表面,就不会不击穿。 ……手动调整啊!😂 ![]() ![]() 没办法,Scratch 的功能其实有限。有时候我们可以创造人工智能,有时候我们也需要智能人工。😂 好了,四个例子玩下来,我们已经能在多平台上表现重力了。下面总算要开始跳了! ❺ 我跳跳跳跳跳! 重力捣鼓清楚了,加入跳的功能其实就是一句话的事儿。 我习惯用空格键来控制跳跃。那么就是:我一敲空格键,就把“Y 速度”设定为一个正向的比较大的数,再让 Y 坐标值增加“Y 速度”值,就 OK 了!就这么简单! 你想啊,你一敲空格,摔猫的 Y 坐标马上要正向移动,就往上蹿,可是它一离开平台,重力部分的代码马上开始起作用,又不停地把它往下拽,没往上升多高,就掉下来了,和真实的跳跃很像。 看看代码和效果。 ![]() ![]() 哈,这摔猫总算蹦起来了!兴奋的童鞋肯定没少让它蹦跶,也肯定发现了一个问题: 你要是使劲儿按空格,它就不下来了!😂 “这么能蹦哒你咋不上天呢?” 它还真上天了!😂 这下知道为啥标题有五个跳了吧!😂 咋办?没事儿,多加个判断,它就老实了。😁 ❻ 防手贱跳 我们要让摔猫好好的,一下一下的跳,把那些疯狂敲键盘的行为都过滤掉,其实加一个判断就可以:判断摔猫有没有趴在平台上。如果有,敲击有效;如果没有,过滤掉就好了。这个好办。 ![]() 试一下?斯文多了吧。😆 氮素……我真的想跳到高的地方去啊!很多游戏里都有空中再跳一次的设定啊! ![]() ![]() 二段跳!这个可以有! ❼ 二段跳! 这个厉害了!游戏里会二段跳的都是狠角色! 越是狠角色,我们越是喜欢做! 来来来,一起分析一下。 二段跳的意思,就是在空中可以再跳一次。那我们就要判断在空中跳过没有,如果跳过,就不能再跳了。靠什么判断呢?最直观的想法,就是靠记录嘛。二段跳之前,先检查记录,有没有跳过;如果没有,就能跳,同时记录一下:摔猫已经二段跳了;如果有,就老老实实落地(本次跳跃完成),同时把记录再改回“没跳”。 这个记录,可以用一个变量搞定。它的值只有两个:跳过、或者没跳;Yes、or No;True、or False. 我们在刚才的程序的基础上来改。 首先我们先建立一个新的变量:“2跳”,它有两个值:true 和 false,用来记录跳了,或没跳; 当我们按下空格键,我们先判断摔猫有没有碰到平台,如果有,把“Y 速度”设为 10,并让 Y 坐标值按照“Y 速度”改变;这和前面的都一样; 但如果没有碰到平台,我们还要判断“2跳”有没有发生;如果没发生(false),就把跳跃的代码再执行一遍,同时把“2跳”设成“true”(跳了)。 ![]() 那如果“2跳”发生了呢?“2跳” = true 呢? ![]() ![]() 如果已经二跳了,什么都不用做,等摔猫回地面,没有代码,所以就没写了,更不用判断。 同时在重力的代码部分,我们要加一行:如果碰到了平台,把“2跳”重新设置为“false”。 ![]() 效果的动画 Alex 老师就不放了,你们自己把代码做出来,运行看看。 最后留个作业吧 开头 Alex 老师也吐槽了,真的能认真学完的人其实很少。 这里最后一个任务,Alex 老师干脆留个作业,看看谁真的动手做了,学了。 (我不会告诉你们我是写不动了不想写了!😭) 任务很简单:用按键时间的长短来控制摔猫的跳跃高度。 怎么样?不难吧? |
|