Puzzle Script是用于为HTML5创建拼图的简约游戏引擎,它具有开放源代码。 可以在
此处找到现成游戏的示例。
第1部分。我们在Puzzle Script上创建了第一个游戏。
Puzzle Script是一个免费的在线程序,用于创建益智游戏。 她以创造像我
的Nodus之类的难题而闻名。 在这一部分中,我们将创建一个游戏,研究了Puzzle Script的基本功能,接下来,我们将开始编程。
转到引擎
网站 。 单击“
制作游戏”以打开“
拼图脚本”编辑器 。
下载范例
首先,让我们看几个例子。 在屏幕顶部,打开“加载示例”列表,然后选择第一个示例“基本”。 现在点击“运行”。
出现游戏画面。 在其窗口内单击,然后按键盘上的Enter。
尝试玩游戏。 您的目标是将橙色框推到黑色目标正方形。 当每个目标上都有一个框时,将通过级别。 您可以按Z取消移动,或按R重新启动级别。
制作第一个游戏
现在,我们将创建几个级别。 我将与您一起创造一个,并建议其他人提出自己的想法。 单击顶部菜单中的“关卡编辑器”。
如果您没有看到关卡编辑器屏幕,则单击“运行”并启动游戏。 进入关卡后,再次单击“关卡编辑器”按钮。 这样您就可以编辑自己的水平。
创建一个新的关卡
最上方是游戏对象。 左键单击时,将绘制选定的对象。 右键单击将绘制一个“背景”对象。 左键单击地图边缘会增加其大小,右键单击会减小其大小。
要通过一个级别,您需要在每个目标上放一个方框,因此在每个级别上都应该有一个最低要求:
右键单击将所有内容变成草。 然后,在级的边缘上单击鼠标左键以使其变大,最后绘制一个类似于下图所示的级。
将其添加到级别列表。
完成创建关卡后,我们将其添加到关卡列表中。 在关卡编辑器中,单击游戏对象列表旁边的白色字母S以保存创建的关卡。
级别编辑器下方应显示一条有关成功编译的信息,并包含一些有趣的字符,如下所示。
这些有趣的字符表示我们刚刚创建的级别。 每个字符代表一个单独的对象。 在屏幕左侧,向下找到“传奇”。 图例提供了每个字符的说明:
。 =背景
#=墙
P =玩家
* =板条箱
@ =板条箱和目标
O =目标
屏幕左侧的所有内容都是游戏代码,分为不同的部分,例如OBJECTS或LEGEND。 转到LEVELS。 在这里,我们看到了示例中使用的级别。
要添加新级别,请在级别部分的底部创建一个新的空行。 然后复制为我们的关卡生成的字符并将其粘贴到此处。 所有级别已添加。
我们将对其进行测试。 创建新关卡后,您需要再次按屏幕顶部的“运行”按钮,以新关卡重新启动游戏。 有时这不起作用,然后您需要单击“重建”按钮,然后再次单击“运行”。
保存和加载游戏
尝试创建更多新的关卡。 准备好保存游戏后,转到代码开头,输入您自己的姓名,作者的姓名和主页,然后单击“保存”按钮。
数量有限的保存存储在计算机的“加载”菜单中。 但是,屏幕顶部有一个“共享”按钮。 当您单击它时,将生成带有两个Web链接的消息。
链接之一是您的项目的源代码。 第二个是指向您可以与朋友分享的游戏可玩版本的链接。 我建议定期创建一个到源代码的新链接,并将其保存在某些文本文档中,以便您拥有该项目的永久存储版本。
游戏导出
您也可以将游戏导出为html5文件,然后将其上传到
itch.io ,
Kongregate或
Newgrounds等游戏门户。 只需单击“导出”,然后将下载的html文件上传到游戏门户。
我们的示例项目可以在
这里找到。
第2部分。Puzzle脚本入门
在这一部分中,我们将学习如何在
Puzzle Script中开始编程。
代号
打开一个
示例项目 。 程序代码在屏幕的左侧,分为以下部分:对象,图例,声音等。 在“规则”部分中,设置了对象交互的规则。 进去吧 应该只有一行代码:
[ > Player | Crate ] -> [ > Player | > Crate ]
这条线表示,如果玩家靠近箱子并朝他的方向移动,则游戏将移动玩家并推动箱子。 为了解释它是如何工作的,您需要了解拼图脚本代码遵循以下结构:
[ ] -> [ ]
这意味着:
[ ] -> [ ]
Puzzle Script检查箭头左侧的条件,例如,玩家的对象是否在盒子对象旁边。 如果条件为真,那么我们可以做一些事情,例如,推箱子。
条件示例
这是条件的示例:
[ object1 | object2 ]
此事件检查object1是否在object2旁边。 您可以通过放置
|
检查两个对象是否彼此相邻
|
通过按Shift + \输入的
|
。 条件总是括在
[ ]
。
[ crate | crate ]
上面的代码检查两个框是否彼此相邻。
[ crate | crate | crate ]
此条件检查附近是否有三个盒子。
[ crate target ]
此条件检查该框是否在目标的顶部,因为
|
两个对象之间
|
。 如果对象位于碰撞的不同层中,则它们可以彼此重叠,我们将在本教程的以下部分中介绍这些对象。
我们保持平等
规则必须平衡。 条件检查和其后的事件都应以相同的方式描述。 我将说明这意味着什么。
[ player | crate ] -> [ player | ]
如果玩家在盒子旁边,那么这行代码会破坏盒子。 您不能写:
[ player | crate ] -> [ player ]
因为左侧条件检查两个单独的网格空间中是否存在相邻对象,但是该事件仅描述了玩家占用的一个网格空间。 拼图脚本需要知道如何处理其检查的空间。 销毁盒子的正确代码应报告以下内容:
[ | ] -> [ | ]
[ player | crate ] -> [ player | ]
也就是说,即使代码中的空白也很重要。 但是,以下条目有效:
[ player target ] -> [ player ]
由于在这种情况下,我们仅讨论一个网格空间,所以该事件描述了相同的网格空间。
如何移动盒子
让我们回到原始代码行。
[ > Player | Crate ] -> [ > Player | > Crate ]
换句话说:
[ | ] -> [ | ]
《箭头》强调运动。
有时我们需要写注释以记住代码的作用。 拼图脚本会忽略注释-它们仅用于用户。 要发表评论,您需要将文本放在方括号中。 我们在规则中写了一条注释,描述了它的作用:
( )
[ > Player | Crate ] -> [ > Player | > Crate ]
现在,在“推送代码”框中,输入以下内容:
( )
[ < Player | Crate ] -> [ < Player | < Crate ]
倒箭头表示如果玩家离开箱子,他将拉箱子。 单击“运行”以测试此操作。 您应该能够推和拖箱子。 在编程中,即使在一个字母中有错字,计算机也可能无法理解该代码,因此请消除所有错误。 更改代码时,再次单击“运行”以下载更改。 如果游戏无法正常运行,请尝试单击“重建”以清除程序的内存,然后单击“运行”。
有时有必要停用一行代码。 只需将其变成注释以保存将来。 让我们注释一下推动盒子的代码,以便播放器只能携带盒子:
( )
([ > Player | Crate ] -> [ > Player | > Crate ])
( )
[ < Player | Crate ] -> [ < Player | < Crate ]
如果可行,请注释掉拉出框的代码,然后尝试以下操作:
[ < Player | Crate ] -> [ < Player | > Crate ]
如果播放器远离盒子,播放器和盒子将朝相反的方向移动。 箭头确定对象向哪个方向移动或将向哪个方向移动。 现在将其注释掉,然后尝试以下操作:
[ > Player | Crate ] -> [ Player | > Crate ]
盒子移动了,但是播放器仍然留在原地。 尝试^和v(字母v),以查看对象如何移动。
失误
让我们故意写错规则,看看会发生什么。 输入以下行:
[ < Player | Crate ] -> [ < Player ]
尝试运行该程序。 您应该看到以下消息:
第81行:通常,左侧要匹配的每个模式都必须在右侧具有相等长度(单元数)的相应模式。
通常,Puzzle Script可以很好地描述错误。 但是,有时拼图脚本本身就是错误的。 在这种情况下,您需要亲自检查代码并找出错误所在。
更多实验
尝试尝试并自己编写规则。 这里有一些例子。
[ > Player | … | Crate ] -> [ > Player | … | > Crate ]
在上面的示例中,如果玩家在关卡的同一行上的任意位置,则他们将按下该框,然后玩家将移至该框。
[ > Player | Crate ] -> [ Crate | Player ]
此代码交换播放器和盒子。
[ > Player | Crate ] -> [ Player | Target ]
在此代码中,如果玩家靠近盒子并朝盒子移动,则玩家将停止移动,但盒子会变成目标。 Puzzle Script最好的事情是易于创建新事物和进行实验的可能性。
第3部分。创建对象
拼图脚本上游戏中的所有图形片段均指示对象。 要在Puzzle Script上创建游戏,您必须创建自己的对象。 在这一部分中,我将告诉您如何创建它们并将它们添加到我的代码中。
一般资讯
打开一个
示例项目 。 创建对象的过程包括以下步骤:
完成所有这些步骤后,就可以开始使用该对象了。
对象创建
已经存在几个对象。 每个游戏必须有一个背景对象。 所有对象均由5 x 5像素的网格创建,并至少具有一种颜色。 背景对象如下所示。
Background
LIGHTGREEN GREEN
11111
01111
11101
11111
10111
数字表示图像中的像素。 每个数字对应其颜色。 第一种颜色的数字为0,第二种颜色的数字为1,依此类推,最多9种。最多可以有10种颜色。 在我们的例子中,每个1为像素以浅绿色(Light Green)着色,为0-以绿色(Green)着色。 结果看起来像这样:
始终按以下方式创建对象:
名称始终在第一行。 颜色始终位于第二行,图像采用接下来的5行,每行5个字符,形成5 x 5的网格,或者您可以执行以下操作:
Background
LIGHTGREEN
此代码将创建一个称为“背景”的对象,该对象将是一个5 x 5像素的浅绿色网格。 如果您不描述图像网格,那么我们会得到一个纯色块,这有时会很有用。
给对象命名
可以随意调用对象,但是名称不能以符号开头,并且必须是一个不带空格的单词。 给对象指定清晰的名称,但不要太过分。 PlayerStill是个好名字,PlayerThatIsStandingStill太长且太冗长。
色彩
您必须声明要用于对象的颜色,并用空格分隔它们。 拼图脚本具有预定义的颜色:
- 黑色的
- 白色
- 灰色的
- 深灰色
- 浅灰色
- 灰色的
- 深灰色
- 浅灰色
- 红色的
- 暗红色
- 淡红色
- 棕褐色
- 黑褐色
- 浅褐色
- 橙色
- 黄色的
- 绿色的
- 深绿色
- 浅绿色
- 蓝色的
- 浅蓝色
- 深蓝色
- 紫色的
- 粉红色
- 透明的
您还可以将颜色设置为十六进制,这为我们提供了更广泛的颜色范围。 您可以使用诸如此类的网站来选择十六进制颜色。 选择所需的颜色,然后在图像上方重写颜色代码。 十六进制颜色代码按以下方式用拼图脚本编写:
#51A2BD #ff0000 #ffffff
颜色代码始终以#字符开头。
向图例添加对象
创建对象后,需要将其添加到图例中。 图例如下所示:
. = Background
# = Wall
P = Player
* = Crate
@ = Crate and Target
O = Target
每个符号代表一个关卡中的一个对象。 也就是说,当我们看到这样的字符网格时:
#p.*.##
#.**.##
#..#..#
##....#
##...o#
#######
它实际上描述了我们的水平:
必须为每个创建的对象分配一个字母,符号或数字,以指定该对象在级别上。 像这样:
P = player
在图例中对对象进行分组
我们还可以在图例中创建对象组。 例如,如果我们有几个彩色框,那么我们可以这样做:
O = OrangeCrate
B = BlueCrate
G = GreenCrate
这将使我们能够使用编辑器级别的框。 但是要创建代码,您可以将它们组合在Legend中,如下所示:
Crates = OrangeCrate or GreenCrate or BlueCrate
所有这些看起来像这样:
=======
LEGEND
=======
O = OrangeCrate
B = BlueCrate
G = GreenCrate
Crates = OrangeCrate or GreenCrate or BlueCrate
为什么这样 因为那样,而不是创建这样的规则:
[ > Player | OrangeCrate ] -> [ > Player | > OrangeCrate ]
[ > Player | BlueCrate] -> [ > Player | > BlueCrate ]
[ > Player | GreenCrate] -> [ > Player | > GreenCrate]
您可以简单地写:
[ > Player | Crates ] -> [ > Player | > Crates ]
此代码将适用于整个对象组。
此外,在“
碰撞层”部分中,您可以引用组所在的层,而不必输入每个单独的对象。
碰撞层
默认情况下,碰撞层部分如下:
Background
Target
Player, Wall, Crate
每行选择其自己图层中的对象。 对象层的顺序确定哪些对象将位于其他对象之上。 顶行中的对象将在最底层,下一行将在其上方的层,依此类推。 背景应始终位于最顶层,位于最底层。 一层中的对象不能彼此重叠。 也就是说,这不能是:
[ player wall ] -> [ player wall ]
您可以使不同层中的对象相互交互。 例如,您可以编写:
[ > Player | Target ] -> [ > Player | > Target ]
实验
创建一些新对象。 创建只能推入的盒子类型。 创建另一个只能拖动的框。 创建一个框,当您触摸它时会消失。 继续进行实验,您将更好地记住所有步骤。
第4部分。胜利条件
每个人都喜欢赢。 我们作为玩家,想赢。 在这一部分中,我们将学习如何对赢得比赛的条件进行编程。
胜利条件
下载
示例项目,然后转到“赢得条件”代码部分。 您应该看到以下内容:
All Target on Crate
如果每个目标上都有一个方框,则赢得比赛。 如果您有3个框和2个进球,那么您只需在目标上设置2个框即可获胜。 如果交换:
All crate on target
那么每个盒子都必须对准目标。
可能存在一个或多个条件。 在多种情况下,必须全部满足。 例如,我们可能具有以下内容:
All Target on Crate
All Target2 on Crate2
如果级别具有target和target2,则分别为crate和crate2。 如果在某个级别上没有满足某个胜利条件所需的对象之一,例如,没有target2,则自动满足此条件。
不同类型的胜利条件
有几种不同类型的胜利条件。
No Object
在这种情况下,当没有一个这样的目标时,胜利就来了。
Some Object
当关卡上至少有一个指定类型的对象时,您将获胜。
Some Object1 on Object2
Object1的至少一个对象必须在Object2上。
No Object1 On Object2
此条件与“
All Target on Crate
的
All Target on Crate
”相反。 在这种情况下,我们需要所有这些对象彼此分开,而不是彼此重叠。 您也可以将不同的胜利条件相互结合。
实验
我们将尝试不同的胜利条件。 如果所有箱子都未对准目标,则尝试创建一个赢球的游戏。 或制作一个游戏,其中您需要销毁某种类型的所有盒子,但还有其他推动盒子的方式。
我完成的示例项目可以在
这里查看。
第5部分。后期命令
PuzzleScript有一个非常有用的命令,称为“ late”。 游戏中事件起源的顺序很重要,有时您需要稍后执行的代码才能获得所需的结果。 在这一部分中,我将讨论使用
late命令。
我们为什么需要它
打开
一个示例项目 ,然后将以下代码粘贴到游戏中并运行它:
[ player | target ] -> [ player | ]
可以预料,只要玩家站在球门旁,球门就会被破坏,但这不会发生。 相反,目标在玩家旁边站立
后消失在路线中。 因此,尝试另一个代码:
late [ player | target ] -> [ player | ]
只要您站在目标旁边,目标就会消失。 发生这种情况是因为指定为
延迟的所有事情都在所有其余代码执行完之后发生。 有时这是必要的。
事件顺序
这是拼图脚本中的代码一步一步执行的方式。
- 拼图脚本发现玩家想要移动
- 只要有可能,规则就会从上至下读取并执行。
- 玩家尽可能移动
- 逾期规则适用
计算机从代码的第一行开始,然后逐行读取。 检查每个条件。 因此,当您尝试四处移动时,Puzzle Script会读取所有规则并检查条件是否成立,如果满足,则执行某些操作。 例如,第一行可能是这样的:
[ player | spikeTrap ] -> [ | spikeTrap ]
如果玩家没有站在筹码陷阱旁边,则代码将继续执行。 这意味着编写代码行的顺序很重要。 在某些情况下,您可以使用late命令,您将在实践中随着时间的推移学习该命令。
后期使用方法
以我的经验,最好在检查对象是否彼此重叠或相邻时使用late命令,但是还有其他情况。 如果您检查一个对象是否在另一个对象上,那么除非下一个命令使用,否则该事件将直到下一轮才注册:
[ player spikeTrap ] -> [ spikeTrap ]
在上述情况下,直到进入陷阱后的下一回合,玩家才会被带木桩的陷阱杀死。 要使玩家立即死亡,只需添加late命令,
late [ player spikeTrap ] -> [ spikeTrap ]
要在角色死亡时重新启动整个关卡,您可以执行以下操作:
late [ player spikeTrap ] -> restart
当玩家落入木桩陷阱时,关卡将重新开始。
您可以在
此处看到完成的项目示例。
第6部分。处理声音效果。
我们在
Puzzle Script上做了一个很棒的游戏,但是现在我们需要为其添加声音。 怎么做? 现在我告诉你!
声音产生
打开一个
示例项目 。 给它添加声音。 在游戏屏幕下,您可以看到带有白色符号的黑色正方形。 它们用于产生声音。 每个角色都会产生独特的声音类型,并且叉号会删除所创建的声音。 尝试单击正方形,然后听声音。
黄色数字是唯一的代码,需要复制并粘贴到需要声音的代码中。
如何使用声音
找到正确的声音后,必须将其插入游戏代码的“
声音”部分。
声音可以通过多种方式使用。 最简单的方法是创建一个新的声音效果(sfx)。 它们必须编号。 我们创建一个新的sfx,在插入数字声音ID时为其分配一个从0到10的数字。 在“声音”列表中,创建一个名为sfx0的新sfx并将其分配给生成的声音:
sfx0 36301705
要使用声音,您需要在事件之后将其插入规则中。 让我们将新创建的sfx0附加到盒子销毁事件(该事件已经存在于项目示例中):
(The player destroys a crate)
[ > Player | CrateVanish ] -> [ Player | ] sfx0
还可以声明声音以进行某些事件的回放,例如:
Crate MOVE 36772507
在这种情况下,移动板条箱时会播放声音。 生成用于拖放CratePull对象的新声音效果,并在移动CratePull时使其播放:
CratePull MOVE 12735307
事件的声音仅应在“声音”部分中声明:它们无需在规则中提及。
声音再现方法列表
以下是可以使用的各种事件声音的列表,摘自Puzzle Script
文档 。
对象动作541566-在移动过程
中将对象暴露于动作时播放。
创建对象641667-创建特定对象时播放。
EndGame 5416789-游戏结束时播放。
EndLevel 6417822-关卡完成后播放。
对象CantMove 781673-当对象尝试在任何方向上移动失败时播放。
播放器CantMove Down Left Left 464674-当对象尝试向下或向左移动失败时播放。
CloseMessage 344456-当播放器关闭消息框时播放。
销毁对象187975-销毁对象时播放。
对象移动264567-当对象成功向任意方向移动时播放。
对象向左下移动765432-在对象成功向下或向左移动时播放。
水平移动对象345367-当对象成功水平移动时播放。 您也可以使用垂直。
重新启动7865435-当玩家按下重新启动按钮R时播放。
SFX0 765743-可以是从SFX0到SFX10的任何东西。 这些是可以根据规则执行的特殊声音事件。
ShowMessage 478483-显示消息时播放。
StartGame 234626-在新游戏开始时播放。
起始级别765436-在每个级别的开始播放。
TitleScreen 876543-加载屏幕保护程序后播放。
撤消436234-当玩家按下取消键(Z)时播放。
您可以指定
移动和
不能移动的方向,以便在朝不同方向移动时会再现不同的声音。
该项目的完成示例在
此处 。
第7部分。播放音乐
我们学习了如何在Puzzle Script上创建游戏,但是向其中添加音乐不是很好吗? 有可能,现在我将告诉您如何做。
注意:目前,Puzzle Script中的此功能似乎已损坏,因此继续下一部分。
怎么办
打开
项目空白 。 音乐在Puzzle Script中的工作方式如下:您可以将来自YouTube的单个视频的链接插入游戏中,PuzzleScript将自动播放该视频的所有声音。 打开Youtube并选择任何视频,或使用以下方法:
youtube.com/watch?v= CKAc3nYEatw要播放视频中的音乐,我们需要获取唯一的视频ID。 上面一行的绿色部分是唯一的ID。
在项目开始时在作者的主页下方,添加youtube标签,然后在其后添加唯一的视频ID,例如,如下所示:
youtube CKAc3nYEatw为确保其正常运行,请单击“共享”,然后单击游戏链接(而非源代码链接)。 在编辑器中进行测试期间,无法播放拼图脚本音乐。 如果您想让游戏带有音乐,则需要将其作为视频上传到Youtube上,并在项目中插入一个唯一的ID。 每个项目只能有一个YouTube视频。
项目实例
在
此处可以找到示例拼图脚本项目。
第8部分。如何使用Action命令
我们已经知道如何移动,推动和拖动块,但是如果我们需要通过按某个键(例如
空格)来做某事怎么办?
PuzzleScript中的输入可能性非常有限,主要是箭头键,Z可以取消,R可以重新启动,我们无法更改它们。
但是引擎为我们提供了一个额外的操作键-按下空格键或X键。与行动小组合作时遵循上述格式。我们使用了基本的PuzzleScript代码格式:[ ] -> [ ]
如果条件为真,则我们执行事件。操作命令的使用方式相同,但是有其自己的规则。看起来像这样:[ Action ] -> [ ]
这是使用Action命令的示例:[ Action Player ] -> [ Crate ]
首先,行动永远是条件的第一句话。其次,如果我们想影响游戏中的某个对象,那么我们需要在条件和事件中都提及该对象(如果我们提及另一个对象,程序将删除原始对象,并用新对象替换它,如果您不指定该对象,则他将退休)。最后,仅应在条件中使用动作一词,但有时在条件和事件中都值得使用它。我将在下面讨论。检查游戏项目中上面显示的代码。您可以从此示例开始。您会看到按空格键或X时,播放器将变成一个盒子。条件显示为[ 如果按下Action键, 并且在该级别上有一个Player对象 ]->然后[ 用一个框替换 该玩家对象]现在,让我们在项目示例中尝试以下代码:[ Action Player | Crate ] -> [ Player | > Crate ]
如上图所示,确保四周都被框包围。您会注意到一个动作一次只影响一个盒子。我不清楚原因到底是什么,但是如果您想使用Action命令影响多个对象,则需要在条件和事件中都指定它。将代码替换为更新的版本:[ Action Player | Crate ] -> [ Action Player | > Crate ]
现在我们可以一次推所有箱子。如果需要将操作应用于多个对象,则将“操作”放入条件和事件中。第9部分。检查多个条件
让我们学习检查几种情况,例如炸弹和可破坏块的存在。打开一个示例项目。现在向其中添加以下代码:late [Player Switch][DoorClosed] -> [Player Switch][DoorOpen]
代码遵循以下格式:[ 1 ] [ 2 ] -> [ 1 ] [ 2 ]
如果条件1为真,条件2为真,则执行步骤1和步骤2,在本例中,在条件1下,检查播放器是否处于Switch状态。如果是,则检查条件2,即是否处于关门水平?如果条件为真,则DoorClosed对象将变成DoorOpen对象,从而打开门。假设我们需要在英雄离开开关时将门关闭,因为我们希望玩家将盒子推到开关上才能打开门。您可以这样写:late [Player | Switch][DoorOpen] -> [Player | Switch][DoorClosed]
如果玩家站在开关旁边,并且在某个水平位置上有一扇打开的门,则我们将门关闭。最后,如果将盒子推到开关上,我们需要使门保持打开状态:late [Crate Switch][DoorClosed] -> [Crate Switch][DoorOpen]
现在,当抽屉在开关上时,门将保持打开状态。您可以在此处看到完成的项目示例。第10部分。创建断点
也许您对玩解谜脚本有一个好主意,但它需要控制点(检查点),以便玩家在死亡时恢复过来。怎么做?非常简单,现在我将解释如何。创建断点
打开一个示例项目。现在我们需要编程一个断点。只需一行代码即可满足此要求:late [ Player FlagRed ] -> CHECKPOINT
FlagRed是一个检查点。当播放器位于标志上方时,此代码将创建一个检查点(CHECKPOINT)。如果不使用较晚,则检查点功能将不起作用。测试游戏。越过控制点,然后再走一点,然后按R键。您将需要从控制点开始。多个控制点
如果有多个控制点,则游戏将使用玩家最后激活的控制点。为了避免重新激活已经使用的控制点,您需要将其更改为另一个对象。为此,请在代码的“对象”部分的红色标记下创建一个白色副本。FlagWhite
White Orange
.1…
.00..
.000.
.1…
.1…
现在,在图例中重写此行:Flag = FlagRed or FlagWhite
我们可以创建一组对象。在这种情况下,Flag将为FlagRed或FlagWhite。虽然为分组对象中的至少一个对象分配了一个符号(我们为FlagRed分配了符号F),但是我们不需要将符号分配给该组的其他对象,并且您只能在代码中访问它们,而不能在关卡编辑器中访问它们。然后,您可以将碰撞层分配给组,我们已经完成了。对一组对象(例如,标志)的访问是指整个组。因此:
[ > Player | Flag ] -> [ > Player | ]
此代码将同时影响红色和白色标志。更改标志对象
以下是将FlagRed更改为FlagWhite的方法:late [ Player FlagRed ] -> [ Player FlagWhite ]
如果在回合结束时玩家处于红旗上,那么我们将其变为白色。但是,在创建断点之后,您需要更改标志图形,因为代码是从上到下读取的。测试程序。更改第二个标志
项目中有两个标志。让我们确保当第二个标志被激活时,旧的白色标志变成黑色,以便不能再次使用。我们编写以下内容:late [ Player FlagRed ][ FlagWhite] -> [ Player FlagRed ][FlagBlack]
代码说:如果玩家在红旗上,并且游戏中某处有白旗,则需要将白旗设为黑色。由于代码是从上到下读取的,因此我们需要按以下顺序进行:late [ Player FlagRed ] -> CHECKPOINT
late [ Player FlagRed ][ FlagWhite] -> [ Player FlagRed ][FlagBlack]
late [ Player FlagRed ] -> [ Player FlagWhite ]
如果您不明白为什么代码应该按此顺序排列,请尝试更改行的顺序并测试程序。为了解决您自己的问题,您需要学习退后一步并思考代码的作用。但是,我会给您一个提示-在您玩游戏时,以下错误示例中的最后一行代码中的红色标记在哪里?[ > Player | Crate ] -> [ > Player | > Crate ]
[ > Crate | Flag ] -> [ Crate | Flag ]
late [ Player FlagRed ] -> CHECKPOINT
late [ Player FlagRed ] -> [ Player FlagWhite ]
late [ Player FlagRed ][ FlagWhite] -> [ Player FlagRed ][FlagBlack]
在此处查看完成的示例项目。此外,我刚刚向您展示了最简单的动画制作方法。在下一部分中,我将讨论创建更复杂的动画,例如爆炸。第11部分。动画
有两种方法可以在PuzzleScript中创建动画。其中之一使用实时,但是在这一部分中,我不会谈论它。另一个用于快速的一次性动画,例如爆炸或角色从垂直梯子下降。打开一个示例项目。我们将创建炸弹和一系列爆炸镜头,然后对其进行动画处理。对象动画
对于2D动画,您需要从一个状态移到另一状态的多个对象绘图,例如正在运行的Mario的子画面。它包含4帧动画。为了模拟动画的一帧到另一帧的过渡,我们将在PuzzleScript中创建几个对象,这些对象将成为动画的帧,然后使用代码在它们之间进行切换。炸弹
创建一个炸弹对象。Bomb
black yellow grey
..1..
..1..
.000.
00020
.000.
请记住将其添加到图层和图例中。为了动画化爆炸,我们需要将动画的每个帧创建为一个单独的对象,然后在代码中在它们之间进行切换。让我们创建爆炸对象。Explosion1
black yellow grey red
..1..
..1..
.000.
00320
.000.
Explosion2
black yellow grey red
..1..
..1..
.333.
03330
.333.
Explosion3
black yellow grey red
..1..
.333.
33333
33333
.333.
Explosion4
black yellow grey red
.333.
33333
33333
33333
.333.
Explosion5
black yellow grey red
.333.
33333
33.33
33333
.333.
Explosion6
black yellow grey red
.333.
3...3
3...3
3...3
.333.
Explosion7
black yellow grey red
.....
.....
.....
.....
.....
它将正确编号对象,以便知道我们需要动画的哪一帧。将它们添加到图层和图例后,我们可以添加几行代码。[Explosion7] -> []
[Explosion6] -> [Explosion7]
[Explosion5] -> [Explosion6]
[Explosion4] -> [Explosion5]
[Explosion3] -> [Explosion4]
[Explosion2] -> [Explosion3]
[Explosion1] -> [Explosion2]
[Bomb] -> [Explosion1]
尝试添加此代码,然后在关卡上放置炸弹并开始游戏。您会注意到,炸弹动画每次移动都会改变一帧。在对象之间切换,我们创建动画。动画之间的切换顺序至关重要。最后一帧应位于顶部,第一帧应位于底部。不要忘了代码是从上到下阅读的。如果动画的帧顺序不同,那么我们将永远看不到这些变化。我们只会看到最后一帧,在我们的情况下,炸弹只会消失。即使在您看到图形之前,它将在一帧中更改为第一帧,然后更改为第二帧,依此类推。通过将最后一帧放置在开始处,我们将在每一个转弯处看到下一个变化。再次使用
为了使所有东西都在一起动画,我们再次需要一个团队。再次表示在读取所有代码之后,PuzzleScript将暂停,然后通过再次运行所有命令再次读取代码。它可用于重力,在冰上滑动,在我们的情况下可用于动画。所需要做的就是重写代码,如下所示:[Explosion7] -> []
[Explosion6] -> [Explosion7] again
[Explosion5] -> [Explosion6] again
[Explosion4] -> [Explosion5] again
[Explosion3] -> [Explosion4] again
[Explosion2] -> [Explosion3] again
[Explosion1] -> [Explosion2] again
[Bomb] -> [Explosion1] again
测试游戏。您将看到整个炸弹动画立即播放。如果您认为速度太慢或太快,则可以更改速度。在程序文本的开头,在主页下方,编写以下代码:again_interval 0.1
这是PuzzleScript称为prelude的一部分。在这里,在其余代码之前,您可以设置其他规则来确定游戏的行为。现在,动画应播放得更快。尝试在again_interval之后更改数字,并检查其是否已更改。您可以在此处看到完成的项目示例。第十二部分。重力
通常,PuzzleScript用于创建自上而下的游戏,但实际上,尽管使用了有限的PuzzleScript规则,但您仍可以逐步模拟侧滚动器的某些元素,即它们仍将是逐步的。在这一部分中,我将告诉您如何实现重力。项目实例
打开一个示例项目。我创建了一个简单的关卡,它有一个播放器,一个壁架上的盒子和一个下门。我们要确保当玩家从壁架上推箱子时,他会掉到地上。我们还希望玩家离开边缘时掉到地上。秋季第一阶段
这是我们将使用的代码的第一部分:down [ Player | no Object ] -> [ | Player ]
down [ Crate | no Object no Player ] -> [ | Crate ]
尝试从边缘推动盒子。您会注意到,移动后,盒子悬挂在空中,但是又移动了,它掉到了地上。这里发生了一些事情。首先,让我们谈谈down关键字。通过添加down,我们将规则限制为仅在向下方向上适用。这就是盒子向下移动的原因。如果更换下来的右侧,你会看到盒子卡在右侧壁,在与反重力游戏。尝试这样做。接下来,我们将做一些不寻常的事情。我们不检查玩家是否在特定对象(例如框)旁边,而是检查玩家是否在广义对象旁边。如果查看示例代码中的图例,您将看到我们已将对象定义为一组对象,也就是说,每次使用对象一词时,我们都意味着一组对象。也就是说,我们检查播放器下面是否有这些对象。如果不是,我们命令玩家占据这个空白区域,并由于向下的单词“ down”,留出前一个空间。但是,您还可以注意到,与壁架碰撞后,盒子才掉下来,直到下一个动作,它立即到达地面。要消除这种延迟的崩溃,可以使用late关键字:late down [ Player | no Object ] -> [ | Player ]
late down [ Crate | no Object no Player ] -> [ | Crate ]
但是如何使其逐渐逐帧下降呢?秋季第二阶段
现在我们使用random关键字。我们将代码重写如下:random down [ Player | no Object ] -> [ | Player ]
random down [ Crate | no Object no Player ] -> [ | Crate ]
运行代码。它的工作原理与先前的代码非常相似,但有一个重要的区别。盒子在空中冻结,但是玩家每次移动时,它都会掉落一个单元格。这是由于单词random所致。严格来说,random是用来创建具有随机元素的游戏的,但是在这里它派上了用场。它强制每转执行一次相应的代码行。PuzzleScript尽可能一次地执行每个规则,然后玩家才能看到图形变化。这就是为什么盒子立即掉到地上的原因。但是,当使用随机一词时,我们一次只能允许它落入一个单元格。秋季第3阶段
现在,我们将再次添加关键字:random down [ Player | no Object ] -> [ | Player ] again
random down [ Crate | no Object no Player ] -> [ | Crate ] again
启动游戏。一切都近乎完美。盒子在空中冻结了一段时间,但是如果再次移动,它会逐渐掉落到地面上。从本质上讲,我们已经很熟悉关键字了,这意味着在转弯结束时,PuzzleScript会再次读取代码并尝试以单独的方式再次执行所有命令,然后暂停并随后重复执行多次。这里重要的是他再次在转弯之间停顿,这使我们能够看到盒子掉落。最后阶段
和最后的接触。为了使盒子从边缘被推下后立即掉落到地面,我们需要在刚刚编写的代码之上添加另一行代码:[moving Player] -> [moving Player] again
random down [ Player | no Object ] -> [ | Player ] again
random down [ Crate | no Object no Player ] -> [ | Crate ] again
播放器前面方括号[]中使用的移动关键字表示我们正在检查播放器是否在移动。这意味着如果一名球员移动了,那么我们命令他继续移动并再次运营该团队。然后,立即再次使用该关键字的所有内容都将起作用;在我们的案例中,这是盒子倒下的动画。您可以在此处看到完成的项目示例。第13部分。检查行驶方向
方向指示
有时,您只需要检查一个方向。例如,您需要制作只能水平推动的块,或者创建只能向左走的鸭子。尽管如此,我们可以指示事件仅在某些方向发生。打开PuzzleScript,基于Basic示例创建一个游戏,并使用以下代码将其替换为Rules:[ Left Player ] -> [ Crate ]
启动游戏,看看会发生什么。如果您尝试向左走,播放器将变成一个盒子。这是定向工作原理的一个很好的例子。我们已经习惯了我解释PuzzleScript代码的格式:[ ] -> [ ]
如果事件为true,则事件发生。但是现在,当我们需要检查路线时,他将遵循新规则:[ Movement Direction Object Affected ] -> [ New State of Object ]
那是我们之前的代码:[ Left Player ] -> [ Crate ]
检查玩家是否向左移动(Left)。如果是这样,那么我们将播放器替换为box对象。目的地类型
您可以从以下类型的目的地中进行选择:- 上
- 往下
- 向左
- 对啊
- 水平(检查是否水平移动)
- 垂直(检查是否有垂直移动)
第14部分。创建自定义动作
由于某些原因,游戏可能需要自定义动作。鸭子只能向左走,盒子只能水平推,依此类推。这很容易做到。让我们再看一下基本的PuzzleScript代码格式:[ ] -> [ ]
如果条件为真,则发生事件。要创建自定义移动,您需要执行以下操作:[ Condition ] -> [ Movement Direction Object To Move ]
示例如下所示:[ Player | Crate ] -> [ Player | Left Crate ]
下载PuzzleScript,打开Basic示例,粘贴此代码,看看会发生什么。转到没有墙壁的盒子。您会看到,当玩家靠近盒子时,盒子被推到左侧。但是,由于没有Late关键字,因此在您迈出第一步之后的过程中会发生这种情况。在事件中指定对象时,除了对象之外,还可以移动对象的方向,例如Left,PuzzleScript会尝试沿指定方向移动对象。这就是为什么盒子而不是播放器向左移动的原因- 左边是Crate旁边。还记得上一部分的这段代码吗?[ ] -> [ ]
如果在对象旁边的状态下指示移动方向,则它将检查该对象是否沿该方向移动。这是一个重要的区别。您可以这样重写它:[ ] -> [ ]
允许的自定义移动
可以使用以下任何一个单词来创建自定义动作:您不能使用Horizontal或Vertical,因为PuzzleScript无法理解您要沿哪个方向移动对象,或者要这样做,将需要很多解决方法。有必要指出一个具体的方向。第15部分。检查对象旁边的单元格
有时有必要检查对象旁边的内容。 这很容易做到。
让我们再看一下PuzzleScript代码格式:[ ] -> [ ]
那就是[ ] -> [ ]
要检查对象的侧面,我们需要添加一个元素。格式如下:[ object1 | object2 ] -> [ object1 | object2 ]
在出现条件之前,我们检查要在对象的哪一侧执行检查。在条件内部,我们假设至少需要两个单元。实际上,一个单元就是在同一空间中而不是彼此相邻的任何对象。[ ]
[ | | ]
第一个单元格是我们要检查其侧面的对象。第二个单元格是我们正在检查其状态的对象。请尝试以下示例:Left [ Player | Crate ] -> [ Player | ]
如果框在播放器左侧的正方形中,则上面显示的代码将删除框。Left [ Crate | Crate ] -> [ Player | Crate ]
此代码检查该框是否在另一个框的左侧。如果是这样,则选中其侧面的框将成为玩家的新对象。Left [ Crate | Crate ] -> [ Crate | Player ]
上面的代码中有相同的复选框,但是左侧的框成为玩家的对象。Left [ Crate | Crate | Crate ] -> [ Crate | Player | Crate ]
此代码也使用类似的模式。如果3个框在水平方向上彼此相邻,则紧靠选中框左侧的框将成为玩家。Left [ Crate | Crate | Crate ] -> [ Crate | Crate | Player ]
如果3个框在水平方向上彼此相邻,则最左边的框成为播放器。如果您测试了每个示例,您将开始理解这种模式。第一个单元格是我们检查以查看下一个对象的对象。从最接近到最远的以下单元格是我们要检查的对象。关键词
- 向上-检查对象
- 下-检查对象下
- 左-检查对象的左侧
- 右-检查对象的右边
- 水平-检查对象的左侧和右侧
- 垂直-检查对象上方和下方