〓 光荣的荆棘道 〓

啥?圣诞节还早呢?我怕到时候自己给忘了嘛……

 
 
 
 
 
 

从零开始的吉里吉里KAG入门 其七:用宏使脚本变得简便

2009-11-27 21:06:48 阅读(3) 评论(0)

宏(MACRO)是将复数的命令行绑定在一起为一条新命令的功能。

在脚本中经常出现大量非常相似甚至是重复的段落,使用宏编集后可以使故事部分的编写输入大幅简化。

 

一、宏的编集法

使用@macro和@endmacro确定编集范围,@macro中指定属性值name=这段命令组成的宏的名字(可以使用英文数字和汉字)。

例如在对话位置显示某npc的台词:

@macro name=lihua

@cm

@position layer=message0 page=fore visible=true opacity=180 left=70 top=400 width=660 height=160

@current layer=message0

@nowait

@font color=0xff0000

【梨花】[r]

@resetfont

@endnowait

@endmacro

使用时写入:

@lihua

这是梨花的台词。[l][r]

请特别注意翻页的地方。[p]

@lihua

翻页符号后请重新写入命令。[l][r]

使用此方法简化了在固定位置填入npc姓名并赋予颜色的步骤,有多少角色就定义多少个对应的宏,在多个pnc对话中可以大幅降低代码输入的繁琐程度。

 

二、自定义宏的属性

在进行宏的编集时,可以使用符号%标注尚未确定的留待以后使用时临时填写的内容,以百分号开头的部分即为这个宏中的属性。

例:

@macro name=newtag

@font color=%rgb

这是彩色文字效果。

@resetfont

@endmacro

使用的时候书写:

@newtag rgb=0x00ff00

在这个例子中自定义了宏newtag,rgb是它的属性。属性rgb所对应的填写内容由定义时其对应的属性所决定,比如此处对应的是@font命令下的color属性,所以其内容格式应该为0xRRGGBB格式。

 

三、宏的使用

由于脚本内容是按行的顺序读入的,在使用自定义的宏命令时,应确保此宏的定义部分在使用地点之前的脚本中。

一般来说,将宏放在一起罗列在脚本最初被读入的位置。

更整洁的做法是将宏放在一个单独的脚本文件中,然后在first.ks脚本的最开始导入这个脚本的内容。具体做法是在存放所有宏的某脚本文件的最底行加入@retrun后,在first.ks脚本最初以@call storage=xxx.ks的方式调来里面的全部内容。

以下是自定义游戏界面的例子,尺寸为800x600,需要使用5个前景层,请用记事本更改Config.tjs中的前景层数量。

以下是放在独立的宏内容脚本mo.ks中的内容。

*mo

;进入场景:放背景、音乐、对话框

@macro name=入场

@bg storage=%背景 time=1000

@bgm storage=%音乐 time=500

@wait time=1000

@fg layer=3 storage=frame.png time=1000

@endmacro

;离场,清理音乐、文字、前景层

@macro name=清场

@stopbgm time=500

@cm

@cl layer=4

@cl layer=0

@cl layer=1

@cl layer=2

@cl layer=3 time=1000

@endmacro

;显示陈述文字

@macro name=陈述

@cm

@position layer=message0 page=fore visible=true opacity=0 left=70 top=420 width=660 height=140

@current layer=message0

@endmacro

;显示角色名

@macro name=角色

@cm

@current layer=message0

@position layer=message0 page=fore visible=true opacity=0 left=250 top=420 width=660 height=140

@nowait

@font color=0xff0000

@emb exp="tf.npc = mp.名字"

】[r]

@resetfont

@endnowait

@endmacro

;显示头像

@macro name=头像

@fg layer=4 storage=%图片 page=fore l=20 t=350

@endmacro

;清除头像

@macro name=无头像

@cm

@cl layer=4

@endmacro

@return

以下是在first.ks中的用法示范(需要两个立绘文件sample1和2,两个头像文件ssample1和2,一个对话框文件frame.png,两张背景图片bg1和2,两个背景音乐文件):

@call storage=mo.ks

*start|开始

@menul

@layopt layer=3 autohide=true

@layopt layer=4 autohide=true

;上面是前期调整,下面是正式内容

@入场 背景=bg1 音乐=bgm01

@陈述

进入到第一个场景,背景图是bg1,背景音乐是bgm01。[p]

@fg storage=sample1 pos=c

@头像 图片=ssample1

@角色 名字=角色A

你好,我是向导。[p]

@角色 名字=角色A

觉得这个场景怎么样呢?[p]

@无头像

@fg storage=sample1 layer=0 pos=r

@fg storage=sample2 layer=1 pos=l

@头像 图片=ssample2

@角色 名字=角色B

嗯……[l]还有别的房间吗?[p]

@头像 图片=ssample1

@角色 名字=角色A

有的哦。[p]

@清场

@入场 背景=bg2 音乐=bgm02

@fg storage=sample1 layer=0 pos=r

@fg storage=sample2 layer=1 pos=l

@头像 图片=ssample1

@角色 名字=角色A

这个房间如何?[l][r]

注:在显示名字的宏中使用了变量,在tjs式中定义变量为待指定属性时使用mp.而不是%来获得值。

在编写脚本时,注意使用命令的先后顺序,使游戏顺畅。

关于对话框图像的说明:

对话框可以由和游戏窗口等大的两张图片共同构成,一张是对话框图片本身,一张是针对对话框图片的透明度过滤图片。对话框图片叫做frame的话,透过图片就叫做frame_m。在透过图片上,纯黑为全透明,全白为不透明,而灰度为半透明。在这种格式下就不要求图片一定为png格式也可实现透过效果。

如果想要实现对话框压住头像的效果,请把对话框所占图层和头像所占图层倒过来,将对话框相应位置完全透明即可。

=================================

入门内容暂时就这些,基本内容和早先那个一样(汗),只是例子更加具体化一些。

如果你想全面了解KAG,请阅读http://kcddp.keyfc.net/bbs/index.php论坛中的官方KAG文档(不完全汉化,但是已经很能看了),或者参照更高级别的教程。

阅读(3) | 评论(0) | 阅读全文>>

EP6肖像画偷跑?快来瞻仰巴托拉卿

2009-11-27 16:23:24 阅读(13) 评论(0)

EP6肖像画? - 天娜.M - 〓 光荣的荆棘道 〓

不知道谁从哪里弄来的图,我上官网转了一圈没找着龙骑士把它放在哪里了,但是从画面上看应该是系列图作者江草天仁画的无误。

虽然龙骑士07在访谈中说过“想让战人也穿新衣服但是一直没什么机会”,但是我们可以看到,不知为何大巴托拉卿他只是拿了老爷子的披风而已……Orz

EP6 Dawn of the golden witch ~黄金魔女的黎明~

多么充满希望的标题,贝阿朵会活过来吗?(对不起我透了)

据说12月31日发售,好快。

另外据汉化者前田K1报告,EP5的汉化也将于年底结束。

阅读(13) | 评论(0) | 阅读全文>>

从零开始的吉里吉里KAG入门 其六:变量的基础使用

2009-11-24 20:30:45 阅读(4) 评论(0)

本节的内容是KAG中变量的定义、比较,以及在脚本用变量对游戏流程进行控制。变量这玩意听起来挺唬人的,但是我们现在用的都是基本中的基本,至少在本节的范围内,我想不用担心搞不懂。

这节的内容只有一个难点——很容易写错。各位,请打起十二分的精神,千万不要写错!在编写这些例子时,我一个字母一个符号地挨着核对哪里有问题,结果还是错了好几回……真是一个不留神就bug,总能让人泪流满面的!

也许这就是我当年C语言考试总是没法合格的原因(默)。

一、变量的定义和赋值

1、变量的类型

KAG中可以定义三种变量:

f.开头的游戏变量,保存在游戏进度存档中,与游戏内容相关的变量基本都用此类型。

sf.开头的系统变量,保存在系统存档中,和游戏进度无关,用于游戏的系统设置以及其它全局数据。

tf.开头的临时变量,不被保存,用于其他变量临时性计算或比较的场合,起助力作用。

变量的命名:

KAG中变量用半角英文或汉字开头,后面还可以接入下划线和数字。

 

1、变量的定义和赋值

变量的定义和计算都使用@eval命令。初次定义变量可以只写变量名而不给予值,这时候被定义的变量是个空值。数字变量可以给予整数或小数。

例:

@eval exp="f.flag1 = 1000"

以及

@eval exp="f.flag1 = f.flag + 10"

上面两行分别是定义一个游戏变量flag1,其值为1000,以及将这个变量的值增加10。

注:exp后面的部分要使用半角扩起,其内部的计算符前后可以加入空格。

===================================

特别提醒

圈起exp内容的引号是一个半角双引号,不是两个半角单引号,也不是汉字模式的双引号。在一些字体模式下这些引号看上去几乎无法分辨,如果你的变量定义后在游戏运行时显示有错误找不到f之类,都是这个引号地方出现问题,请把字体切换到其他样式再检查。

===================================

变量值一般使用整数,也可以使用小数,如果给某变量指定了文字串内容,则其为文字变量。

定义文字变量时,文字列的内容要用半角单引号圈起来。

例:

@eval exp="f.flag2 = '文字列'"

只有同类型的变量才能进行计算和比较,数字变量和文字变量无法进行比较或计算,例子中的flag1和flag2是不能比较或计算的。

 

# 如果想要在游戏中显示变量的值使用emb命令,例:

变量f.flag1的值是[emb exp="f.flag1"]。[l][r]

直接显示某数字变量的内容在游戏中是很少用到的功能,大多是测试用,如果将变量值定为需要玩家输入的文字列,它倒是可以用于自定义角色名字之类的地方。

 

二、变量的计算和比较

1、变量的计算

数字变量可以进行加减乘除的计算(+ - * /),文字变量可以相加(+)。

例:

@eval exp="f.flag2 = ’hoge'"

@eval exp="f.flag3 = 'une'"

@eval exp="f.flag1 = f.flag2 + f.flag3"

在这个例子中,f.flag1是一个文字变量,其值是hogeune。

 

2、变量的比较

KAG中变量的比较使用这些判断式:

a==b:a等于b

a!=b:a不等于b

a<b:a小于b

a>b:a大于b

(还可以使用>=和=<)

注意:判断“a等于b”用的是两个等号,如果使用一个等号的话意思是把等号右边的值给予左边。

判断式不计算两个数据的内容,它只产生两种结果“真”或者“假”。利用这个“真”还是“假”的结论,可使用if指令判断某一段内容是否被执行——如果exp的值是真,则执行从if到endif的脚本,如果exp的值是假则直接跳过这段内容。

例:

@eval exp="f.flag1 = 1000"

@eval exp="f.flag1 = f.flag + 10"

@if exp="f.flag1 > 1000"

变量flag1大于1000。[l][r]

@endif

@if exp="f.flag1 <= 1000"

变量flag1不大于1000。[l][r]

@endif

在这个例子中,由于flag的值是1010,所以游戏运行后显示的是"变量flag1大于1000"。

 

三、变量的利用

1、利用游戏变量监视某一段脚本的被执行情况

假设我们想要知道玩家在前面的游戏中是否完成过某一段情节,比如访问角色A,则事先定义某变量f.talk_a,在访问A的部分将其值变更为1,在需要的时候只要看看talk_a的值就知道了。

下面的例子是让玩家通过选择肢自由走访另两个场景,但是限定为在全部访问完毕后才能离开。

我在其中使用了两个游戏变量visit1和visit2用于判断进入两个场景的情况,并且在判断时将两个if套用。

@position layer=message0 page=fore visible=true opacity=180 left=70 top=450 width=660 height=140

@eval exp="f.visit1 = 0"

@eval exp="f.visit2 = 0"

 

*stage01|走廊

@cm

@bg storage=bg1 time=1000

 

这里是走廊。[l]四处转一转吧,去哪里好呢:[r]

[link target=*stage02]教室 [endlink][r]

[link target=*stage03]办公室 [endlink][r]

@if exp="f.visit1 == 1"

@if exp="f.visit2 == 1"

[link target=*end]都去过了,算了吧[endlink]

@endif

@endif

@s

 

*stage02|教室

@cm

@bg storage=bg2 time=1000

@eval exp="f.visit1 = 1"

这里是教室。[l][r]

再转转吧。[p]

@jump target=*stage01

 

*stage03|办公室

@cm

@bg storage=bg3 time=1000

@eval exp="f.visit2 = 1"

这里是办公室。[l][r]

再转转吧。[p]

@jump target=*stage01

 

*end

@cm

刚才所有的场景都看过了。[l][r] 

在这个例子中,玩家每次选择进入教室或者办公室后,对应的游戏变量visit1或者visit2的值会变成1。在两个变量的值变成1的时候,在走廊的选项栏中才会显示第三个项目。

注1:由于我们每次都会返回走廊,两个变量一定要放在走廊的标签更前面的地方,否则它们会被再次赋值为0而失去了判断的依据。

注2:使用完毕后可以用类似@eval exp="delete f.flag1"的句子删除不需要的变量。当然如果不会妨碍游戏进程的话,放置着留待下次使用也可以。

这种判断思维可以用在很多地方,例如制作CG图片展:游戏中的CG各对应一个变量(此处应该用系统变量了),然后在展览界面里把CG的缩略图弄成按钮,如果CG打开过就显示,没打开过就不显示。

 

2、比较NPC的好感度变量,选择数值最高者所对应的结局

假设游戏有四个可攻略人物,其好感度变量是f.a、 f.b、 f.c、 f.d,在游戏过程的每个选择肢目标后根据实际内容对好感度值进行加减。然后在游戏面临进入结局分支时……

以下内容中,首先利用一个临时变量取得四个变量中的最高值,然后再进行一次比较,看四个变量中哪个值最先和最高值相等,就跳到其对应的结局标签。

例:

@eval exp=" f.a = 100"

@eval exp=" f.b = 100"

@eval exp=" f.c = 100"

@eval exp=" f.d = 100"

;========在游戏过程中累计加减=========

;========以下是变更后的假定值=========

@eval exp=" f.a = 134"

@eval exp=" f.b = 167"

@eval exp=" f.c = 79"

@eval exp=" f.d = 201"

;========下面将要进行比较判断=========

@eval exp="tf.judge = 0"

;设置了一个比较用的临时变量judge

 

@if exp="f.a > tf.judge"

@eval exp="tf.judge = f.a"

@endif

 

@if exp="f.b > tf.judge"

@eval exp="tf.judge = f.b"

@endif

 

@if exp="f.c > tf.judge"

@eval exp="tf.judge = f.c"

@endif

 

@if exp="f.d > tf.judge"

@eval exp="tf.judge = f.d"

@endif

;用这个临时变量获得了abcd中的最大值

 

@if exp="tf.judge == f.a"

@jump target=*a

@endif

 

@if exp="tf.judge == f.b"

@jump target=*b

@endif

 

@if exp="tf.judge == f.c"

@jump target=*c

@endif

 

@if exp="tf.judge == f.d"

@jump target=*d

@endif

;根据临时变量的值判断abcd中谁和他相等,谁就是最大值。如果有两个相等,则较靠前的获得优先。

;以下是四个结局的标签,其中用emb显示了对应的好感度值。

*a

好感度是

@emb exp="tf.judge"

,分支A。[p]

@jump target=*end

*b

好感度是

@emb exp="tf.judge"

,分支B。[p]

@jump target=*end

*c

好感度是

@emb exp="tf.judge"

,分支C。[p]

@jump target=*end

*d

好感度是

@emb exp="tf.judge"

,分支D。[p]

@jump target=*end

 

*end

游戏结束。[l][r]

注:好感度变量最好根据角色的个数和名字在一起进行指定。本例子中为了打字能省事一点使用的变量名和标签名都非常简短,在实际的游戏操作中请注意不要使用过于简单的命名,最好是使用能够一看就知道是指什么的名字。

阅读(4) | 评论(0) | 阅读全文>>

从零开始的吉里吉里KAG入门 其五:文字链接与按钮

2009-11-23 21:42:41 阅读(5) 评论(0)

现在大家应该都心里有数了,吉里吉里是从上至下运行脚本first.ks中的内容来构建游戏画面的。在实际的脚本编写中,我们把游戏内容分割成几个互相关联的脚本,并将同脚本内的内容分割成多个块,通过在不同块之间跳跃组合,令游戏内容变得灵活多变。

 

一、游戏内容的分割与标注

1、在脚本中使用标签

脚本中以星号开头的地方是标签,标签单独占一行,格式如下:

*标签名|显示名

标签名使用半角英文开头,后面可加入数字

竖线后的显示名可以使用中文,这个内容会在游戏存档位被显示出来(注:使用游戏窗口上面的保存和读取的时候,只有带显示名的标签才是保存位置)。

 

2、跳跃到某标签

需要跳跃到某个地方时用@jump命令,常用属性有指向目标脚本的storage和指向具体标签的target两项,根据具体需要可以省略地运用,比如同脚本内时就可以省略storage。

例1:

*ch01|第一章

跳跃到第三章。[l][r]

@jump target=*ch03

*ch02|第二章

这里的文字其实不会被运行。[l][r]

*ch03|第三章

你看到的是第三章的内容。[l][r]

在上例中脚本运行直接从ch01跳到ch03部分,不运行ch02的部分。

例2:

@jump storage=01.ks target=*ch01

运行到这一行时会直接跳向另一个脚本01.ks中的*ch01标签。

 

二、制作文字链接

1、基本命令@link和@endlink

利用@link和@endlink可以将其之间的文字设置成链接。

例:

@link storage=01.ks target=*ch01

第一章

@endlink

这段脚本是一个指向01.ks的*ch01的文字链接“第一章”

另外这个脚本也可以写成:

[link storage=01.ks target=*ch01]第一章[endlink]

因为只需要一行这样写多个放在一起时会比较整齐。

@link的常用属性:

storage=目标所在的脚本文件名

target=目标标签

exp=tjs式(填入tjs式,比如关闭游戏窗口之类)

color=0xRRGGBB鼠标指上去时候高亮块的颜色

hint=鼠标指向时出现的说明文字

clickse=点击时效果音

enterse=指向时效果音

以上属性根据需要选择性使用

 

2、文字菜单制法

单靠以上的链接命令,我们的链接是没法正常地显示在游戏画面中的。在定位并建立好与目标的联系之后,还必须使用一个等待命令@s来等待玩家选择。

每个链接组的所有项目共用其末尾的一个@s命令。

例:

;文字区扩到最大,无底色

@menul

;定位第一个链接的位置、内容

@locate x=300 y=180

[link storage=01.ks target=*ch01]第一章[endlink]

;定位第二个链接的位置、内容

@locate x=300 y=220

[link storage=01.ks target=*ch02]第二章[endlink]

;定位第三个链接的位置、内容

@locate x=300 y=260

[link storage=01.ks target=*ch03]第三章[endlink]

;等待玩家选择

@s

这段命令构筑了一个跳往1、2、3章的竖排列选单。

在我们下载的程序包中有个范例游戏《超分支》,它的菜单就是用此方法制作的,在开始处和结尾处使用了@nowait于@endnowait命令组来使菜单文字瞬间显示。

 

3、 游戏对话中的选择肢

在游戏中加入选择肢可以使玩家更具参与感,不同的选择肢使故事走向不同结局是文字ADV常见的方式。将对话文字直接设置为选择肢的例子如下:

*start|开始

请在下面的选项中选一个吧:[r]

[link target=*select1]选项1[endlink][r]

[link target=*select2]选项2[endlink][r]

[link target=*select3]选项3[endlink][r]

[s] 

*select1

[cm]

你选择了选项1。[l][r]

@jump target=*end

*select2

[cm]

你选择了选项2。[l][r]

@jump target=*end

*select3

[cm]

你选择了选项3。[l][r]

@jump target=*end 

*end|结束

点击返回最开始处。[p]

@jump target=*start

这是一个非常基本的例子,在各分支的内容末尾合龙到一起后跳回开头形成一个循环,所以可以反复无限选择。如果想要强制玩家进行所有的分支项目才能从对话中脱出,可以加入变量判断(此部分内容请参考后面的章节六)。

这里要特别指出的是,把文字做成链接,其位置会受到其所在文字层画布属性的限制。例如在使用底部对话模式的文字层时无法将选项脱离对话框放置在画面中央,而如果狭窄的对话框区域内选项行过多,可能会妨碍显示效果的情况。

如果想要脱离对话框将选项放置在游戏画面的中间,应该将选项放置在另一个全屏的透明文字层上。

例:

*start|开始

@position layer=message0 page=fore visible=true opacity=180 left=70 top=450 width=660 height=140

@position layer=message1 page=fore visible=true opacity=0 left=0 top=0 width=800 height=600

请从画面选择一个项目:

@current layer=message1

@nowait

@locate x=300 y=200

[link target=*a01]选项1[endlink]

@locate x=300 y=300

[link target=*a02]选项2[endlink]

@endnowait

@s 

*a01

@cm

@current layer=message0

你选择了选项1.[l][r]

点击返回。[p]

@jump target=*start

*a02

@cm

@current layer=message0

你选择了选项2.[l][r]

点击返回。[p]

@jump target=*start

 

三、制作按钮

按钮的基本原理和文字链接大致相同,只是需要用到按钮图像。

1、按钮图像的格式

按钮可以使用带透明度的PNG图像(jpg也没问题,但是就不能透明了),是“通常”“按下”“悬浮”三种状态水平并列的一张合并图像。

 

2、按钮命令

按钮使用@button命令,其常用属性有

graphic=图像名

storage=脚本文件名

target=标签

exp=tjs式

recthit=图片上透明的地方是否有点击效果(true或者false)

hint=鼠标悬浮时候的说明文字

clickse=点击音效

enterse=指向音效

以上属性根据需要选择性使用。

按钮虽然使用图片,但是其位置在文字层上,同样也受到文字层画布属性的限制。

准备好“开始游戏”和“结束游戏”的按钮图片以及背景图片,我们可以做出一个简单的开始菜单。

例:

;设置message0的属性

@menul

;导入背景图像

@bg storage=bg1 time=1000

@wait time=1000

;安排按钮的位置和目标

@locate x=300 y=380

@button graphic=start.png target=*ch01

@locate x=300 y=480

@button graphic=end.png exp= kag.close()

@s 

*ch01|第一章

;在开始前,要清空菜单内容

@cm

;切换一张新的背景图像

@bg storage=bg2 time=1000

;重定义文字层0的属性

@position layer=message0 page=fore visible=true opacity=180 left=70 top=450 width=660 height=140 marginl=10 margint=10 marginb=10 marginr=10

游戏开始。[l][r]

注:这个例子中的结束按钮使用的即是关闭游戏窗口的tjs式,使用tjs式可以给予按钮各种复杂的功能。

按钮的使用和文字链接的使用原理基本相通,想要使用字体漂亮的游戏内选择肢,可以把选择肢内容做成按钮安排在新的文字层,即可安置在画面的任何位置。

阅读(5) | 评论(0) | 阅读全文>>

红茶给的贺图

2009-11-22 22:06:01 阅读(14) 评论(6)

红茶给的贺图 - 天娜.M - 〓 光荣的荆棘道 〓

不知道直接贴她相册里的地址能不能顺利显示厄……

话说我都想不起看点击数的,看到红茶的blog上更新了贺图回家一看才明白:“啊,原来真的是我啊”(默)

阅读(14) | 评论(6) | 阅读全文>>

查看所有日志>>

 
 
 
 
 
 
 
 

  天娜.M

 不腐不烂不宅会死星人 金牛座

 发消息  写留言

 
自我介绍宅度70%、腐20%、烂10%、特技赖床蹲家不出门、加强型大叔控属性——听说每个大叔控的心里都住着一个大叔,在我心里的大概是个热血闷骚型吧 XD
博客等级加载中...
今日访问加载中...
总访问量加载中...
最后登录加载中...
 
 
 
 
 
 
 
心情随笔列表加载中...
 
 
 
 
 

自定义模块

 
 
模块内容加载中...
 
 
 
 
 
 
 
博友列表加载中...
 
 
 
 
 

自定义模块

 
 
模块内容加载中...
 
 
 
 
 
 
 
圈子列表加载中...
 
 
 
 
 
 
 
列表加载中...
 
 
 
 
 
 我要留言
 
 
 
留言列表加载中...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2009