【教程】【搬运】ONScripter完全教程,实用篇

搬运自X‘moe Project


真﹒函数部分
前面第一节提过的。函数需要在define区域使用 defsub 来定义函数名,再在define区域以下的地方写函数的本体。而前面没有讲的是,ONS的函数是接受变量的,放回的是一个过程。
而获得参数需要getparam 指令来实现,参数用半角逗号隔开。
例子:

*define ny_fun
game
*start
*ny_fun
Getparam %1,$2
$2
Wait %1
Return

;实际上的调用:

Mov $3,”这是一个函数。”

Ny_fun 500,$3

这样就是函数的书写的函数的调用。

而且ONS不存在局部变量,也就是说,我先把$2赋值,而不是$3也是一样的。
假设我调用时,忘把$3打上去,那个wait指令还是有效的。
关于这种参数少加的bug,ONS一般是没有提示的。

最后一定要有return作为函数的结束标志!

我再拿一个语音播放作为例子吧。
大开发时。我们不可能这样写语音系统的:
Dwave 2,”koe/voice/k254/00.ogg”

我们一般用函数。
假设目录koe\voice都是共同的,那么所谓的变量只有00.ogg上一个目录名和00.ogg它本身。

*koe_player
Getparam $1,$2
Dwavestop 2 ;停止上一个语音的播放
Dwave 2,”koe/voice”+$1+”/”+$2+”.ogg”
Return

调用时:
Koe_player “k111”,”113” 这样就可以了
还有那个字符串直接加起来是有风险的,一般我们避免风险我们可以这样:
Mov $3,””
Add $3, ”koe/voice”
Add $3,$1
Add $3,”/”
Add $3$2
Add $3,”.ogg”

Dwave 2,$3
虽然这样很麻烦,但是可以避免很多bug,毕竟ONS脚本多嵌套能力是很弱的。所以说,在ONS脚本里面,双循环我觉得都是比较危险的做法。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

前面我们学习了itoa和atoi这两个指令,今天这里还有一个很实用的指令。
itoa2
其作用将数字变量转化为全角的字符串变量
那些数字就可以直接使用lsp等指令打印在屏幕上了。

例如
Mov %5,150
Itoa2 $2,%5
那么$2里面存储的就是150(全角的)

但今天主要讲的是window的自定义。

我们是可以把这货写成函数的。

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

*system_window_1
btndef clear
force_draw2

saveoff

spbtn 102,212
spbtn 103,213
spbtn 104,214
spbtn 105,215
spbtn 106,216
spbtn 107,217
spbtn 108,218
spbtn 109,219
spbtn 110,220
spbtn 111,221
spbtn 112,222
spbtn 113,223
spbtn 114,224
spbtn 115,225
spbtn 116,226
spbtn 117,227

textbtnwait %winbtn

if %winbtn == 212 messagebox “该对象未移植!”:goto *system_window_1
if %winbtn == 213 gosub *koe:goto *system_window_1
if %winbtn == 214 goto *system_window_1
if %winbtn == 215 systemcall automode:goto *system_window_1
if %winbtn == 216 systemcall skip:goto *system_window_1
if %winbtn == 217 goto *system_window_1
if %winbtn == 218 wipe_window:goto *system_window_1
if %winbtn == 219 messagebox “该对象未移植!”:goto *system_window_1
if %winbtn == 220 messagebox “该对象未移植!”:goto *system_window_1
if %winbtn == 221 force_btn_debug:textoff:mov %saveload_flag,1:gosub *saveload:texton:goto *system_window_1
if %winbtn == 222 force_btn_debug:textoff:mov %saveload_flag,2:gosub *saveload:texton:goto *system_window_1
if %winbtn == 223 ready_return_title:goto *system_window_end
if %winbtn == 224 ready_quit:goto *system_window_1
if %winbtn == 225 goto *system_window_1
if %winbtn == 226 goto *system_window_1
if %winbtn == 227 goto *system_window_1
if %winbtn == 0 goto *system_window_end
if %winbtn == -1 goto *system_window_end
if %winbtn == -2 goto *system_window_end
if %winbtn == -3 goto *system_window_end
goto *system_window_1

*system_window_end
btndef clear

texec
saveon
erasetextwindow 0
return

其中force_draw2是这样一个函数。

是这样的一个函数
*force_draw2

lsp 117,”:a/1,0,3;image/window/mn_mw_mw00c00/0000.png”,170,438
;; “sys10_mw00”

;;”msg_log”
lsp 102,”:a/1,0,3;image/window/mn_mw_mw00c01/0000.png”,228,438

;;”koe_play”
lsp 103,”:a/1,0,3;image/window/mn_mw_mw00c02/0000.png”,285,438

;;”global_switch”
lsp 104,”:a/1,0,3;image/window/mn_mw_mw00c03/0000.png”,342,438

;;”auto_mode”
lsp 105,”:a/1,0,3;image/window/mn_mw_mw00c04/0000.png”,399,438

;;”read_skip”
lsp 106,”:a/1,0,3;image/window/mn_mw_mw00c05/0000.png”,455,438

;;”a_skip”
lsp 107,”:a/1,0,3;image/window/mn_mw_mw00c06/0000.png”,513,438

;;close_win
lsp 108,”:a/1,0,3;image/window/mn_mw_mw00c07/0000.png”,570,438
;==================side
;;qsave
lsp 109,”:a/1,0,3;image/window/mn_mw_mw00c08/0000.png”,686,364

;;qload
lsp 110,”:a/1,0,3;image/window/mn_mw_mw00c09/0000.png”,739,364

;;save
lsp 111,”:a/1,0,3;image/window/mn_mw_mw00c10/0000.png”,686,383

;;load
lsp 112,”:a/1,0,3;image/window/mn_mw_mw00c11/0000.png”,739,383

;;title
lsp 113,”:a/1,0,3;image/window/mn_mw_mw00c12/0000.png”,686,400

;;quit
lsp 114,”:a/1,0,3;image/window/mn_mw_mw00c13/0000.png”,739,400

;;memory
lsp 115,”:a/1,0,3;image/window/mn_mw_mw00c14/0000.png”,686,418

;;config
lsp 116,”:a/1,0,3;image/window/mn_mw_mw00c15/0000.png”,739,418

lsp 140,”:a/1,0,3;win/win2.png”,0,0

print 1

return

相当于把那些window所需要的sp图再加载一次。至于为什么要这样做,我后面说。

我们从主函数开始说。。
主函数是 system_window_1
但是我们要在*define里面这样加:

Textgosub *system_window_1
至于为什么还有这样一个猎奇的东西,我只能告诉你,ONS是单线的。。

这样,window那里定义的按键才会正常。不然你试试?
相同的指令还有loadgosub
Pretextgosub
我们后面再说。

Saveoff 用在这里是我的习惯。只要在函数结束开启save就可以了saveon

然后是定义按键,等待按键。这个都是我讲过的。
当点击没有点中按键时,跳跃到*system_window_end 文字继续显示下去。

比如你想有这样的一个功能,在这里开启了读档界面后,我关闭了这个界面但我还想回到window显示状态。那么我要在if的最后加上goto *system_window_1 这样就相当于返回了,文字也没有继续。

texec
erasetextwindow 0

在*system_window_end里面,这两个好基友一定要在一起。我也不知道这是什么设计。
总之你用了 textgosub就要加上这两句,文字才有可能正确显示,要不然就是一闪而过。

我现在要说那个force_draw 函数了。放在*system_window_1里面的那个。貌似没有用。但是一旦使用了textgosub 就会出现字体显示残缺的问题,特别是指宽屏模式里。
这样做就是重新载入对象,我认为就是一个刷新的作用,反正最好是加上。
紧接着,下一节我们讲Saveload系统。(好热啊!8月能不热么=。=)

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
saveload系统。我定义是要使用10到99号sp图。

还是先上代码我再讲。代码来自我Rewrite移植工程。

*saveload
;texthide
erasetextwindow 0
if %saveload_flag == 1 goto *ny_save:mov %saveload_flag,0
if %saveload_flag == 2 goto *ny_load:mov %saveload_flag,0
;if %saveload_flag == 3 goto *ny_autosave:mov %saveload_flag,0
;if %saveload_flag == 4 goto *ny_auto2load:mov %saveload_flag,0

;=================================================
*ny_save ;;开始加载基本的图片,注意顺序。
getscreenshot 80,45 ;;在进入界面之前获取截图
;btndef clear
if %savepage == 0 mov %savepage,1 ;;初始化,如果savepage为0则赋值为1(全局变量)
lsp 98,”image\menu\mn_sva_bg00.png”
lsp 97,”image\menu\mn_sva_bg01.png”,-2,-2
print 10,10
lsp 96,”image\menu\save\1.png”,170,0
lsp 95,”image\menu\save\2.png”,210,0
lsp 94,”image\menu\save\3.png”,250,0
lsp 93,”image\menu\save\4.png”,290,0
lsp 92,”image\menu\save\5.png”,330,0
lsp 91,”image\menu\save\6.png”,370,0
lsp 90,”image\menu\save\7.png”,410,0
lsp 89,”image\menu\save\8.png”,450,0
lsp 88,”image\menu\save\9.png”,490,0
lsp 87,”image\menu\save\10.png”,530,0
lsp 40,”image\menu\re.png”,690,420
itoa $3,%savepage ;;讲savepage转化为字符串变量,方便显示

for %0 = 1 to 5 ;;用循环加载好存档按键
itoa $1,%0
lsp 81+%0,”saveload\0001.png”,50,60+(%050)
lsp 76+%0,”saveload\0001.png”,390,60+(%0
50)
print 1
next

mov %0,0

;;加载截图
for %0 = 1 to 10
itoa $1,%0 - 1
savefileexist %10,10*(%loadpage-1)+%0-1 ;;检查存档文件,如果没有就跳过
if %10 == 0 jumpf
if %0 <= 5 lsp 66+%0,”:c;sav_screenshot_”+$3+”“+$1+”.bmp”,95,67+(%0*50)
if %0 > 5 lsp 60+%0,”:c;sav_screenshot
“+$3+”_”+$1+”.bmp”,435,67+(%050 - 550)
print 1
~
next

;;显示save数据的info,这个可以自己定制的
for %0 = 1 to 10
itoa $1,%0 - 1
savetime 10*(%40-1)+%41-1,%21,%22,%23,%24 :itoa $21,%22:itoa $22,%22:itoa $23,%23:itoa $24,%24
savefileexist %10,10*(%loadpage-1)+%0-1
if %10 == 0 jumpf
if % <= 5 lsp 55+%0,”:s/15,20,0,0;#FFFFFF$27”,40,45+(%040)
if % > 5 lsp 55+%0,”:s/15,20,0,0;#FFFFFF$27”,260,45+(%0
40)
print 1
~
next

lsp 50,”:s/15,20,0,0;#FFFFFF$3”,390,380
print 1

*wait_save ;;返回点
btndef clear

;把图片设定成按键
exbtn 81,100,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 82,101,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 83,102,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 84,103,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 85,104,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 76,105,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 77,106,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 78,107,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 79,108,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

exbtn 80,109,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

;;page的定义
for %0 = 1 to 10 ;;
exbtn 86+%0,120+%0,”P55C45S2,(se/MN_SS_SE10.ogg)”
next

;;返回键定义
exbtn 40,20,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

btnwait2 %1
if %1 <= 0 goto *wait_save

;;点击的是页面按键。先使用saveload_updata刷新截图和存档信息,然后加载相应的页面
if %1 == 121 mov %savepage,10:saveload_updata:goto *ny_save

if %1 == 122 mov %savepage,9:saveload_updata:goto *ny_save

if %1 == 123 mov %savepage,8:saveload_updata:goto *ny_save

if %1 == 124 mov %savepage,7:saveload_updata:goto *ny_save

if %1 == 125 mov %savepage,6:saveload_updata:goto *ny_save

if %1 == 126 mov %savepage,5:saveload_updata:goto *ny_save

if %1 == 127 mov %savepage,4:saveload_updata:goto *ny_save

if %1 == 128 mov %savepage,3:saveload_updata:goto *ny_save

if %1 == 129 mov %savepage,2:saveload_updata:goto *ny_save

if %1 == 130 mov %savepage,1:saveload_updata:goto *ny_save

;;点击的是存档按键
if %1 == 100 mov %present_number,1:goto *save_loop

if %1 == 101 mov %present_number,2:goto *save_loop

if %1 == 102 mov %present_number,3:goto *save_loop

if %1 == 103 mov %present_number,4:goto *save_loop

if %1 == 104 mov %present_number,5:goto *save_loop

if %1 == 105 mov %present_number,6:goto *save_loop

if %1 == 106 mov %present_number,7:goto *save_loop

if %1 == 107 mov %present_number,8:goto *save_loop

if %1 == 108 mov %present_number,9:goto *save_loop

if %1 == 109 mov %present_number,10:goto *save_loop

if %1 == 20 goto *saveload_end ;;返回键

;;进入存档确认界面。
;; messagebox 为系统界面函数,自己写。
*save_loop
itoa $1,sub %present_number,1
messagebox “确定要保存在这里吗”
if %yesno = 0 goto wait_save
savescreenshot “sav/screenshot“+$3+”_”+$1+”.bmp” ;;针对存档截图进行命名、保存。
savegame2 10
(%savepage-1) + %present_number – 1 ;;使用savegame2指令,这样就可以存档到任意编号的 。我默认是从编号0开始,最大是99。

goto *ny_save ;;存档完成后返回界面。
return

;===========================================
;;读档就是存档的逆过程。我只讲不同的。
*ny_load
;btndef clear
if %loadpage == 0 mov %loadpage,1
lsp 98,”image\menu\mn_svb_bg00.png”
lsp 97,”image\menu\mn_svb_bg01.png”,-2,-2
print 10,10
lsp 96,”image\menu\load\1.png”,170,0
lsp 95,”image\menu\load\2.png”,210,0
lsp 94,”image\menu\load\3.png”,250,0
lsp 93,”image\menu\load\4.png”,290,0
lsp 92,”image\menu\load\5.png”,330,0
lsp 91,”image\menu\load\6.png”,370,0
lsp 90,”image\menu\load\7.png”,410,0
lsp 89,”image\menu\load\8.png”,450,0
lsp 88,”image\menu\load\9.png”,490,0
lsp 87,”image\menu\load\10.png”,530,0
lsp 40,”image\menu\re.png”,690,420
print 1

itoa $3,%loadpage

for %0 = 1 to 5
itoa $1,%0
lsp 81+%0,”saveload\0000.png”,50,60+(%050)
lsp 76+%0,”saveload\0000.png”,390,60+(%0
50)
print 1
next

mov %0,0

for %0 = 1 to 10
itoa $1,%0 - 1
savefileexist %10,10*(%loadpage-1)+%0-1
if %10 == 0 jumpf
if %0 <= 5 lsp 66+%0,”:c;sav_screenshot_”+$3+”“+$1+”.bmp”,95,67+(%0*50)
if %0 > 5 lsp 60+%0,”:c;sav_screenshot
“+$3+”_”+$1+”.bmp”,435,67+(%050 - 550)
print 1
~
next

;saveinfo
;$20 year
;$21 month
;$22 date
;$23 hour
;$24 minute
for %0 = 1 to 10
get_saveinfo %loadpage,%0-1,”getsavetime”
;;;;;;get-saveinfo是我自己写的函数。至于如何实现。我下面说

savefileexist %10,10*(%loadpage-1)+%0-1
if %10 == 0 jumpf
mov $2,””
add $2,$20
add $2,”/”
add $2,$21
add $2,”/”
add $2,$22
add $2,”(”
add $2,$23
add $2,” “
add $2,$24
add $2,”)”

if %0 <= 5 lsp 45+%0,”:s/15,20,0,0;#FFFFFF$2”,180,85+(%040)
if %0 > 5 lsp 45+%0, “:s/15,20,0,0;#FFFFFF$2”,515,85+(%0
40 - 5*40)
~
next

for %0 = 1 to 10
itoa $1,%0
getsavestr $27,10*(%savepage-1)+%0-1
savefileexist %10,10*(%loadpage-1)+%0-1
if %10 == 0 jumpf
if % <= 5 lsp 55+%0,”:s/15,20,0,0;#FFFFFF$27”,40,45+(%040)
if % > 5 lsp 55+%0,”:s/15,20,0,0;#FFFFFF$27”,40,45+(%0
40)
print 1
~
next

lsp 50,”:s/15,20,0,0;#FFFFFF$3”,390,380 ;;显示page
print 1

*wait_load
btndef clear

;;先检查是否有存档,有的话再设定成按键。
savefileexist %10,10*(%loadpage-1)+0
if %10 != 0 exbtn 81,100,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+1
if %10 != 0 exbtn 82,101,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+2
if %10 != 0 exbtn 83,102,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+3
if %10 != 0 exbtn 84,103,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+4
if %10 != 0 exbtn 85,104,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+5
if %10 != 0 exbtn 76,105,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+6
if %10 != 0 exbtn 77,106,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+7
if %10 != 0 exbtn 78,107,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+8
if %10 != 0 exbtn 79,108,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

savefileexist %10,10*(%loadpage-1)+9
if %10 != 0 exbtn 80,109,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

for %0 = 1 to 10
exbtn 86+%0,120+%0,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”
next

exbtn 40,20,”P76P77P78P79P80P81P82P83P84P85P86,(se/MN_SS_SE10.ogg)”

btnwait %1
if %1 <= 0 goto *wait_load

if %1 == 121 mov %loadpage,10:saveload_updata:goto *ny_load

if %1 == 122 mov %loadpage,9:saveload_updata:goto *ny_load

if %1 == 123 mov %loadpage,8:saveload_updata:goto *ny_load

if %1 == 124 mov %loadpage,7:saveload_updata:goto *ny_load

if %1 == 125 mov %loadpage,6:saveload_updata:goto *ny_load

if %1 == 126 mov %loadpage,5:saveload_updata:goto *ny_load

if %1 == 127 mov %loadpage,4:saveload_updata:goto *ny_load

if %1 == 128 mov %loadpage,3:saveload_updata:goto *ny_load

if %1 == 129 mov %loadpage,2:saveload_updata:goto *ny_load

if %1 == 130 mov %loadpage,1:saveload_updata:goto *ny_load

if %1 == 100 mov %present_number,1:goto *load_loop

if %1 == 101 mov %present_number,2:goto *load_loop

if %1 == 102 mov %present_number,3:goto *load_loop

if %1 == 103 mov %present_number,4:goto *load_loop

if %1 == 104 mov %present_number,5:goto *load_loop

if %1 == 105 mov %present_number,6:goto *load_loop

if %1 == 106 mov %present_number,7:goto *load_loop

if %1 == 107 mov %present_number,8:goto *load_loop

if %1 == 108 mov %present_number,9:goto *load_loop

if %1 == 109 mov %present_number,10:goto *load_loop

if %1 == 20 goto *saveload_end

goto *wait_load

*load_loop

savefileexist %10,10*(%loadpage-1)+%present_number - 1
if %10 == 0 return
messagebox “确定要读取这个记录吗”
if %yesno = 0 goto *wait_load

;先清除saveload的系统,再调用loadgame指令调用指定番号的存档
for %0 = 1 to 99
csp %0
next
bg black
print 10,10
loadgame 10*(%loadpage-1)+%present_number - 1

goto *wait_load

return

;;点击返回时,清除saveload系统。
*saveload_end
for %4 = 1 to 99
csp %4
next
print 1
erasetextwindow 1 ;;文字重新显示,前面别用texthide,有bug
return

;;页面更新使用的。
*saveload_updata

for %4 = 40 to 75
csp %4
print 1
next

return

使用循环的时候一定要记得和对象对齐=。=
其实有些东西我偷懒没有写。比如quicksave和quickload。反正按照这个思路是没有问题的。
可能很多人都没有发现,在存档界面也可以存档的。这个你可以用变量判断现在是否在存档系统里面,如果是的话就跳回去,总之就是在这里存不了档就ok。

再复杂一点我们可以用getcursorpos这个指令。
Getcursorpos %1,%2 获得当前指针坐标。
那个适合DC II的存档方式。。我们不谈。

我要谈的是有一个savegame2的指令
savegame2 存档编号,字符串变量
这样可以吧字符串保存进去,但貌似不能保存整形变量
但是你可以装换的么。

那么对于的也有一个loadgame2 语法都是一样的。
就是负责把字符串变量读出来。
但是你保存的时候用的是 $name的话。读取的时候也要读取$name。名字是不变的。
这样的话。就可以做出许多愉悦的系统了。

对了!许多game的window那里都有一个小CG在显示(如 脏翅膀),还有那什么如何获得当前显示的window文字,我好放进存档系统之类的问题,我们下一节再讲。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
学习前先确认一下你的节操是否还在(误)
什么你的节操和三观还在?那我这节怎么叫你学点代码美化?你以后还怎么学lua?
先不管这么多。

我先告诉你们一个指令就是 pretextgosub 。用法和textgosub一样,需要在*define处定义。
所谓的pretextgosub 那就是要在每次显示文字之前就要干完的事。

这里我借用了别人写的代码。
原作者你不会生气的吧=。=
例如:
Pretextgosub *ny_pretext

*ny_pretext
dwavestop 2 ;停止上次未放完的语音,你用其他的方式代替也行。
gettag $0 ;获取[]中的变量,也就是字符串变量

if $0 != “” split $0,”|”,$voice,$name ;使用”|”分隔$0,分别存入$voice,$name
if $0 == “” indent 0:csp 141:csp 142:print 10,200:mov $voice,””:return ;清除lsp 141,142 即姓名标签,清除$voice内容
if $voice != “none” voice $voice ;为”none”时不播放
if $name != “” name $name:indent 1
if $name == “” indent 0

return

;;同时。语音系统也可以这样写的。和pretext系统和在一起写。视具体的移植项目而定。
*voice

dwavestop 0 ;停止上次未放完的语音
getparam $1 ;获取传递变量值
isskip %0 ;返回当前模式值
if %0==1 jumpf ;isskip 返回1(skip mode) 跳过播放语音
;jumpf 跳至下一个~
dwave 0,”voice/“+$1+”.ogg” ;播放语音,语音文件位于 voice 文件夹中
~

return

;======================name===============================
*name

好。这里就是我之前说的那个window对话框旁边那个小的cg显示。
就是这样做的。非常简单。
当然你这里也可以不print 等到cg加载好后再print就可以同时显示。一般原版的GAL就是这样的。
getparam $1 ;获取传递变量值

;以下为显示姓名标签
if $1 == “穗乃香” lsp 142,”system/nameimage.b_000001.png”,0,440:print 10,200:return
if $1 == “米露菲” lsp 142,”system/nameimage.b_000002.png”,0,440:print 10,200:return
if $1 == “雫” lsp 142,”system/nameimage.b_000003.png”,0,440:print 10,200:return
if $1 == “十六夜” lsp 142,”system/nameimage.b_000004.png”,0,440:print 10,200:return
if $1 == “诚” lsp 142,”system/nameimage.b_000005.png”,0,440:print 10,200:return
if $1 == “琥珀” lsp 142,”system/nameimage.b_000006.png”,0,440:print 10,200:return
if $1 == “凛” lsp 142,”system/nameimage.b_000007.png”,0,440:print 10,200:return
if $1 == “二人” lsp 142,”system/nameimage.b_000008.png”,0,440:print 10,200:return
if $1 == “三人” lsp 142,”system/nameimage.b_000009.png”,0,440:print 10,200:return
if $1 == “优” lsp 142,”system/nameimage.b_000010.png”,0,440:print 10,200:return
if $1 == “店主” lsp 142,”system/nameimage.b_000011.png”,0,440:print 10,200:return
if $1 == “穿黑衣的女性” lsp 142,”system/nameimage.b_000012.png”,0,440:print 10,200:return
if $1 == “日和” lsp 142,”system/nameimage.b_000013.png”,0,440:print 10,200:return
if $1 == “白猫” lsp 142,”system/nameimage.b_000014.png”,0,440:print 10,200:return
if $1 == “???” lsp 142,”system/nameimage.b_000015.png”,0,440:print 10,200:return

;也可以使用以下方法,不使用图片,使用文字
lsp 141,”:s/22,22,0,2;#000000$1”,30,455
lsp 142,”system/nameimage.png”,0,440
print 10,200

return

说明一下ONS读取文本的流程:

\1. 读取 [ ] 中字符串(若不存在[] 认为字符串为空
\2. 将 [ ] 中字符串,传递给pretextgosub定义的事件,并执行pretextgosub后返回
\3. 显示正文
\4. 进入textgosub定义的事件,执行后进行下一行重复1.

例如:

我和她在同一个学校上学,还是同班同学,从各方面来说两人都很熟悉。\

[hon_0004|穗乃香]「有点累了吧?」\

第一句 不存在 [] 字符串为空
执行pretext,传递字符串为””
读取”我和她在同一个学校上…”并显示
执行下面的函数,并返回
读取[hon_0004|穗乃香],获得字符串 “hon_0004|穗乃香”
执行pretext,传递字符串为”hon_0004|穗乃香”
读取”「有点累了吧?」”并显示

这样的话之前获取的$name 是可以直接打印出来的

例如一个函数:

*namewindow
Getparam $2 ;;就是获得name
If $2 == “” return
If $2 != “” $2:br
Return

大概就是这个意思。
那个loadgosub 含义可以以此类推,只不过一般不会用上它。要看你制作的系统咯。
也可以这样实现获得window显示文字的函数。还是在pretextgosub中使用gettag $0这样的函数。我们可以这样来分割。
没有名字的时候
[||这个是正文]

有的时候
[CGM_00|萌喵|这个不是正文]

我们还是可以分割开的。然后以上面的方式打印在window对话框那里。
其实貌似还有其他专门的函数。但是我记不得。后面我要教你们更高端的方法。
选项系统我就不教了。你们参照按键制作的办法来搞定。会很简单的。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
剩下的只有鉴赏和lookback系统
鉴赏模式ONS针对lsp还有一种新用法。
lsp 图片编号,(“图片a路径”),”图片b路径及参数”,”图片c路径及参数”,左上角x坐标,y坐标,透明度
专用于cg一览模式的语法,当图片a被载入过时,显示图片b,否则显示图片c。

我还是觉得没什么用。毕竟很局限。
我们只有会lsp的基础语法就可以自己做鉴赏了。
我的办法就是为每一个CG建立一个对应的整形变量。这个CG加载过后,就将对应的变量赋值为1,初始化是0.这个是全局变量。
这样我们就可确认哪些图片是加载过的。
鉴赏图片加载可以使用类似于saveload那样的系统。

我也不细讲。无论你用怎样的代码实现都ok。选择了ONS就不要给我提效率问题。

我们最后一个需要谈的系统就是lookback系统。

在这之前,我们需要在*define标签加入一个指令
maxkaisoupage 30
其意思就是记录30页window文字。

还有。如果你嫌快进的时候速度慢了。我们可以在*define处加入effectcut指令。
这样就可以跳过ONS内部的效果了(其实都被改成瞬时效果了)

下面是例子(栗子):
*textlog

checkpage %0,1 ;检查第一张log页是否存在
if %0=0 return ;如果不存在返回

btndef clear

dwavestop 0 ;停止未放完的语言,这可有可无。

;清除文本框,载入背景。函数自己写
vsp_btn0:textoff

lsp 50,”system/customlog/back.b_000001.png”,0,0,230
lsp 49,”system/customlog/captionlog.png”,0,20
lsp 48,”system/customlog/systembutton.b_000001.png”,200,20
lsp 47,”system/customlog/scrollbar_bar.b_000001.png”,760,115
lsph 46,”system/customlog/systembutton.b_000002.png”,200,20

;;加载上基本的按键和图片

mov %backlogtotal,0 ;回顾页数统计变量初始化
gosub *textlog_page ;回顾页数统计

mov %10,0 ;页码初始化

*text_go

btndef clear

mov %0,(372*%10)/(%backlogtotal-4)
lsp 45,”system/customlog/scrollbar_button.b_000001.png”,749,487-%0
lsph 44,”system/customlog/scrollbar_button.b_000003U.png”,749,487-%0
lsph 43,”system/customlog/scrollbar_button.b_000003D.png”,749,487+34-%0

;清除上一页图片,重新刷新
csp 11
csp 12
csp 13
csp 14

csp 21
csp 22
csp 23
csp 24

csp 31
csp 32
csp 33
csp 34

;取得文本信息,并打印出来
if %backlogtotal>0 : getlog $11,%10+0 : logsp2 26,$11,120,490-5,20,20,0,1,#FFFFFF
if %backlogtotal>1 : getlog $12,%10+1 : logsp2 27,$12,120,370-5,20,20,0,1,#FFFFFF
if %backlogtotal>2 : getlog $13,%10+2 : logsp2 28,$13,120,250-5,20,20,0,1,#FFFFFF
if %backlogtotal>3 : getlog $14,%10+3 : logsp2 29,$14,120,130-5,20,20,0,1,#FFFFFF

;取得标签及声音信息,并打印出来。这个就是核心代码了。
;可能新学的看上去有点痛苦。但是会习惯的。

notif $11=”” : gettaglog $21,%10+0 : notif $21=”” : split $21,”|”,$41,$31 : lsp 21,”:s/20,20,0,0;#FFFF44”+”【”+$31+”】”,120,490-16 , 255 : if $41!=”none” && $41!=”” : lsp 31,”:a;system/customlog/systembutton_voice.b_000001.png”,48,490-9 , 255 : lsph 11,”:a;system/customlog/systembutton_voice.b_000002.png”,48,490-9 , 255 : exbtn 31,10,”P11C31”
notif $12=”” : gettaglog $22,%10+1 : notif $22=”” : split $22,”|”,$42,$32 : lsp 22,”:s/20,20,0,0;#FFFF44”+”【”+$32+”】”,120,370-16 , 255 : if $42!=”none” && $41!=”” : lsp 32,”:a;system/customlog/systembutton_voice.b_000001.png”,48,370-9 , 255 : lsph 12,”:a;system/customlog/systembutton_voice.b_000002.png”,48,370-9 , 255 : exbtn 32,11,”P12C32”
notif $13=”” : gettaglog $23,%10+2 : notif $23=”” : split $23,”|”,$43,$33 : lsp 23,”:s/20,20,0,0;#FFFF44”+”【”+$33+”】”,120,250-16 , 255 : if $43!=”none” && $41!=”” : lsp 33,”:a;system/customlog/systembutton_voice.b_000001.png”,48,250-9 , 255 : lsph 13,”:a;system/customlog/systembutton_voice.b_000002.png”,48,250-9 , 255 : exbtn 33,12,”P13C33”
notif $14=”” : gettaglog $24,%10+3 : notif $24=”” : split $24,”|”,$44,$34 : lsp 24,”:s/20,20,0,0;#FFFF44”+”【”+$34+”】”,120,130-16 , 255 : if $44!=”none” && $41!=”” : lsp 34,”:a;system/customlog/systembutton_voice.b_000001.png”,48,130-9 , 255 : lsph 14,”:a;system/customlog/systembutton_voice.b_000002.png”,48,130-9 , 255 : exbtn 34,13,”P14C34”

print 10,200

exbtn_d “C11C12C13C14C43C44P45C46P47P48P49”
exbtn 46,20,”P46C48S2,(system/se/systembutton_voice1.wav)”
exbtn 44,21,”P43P44C45” ;此处翻页按钮我拆为两部分
exbtn 43,22,”P43P44C45” ;上半部分返回21向上翻页,下半部分返回22向下翻页

textbtnwait %0 ;获取返回按键值

;返回
if %0 = -1 wave “system/se/systembutton_voice.wav” : goto *textlog_end
if %0 = 20 wave “system/se/systembutton_voice.wav” : goto *textlog_end

;向上,向下控制

;;不懂||运算的自己找谭浩强。
if %0 = -2 || %0 = 21 if %backlogtotal > %10+4 : add %10,1 : goto *text_go
if %0 = -3 || %0 = 22 if %10 > 0 : sub %10,1 : goto *text_go
if %0 = -3 || %0 = 22 if %10 = 0 : wave “system/se/systembutton_voice.wav” : goto *textlog_end
;返回-3的注释,若%10(当前页)大于零,减一重新返回text_go,绘制%10-1页的回顾信息
; 若%10等于零,说明当前在最后一页,退出回顾模式

;语音回放控制
if %0 = 10 voice $41
if %0 = 11 voice $42
if %0 = 12 voice $43
if %0 = 13 voice $44

goto *text_go

*textlog_end

dwavestop 0 ;停止未放完的语言

;清除回顾图片,文本框重新显示
for %0=10 to 50
csp %0
next

for %0=141 to 142
vsp %0,1
next

print 10,200
texton

return

*textlog_page

inc %backlogtotal ;backlogtotal+1
checkpage %0,%backlogtotal ;确认该页是否有回顾
if %0=1 goto *textlog_page ;如果有回顾返回确认下一页

return

Checkpage就这用法。
这个就是目前最常用的lookback系统。
一些没有见过的指令自行理解吧。这个是使用篇的最后一章了。如果这能力还没有的话,你该回去复习一下前面的内容。
其他的东西该自己去写写了。
完结了么?没有完结。