分享到新浪微博 分享到QQ空间 打印

[脚本] XSE脚本进阶教程【2010.03.12更新,修正了有关trainerflag的误导】

XSE脚本进阶教程【2010.03.12更新,修正了有关trainerflag的误导】

XSE脚本进阶教程


在熟练于基本脚本之后,大家是否开始想要更多更有趣的效果或是更加复杂的功能了呢?这里我将把一些更深入的脚本知识教给大家,使大家的改版更入流.

友情提示:如果您还没有足够的基本知识,请回到基本教程继续学习.

一、一些不错的效果
1.音乐
其实在游戏当中,音乐的适时出现总会给人清新的感觉.在脚本中,主要有四个命令负责音乐的启动.

第一种最为常用:fanfare
fanfare是一个只负责效果音的命令,比如PM被治疗时的声音、得到道具的声音等.它只有一个参数,即要触发的音乐编号.这个编号是游戏内部的,我们暂时没有一张详细的对照表.
我们来看一个例子:
001 #org @take
002 givepokemon 0x4 0x5 0x0 0x0 0x0 0x0
003 fanfare 0x13E
004 msgbox @3 0x4
005 waitfanfare
006 closeonkeypress
007 setflag 0x828
008 msgbox @4 0x5
009 compare LASTRESULT 0x1
010 if 0x1 gosub @name
011 msgbox @5 0x6
012 release
013 end
点击查看原始代码
这是一个脚本段,大家应该能看出fanfare是在主角得到PM后触发了得到PM的效果音.
那么
waitfanfare
closeonkeypress
是在做什么呢?
事实上,fanfare虽然是在瞬间触发的,但效果音却长达数秒.在这段时间里,waitfanfare命令便可以保持对话框健在,其后的closeonkeypress则恢复了对话框的控制,使其可以被关闭.
一般来说fanfare和waitfanfare总是成对出现的,但closeonkeypress则只在有对话框参与时才需要.
引用:
两个常用的fanfare:
fanfare 0x100  治愈PM效果音
fanfare 0x13E  得到PM效果音
第二种触发音乐的命令就是playsong.
playsong是一个负责播放背景音的命令,它同样只有一个参数但却需要额外补上一个0x0作为填充字节.
例子:
001 #org @1
002 lock
003 faceplayer
004 ......
005 ......
006 playsong 0x13E 0x0
007 release
008 end
点击查看原始代码
大体如此.playsong的这个唯一的参数同样代表曲目编号,但这里的编号与fanfare完全不同(应该是因为乐曲库不同的缘故吧),需要从AM或sappy中自行查找.

第三种是fadesong.
fadesong和playsong可以说是孪生兄弟了,因为其作用几乎完全相同,只是不再需要填充字节.
另:fadesong的音乐转变似乎是淡出淡入的...

这里大家注意下,playsong和fadesong都是单向命令,也就是说它播放的音乐要持续到地图重新刷新音乐,其间不会自动还原,所以如果要还原则需要再度调用它们载入该地图的背景乐.

最后一种最为轻量:cry.
cry是专门负责播放PM叫声的一个命令,它需要一个参数──PM的内部编号(HEX),以及一个填充字节(事实上并不是填充,而是一个很不稳定的参数,在此大家把它作为填充对待即可).
例子:
001 #org @start
002 lock
003 faceplayer
004 msgbox @1 0x6
005 cry 0x6 0x0
006 wildbattle 0x6 0x0 0x1E 0x8B 0x0
007 release
008 end
点击查看原始代码
虽然说游戏里的PM叫声都很次,但有这么一声似乎更合适...

2.屏幕变化
有时候为了剧情的需要,我们会希望屏幕能够黑那么一下.这样的命令其实是存在并且十分好用的.
屏幕只有一个命令,即fadescreen,它只有一个参数,表示不同的变化.
引用:
0x0 使屏幕由黑会到原状
0x1 使屏幕变黑
0x2 使屏幕由白会到原状?0x3 使屏幕变白
使用范例:
001 #org @start
002 lock
003 faceplayer
004 msgbox @1 0x6
005 cry 0x6 0x0
006 wildbattle 0x6 0x0 0x1E 0x8B 0x0
007 fadescreen 0x1'使屏幕变黑
008 fadescreen 0x0'使屏幕由黑会到原状
009 msgbox @2 0x6
010 release
011 end
012  
013 #org @1
014 = CHARIZARD: Raaarrgghh!
015  
016 #org @2
017 = God...
点击查看原始代码
二、涉及坐标的命令
引用:
关于"屏幕坐标"
"屏幕坐标"是一个比较抽象的概念,它是一个虚构建立在GBA屏幕上的一个坐标轴.它以屏幕的左上角为原点,以屏幕上线为X轴并以右为正方向,以屏幕左线为Y轴并以下为正方向.所以,左上角即可记为(0,0).
当然,屏幕并不是无限大的,我们在取用的时候要注意不要太过分.
1.显示PM的图片
还记得在大木博士那里挑选PM的情景吗?每当我们选择一只PM时,都会在屏幕上出现该PM的图片(早期没有汉化版时可以靠它来搞清自己选的什么...).
显示PM图片的整个过程需要2个命令:
引用:
showpokepic 负责显示
hidepokepic 负责关闭它
来看实例:
001 .........
002 .........
003 showpokepic 0x01 0x0A 0x03
004 msgbox @1 0x5
005 compare 0x800D 0x1
006 if 0x1 goto @seen
007 hidepokepic
008 msgbox @2 0x6
009 .....
010 .....
011  
012 #org @seen
013 hidepokepic
014 msgbox @3 0x6
015 .........
016 .........
017  
018 #org @1
019 = Have you seen this Pokemon?
020  
021 #org @2
022 = That's too bad.
023  
024 #org @3
025 = That's cool. I wish I could\nsee it.
点击查看原始代码
可以看到hidepokepic没有参数,那么showpokepic后面跟的是什么呢?
引用:
showpokepic [PM] [X 坐标] [Y 坐标]
幸好有前面的知识铺垫,以上的参数应该比较好理解了.(均为HEX)
一般我们都会取屏幕中心来放图,所以坐标是这样的:(10,3).换成HEX就是0x0A 0x03了.


2.金钱命令

呵呵,大家盼这个命令有多久了呢?
赶快来看看用法:
引用:
给玩家金钱 givemoney [金额] 0x00 '0x00其实是个比较麻烦的参数,我们不去详细研究了

从玩家那扣除金钱 paymoney [金额] 0x00 '0x00同上

检查玩家身上是否有这些金钱 checkmoney [金额] 0x00 '0x00同上.这个命令和checkflag一样会返回一个值来表示足(0x1)或不足(0x0)

显示一个包含有玩家身上金额的框 showmoney [X 坐标] [Y 坐标] 0x00 '0x00同上.

关闭上述的框 hidemoney [X 坐标] [Y 坐标] '注意,没有0x00

更新上述框中的金额为当前值 updatemoney [X 坐标] [Y 坐标] 0x00 '0x00同上.

提示:[金额]为HEX.
3.硬币命令
硬币命令和金钱命令十分相似.
引用:
给玩家硬币 givecoins [数目]

从玩家那扣除硬币 removecoins [数目]

检查玩家身上是否有这些硬币 checkcoins [数目]

显示一个包含有玩家身上硬币数量的框 showcoins [X 坐标] [Y 坐标]

关闭上述的框 hidecoins [X 坐标] [Y 坐标]

更新上述框中的数目为当前值 updatecoins [X 坐标] [Y 坐标]

提示:[数目]为HEX.
关于"地图坐标"
和"屏幕坐标"的定义很相似,只不过"地图坐标"是在整张地图上建立坐标系而已.
当然"地图坐标"的坐标值不需要数,因为AM已经给我们提供好了,如图:


4.门命令

门命令充其量只能算得上是移动命令的辅助命令,它的作用就是打开地图上指定的门.当然,你也可以拿它做点别的特效.

门命令实际上不是一个命令,而是一个几命令共同完成的.
引用:
setdooropened 准备打开
setdoorclosed 准备关闭
doorchange 激活动画
其用法分别是这样的:
引用:
setdooropened [X 坐标] [Y 坐标]
setdoorclosed [X 坐标] [Y 坐标]
doorchange '无参数
这里注意了,坐标指的是地图坐标,而不是屏幕坐标.其指向的就是门.
来看实例:
001 #org @e
002 ......
003 ......
004 setdooropened 0x10 0x0D
005 doorchange
006 applymovement 0xFF @move
007 waitmovement 0x0
008 setdoorclosed 0x10 0x0D
009 doorchange
010 ......
011 ......
点击查看原始代码
这里的门命令和移动命令很好的结合在了一起.



5.天气命令
在学习下一个麻烦的命令之前,我们先来看一个简单的命令吧.
天气命令的作用就是在脚本中实时的改变游戏的天气,但这种改变会在地图刷新时恢复.
和门命令比较相似的是,天气命令同样也是多个命令协作成.

用法:
引用:
setweather [天气]
doweather'无参数
惟有2条命令都执行,天气才会改变.

关于参数天气:


实例:
001 #org @start
002 checkflag 0x200
003 if 0x1 goto @next
004 setweather 0x3
005 doweather
006 setflag 0x200
007 release
008 end
009  
010 #org @next
011 setweather 0x2
012 doweather
013 clearflag 0x200
014 release
015 end
点击查看原始代码
这里的脚本将变天为雨天.

当然,我们还有一个还原地图天气的命令:resetweather(无参数),同样的,它要实现也需要doweather来激活.




6.瞬移命令
提到瞬移命令大家可能立刻就会联想起移动命令来,不过它们却是两回事.瞬移命令是一种我以前几乎没提过一种命令,其作用是把主角从一张地图瞬间移动到另一张地图.
这样的命令一般在普通的脚本中并不露面,但当剧情发生在不止一张地图时,它便登场了.

不过瞬移命令有很多种,其效果各不相同,我们首先来看最基本的:
引用:
warp [地图库号] [地图号] [出口号] (X坐标) (Y坐标)
这里的参数比较复杂,我想我得详细的说明一下:
warp的5个参数全部来自于AM.
首先,[地图库号] [地图号]可以从下图所示得到:

注意,前面的为地图库号,后面的为地图号;比如(3,0)中3为地图库号,0为地图号.

而[出口号]则从下图位置得到:

这里的[出口号]其实在AM中是可以定制的,具体大家可以稍微摸索一下.
(X坐标) (Y坐标)则是地图坐标.

咳、咳,注意了,相信大家一定在疑惑warp究竟会把主角送到哪呢?其实warp的参数很有意思,它的(X坐标) (Y坐标)是变相可选的.
当我们在[出口号]中写明一个出口的编号时,warp会把主角从该出口送出(如果是一个门,则主角开门出来;若是其它,则直接出现在那里),此时的(X坐标) (Y坐标)无论写什么都不会奏效,但这个位置必须写东西.
例如:
001 #org @1
002 lock
003 faceplayer
004 warp 0x3 0x0 0x1 0x0 0x0'瞬移到主角家门口
005 release
006 end
点击查看原始代码
而当我们在[出口号]中写0xff时,warp则将主角送别指定的坐标,即随后的(X坐标) (Y坐标).此时的(X坐标) (Y坐标)不能乱写.
例如:
001 #org @1
002 lock
003 faceplayer
004 warp 0x3 0x0 0xff 0x1 0x1'瞬移到地图左上角(会被卡死...
005 release
006 end
点击查看原始代码
特别的,warp [地图库号] [地图号] 0xff 0xff 0xff会把主角送至该地图的正中央.

另外,warp命令有一个极其特殊的地方:一旦成功执行,其后的脚本都自动无视.即:
001 #org @1
002 lock
003 faceplayer
004 warp 0x3 0x0 0xff 0x1 0x1
005 checkflag 0x200
006 if 0x1 goto @next
007 setweather 0x3
008 doweather
009 setflag 0x200
010 release
011 end
点击查看原始代码
完全等同于:
001 #org @1
002 lock
003 faceplayer
004 warp 0x3 0x0 0xff 0x1 0x1
点击查看原始代码
注:之前的warp脚本中仍写有release,end是出于礼貌,并非必须.

有了以上的认识,我们来看看剩下的瞬移命令:
引用:
无声的:warpmuted [地图库号] [地图号] [出口号] (X坐标) (Y坐标)
走路效果:warpwalk [地图库号] [地图号] [出口号] (X坐标) (Y坐标)
传送效果:warpteleport [地图库号] [地图号] [出口号] (X坐标) (Y坐标)
另一种传送效果:warpteleport2 [地图库号] [地图号] [出口号] (X坐标) (Y坐标)
掉进洞中的效果:warphole [地图库号] [地图号]'该命令不支持位置选择.
7.交易脚本

是否研究过商店的运作原理呢?当我们和一个服务员对话时,事实上我们进入了一个交易脚本.
交易脚本的主体就是交易命令,它负责触发一次"买"事件,并展开一张定制的菜单.
引用:
用法:
pokemart @somewhere'这个结构和移动脚本类似,只是这里指向的地址是物品清单.
...
...
#org @somewhere
#raw word [值1]
#raw word [值2]
......
#raw word 0x0
清单中的[值]实际上是道具的编号,而最末的0x0则是清单结束的标志.

实例:
001 #org @start
002 lock
003 faceplayer
004 pokemart @values
005 release
006 end
007  
008 #org @values
009 #raw word 0x1
010 #raw word 0x2
011 #raw word 0x3
012 #raw word 0x4
013 #raw word 0x5
014 #raw word 0x6
015 #raw word 0x7
016 #raw word 0x8
017 #raw word 0x9
018 #raw word 0xA
019 #raw word 0xB
020 #raw word 0xC
021 #raw word 0x0
点击查看原始代码
以上的脚本将售出多种PM球.遗憾的是,物品的价格我们无法操纵...

8.图腾脚本

呵呵,这次真是一个小品级的脚本了...图腾脚本就是让对话框中输出的文字变为图腾样.

实际上完全是braille命令在唱主角...
直接看例子吧,注释应该到位了:
001  
002  
003 #org @start
004 lock
005 faceplayer
006 message @3 MSG_NORMAL '必须前置一个对话框
007 braille @4 '指向要变为图腾的文字
008 waitkeypress'使得文本可关闭
009 release
010 end
011  
012 #org @3
013 = There is something strange on the stone...
014  
015 #org @4
016 #braille abcdefg
点击查看原始代码
关于special,special2
special不是一个命令,而是一类效果命令.special提供了许多方便的功能且使用简单,一般的,special 0xn即可表达一个special命令.不同的n值将产生不同的效果.
目前仍有相当的special处于未知状态,而有些special则很常见:
引用:
      special 0x0 - 恢复PM
      special 0x3C - 进入PM存储系统 (FR/LG)
      special 0x98 - 览车 (R/S)
      special 0x10F - 游戏重启
      special 0x110 - 胜利殿堂
      special 0x111 - 电梯动画
      special 0x131 - 地震 (R/S)
      special 0x132 - 显示楼层
      special 0x136 - 地震 (FR/LG)
      special 0x137 - 教学战
      special 0x156 - 触发幽灵 (FR/LG)
      special 0x157 - 骑车 (FR/LG)
      special 0x161 - 冲浪 (FR/LG)
      special 0x16F - 激活全国图鉴 (FR/LG)
      special 0x17B - 快艇动画
      special 0x191 - 圣安奴号离开
      special 0x1F3 - 激活全国图鉴 (Emerald)
至于用法呢,就是把special插入脚本即可.
special2和special很类似,但是除了完成特定的功能之外还会反馈一个值,并且把这个值储存在你想储存的变量当中(通常我们会存在0x800开头的几个运行变量中)。
比如:
special2 0x800D 0x12

9.定点教学脚本
定点教学是火叶才引入的要素,增加了PM成长的趣味性.而我们通过脚本是可以随意设置定点教学的.
其实说起来,定点教学脚本已经不是单个命令所能写成的了,而是很多命令组合出来的.以后大家在用的时候把范例当作模板来套.
001 #org @Start
002 lock
003 faceplayer
004 checkflag 0x200'只是一个用来确定事件是否发生过的flag
005 compare LASTRESULT 0x1
006 if 0x1 goto @AlreadyLearnt
007 msgbox 0x5 @WantToLearn
008 compare LASTRESULT 0x0
009 if 0x1 goto @DontWant
010 setvar 0x8005 0x1 ' 0x[定点招式编号(0~F)],这里是在变量0x8005中写入了之后要调用的招式号
011 special 0x18D'这是一个很好的special,它会完成包括选PM、学习招式的整个过程.
012 setflag 0x200
013 release
014 end
点击查看原始代码
这里注意了,所谓的定点招式编号和之前的招式编号完全是两个概念.火叶的定点招式编号都是定值,如果想要改,推荐用以下这个小程序:

这个程序非常简单易用,相信大家很快就能上手。
另外该程序目前只支持火红美版……

10.训练师脚本的重复触发

在初级教程当中,我曾提到过训练师标识(trainerflag)。游戏为了防止训练师脚本不止一次地被触发,于是就用训练师标识来区别已经发生过的训练师战斗和未曾发生过的训练师战斗。借助Advance Trainer,我们可以知道,训练师信息在ROM里大概是这样的形式:
引用:
训练师编号 名字 性别 所用训练师图片编号 战斗音乐编号 训练师组别 金钱赠予级别 其它信息(…)
注:这里指的是最一般类型的训练师,战斗塔、战斗边疆等特殊训练师除外

ROM里有一张大表来存放这些信息,其中的训练师编号是唯一的,其它都可以重复。“一个训练师”可以有多组信息,这样在游戏里,就好象反复与这个训练师战斗,并且它的精灵什么的也是在变强的。而所谓“一个训练师”是我们在游戏里看到的一个训练师,并不是说可以让训练师编号重复。

以火叶中的对手(小茂)为例,对手在和玩家都得到PM之后就发生了一场战斗,那么这张表里就里就会有这场战斗对手的信息,而在之后对手变强了又和玩家有一战,那么表里又会有这样的一组信息。

训练师战斗脚本命令通常只需要这组信息里的训练师编号就可以了。
引用:
命令RAW:0x5C
命令名称:trainerbattle
命令说明: 触发一个训练师战斗,根据战斗类型的不同,最后一个参数也会有所不同
占用字节:14 字节
参数及类型:
[字节]-战斗类型
[字]-触发的训练师编号
[字]-保留参数
[指针]-挑战文本的指针
[指针]-战败文本的指针
其中的第二个参数就是我们的训练师编号。

不过每当该训练师编号被唤起战斗之后,这个训练师的flag就会被清除。以下列脚本为例:
001 #org @start
002 trainerbattle 0x0 0x001 0x0 @before @after
003 msgbox @beaten 0x6
004 release
005 end
006  
007 #org @before
008 = Go, all my PIKACHUs!
009  
010 #org @after
011 = Nooo! My PIKACHUs!!!!!
012  
013 #org @beaten
014 = My PIKACHUs can be used to\ncharge my Nintendo DS Lite.
点击查看原始代码
一旦被触发之后再和这个人物对话,那么出现的对话就一定是@beaten的内容了,不会再次发生战斗。
那么如何才能再次战斗呢?这就需要我们再次设立这个训练师标识。
我曾经以为trainerflag和一般的flag一样,要靠clear来进行清除才能继续战斗,但事实是,只有一个训练师的trainerflag被设定之后,才能进入战斗;而一旦trainerflag被清除,则战斗无法发生
相关命令其格式如下:
001 settrainerflag [训练师编号]
点击查看原始代码
以上面脚本中的训练师为例,使战斗再度可行就需要这样:
001 settrainerflag 0x001
点击查看原始代码
而如果需要在不战斗的前提下就使得训练师标识被设置,则需要:
001 cleartrainerflag [训练师编号]
点击查看原始代码
另外,如果希望这次脚本触发的战斗恰好是上一次的战斗,那么可以这样:
001 repeattrainerbattle
点击查看原始代码
注意这个命令没有参数要求,触发的就是上一次的战斗。


二、高等脚本

1.人物的控制脚本

基础教程中我们一起研究过了人物的移动脚本.移动脚本可以使人物更加逼真的进行走动.但很多时候我们需要的不仅仅是走动.

首先来说说人物的机械移动吧.曾经有人问我,如何让一个人物在进入地图时就待在一个固定的位置?大家第一时间想到的可能是AM中的设置,如此确实是一种办法,但这种就剥夺了人物在我们看到后的自由权,画面会很生硬.那么怎么做呢?我们用地图脚本(Level script)加机械移动脚本就可以搞定了.
在本节的学习中,我们暂且放下地图脚本,先来看看简单的机械移动吧.

机械移动在移动人物时将不再带有动画效果,因此立竿见影.

用法:
movesprite [人物编号] [X 坐标] [Y 坐标]

其中[人物编号]与移动脚本相同,[X 坐标] [Y 坐标]均为地图坐标.

实例:
001 movesprite 0x4 0xC 0x5
点击查看原始代码
接下来我们来说说人物的消失与出现吧.因为5944已经讲给大家了,这里就从略了.不过这里还是有些需要关注的细节.

人物的消失事实上分为两种:暂时消失、长期消失.
暂时的消失只需要一个命令:hidesprite [人物编号].
hidesprite的参数极其简单,只是[人物编号].比如:hidesprite 0x04
这里还有个小技巧,当我们之前的脚本已经触发了一个人物时,hidesprite 0x800F会直接让其消失.因为此时的变量0x800F被系统写入了那个人的ID.
长期的消失比短暂消失只多了一步:setflag.
很多人搞不清楚flag和人物有什么关系,其实我们没必要弄清楚.我们需要做的就是在AM的下图位置处为人物设置一个空闲的flag:

另外,当一个flag既被你当作剧情标识又为某个人物消失而用时,它们同时生效.

例:
001 #org @1
002 lock
003 faceplayer
004 msgbox @2 0x6
005 hidesprite 0x800F
006 setflag 0x810
007 release
008 end
点击查看原始代码
与以上相反的是人物的再现.
大家主要记一个简单命令:showsprite [人物编号]
而对于使用flag设置的消失,只需clearflag它就OK了.

2.地图块脚本

同样是5944介绍过的一个命令,这里取名"地图块脚本"主要还是了防止和真正的地图脚本混淆...
地图块脚本的主体就是setmaptile,其格式为:
setmaptile [X 坐标] [Y 坐标] [图块编号] [移动许可]

其中的[X 坐标] [Y 坐标]为地图坐标,[图块编号] [移动许可]则分别可由下图位置得到:



大家在用setmaptile的时候可以放开些,可以一次堆上很多个.另外在setmaptile后追加special 0x8E可以实现地图的即时刷新,否则地图的变化只有在地图重新载入时才能显现.

例子:
001 #org @start
002 setmaptile 0x0E 0x13 0x1 0x0
003 setmaptile 0x0F 0x13 0x1 0x0
004 setmaptile 0x0A 0x13 0x1 0x0
005 setmaptile 0x0B 0x13 0x1 0x0
006 setmaptile 0x0C 0x13 0x1 0x0
007 special 0x8E
008 release
009 end
点击查看原始代码
变量专题

考虑到变量还从来没有具体说过,我决定在讲Level Script之前还是写一个专题,便于大家理解其用法.这样在以后的教程中,它的使用我就不再多说了.
变量(Variable,简称Var)是一个用来存放数值的一种"空间".就像一个盒子,用来放东西.你可能会有疑问,我们为什么要在脚本里存放数值呢?来看实例:
001 special2 0x800D 0x17C
002 compare 0x800D 0x1
003 if 0x1 goto @have
点击查看原始代码
special2配合0x17C可以得出队伍中PM的数量,这个数量我们可能在后续的脚本中需要进行比较,以判断是否给主角某只精灵.
这个数量在脚本设计的时候我们并不知道会是多少,因为玩家可能是带着6只PM,也可能只有1只,所以为了进行比较,我们只好把得到的这个数量保存在一个地方,它就是变量.
大家把变量可以看作是数学中的未知数,使用变量就是在不断对其赋值、运算.
在进行深入的讨论之前,我们先来把逻辑运算和数字运算分开.所谓数字运算就是+-×÷等一般的运算;而逻辑运算我们这里只需要知道一种,就是比较(其实我把逻辑运算没怎么弄清楚,说错的话希望大家指正...)
比较是怎样一种运算呢?其实就是比较两个数字的大小关系.
脚本中的变量既可以进行比较,也可以进行+和-.
下面我们来看看具体用法.

变量赋值:
这个最为简单,
setvar [变量名] [变量值]
例:
001 setvar 0x800D 0x1
点击查看原始代码
变量值加减:
addvar [变量名] [要加上的值]
例:
001 setvar 0x800D 0x1
002 addvar 0x800D 0x1'现在0x800D值为0x2
点击查看原始代码
subvar [变量名] [要减去的值]
例:
001 setvar 0x800D 0x1
002 subvar 0x800D 0x1'现在0x800D值为0x0
点击查看原始代码
变量间复制:
copyvar [被覆盖的变量] [被复制的变量]
例:
001 setvar 0x800D 0x1
002 setvar 0x8008 0x5
003 copyvar 0x800D 0x8008'现在变量0x800D成了0x5,而变量0x8008依旧为0x5
点击查看原始代码
copyvarifnotzero [被覆盖的变量] [被复制的变量]
假定有copyvarifnotzero A B
那么这个命令只有在B不为0x0时才发生复制行为否则二者均不变.

变量值比较:
compare [变量名] [值]
例:
001 setvar 0x800D 0x1
002 compare 0x800D 0x2
003 if 0x0 goto @2'这个跳转必然实现,因为0x1必然小于0x2
004  
005 #org @2
006 ...
点击查看原始代码
再次回顾一下if后值的逻辑意义:
小于(0x0)
等于(0x1)
大于(0x2)
小于等于(0x3)
大于等于(0x4)
不等于(0x5)

变量的值在脚本运行其间一般是不会显示出来的,它只是在系统内部运转,即使是message命令也不能直接显示变量.但我们用一些特殊的办法可以实现变量的显示.这一点我们先按下不讲,后面我在buffer命令组里会专门提到.

变量的小应用:
getplayerpos
前面我们提到过地图坐标,这里的getplayerpos可以获得主角在游戏中的坐标值并将其写入变量:
getplayerpos [写入X坐标的变量] [写入Y坐标的变量]
例:
001 getplayerpos 0x4000 0x4001
点击查看原始代码
random
random命令可以生成随机数,利用它加上其它脚本,我们甚至可以创造自己的幻岛!
random [值上限]'值下限只能为0x0,生成的值自动存入变量0x800D
例:
001 random 0x03
002 compare 0x800D 0x0
003 if 0x1 goto @option1
004 compare 0x800D 0x1
005 if 0x1 goto @option2
006 compare 0x800D 0x2
007 if 0x1 goto @option3
点击查看原始代码
如果你仍旧没能理解变量的用途,那么请继续欣赏以下的实例,领悟"变量是为了让脚本更丰富强大"这个观点:

用变量给脚本增添活性:
001 #org @start
002 givepokemon 0x19 0x5 0x0 0x0 0x0 0x0
003 end
点击查看原始代码
这是一个极其简单的PM赠送脚本,但这个脚本很死板,想象我们要使玩家得到的PM更丰富,那么在有限的ROM空间里,我们就不得不多次写下不同的赠送命令,比如这样:
001 #org @start
002 givepokemon 0x16 0x5 0x0 0x0 0x0 0x0
003 ......
004 givepokemon 0x17 0x5 0x0 0x0 0x0 0x0
005 ......
006 givepokemon 0x18 0x5 0x0 0x0 0x0 0x0
007 ......
008 givepokemon 0x19 0x5 0x0 0x0 0x0 0x0
009 ......
010 ......
011 end
点击查看原始代码
加上省略掉的判断和跳转脚本,一个本来很有趣的脚本竟然成了一项如此奢侈费神的工程.

观察上述脚本我们很容易发现,赠送命令本身只有一个参数在发生变化.就像前面说过的,我们可以设想一个未知数X来替代这个参数,它就是变量:
001 #org @start
002 random 0x3'在更现实的脚本中,变量值很可能是由一个综合选择命令所得到的.关于综合选择命令,我们后面会说到
003 addvar LASTRESULT 0x16'铭记,LASTRESULT就是变量0x800D的别称
004 givepokemon LASTRESULT 0x5 0x0 0x0 0x0 0x0
005 end
点击查看原始代码
有趣么?变量竟然可以替代参数!
尽管这段脚本的随机性很大,但它却能大大节省掉一笔空间开支.
001 #org @main
002 random 0xF
003 giveitem 0x800D 0x1 0x0
004 end
点击查看原始代码
好了,在16个道具中随机得到吧!
001 #org @main
002 random 0xF
003 copyvar 0x4001 LASTRESULT
004 addvar 0x4001 0x89'不难看出,前面给出的那些关于变量的命令其实就是为了更好的对变量进行运算,倘若没有addvar,copyvar等命令,这里就很难实现了.
005 giveitem 0x800D 0x4001 0x0
006 end
点击查看原始代码
干脆连数量也随机吧!

PS:我也不清楚是否所有的命令参数都能用变量替代,有兴趣的朋友自己动手试试吧



一个很好的变量综合利用实例:
首先这里得讲一下综合选择命令.综合选择命令是是/否疑问命令的拓展,它最终是这样的:


其格式为:
multichoice [x坐标] [y坐标] [列表编号] [是否可被取消]

详细的来说,这个命令其实只是调出了一个带指针的列表,X,Y坐标决定其位置.而表中的每个选项则早已储存于ROM,由ID来调用.最后一个参数如果为0x0则在选择时可按B退出,否则B无效.最终,选择的结果会被储存在变量0x800D中.
以下为列表(火叶用,宝石暂无):
引用:
      [00] - Yes
      No
      [01] - Eevee
      Flareon
      Jolteon
      Vaporeon
      Quit looking.
      [02] - Normal
      Black
      Pink
      Sepia
      [03] - Hall of Fame
      Quit
      [04] - Eggs
      Quit
      [05] - Victories
      Quit
      [06] - Hall of Fame
      Eggs
      Quit
      [07] - Hall of Fame
      Victories
      Quit
      [08] - Eggs
      Victories
      Quit
      [09] - Hall of Fame
      Eggs
      Victories
      Quit
      [0A] - Exit
      [0B] - Exit
      [0C] - Exit
      [0D] - Bicycle $1,000,000
      No Thanks
      [0E] - Abra 180 coins
      Clefairy 500 coins
      Dratini 2,800 coins
      Scyther 5,500 coins
      Porygon 9,999 coins
      No Thanks
      [0F] - SLP
      PSN
      PAR
      BRN
      FRZ
      EXIT
      [10] - Yes
      No
      Info
      [11] - Single battle
      Double battle
      Multi battle
      Info
      Exit
      [12] - Yes
      No
      Info
      [13] - Make a Challenge
      Info
      Exit
      [14] - Rooftop
      B1F
      Exit
      [15] - Helix Fossil
      Exit
      [16] - Dome Fossil
      Exit
      [17] - Old Amber
      Exit
      [18] - Helix Fossil
      Old Amber
      Exit
      [19] - Dome Fossil
      Old Amber
      Exit
      [1A] - Fresh Water $200
      Soda Pop $300
      Lemonade $350
      Exit
      [1B] - 50 coins $1,000
      500 coins $10,000
      Exit
      [1C] - Excellent
      Not So Bad
      [1D] - Right
      Left
      [1E] - TM13 4,000 coins
      TM23 3,500 coins
      TM24 4,000 coins
      TM30 4,500 coins
      TM35 4,000 coins
      No Thanks
      [1F] - 5F
      4F
      3F
      2F
      1F
      Exit
      [20] - Fresh Water
      Exit
      [21] - Soda Pop
      Exit
      [22] - Fresh Water
      Soda Pop
      Exit
      [23] - Lemonade
      Exit
      [24] - Fresh Water
      Lemonade
      Exit
      [25] - Soda Pop
      Lemonade
      Exit
      [26] - Fresh Water
      Soda Pop
      Lemonade
      Exit
      [27] - Trade Center
      Colosseum
      Exit
      [28] - Game Link Cable
      Wireless
      Exit
      [29] - Smoke Ball 800 coins
      Miracle Seed 1,000 coins
      Charcoal 1,000 coins
      Mystic water 1,000 coins
      Yellow flute 1,600 coins
      No Thanks
      [2A] - B1F
      B2F
      B4F
      Exit
      [2B] - Linked game play
      Direct Corner
      Union Room
      Quit
      [2C] - Two Island
      Three Island
      Exit
      [2D] - One Island
      Three Island
      Exit
      [2E] - One Island
      Two Island
      Exit
      [2F] - Trade Center
      Colosseum
      Berry Crush
      Exit
      [30] - Nada
      Nada
      Exit
      [31] - Pokemon Jump
      Dodrio Berry-Picking
      Exit
      [32] - Trade Center
      Colosseum
      Exit
      [33] - 2 Tinymushrooms
      1 Big Mushroom
      [34] - Trade Center
      Colosseum
      Berry Crush
      Exit
      [35] - Trade Center
      Colosseum
      Exit
      [36] - Sevii Islands
      Navel Rock
      Exit
      [37] - Sevii Islands
      Birth Island
      Exit
      [38] - Sevii Islands
      Navel Rock
      Birth Island
      Exit
      [39] - One Island
      Two Island
      Three Island
      Exit
      [3A] - Vermilion
      Two Island
      Three Island
      Exit
      [3B] - Vermilion
      One Island
      Three Island
      Exit
      [3C] - Vermilion
      One Island
      Two Island
      Exit
      [3D] - Vermilion
      Exit
      [3E] - Blank
      Blank
      Exit
      [3F] - Join Group
      Become Leader
      Exit
      [40] - Single
      Double
      Knockout
      Mixed
      Exit
以上的选项都是可以用UE手工修改的,所以这个表只是便于搜索罢了.
具体应用:
001 msgbox2 @question'大家记住这个模式,以后照搬就是了
002 waitmsgbox
003 multichoice 0xE 0x0 0x1E 0x0
004 copyvar 0x8000 0x800D
005 compare 0x8000 0x0
006 if 0x1 goto @option1
007 compare 0x8000 0x1
008 if 0x1 goto @option2
009 compare 0x8000 0x2
010 if 0x1 goto @option3
011 compare 0x8000 0x3
012 if 0x1 goto @option4
013 compare 0x8000 0x4
014 if 0x1 goto @option5
015 compare 0x8000 0x5
016 if 0x1 goto @option6
017 compare 0x8000 0x7F'点B取消回答的情况
018 if 0x1 goto @canceled
019 end
020  
021 #org @question
022 = What do you want?
点击查看原始代码
有了上面的铺垫,来看变量的综合利用吧:
001 #org @start
002 lock
003 faceplayer
004 msgbox2 @question
005 waitmsgbox
006 multichoice 0xE 0x0 0x1E 0x0
007 copyvar 0x8000 0x800D
008 compare 0x8000 0x0
009 if 0x1 goto @option1
010 compare 0x8000 0x1
011 if 0x1 goto @option2
012 compare 0x8000 0x2
013 if 0x1 goto @option3
014 compare 0x8000 0x3
015 if 0x1 goto @option4
016 compare 0x8000 0x7F
017 if 0x1 goto @option4
018 end
019  
020 #org @option1
021 message @A 0x6
022 random 0x64
023 givepokemon 0x3 0x800D 0x0
024 end
025  
026 #org @A
027 = It's an answer...
028  
029 #org @option2
030 message @B 0x6
031 random 0x63
032 giveitem 0x1 0x800D 0x0
033 end
034  
035 #org @B
036 = Maybe...
037  
038 #org @option3
039 message @C 0x6
040 random 410
041 addvar 0x800D 0x1
042 givepokemon 0x800D 0x64 0x0
043 end
044  
045 #org @C
046 = Good,I like you!
047  
048 #org @option4
049 addvar 0x4001 0x1
050 compare 0x4001 0x64
051 if 0x1 goto @good
052 message @D 0x6
053 end
054  
055 #org @D
056 = You're so boring...
057  
058 #org @good
059 compare 0x4001 0x64
060 if 0x2 goto @end
061 subvar 0x4001 0x63
062 giveitem 0x4001 0x1
063 message @E 0x6
064 end
065  
066 #org @D
067 = Okay,Okay,/nI'll give you something...
068  
069  
070 #org @end
071 end
072  
073 #org @question
074 = What do think of Pokemon?
点击查看原始代码
附件: 您所在的用户组无法下载或查看附件
本帖最近评分记录
  • chaotix PT币 +20 我终于忍不住加了 支持+崇拜 2009-4-7 21:23
  • roywillow PT币 +20 恶意灌水 2009-4-5 17:32
  • 海洋之囧 PT币 +10 严重支持ing…… 2009-4-5 12:06


想死你们了!

TOP

进阶教程等了好久了~
继续跑来支持~
MS硬币命令米有见过
中考完毕,暑假开始。

TOP

啊!嗯?进阶教程.........不错不错,里面的内容应该值得我再去打印一下了........
硬币命令?硬币是ROM里面的游戏币吗?
本人对那个游戏厅不感兴趣......
本帖最近评分记录
  • roywillow PT币 +20 是金钱吧……? 2009-4-5 17:34
简约唯美

TOP

引用:
原帖由 pokemon002 于 2009-4-5 12:57 发表
啊!嗯?进阶教程.........不错不错,里面的内容应该值得我再去打印一下了........
硬币命令?硬币是ROM里面的游戏币吗?
本人对那个游戏厅不感兴趣......
呵呵,我会慢慢加进去更多有用有意思的东西的~


想死你们了!

TOP

顺便再问一下,那个sappy中的音乐编号代码是不是这个教程中说的音乐编号?
用sappy改出来的音乐在ROM里面不是连续播放,那请问这个脚本可以解决此问题吗?
简约唯美

TOP

引用:
原帖由 pokemon002 于 2009-4-5 13:45 发表
顺便再问一下,那个sappy中的音乐编号代码是不是这个教程中说的音乐编号?
用sappy改出来的音乐在ROM里面不是连续播放,那请问这个脚本可以解决此问题吗?
playsong,fadesong两者的参数都与sappy的相同,其它两个不同。导入的音乐本身没有循环符,这里也不会自动循环。


想死你们了!

TOP

似乎让音乐循环是个很复杂的问题……


那个……我替花子说了吧
那些参数,如果仅仅是个数字(不是指针、变量、标识什么的),数字前加0x表示数据是Hex,不加则是Dec……如果你实在是懒,不想转换hex,直接输入十进制应该也可以的……
但是不建议哦

TOP

在这里问个问题...
我想问怎样可以改游戏一开始博士说的话?
另外怎样可以令战斗输后不会重开游戏?像是火红拿完初始精灵后打宿敌输了还能继续剧情这样

期待lz的教程啊
本帖最近评分记录
  • pokemon002 PT币 +1 修改文本的方法在一些文本教程上有..你没看 ... 2009-4-6 17:23

TOP

引用:
原帖由 treeckopa 于 2009-4-5 23:11 发表
在这里问个问题...
我想问怎样可以改游戏一开始博士说的话?
另外怎样可以令战斗输后不会重开游戏?像是火红拿完初始精灵后打宿敌输了还能继续剧情这样

期待lz的教程啊
可以用advance text在英文环境下改,也可以用UE自己搜索着改~
trainerbattle 第一个参数如果为0x9,则战斗进入教学模式。

下次别在这问无关的问题了~


想死你们了!

TOP

强呀!
好长时间没来看教程了!
现在好好学下!

TOP

引用:
原帖由 liuyanghejerry 于 2009-4-6 00:44 发表

可以用advance text在英文环境下改,也可以用UE自己搜索着改~
trainerbattle 第一个参数如果为0x9,则战斗进入教学模式。

下次别在这问无关的问题了~
噢,我还以为用XSE能修改= =
下次不会了

TOP

看不懂!
本帖最近评分记录

TOP

再次更新~~图片稍后附上


想死你们了!

TOP

小更新~顺便把图补齐了……


想死你们了!

TOP

movesprite感觉叫做NPC瞬移脚本比较好吧……warp针对主角,movesprite应该是针对NPC,让他瞬间到达指定位置吧……

图腾脚本不如叫做点状文字脚本……或者干脆叫盲文……这个词本来就是盲文的意思

为什么把定点教学给阉割了……

话说……一个人物的ID(flag)被set了……这个人真的会消失?

TOP

引用:
原帖由 roywillow 于 2009-4-26 22:03 发表
movesprite感觉叫做NPC瞬移脚本比较好吧……warp针对主角,movesprite应该是针对NPC,让他瞬间到达指定位置吧……

图腾脚本不如叫做点状文字脚本……或者干脆叫盲文……这个词本来就是盲文的意思

为什么把定点 ...
XD放假再说这些吧~~再次小幅更新~


想死你们了!

TOP

变量部分的内容看的很晕呢!!!!花子都没说这些命令的作用!

TOP

引用:
原帖由 5944 于 2009-5-2 20:52 发表
变量部分的内容看的很晕呢!!!!花子都没说这些命令的作用!
因为还没到用那些的时候,以后用到的时候你会看到他们的作用的。关于变量的命令都是很灵活的,他们不是效果命令。


想死你们了!

TOP

变量的范围至少提一下吧……
我只知道0x40XX游戏中常见,0x80XX大都是作为ASM,special脚本的参数变量……
之间的难道都是自由使用的?

TOP

引用:
原帖由 roywillow 于 2009-5-2 22:28 发表
变量的范围至少提一下吧……
我只知道0x40XX游戏中常见,0x80XX大都是作为ASM,special脚本的参数变量……
之间的难道都是自由使用的?
其实你应该看看XSE自带的新版guide.chm,里面有很多资料性质的东西,其中就包括这个。
R/S 可以用 0x5000 - 0x6FFF 左右的变量, E/FR/LG 可以用 0x5000 - 0x7FFF 左右的变量.


想死你们了!

TOP