【教程】【搬运】ONScripter完全教程,基础篇

搬运自X‘moe Project


放弃了ONScripter,但总觉得还是要做点什么。我不会介绍ONScripter那是个啥,也不会解释ONScripter为什么用户量这么大,或者和NScripter有什么基情。请自己百度或者维基。转载么,你不给我打招呼也得注明个原作者(X’moe Project)吧,码字痛苦。

废话不说了,上教程。本教程就是的目的就是整合ONScripter全部的指令(完全没用的就算了)。

首先我要给ONScripter(下面简称为ONS)一个属性定义:单线程。
单线程就是不能有几个图形或内部操作同时进行的,所以在移植游戏的时候要注意。
关于ONScripter的显示效果:幻灯片。
用户不能进行像素级别的操作,唯一最“高端”的操作就是mask操作。

剩下的就在教程里讲了:

ONS的启动需要 0.txt 或者 00.txt(可以命名到99.txt)或者加过密的nscript.dat、nscript.__
然后还有一个名字叫什么的。 无视了吧,常用的就是前三种。
还有default.ttf(字体文件,用中文支持的ONS那么字体文件也是支持ONS基于Unicode的)
最后就是arc.nsa(也有ns2打包之类的,别期待其中的压缩率),你不打包也行。我建议打包,大文件好发布。

这个需要的开发包我要给的,等一下下面找链接。

我们建立一个0.txt 在(编码用gbk的,也就是windows默认的,unix的用户需要自行转码)

;mode800
*define
caption “text”
versionstr “ X’moe Project”,”xmoe.project@gmail.com
defsub com_1
numalias var,1000

game
*start

*com_1
这是一个函数
Return

这是主要部分
Com_1 ;我是注释

End

我相信很多初学者是不怎么看得懂的。
我觉得第一课这些东西都应该讲的。
首先ONS的代码都是用半角的 而文字输出内容都是用全角的。还有就是ONS对大小写不敏感,也就是Start等效于start。
分号;表示注释,也就是分号后面的内容无视,直到下一行
但有个特例,那就是指令 ;mode800 前面一定要加分号,而且要位于define标签之前。
;mode800 的意思是指定窗口大小 800*600
还有一个特殊的指令 value ,也要位于define标签之前。
例如 value 800 就是开启变量的分割 800以下的变量名它们就是临时变量,而 800以上则是 全局变量,在define标签内打上 globalon 就会开启全局变量记录。这个是很有用的。

下一个是caption 指令 其中“”的内容可以接纳半角文字,作用:设定windows窗口标题。
Versionstr 指令,可以接受两个””,””(只有一个也可以),作用:可以放点版本信息,接受半角。
Defsub 指令,定义一个函数名。
用户自定义函数有这几个过程的。
先是在define标签内定义函数的名字(相当于head),
defsub com_1
然后在game指令下面哪个位置开始写函数。 此时函数名前面要带*号
*com_1
这是一个函数
Return

以return注明函数的返回,return后面没有C/C++那样带内容的(其实理解成过程会好一点)
一定要有return。。要不然脚本会一直找return的。。

game是ONS的系统函数,必需有的,最好紧挨start标签,其中define标签也是必需有的。
多嘴一句,define到start之间是不能有window类型的文字输出的。
定义的函数名一定要以英文字母开始,不能以数字开始。
例如: defsub me2 是合法的
Defsub 2me 是有问题的。

继续。。。
这是一个函数\

其中 这是一个函数 就是window文字输出内容(就是Gal下面的对话框)。
这是一个函数\ 后面的\表示翻页,就是点击一下页,前一页的文字将会清空。

追加①:
这是一个函数/
的喵
其中/表示的意思是接着下一句显示,最后显示效果就是:
这是一个函数的喵

追加②:
这是一个函数@
的喵\

其中@表示NewLine,也就是下一句的显示在下一行的。
显示效果:
这是一个函数
的喵

继续。。。。
然后执行 com_1 自定义命令

发现com_1 其中的包含的执行内容是 显示“这是一个函数”。
(函数具体的使用我后面讲。)

然后执行到 end (这个也是系统指令,高级一点的用法我后面讲),自动退出ONScripter,其中表现形式就是闪退。

什么?!有不懂的?自行理解ok?
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
上面说了一个叫Window文字输出。
这个东西其实有很多参数我们是可以定义的。
指令 setwindow 只是参数很长。。 还有几种写法。。

setwindow 170,310,30,10,15,15,0,0,2,0,1,#ffffff,170,200,640,450

170 文字开始显示的坐标x
310 文字开始显示的坐标y
30 每行显示的文字数目(全角)
10 最大行数
15 字体长
15 字体宽
0 字间距
0 行间距
1 单个字显示的毫秒数
0 是否为粗体
1 是否为阴影
#ffffff 窗体颜色 (可以吧#ffffff替换成图片,例如”win.png”,包括半角引号)
170 窗体的左上x坐标
200 左上y坐标
640 右下x坐标
450 右下y坐标

最后强调几句,
\1. setwindow 可以在任何位置使用
\2. 输出的文字最好是全角的,英文的符号,半角英文应当转换成全角。
\3. 无视setwindow2 的存在,没有什么用
\4. Setwindow可以随时更变
\5. 窗体的大小应该大于文字输出的范围大小!!!
\6. 没有了=。=

与文字有关的:
Textoff 关闭window文字输出
Texton 开启window文字输出
Texthide 隐藏window文字(当前的这句,这个指令有bug的,后面提)
Erasewindow 执行其他效果的时候是否消失window文字,0是不消失,1是消失。
Textclear 清空window里面的文字
Br 显示空行

Shadedistance 1,1 文字阴影自定义:横向偏移量,纵向偏移量(这个指令一般用在define标签内)

下面开始关于文字的一些特定功能:
!s 200 后面的文字显示速度,可以放在文字之间
例如:
喵喵喵!s 200 喵喵
!d 的用法也和!s相同的,不知道为什么存在。
!w 是强行等待,不像上面两个点鼠标时可以略过的。
参数还是以毫秒计时。
文字注释:
喵(喵/很萌)~~~~~~~ 就是在文字上加上小字注释的。
(注释对象/注释内容)

无视locate指令的存在
暂时无视puttext

Textspeed 400
改变文字显示速度。ONS里面的计时都是以毫秒为基准。

无视clickstr 、linepage的存在。
Clickvoice “00.ogg”,”01.ogg”
点击时发出音效 一般等待时音效,换页时的音效

关于文字的最后几点。
Click 单击以继续
Autoclick 400 等待400毫秒系统自动单击以继续
直接在空白行打:
#ffffff
可以改变window文字颜色,#符号就是ONS里面的颜色标记。

我个人觉得这些没有什么好说的。ONS应该是看看就会的引擎。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

我们再谈谈音频的问题。
ONS支持*.ogg *.wav .mp3 这3种格式,只不过我个人推荐使用.ogg,又小又强大。

Bgm
Dwave
Dwaveloop
Mp3
Mp3loop
……
说多了都是泪,还有几十个指令我没有说,我不知道设计者是怎么想的=。=
好吧,下一话我们再谈ONS混乱的显示系统。

什么wave、waveloop、wavestop我不会讲。
CD和midi播放的内容我也不会讲,因为没用。

有用的:
Bgm “bgm01.ogg”
Bgm播放,没有对象编号,兼容以上三种格式。
Dwave 可以放语音、效果音什么的。
Dwaveloop 也一样,只不过循环播放的。
这几个都兼容三个格式

用法:
Dwave 1,”0.ogg”
其中引号前的番号1就是该音频的对象编号(我自认为ONS/NS值得赞扬就是这样的对象系统,很好的设计)
这个对象好有别于其他函数产生的对象编号,不会冲突的。

比如要停止一切声音可以用stop 指令
但是有停止某一个的话,对于bgm有bgmstop指令,
对于dwave,dwaveloop放出的声音可以这样停止:
Dwavestop 1 停止对象1的播放,很方便的。不带参数就是dwave和dwaveloop放出的一切声音停止。(别玩过火了,SDL mix我记得是软解的,你同时放20个dwave可能你的爪机cpu就烧起来了)
再如:
Chvol 1,100
将 1号对象的音量调至100
对于bgm就直接 bgmvol 100.
当然也有 bgmfadeout和 bgmfadein 淡出和淡入
举其中一个例子:
Bgmfadeout 1000 设定淡出时间为1000毫秒,可以不在*define处定义
最后关于mp3,在这里有一个特异功能:指令 mp3save 保存当前的mp3播放的位置,load后继续从这里播放=。=
那么mp3专有的播放指令就是mp3、mp3loop,没有对象号=。=
其实没也什么用处。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
谈个轻松点的内容,那就是视频播放。
播放标准avi格式:
avi “文件路径”,播放参数
播放标准mpeg格式:
mpegplay “文件路径”,播放参数
1 -鼠标点击时可以中止播放;0 -强制播放到结尾
什么标准avi格式,你自己去查。
但我想提的是,很多ONScripter第三方维护组都在 mpegplay 上面做了手脚的。可以播放更多的格式。 我个人推荐是用mp4作为盒子,编码是H.264+AAC的,兼容性和效果都比较好。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
下面开始ONScripter的坑爹的图形显示

在讲图片显示之前,我要先将一个用在define标签那里的指令,那就是transmode
Transmode一共有三种状态 leftup、copy、alpha
Leftup就是指以图片的左上角(0,0)像素颜色作为透明色,适用于jpg(jpg没有alpha通道)
Copy就是不做处理,直接显示,适用于bmp位图。
Alpha就是把alpha通道作为透明色显示。
(貌似ONS可以显示索引图,没试过233)
既然在
define那里使用的话,那么这个就是全局设定了=。=之后我会将针对于个别图片的专门设定。
首先是bg(background)的显示,其中指令就是bg:
Bg “image/00.png”
这样就在内存里面载入了bg图片。显示要配合print指令
Print 效果编号,时间(毫秒)
关于效果编号有这几种:
0- 依下一个显示命令显示
1 -瞬间显示
2 -左快门
3 -右快门
4 -上快门
5 -下快门
6 -左窗帘
7 -右窗帘
8 -上窗帘
9 -下窗帘
10 -透明渐变
11 -左卷动
12 -右卷动
13 -上卷动
14 -下卷动
15,18 -遮片/ALPHA遮片
16,17 -马塞克效果

其中ONS是可以自行定义效果的,编号从2开始,后面讲(其实我自己觉得这样会混淆)

例如print 10,500
当然,可以写成这样
Bg “001.png”,10,500:print 1
或者:
Bg “001.png”,10,500
Print 1
其实print 1的作用就是更新画面,因为是瞬时显示,所以没有时间参数。效果0最好别用。
Bg加载的图片默认是位于最低层的。
对于纯色的背景可以这样:
Bg #000000,10,500:print 1
反正#符号后面就是定义RGB颜色的。
我记得还有几个 bg black bg white 之类的。个人觉得没什么用,常见颜色的16进制应该能被下来的。

好,我花了这么大的篇幅来讲bg之类,也提了print指令以及他的小伙伴们,下面就改我吐槽了。
ONS里面两大灵魂指令 lsp 和 csp:
Lsp就是加载sp图片,csp就是消除图片的。和dwave一样,是要指定对象的。
我写一个最简单的:
Lsp 1,”00.png”,20,10,255
其实那个对象1还有一个作用就是指定图片的遮罩,对象编号越小,那么它就显示在前面。
也就是对象2和对象1显示在通一区域,那么对象1会挡住对象2。就是这个意思=。=
后面的参数: 20,10,255 ——> x坐标,y坐标,alpha数值
最后的一个参数是可以不写的。默认是255(就是我们平时说的透明度)
还有我要提醒的是lsp计算坐标的是这样的,以你图片左上角来算坐标的。然后ONS窗口左上点坐标为(0,0)向下y轴加,向右x轴加,不懂的你确认你上过初中么。

好,我又要开始谈那个transmode了。
如果我加载的图片是jpg呢,是bmp呢?
你可以这样指定:
Lsp 1,”:c;00.png”,20,10,255
其中c表示copy,a表示alpha,l表示leftup。
我纠正一下,不一定jpg就要leftup。要看你是什么用途。Leftup主要是拿去给jpg挖CG mode(立绘)的。实际的你自己试,我不码字,因为还有很多要讲。】
另外lsp加载的图还是需要print来刷新,用法是:
Lsp 1,”:c;00.png”,20,10,255
Print 1
就没有bg的那种简便写法了。

我先讲csp的作用
Csp就是清除由lsp加载的图,用法就是csp 对象编号:
Csp 1
这样1号图就从内存里面清除了,但还在显存里面,
然后再使用个print 指令,1号图就可以从画面上面消失了。
再提一点,用csp消除过的图是不能进行操作的,它只能等待下一个print来刷新它(消失)

以及lsp还可以显示文字,但是要保证是全角的。

lsp 文字编号,”:s/字宽,字长,字间距;颜色{次颜色}文字内容”,左上角x坐标,y坐标,(alpha)

一般{次颜色}不需要打上,没有多大的用。
但一定要标注上head: :s/
颜色还是像这样 #000000 来指定。

Lsp还有其他的参数,我们将按键的时候再说。

还有一个vsp的指令,就是改变lsp图片的是否显示。
Vsp lsp的图片编号
需要print刷新
再次可用vsp让图片显示出来。
既然这样,我们还有一个指令lsph,默认加载的图片不显示,需要vsp来改变。
Lsph参数和lsp一模一样。

讲完lsp系列我们还得再将lsp2系列。如果ONS真的没有lsp2,那么它真的就死了。
注意的是:lsp2 的对象编号貌似和lsp公用,要注意一点,lsp2的消除只能用csp2,至于有没有vsp2和lsph2我不知道,本来也没什么用=。= 你自己可以试试的喵~

Lsp2 的参数是:
Lsp2 1,”02.png“,10,10,100,100,0,255
前两个还是坐标,第3个是x的比例,第4个是y的比例,一般来说100就是原来的样子,那个0表示角度,255还是透明,可有可无。

与lsp不同的是,lsp2坐标计算不同!lsp2是以图片的中心来计算坐标的。而不是左上角。
Print还是不会变的=。=

忘记说了,在清除lsp、lsp2图的时候,当清除所有的时候可以csp -1(csp2 -1),然后再print
Allsphide 也可以隐藏一切sp图,需要print刷新
Allspresume 取消全部隐藏,需要print刷新

我觉得剩下的留给你们自己想象了,毕竟做游戏又不是死读书。
Blt和btndef 这两种显示图片的方式我不推荐,特别是blt要配合ofscpy使用,应该这货总要和print起冲突,其实lsp2可以完全代替blt。Btndef只有一个用(在我的眼中),在讲按键的时候说。
到此,你可以喝喝茶,着手做点小练习了。为什么我不讲立绘?那是我下一节的内容。
哦,还有一个废柴指令,那就是repaint,如果print使用时效果出问题了,试试加上这句。
立绘?还用ONS自带的?
首先我得说的是ONS自带的立绘系统没有什么利用价值。
最多显示3个(左中右),而且不能移动、旋转等等之类的。。
所以一般做Gal的时候我是用lsp或lsp2来代替的,虽然代价比较大(也没什么)。
我还是给出指令吧,至于用不用那是你们自己的事。

ld 显示立绘
ld 位置参数,图片名,显示效果编号
l-左侧;c-中央;r-右侧
cl 清除站立图
cl {l,c,r,a},显示效果,其中a表示全部清除
tal 改变站立图的透明度
tal {l,c,r},透明度
humanz 站立图相对其他对象(lsp、lsp2)的显示遮罩关系(就是这张图挡那张图什么的,在define区域使用)
windowback 使立绘图与window文字位于同一遮罩,就是最前面。
define区使用
underline 设定立绘底端坐标(数值)在*define区使用。

我想说的就这么多。
还有一个不常用的指令是关于背景图的。
bgalia 背景左上角x坐标,y坐标,背景宽,背景高
其实没用=。= 自己在设计UI时完全可以用lsp和lsp2来代替以上内容。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
我们该说图片效果了。
前面我们接触的唯一所谓的效果顶多就是 print那个,调用内部的效果器。
下面我们将effect里面的mask应用。其中编号15和18都支持mask的,只不过18是alpha的。对于这两个我们可以在*define区重新定义编号

effect 自定义效果编号,显示效果编号{,显示时间毫秒数,遮片图片路径}

举个例子:
Effect 20,,18,500,””mask.png”

到时候使用时直接就 print 20 就可以了
自定义编号最好从19开始,比如你命名为10,那原来的10号就不能直接使用了,就要这样定义了,所以15和18以外的就不要这样定义了。

自己给图片加动作。
由lsp加载的对应 msp和amsp
由lsp2加载的对应 msp2和amsp2
其中msp和msp2是相对变化,amsp和amsp2是绝对变化。我们举个例子,方便说明:

Lsp 1,”m.png“,1,1,

For %1 = 1 to 20
Msp 1,1,1,0
Print 1
Next

我这里先把循环讲了。
%1 是定义的一个临时变量。For中间 1是初值,20是终值。
Next是循环体末尾的标准,一定要有!!(有点像basic的语法)
当然也能是 For %1 = 0 to 20 step 2 就是步长为2,每步.跨2个。
这些基础知识不懂自己解决。

此时这个循环体结束时,对象1图片向右移动20,向下移动20,透明度不变。
那么msp的用法就是:
Msp lsp数值,x相对平移量,y相对平移量,透明度相对变化量

Print 1的作用是每次平移时更新画面,才能看见图片的变换过程。
那么amsp我就不讲了 那个是直接用=。= 变换到绝对位置,不配合循环体使用。
那么amsp2也同理。需要print刷新

Msp2就是针对lsp2的了。

Msp lsp2对象号,x相对,y相对,x相对伸缩,y相对伸缩,相对角度,相对透明度

我不细讲,内容还多。

关于晃动的:
画面晃动效果,单次不规律晃动
quake 位移像素数,晃动时长毫秒数
更细节的——>
quakex 画面横向晃动
quakex 晃动次数,晃动总时长毫秒数
quakey 画面纵向晃动
quakey 晃动次数,晃动总时长毫秒数

注意。ONS的quake是背景和所有图一起晃动。。如果只想晃动sp图形请自行写函数。

图片后期效果:
monocro 画面褪色效果,画面变为以指定颜色为主色调的单色图。需配合print命令使用
monocro 颜色
monocro off ;结束退色效果,也需要print
nega 底片效果,参数为1表示和monocro并用时与褪色效果指定的色调统一,2表示和monocro并用时与褪色效果指定的色调反相,0表示还原为原图色彩。都需要配合print使用:
nega 效果参数

需要注意的是。上面两个效果都是背景图的效果,对其他图没有用的。
PS:再去喝口茶吧,下面我要讲按键了。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
按键喵~

对于按键本来是用btndef或者blt加载图片的。结果我发现没有任何意义。因为lsp和lsp2都可以代替他们。
但是关于btndef,它还是有一个用的。 那就是:
Btndef clear 可以消除之前定义好的按键。防止一系列错误。
按键怎么定义?ons给我们提供了多种方式,虽然他们的作用基本相同。我不知道作者是怎么想的。
我们还是开始讲吧

Lsp 1,”o.png“,1,1
Print 1

Spbtn 1,1 将1号图片对象定义成1号按键。

Btnwait %0

这里的btnwait 作用就是判断用户是点击了那个按键 ,如果点击了1号按键,那么%0被赋值1,点击了别的地方就赋值0,右键点击屏幕任何地方赋值为-1,假设*define标签里面定义了usewheel,那么鼠标滑轮上翻将%0赋值为-2,下翻就赋值为-3.

完整的我们可以这样定义:

Lsp 1,”o.png“,1,1
Print 1

Spbtn 1,1

*btn_loop
Btnwait %0
Btndef clear 清除原来定义好的按键,防止错误。

If %0 == 1 goto *btn1
If %0 <= 0 goto *btn_loop
Goto *btn_loop
*btn1
这样,一套比较完整的系统就写成了。
我简单地提一下if语句:其作用就是判断。例如:
If %0 == 1 如果变量%0 为 1
If %0 <= 1 如果变量%0 小于等于 1
还有一个 if %0 <> 0 等效于 if %0 != 0 如果变量%0 不为 0
自行理解,理解不能的,自行找谭浩强=。=

其实还有一个btnwait2 ,一般不用,因为ONS的单线,btnwait2就显得废柴了。

下面的if语句就是判断你点击了什么。
假设你没有点中按键的话就是跳回 *btn_loop 标签
然后再加一个Goto *btn_loop 来锁定游戏,防止略过按键前进。
可以说spbtn是最简单的按键了。下面我讲几个复杂的。

首先我们放弃spstr指令,因为它和exbtn指令基本上一样。

exbtn 101,1,”P101P102P103P104S2,(se/MN_SS_SE10.ogg)”

那个 101,1 我不解释,和spbtn一样的。我们先解释()里面的。那里是指定按键音效的音频路径。
P101P102P103P104S2 的意思是,点击按键时显示101 102 103 104号sp图片,并且设定音效的音频通道为2(就是对象编号)。这一串东西称为控制文字列。
要记得。Exbtn定义的控制文字列是按键按下去显示的。

那么我们再讲和exbtn配合使用的exbtn_d
exbtn_d “P106P107P108P109”

exbtn_d定义的效果是鼠标悬浮在按键上面,但没有点下去的效果。
其中106 107 108 109号图可以由lsph预先加载。
注意的是无论exbtn还是exbtn_d打上屏幕都不需要print刷新(你加一个也不会怎样)
这样就有一个疑问了,我后来加载的 106 107 108 109不是会被exbtn的101 102 103 104给挡住么? 这样我们的控制文字列还有一个C的指令,其作用就是csp。
我们就可以这样写了:
exbtn_d “C101C102C103C104P106P107P108P109”
这样复杂一点的效果就做成了。
追加一点。。。
getbtntimer 数字变量
取得在btnwait状态下停留的时间。此期间如果点了鼠标右键或空白处,返回了btnwait上面的标签的话,就重新开始计时。
btntime 数字变量
btntime 给按钮设置时间限制。写在btnwait前一行,此期间如果点了鼠标右键或空白处,返回了btnwait上面的标签的话,就重新开始计时。说白了就是一定时间内用户不能点按键。

其实ONS还有一个做按键的方法,可以指定sp显示哪一帧的。只不过我个人不推荐,因为上面我讲解的方法完全可以代替此方法。
但我还是我还是把使用方法写出来。(我这么多年也没有用过几次=。=)
按键的定义方法还是那样,只不过lsp的语句有点不同,还要配合cell指令。
Lsp的完整语句是:
lsp 图片编号,”{:透明方式}{/划分动画格数,}{动画间隔时间毫秒数,}{动画播放模式}{;}图片路径”,左上角x坐标,y坐标,透明度

实际写代码的时候是没有{}这个花括号的。
划分的动画格数指的是将图片平均分成多少份。
实际上是把按键的状态图从左至右做成一张图,推荐是png的。
理解不能?这样的话就可以用lsp指令囊括exbtn、exbtn_d的部分作用。
然后就是cell指令。
cell 指定sp对象显示的为哪一祯。0为第一祯,1为第二祯,2为第三祯……以此类推。指定祯号超过现有祯数显示最后一祯。默认为0。

cell 对象编号,祯号

我说了,这个我不会具体讲,自行尝试。
按键基本上就这样。对于window自定系统的按键,我后面要说。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
按键和图形还有计时的追加

delay 鼠标点击可以略过的等待。可以使用变量。
delay 毫秒数
wait 强制等待。可以使用变量。不可略过。
wait 毫秒数

下面我介绍的是ONS最为精确的计时指令
那就是gettimer指令
但是使用前,我们先要用resettimer清空内部的计时器。
Resettimer是没有参数的

waittimer 以内部时钟计时指定等待时间。和wait不同,这个计时和Wait、delay不同的=。=
waittimer 毫秒数
下面的一个指令是gettimer
gettimer 取得内部计时器从resettimer开始经过的时间。
gettimer 数字变量
最后就关于按键的计时。
spwait 等待指定号码的图片对象的动画播放完毕后再执行下一步操作。
spwait 对象编号
我个人觉得这个指令没有什么作用。等别人自己实现了ONS多线程我们再谈吧。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
ONS的图形这样就差不多了。下面我们讲的才是与编程有关的。
变量及语句。
If 语句我前面讲过了,我就不管了。
但需要注意的是。。
If 条件1 && 条件2 这样的判断就是条件1和2都成立的情况
而notif就是什么什么不成立的条件下。。
这种语句自己学
For next 循环我前面也讲了,只不过我追加的是,break语句可以破坏循环。例子:

For %2 = 1 to 10
If %2 == 3 break
Next

这样,当%2等于3的时候,循环终止。也就是说,后面的操作就没有了orz

len 获得文字变量的字数
len “喵喵”,%2
那么此时%2等于4,一个汉字有两个字节。

Mov 指令,和汇编有点类似。
Mov %3,2 那么此时%3就等于2了。

我们前面用的都是数字变量。和其他的脚本不同的是,ONS脚本只支持整数变量,没有浮点运算。 那个%3就是在定义一个临时变量了,更改%3这个变量的方法本教程第一章有讲解,包括下面讲的字符变量也是这样定义名字的。
但比如我定义 %3的名字为 %int_o 那么此时%3和%int_o是同一个变量。这两个变量是等价的。

$2 就是一个字符变量了。字符变量也能使用mov指令:
Mov $2,“喵喵” 而且ONS的字符串变量是不受半角全角的限制的。
那么此时$2的内容就是 喵喵。
这样也可以用判断 if $2 == “喵喵” 之类的=。=

字符串变量也可以相加:
Mov $1,$2 + “就是我”
包括add指令也可以的。

那么此时 $1的内容就是 喵喵就是我
很简单吧~

Add 是加 sub是减,字符串变量都可以用的
add 数字变量,数值
add 文字变量,”追加文字”
sub 数字变量,数值或变量

还有几个没什么用的,就是加1减1的:
inc 加1
inc 数字变量
dec 减1
dec 数字变量

mul 乘
mul 数字变量,数值

div 除,只保留整数(不是四舍五入)
div 数字变量,数值
mod 求余
mod 数字变量,数值

ONS里面会出现小数的地方都是取整,也就是int();
不是四舍五入,比如算得4.6,而你实际获得的是4而不是5.
这个系统褒贬不一,我们不重点讨论这个。

好,下面的又是重要的指令:

mid 从一个文字变量中截取一段文字赋予另一个文字变量,后面的第一个数字为截取开始位置,从第一个字开始截取就设为0;第二个数字为截取长度。(一个汉字占两字节)
mid 被赋值的文字变量,作为母本的文字变量,数字或数字变量,数字或数字变量

我举个例:
Mov $1,”123456”

Mid $2,$1,2,1
那么 $1等于“3”

itoa 将数值转换为文字列,只能转换为半角
itoa 文字变量,数值
atoi 以上反之,文字列只能为半角数字。
atoi 数字变量,文字列
C里卖都有这个的=。=

还有一个坑爹random函数,直接用,不用置种。

rnd 获得0-给出数字之间的随机数
rnd 数字变量,数字
rnd2 获得数字1-数字2之间的随机数
rnd2 数字变量,数字1,数字2

对了||||还有几个指令

mov3~mov10 可以同时给指定变量以后连续的10个以下数字变量赋值,
movN 数字变量,第一个值,第二个值,……第N个值
movl 给数组变量的某一行赋值。
movl数组变量[行号],第一个值,第二个值,第三个值……

一般用得少。。
下面是数组:
dim 数组变量[行数][列数]

我是例子:
Dim texture?[9][9]
这样我们就定义好一个9*9的数组了~
从这里可以看出。半角的?也是一个造成bug的起源,一旦有非法数组,ONS就会跳出。

数组一样可以参与各种运算。。。
这个我不想多说,都是基础编程的内容。我只举例子

Mov texture?[2][3],1

还有需要说的是,ONS的数组不需要初始化,每个单位默认为0,有些边界问题就不用管了。

其实赋值没有怎么麻烦。。 可以这样的,直接带计算式:

Mov %6,7*(5-1) 这样的操作也是合法的。

那么我们下一节改讲ONS的AVG系统了。其实很多UI得自己做。。。。。。。。。。。。。。。。。。。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
我们开始AVG那种没用的系统介绍

其中我最少用的立绘系统我前面已经讲过了。我这里就不管了。
在这之前,我首先要介绍一个名为systemcall的指令,其含义就是调用系统机能
Systemcall 能够接受的参数有save load automode skip end lookback reset rmenu
其中最没用的就是reset了,只能返回脚本的最开始,不能满足现代GAL制作的需求。
Save 和 load 我不解释,就是ONS自带的那个条状的存档系统,你们懂的。
Lookback系统也可谓非常简陋,普通来说只有上翻和下翻。我的意思是,这个上下翻是在window对话框那里翻的,9几年的GAL就是这样的。我们下面会谈lookback系统自带的UI制作。
End就是退出游戏。
唯一需要特别说明的是automode,因为NS里面没有systemcall automode 这个写法。。
NS你是要作甚? 但是使用automode需要在define标签处定义。
定义的内容就是 automode (没有参数)和 automode_time (加毫秒,就是自动等待的时间)
最奇怪的就是rmenu,其实rmenu本身就是一个指令。其作用就是唤起右键菜单。
但是右键菜单需要在
define处定义。
例子:

rmenu “储存进度”,save,”读取进度”,load,”回想模式”,lookback,”快进”,skip,”消除文字框”,windowerase,”自动阅读”,automode,”返回标题画面”,reset,”退出”,end

显示的也是那个自带的细条菜单,所以说,ONS提供给我们的UI我们是不好意思去用的。
其实前面该讲讲ONS自带的那个选项系统,那个更简陋。我想了想,还是算了,我提都不提,你可以用我之前讲的那个按键制作去代替一切UI。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
menusetwindow 右键呼出菜单的外观设置。除文字以外只能改变窗口颜色。默认为menusetwindow 26,26,0,2,0,0,#999999
menusetwindow 文字高,宽,字间距,行间距,粗体字状态,黑体字状态,窗体颜色
savename 右键呼出菜单中的储存读取菜单具体名称设置。默认为“保存”,“读取”和“档案”
savename “自定义储存菜单标题”,”自定义读取菜单标题”,”自定义档案名”
menuselectcolor 右键呼出菜单中的文字颜色设定。
menuselectcolor 鼠标悬停颜色,一般状态颜色,尚未保存过的档案颜色
menuselectvoice 右键呼出菜单中的音效设定。如写作””代表无音效。
menuselectvoice “菜单打开时的音效文件路径”,”关闭时的音效”,”鼠标悬停时”,”点击时”,”点击了无法进行的操作的警示音”,”选择「是」的时候”,”选择「否」的时候”
rlookback 设置右点击为回顾上一段文字
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
加号之中的是需要在*define里面定义的

roff 右点击无效
rmode 右点击功能开关
rmode 1 右点击有效
rmode 0 右点击无效
这里我也觉得没有什么用
如果用系统子自带的save系统 我们还可以在*define区定义savenumber
Savenumber 20
默认为9个存档位,最多可以提供20个。
Saveload系统也是我们将来要自己写的东西。

Lookback系统
lookbackbutton 设定回顾功能按钮,默认的文件名为”uoncur.bmp”,”uoffcur.bmp”,”doncur.bmp”。要求图片大小一致,不支持动画,不能改变位置(按钮位置为文字框的右上角和右下角)。
lookbackbutton “向前按钮选中状态图片路径”,”向前按钮一般状态”,”向后按钮选中状态”,”向后按钮一般状态”
lookbackcolor 设定回顾模式的文字颜色
lookbackcolor #rrggbb
lookbackvoice 设定回顾模式音效
lookbackvoice “音效文件路径”
lookbackflush 取消回顾模式

说实在话,我不想讲这个,放在这里只是为了让你知道有这么一个东西。
一般来说别用就是了。

ONS指令混乱的问题一直都有,但最大的问题是ONS的脚本是死板的,没有活力的。不想C#和JAVA,还有扩展的空间,最后貌似作者也意识到这个问题,在后期加入了lua的支持,就是为了解决ONS语句的单一性和混乱的问题。下面我们还是边吐槽边讲课,吐槽没有人身攻击的意思哟。

前面我们提到了skip指令,其实这个指令时可以接受从参数的,而且连用法也不同了。就是单独使用的。
Skip 3
意思就是跳3行显示,那么前面的3行就不会打印到window的文字框中。

kidokuskip 打开初次阅读判断,设置后脚本运行时会自动生成一个kidoku.dat文件记录已经读过的文字。对于初次阅读的文字部分禁用菜单的快速略过功能。定义在*define区域。
这个也是个bug功能,我承认,一般的GAL都有这个机能,但是我一般的skip就没用了=。= 何等凶残,一般我们是放弃了这个功能的。

下面3个还是定义在*define区域的。
filelog 用来记录调用过的文件的相关数据。如果调用时的参数不同则视为不同的文件。和globalon同时使用时的会有特殊情况。
这个我们就不要管了,我还没见过谁用过。

globalon 全局变量 这个很有用,我貌似前面是讲过的。
labellog 记录读取过的标签的日志。这个有一点用,也有很多会去用,但是我个人观点是可以用变量自己代替的。

然后我们再说说save和load吧

savegame 存档到指定编号的档案,自动存储,不会出现任何确认提示。
savegame 档案编号
loadgame 从指定编号档案读取存档,自动读取,也没有任何确认提示。如无法读取(如该档案无存档等)继续执行下面的命令。
loadgame 档案编号
savefileexist 判断某一编号档案上有无存档。有存档变量赋值1,无存档为0。
savefileexist 数字变量,档案编号
saveon 重新开启即时存档功能
saveoff 禁止即时存档,与以上配合,在saveoff与saveon之间区域的存档内容强制为saveoff之前。

这个自己看,没有什么好说的。

像killmenu和defaultspeed也没有什么好说的,没有用=。=

还有几个信息获取,是ONS比较重要的部分

date 获得系统日期(年月日)
date 获得年份数值的数字变量,获得月份数值的数字变量,获得日期数值的数字变量
time 获得系统时间(时分秒)
time 获得时数值的数字变量,获得分数值的数字变量,获得秒数值的数字变量
savetime 获得指定编号的档案的存档时间(月日时分)。当该编号档案无存档时月份的返回值为0。
savetime 档案编号,获得月份数值的数字变量,获得日期数值的数字变量,获得时数值的数字变量,获得分数值的数字变量

其实都是很简单的,都是看看就懂的。
这一篇教程的作用就是给你扔指令,说什么做UI都是骗人的。那个是后话。

在*define 区域里面有一个叫 nsa 的指令,指定资源从nsa压缩包里面读。
我睡了,下一篇我们接着吐槽。吐完槽我就该正式地叫你们函数了,这个是自定义系统很重要的中心枢纽。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
这篇教程我们以符号开始

: 一行出现多条命令之间的分隔符
分号的作用就是这个:

if %2 == 6 dwave 0,”se/TT_TTA00.ogg”:bgmstop_se:bg black,1:csp -1:print 1:stop:goto *seen08000
在同一行就可以依次执行多个命令,我个人认为这个是很有用的。

% 数字变量的开头标记
$ 文字变量的开头标记
? 数组变量的开头标记

下面就是是重要的标签,ONS里面以*为标记。

* 标签开头标记

而goto 指令则是跳跃到哪个标签。
定义标签也很简单。

*my_label

这样就定义好一个标签了。

*label1
喵喵
*label2
Goto *label1
喵你妹=。=\

这样的话 喵你妹 就不会显示了。
需要注意的是:ONS程序是这样编写的,所以的标签的信息装入label_info的数组里面的,还是依次的,那么有的人就有问题了。

*label
*label
*label

Goto *label

那么我究竟是进哪个label??
答案我上面也给出了,肯定是第一个,无论Goto label这句放在哪里,都一样的。
还有。那个
start和*define标签是系统的,用户不能占用。

还有一个很有用的但是很危险的符号
~ jumpf和jumpb的跳跃标记
就是半角的~
Jumpf 是向上跳
Jumpb 是向下跳
两个都忽略标签的存在,忽略一切的存在,甚至可以跳出函数到另外 函数里面。
全角的~可能也会被视为半角的~,估计是bug。
比如:
喵喵喵喵
~
Miaomiaomiaomiaomiao
Jumpf

你可以试试。

ONS还提供了条状系统(说白了就是显示MP和HP的东西,极其简陋)
不细讲

bar 设定条块对象,需要用print来显示
bar 条块编号,当前长度比例,左上角x坐标,y坐标,长度,高度,总长度比例,颜色
barclear 清除条块对象的设定。要配合repaint才有效果
prnum 显示0-999之间的数值
prnum 数字编号,欲显示的数值,左上角x坐标,y坐标,字宽,字高,颜色
prnumclear 清除数字标签的设定。要配合repaint才有效果

感觉又是比较混乱的样子。Repaint在这里就有用了。但是一个单线程引擎我来做RPG系统太麻烦了。

还有几个系统状态的判断指令:

Isskip 整形变量
是否为快进模式,是则返回1,否则为0

Isfull 整形变量
文字是否满屏。是则返回1,否则为0

Ispage 整形变量
文字是否到下一页。是则返回1,否则为0
其他的貌似还有,只不过没有什么用了。我也记不得了。

=。=。=。=。=。=。=。=。=。=。=。=。=。=。=
ONS比较基础的教程就到此为止。
下面的是实用教程了
自己在blog里面找=。=


原贴评论

mil(B站混的 过来看看。)

​ “还有我要提醒的是lsp计算坐标的是这样的,以你图片左上角来算坐标的。然后ONS窗口左上点坐标为(0,0)向下y轴加,向左x轴加,不懂的你确认你上过初中么 “

确认不是向右x轴加么…… 想想window 170,440 这种语句总不能加到屏幕外吧。。。

#1-1 - 2014-6-16 09:18

X‘moe Project

屏幕左上角是(0,0) 向下是y轴 向右是x轴
手误

#2 - 2014-7-24 00:40

Ons新手

​ 大神还在吗?
不知道为什么我测试后发现里面的字乱码…
另外能留个Q号吗?我还有一些不懂的。

#2-1 - 2014-7-26 01:01

X‘moe Project

留个邮箱 我给你发

#2-2 - 2014-7-28 19:29

Ons新手

X‘moe Project 说: 留个邮箱 我给你发

十分感谢你的热心,但我听了其它人的建议转用比较新的BKE,不过怎么样也好,还是谢谢!


END