Scratch克隆技术、多线程编程及通讯技术初探

一、引言

Scratch,作为世界流行的青少年编程语言,其对青少年智力的开发及计算思维的培养根本毋庸置疑。既然定位在青少年,那就不能复杂,但是,又要遵循“低门槛,高上限”两个基本特征。让青少年尽快入门的同时,又可以让部分能够深入钻研的同学深刻体会到编程的创造性、复杂性及内在乐趣。而后者,在全国青少年编程竞赛与等级考试中肯定要体现出来——自然也是体现参加者作品创意与难度的所在。

Scratch开发者恰当地把握了上述要求与特征:最基础最重要的计算机编程语言特征必须具备,同时又尽可能巧妙地“屏蔽”程序设计算法及内在原理的复杂性,在界面设计上追求“极简且稳定第一”的风格——就像小朋友手中的真实积木,任意摔打而毫无问题。

我们知道,Scratch程序运行原理上是基于事件驱动的,这一点学起来并不复杂。但另一方面,多线程编程及其同步技术这种“高上限”又无法回避——这是开发复杂应用程序最实用但又最复杂的技术之一。

还是那句话,Scratch绝不是玩具式语言!下面通过实例来说明问题。

二、问题需求

在本文中,我们想使用Scratch开发一个如图所示的小程序。

在三消游戏、卡牌游戏中经常出现本程序中的需求,即按指定矩阵排列规律在屏幕特定区域布局精灵。为了简化问题,我使用了大写的26个英文字母来做试验,如图所示。
为了朋友们看起来方便,有些基础性的准备工作我简单介绍一下。

为程序准备大小相同的26个英文字母角色

手段多样。我使用的办法是结合Scratch的导出功能与Photoshop联手搞定。


有兴趣的朋友高度推荐自学一下Photoshop,这个软件类似于日常办公中的Office软件,在日常图形图像处理中功能极其强大!一经学会,终生受益!



总体步骤如下:

【第一步】Scratch中内置的角色库的”字母“类型中已经提供26个字母的造型,如图所示:

【第二步】添加一个空白角色,切换到造型编辑器(或者称图形编辑器)状态下,从内置角色库中把上述字母造型逐个按序加入到本角色中,参考下图:

【第三步】仔细观察,这些字母的造型大小并不一致(我上图中给出的是经过我加工的,所以大小一样),而且大小差距不少。如果根据我们上面程序要求,非常有必要把它们调整得一样大小。怎么办?

考虑到系统内置造型编辑器的有限功能,想到:把它们导出,然后用Photoshop统一处理。请参考接下来的步骤。

【第四步】先在造型编辑器中把上述造型逐个转换成位图类型。注:默认添加的字母造型是矢量的,只能导出为.SVG格式。在转换成位图类型后即可把它们导出成.PNG格式,然后使用Photoshop处理。有兴趣的朋友,可以分析一下直接使用矢量编辑软件如CoreDraw或者Illustrator等直接处理.SVG文件。因为我的Photoshop是CS6,默认不能直接处理.SVG,所以我先转换成位图类型。
【第五步】在得到位于同一文件夹下的26个.PNG文件后,可以很轻松地使用Photoshop把它们批量修改成同一尺寸(有兴趣的朋友可以参考我本文稍后整理的短博文,在此省略介绍)。考虑到Scratch的创作屏幕为480X360像素,所以,我把每一个字母的大小修改成30X34像素大小。

为了度量方便性,这里还有一个小技巧是:我把背景图替换成了Scratch系统内置的背景图,名字为Xy-grid-30px。

克隆技术的需求

针对上面如图所示的字母排列,不少中学信息学教材中介绍逐个角色方式创建,并逐个排列到屏幕上。这种方法是最原始、最简单、最直接的,但往往也是最有问题的方法。不妨设想:在拥有几十甚至上百个关卡的卡牌或者消除类游戏中,如果使用这种排列方法,麻烦大了!
显然,最好的办法是利用Scratch中的克隆技术:创建一个角色,并让这个角色拥有上面26个英文字母的26种造型。那么问题来了:

【问题1】如何利用克隆技术?
【问题2】如何有效管理这些造型并适时地动态调整?



克隆对应的英文单词是“Clone”,意思是完全复制。在Scratch编程中,克隆不仅复制母体的所有静态属性,还复制包括执行代码在内的一切。在游戏软件开发中,常常要求相同的角色的大量不同的副本,而且要求这些副本表现出与母体完全相同的行为;例如,大量的僵尸与小鱼、无数的雨点与雪花……
因此,巧妙地使用克隆技术,能够生成大量相似或相同表现的角色,并极大地简化程序、特别是游戏软件的开发过程。
【注】在本文中,我们把作为克隆种子的角色统一称为“母体”,把每一个克隆生成的角色简称为“克隆体”,理解与搞清“母体”与“克隆体”之间的关系是克隆技术编程的关键。


克隆技术使用的情形

例一:生成天空中的雨点

下面的两段代码针对故事中的“雨点”角色编程:
第一段

第二段

【技术总结】此处代码的特点是:母体角色(只有一个)只负责生成克隆体角色,各种属性的设置统一由克隆体自身处理。这属于克隆技术编程的最简单的情形。这种情形下,第二段代码可以尽情使用程序中定义的全局变量,但要注意各克隆体之间使用上不应出现冲突。
【问题】这两段代码属于两个线程,这两个线程的执行看起来没有什么共享数据或者同步要求,所以,这种情形下的克隆编程是比较简单的。


多线程、多进程编程是几乎每一个中级程序员必须面对和要克服的难题,Scratch后台系统的特征与实际程序开发的需求要求它不得不引入多线程技术,尽管Scratch竭力巧妙地掩盖这种技术,但这些技术本身具有的复杂性在使用Scratch编写比较复杂的程序时必然(而且已经)彰显出来且需要克服。值得庆幸的是,Scratch开发者早已预料到这一点,并已经给出了圆满的解决方案。

例二:生成三只有规律排列的小猫
先看下图:

【问题一】哪一个是母体?答案见下图:

即最右边一个是母体!
截止到目的,我们对克隆技术使用要求是生成满天的雨滴或者是三只猫,并没有要求区别母体与克隆体!但是,有些,甚至是更多,应用情况下要求区别对待母体与克隆体(甚至是各克隆体之间也要区别)。
【问题二】要想使左边第一只猫成为母体,怎么办?

先看下面的图示:

结合上图,得出目前结论是:克隆体总是由母体生成的!

因此,要解决上面【问题二】要求在克隆体内修改坐标,而不能在母体代码中修改坐标(母体代码中修改总是修改母体角色的属性值)。自然,要实现“在克隆体内修改”这种目标,于是积木命令登场!

那么,看接下来的这段代码及结果图示:

这段代码也好理解不是?【问题二】的答案初步有眉目了!但是,新的问题又出现了:

【问题三】第三只(最右边)小猫(克隆体)如何生成?

如果相当然修改,可能会有如图结果:

有关克隆体代码(积木【当作为克隆体启动时】所属代码)中继续克隆自己的问题暂时不讨论(涉及到克隆递归及最大递归深度的问题)。

继续修改,尝试如下代码(与结果图):

细心的朋友容易观察出,克隆母体两次,这两个克隆体都调用了积木【当作为克隆体启动时】所属代码,所以结果是:这两个克隆体小猫的位置是重合的。

再想办法(结果还是不行!):

不再纠缠下去了,其实,解决上面的【问题二】的办法是把两次克隆体代码区别开来,即区别哪是第一次克隆哪是第二次克隆,问题就好办了。于是,我们想到下面的解决办法:

运行结果如下:

注意到,这种方案具有代表性,即如果生成N个位置的X只小猫的话,只要区别这X次克隆问题就迎刃而解了。
上面提供的办法运用到了在克隆体执行代码中使用全局变量的功能,其实,大家顺着这个路子还会想出更复杂的与克隆有关的问题来。

有兴致的朋友可以考虑:解决上面【问题二】是不是还有其他更好的办法?

三、26个字母排列问题

其实,在前面的举例中,都涉及到了多线程编程的问题。此时,一旦涉及到数据的共享访问(或者称数据同步),则必须设法解决其中同步的问题。现在,让我们回到本文开始第一张图所展示的问题上。

篇幅所限,我们仅考虑如图所示的这一种情形,其他情形类似,有兴趣的朋友可以参考本文程序在51CTO上的源码(突然发现要联系博客主管才能上传,争取明天解决这个问题)。下面直接给出代码并辅助一定的解释。

角色按钮3X8+2的代码

含义一目了然。

角色字母A的代码

(1)第一段


这是消息接收到后的初始化工作,注意全局变量“gv克隆体计数器”是用来区别各个克隆体使用的(当然,本例子仅是一个入门,并没有深入区别对待每一个克隆体的操作)。

(2)第二段

注意:本例子中为了数据管理的方便,引入了两个分别记录屏幕上按规律排列的每一个角色横纵坐标的两个列表,如图所示:

其中,“const横坐标列表”用来存储垂直方向平均切割成16份(30X16=480)每一个角色的中心点的横坐标,“const纵坐标列表”用来存储水平方向平均切割成10份(10X34+20=360)每一个角色的中心点的纵坐标。

上面代码开始时,母体定位,并初始化几个辅助变量,例如row和column分别用来记录屏幕上角色所在的行与列(正好也与下面的二重条件循环次数大致相对应——并非严格对应)。

接下来,变量“____克隆结束2”的作用是非常重大的。我们引入这个变量的目的是让程序严格地接次序生成屏幕上的克隆体角色(如第1个、第2个、第3个......)。
接下来,两个循环的循环次数含义不用解释了,分别对应行数与列数。当生成了第26个角色(Z字母)后,循环结束。这里循环结束前的“隐藏”积木调用的作用是,用于隐藏母体!!!请各位根据前面克隆体与母体的举例仔细体会。

row和column在循环体内的修改用于控制屏幕上行数与列数。
接下来,看克隆体执行部分的代码。

(3)第三段

语句的作用是,等待上一个角色操作结束(可能是很长时间,本例中时间是非常短暂的)。

接下来的语句作用是,按字母顺序生成屏幕上的角色。

接下来,根据两个数组对应坐标值来修改当前角色的坐标值。
最后,克隆体计数加1,并设置克隆操作结束的标记。

总体来看,在本实例中,协调主程序与克隆体运行代码(其实这是典型的两个线程)的变量“____克隆结束2”的作用功不可没。

小结

在本文中,我们还只是初步探讨了Scratch多线程编程通讯技术与克隆体技术编程的部分内容,并未涉及到全部。但是,相信朋友们已经觉察出Scratch并非市面上谈论得那么“简单”。也正因如此,Scratch(及其各种“克隆体”)才成为风靡世界的青少年编程语言。在以后的文章中,我还会给出更多的有关使用Scratch开发创新性应用与游戏的实例,并进一步探讨Scratch编程的奥秘,敬请期待。不足之处,欢迎广大同仁与青少年朋友批评指正。

原文地址:https://blog.51cto.com/zhuxianzhong/2473498

时间: 2024-10-18 23:26:02

Scratch克隆技术、多线程编程及通讯技术初探的相关文章

IM-即时通讯技术概述

IM-即时通讯技术概述 简述 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容.大多数常用的即时通讯发送程序都会提供各种各样的功能 即时通讯 - 在用户和在线朋友之间来回发送信息 聊天 - 创建用户与朋友或工友的自定义聊天室 网页链接 - 共享用户喜爱的网址 支持图片 - 浏览朋友计算机中的图片 支持声音 - 给朋友播放音乐 支持文件传输 - 直接将文件发送给朋友,以便于共享 交谈 - 使用 Int

.NET面试题解析(07)-多线程编程与线程同步

系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等,本文只是从常见面试题的角度(也是开发过程中常用)去深入浅出线程相关的知识.如果想要系统的学习多线程,没有捷径的,也不要偷懒,还是去看专业书籍的比较好. 常见面试题目: 1. 描述线程与进程的区别? 2. 为什么GUI不支持跨线程访问控件?一般如何解决这个问题? 3. 简述后台线程和前台线程的区别? 4. 说说常

【转】iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

转自容芳志的博客 简介 iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (三)GCD(全称:Grand Central Dispatch) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 三种方式的优缺点介绍: 1)NSThread: 优点:NSThread 比其他两个轻量级 缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 NSThread实现的技术

iOS有三种多线程编程的技术

1.NSThread 2.NSOperationQueue 3.GCD Thread 是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步.线程共享同一应用程序的部分内存空间, 它们拥有对数据相同的访问权限.你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销.在 iOS 中我们可以使用多种形式的 thread: Cocoa threads: 使用NSThread 或直接从 NSObject 的类方法 perfo

iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

简介iOS有三种多线程编程的技术,分别是:(一)NSThread(二)Cocoa NSOperation(三)GCD(全称:Grand Central Dispatch) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 三种方式的优缺点介绍:1)NSThread:优点:NSThread 比其他两个轻量级缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 NSThread实现的技术有下面三种:一般使用cocoa

多线程编程技术基础知识

GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=414 多线程编程技术基础知识 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同

IOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

前言:在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间和资源)等等.也就是说,我们可以使用线程把占据时间长的任务放到后台中处理,而不影响到用户的使用. 线程的定义: 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理

JAVA读书推荐----《深入分析Java Web技术内幕》--《java多线程编程核心技术》--《大型网站技术架构 核心原理与案例分析》-《Effective Java中文版》

(1)  首先推荐的不是一本书,而是一个博客,也是我们博客园另外一位博友java_my_life. 目前市面上讲解设计模式的书很多,虽然我前面讲了看书是最好的,但是对设计模式感兴趣的朋友们,我推荐的是这个博客.这位博友的设计模式讲得非常非常好,我认为90%的内容都是没有问题且很值得学习的,其讲解设计模式的大体路线是: 1.随便开篇点明该设计模式的定义 2.图文并茂讲解该设计模式中的结构 3.以详细的代码形式写一下该种设计模式的实现 4.补充内容 5.讲解该设计模式的优缺点 对于一个设计模式我们关

C#进程间通讯技术-整理。

原文:C#进程间通讯技术-整理. 扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1)共享内存 包括:内存映射文件,共享内存DLL,剪切板. 2)命名管道及匿名管道 3)消息通讯 4)利用代理方法.例如SOCKET,配置文件,注册表方式. 等方式. 方法一:通讯. 进程间通讯的方式有很多,常用的有共享内存(内存映射文件.共享内存DLL.剪切板等).命名管道和匿名管道.发送消息等几种方