记录一下同事在做一个scratch小游戏开发过程中遇到的一些问题。
有同事本身代码的问题,也有scratch本身的问题。
要实现的功能很简单,就是两幅图循环移动,实现无限长路面的效果。
下面是同事的代码。
我们逐句来分析一下。两个代码几乎是一样的,只有初始y坐标不一样,一个是0,一个是-1080,舞台高度是1080的。
第1句:“当开始被点击”时,运行代码;
第2句:“切换造型”,好像是为了解决某个问题,因为我们用的是另一个图形化编程的代码,不是scratch,不知道scratch不加这句会不会有问题;
第3句:“移动到”,设置初始坐标;
第4句:"重复执行";
第4-1句:重复执行直到y坐标小于-1080,也就是背景出了边界;
第4-1-1句:重复执行直到的内容,是将y左边增加“移动速度”,其中,“移动速度”是用户控制的小车的速度。负的,说明和小车是反向的。(这里就有物理中相对运动的概念)
第4-2句:y坐标小于-1080之后,将背景移动到y坐标1080的位置。(这句有问题,后边详细分析)
第4-3句:下一个造型。(每个图里边有3个造型,循环的时候,切换造型,刚好能对上,所以最后有一句“下一个造型”,这个不影响逻辑。)
最后发现,运行之后,有时候两个背景之间会有一个缝隙。
第一个问题:第4-2句是不对的,不应该移动到1080的位置。
应该是移动到当前y坐标-1080*2,也就是y-2160的位置。刚好移动两个背景的高度。
因为不一定是刚好移动到-1080的位置,比如上一帧还在-1079,这一帧有可能会移动到-1082的位置,而且判断那里是没有等号的。如果刚好会到-1080,下一帧才会小于,就晚了一帧。
同事测试的时候,用的速度是10,刚好会经过-1080。
小车是匀加速的,加速的时候,最大速度也是10,加速度是1,加速过程的位移是a*t*t/2=v*t/2=10*(10/1)2,也是10的倍数,也能搞好到-1080。
但是就像上边说的,刚好到-1080,刚好差一帧,两个背景的间隔是1090。有个10像素的缝隙。
这个解决了。再试试,发现还是有问题。缝隙不是每次都有了,是偶尔会出现。
加了个计数器,发现,两个背景移动y坐标的次数并不一致,有时候会差一帧,不是每次都差。
经过观察和分析,scratch的两个角色的代码是在独立的线程中运行的(应该是每个事件对应一个线程),(js本身没有多线程,scratch模拟实现了多线程),渲染是在一个线程中运行的(我们称这个为主线程)。主线程和角色的线程是独立的,当渲染的时候,角色中的代码,运行到哪里,是完全不确定的,所以就会出现,一个角色里边的y坐标变了,另一个没变,差了一帧的情况。
这个没办法给小孩解释线程的概念,也不适合写的太复杂,所以最好的方式是通过设计来解决,比如用一个角色实现道路的循环播放。
以上。
很简单的功能,很简单的小游戏,但是认真分析,里边包含了物理学相对运动的原理,包含了物理学中的匀加速直线运动,还涉及到了多线程。
同事作为成年人,而且算是专业的老师,都没有算清楚。
一个小游戏,如果真的能深入去思考,认真去做,还是能学会很多东西的。做好也不简单。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。