Project1
标题: 一个文字类游戏脚本的构思 [打印本页]
作者: 沉滞的剑 时间: 2013-4-19 23:48
标题: 一个文字类游戏脚本的构思
打算在开工之前讨论一下可行性
特点:
1、从其他文字编辑器中批量输入文本
2、支持批量导入条件判断和对话选项
3、提供显示文字信息模板,把”对话“、”获得物品信息“”任务“模块化
构思:
interpret[index] 哈希表{”字符串“ => 数字} 标签解释器 读取标字符串label,转换成dialog\condition\option[index]数组内可以使用的整形label索引
Class Dialog 实例$game_dailog[index][label]
属性
index 组编号 给对话分组
label ”字符串“
label_target ”字符串“ 指向性标签,用于上下文 ”!“表示终结
condition ”条件label“ 读取Option类,只有当真的时候这句话才被执行,并按Option类的标签执行下一句,否则按自己的labeltarget执行 ”!“表示true
option ”选项lable“ 当不为”!“时,执行$game_option[index][labeltarget]
picid 图像编号 表示显示文字时的头像编号
content ”“ 对话内容
方法 self.setup
$game_dailog[index][label] = Dialog.new(index,label)
读取文本
{......} 表示一段文字
{......}! 表示文本全部完结
匹配信息{*(index)@("label")#(condition)&(condition)$(picid)%("content")>>("label_target")}
Class Condition 实例$game_condition[index][label]
属性
index 序号
label ”标签“
self 自身 = 真值
Class Option 实例
index 序号
label ”标签“
options 数组{["content","label_target"]}"content" 选项文字 ”label_target“返回dialog的标签
方法
run 遍历整个options数组,创建选项窗口,选择后返回序号i
匹配信息{*(index)@("label")#(condition)%("content")>>("label_target")}["content","label_target"]把添加到实例[index][label].options的末尾 当condition 为true
按格式写文本,然后匹配就能得到所有Option和Dialog信息,数据库算是建立好了
index用来区分不同的对话内容,方便管理
”label“用字符串来写方便查找转向位置比如可以写成1.2a这样的
接下来可以尝试模块化这些东西
比如你设定所有人都包含以下对话
1、初次见面对话
2、例行问好 当 有特定任务剧情的时候跳转到任务....
3、你可以选择和他 1)谈论近况2)了解信息3)交易(如果他是个商人)4任务)5)同伴6(管理队列交换物品感情交流等))7)告别
4、任务信息.......
.......
你可以按照一个模式给这些对话设置一个index标签,当新建另外一个人物的时候,你只需要修改index就可以了,只要你包含了所有可能的逻辑,就可以套用公式。
因为我要做一个纯文本类游戏,文字量巨大,用RMVA本身脚本首先选项就只有4个,而且非常不好搞清楚脉络,所以打算采取这么个形式,不知道大家有什么看法。
作者: 6rp 时间: 2013-4-20 15:16
ruby 有load 方法,可以调入外部文本来执行的。
你的文本就设计成ruby认可的格式就行了,不用从新写编译器的。
作者: 沉滞的剑 时间: 2013-4-20 15:35
本帖最后由 沉滞的剑 于 2013-4-20 15:41 编辑
6rp 发表于 2013-4-20 15:16
ruby 有load 方法,可以调入外部文本来执行的。
你的文本就设计成ruby认可的格式就行了,不用从新写编译器 ...
我是打算从外部读取的,因为RM内部没有好的文字编辑器。
但是读入的只是字符串,这些字符串没法表示上下文的关系,
没法表示出现的条件。还得进行2次编辑成一个集合了对话元素的类才行。
就算我读入了对话,我最多也只能按行读取,然后编号,但是关键的是我没有方法调用。
读取的文字还得带上处理标签,然后实例化。头像是什么,什么条件出现,哪一句台词指向它,它指向哪一句台词或者选项等等
读取了文字没法变成对话还是无用。
这是我写的Dialog类
已经debug完毕无误。
$dialog = Array.new(72,Array.new)
$text = '{1#2@3&4*5$我爱你<6>}'
##暂时用全局变量代替输入数据,io类我还在学习中
#=============================================================================
class Dialog
attr_accessor :index
attr_accessor :label
attr_accessor :label_target
attr_accessor :condition
attr_accessor :option
attr_accessor :picid
attr_accessor :content
@@interpret = [Hash.new]
##============================================================================
##============================================================================
def self.getsentence (text)
i = []
j = []
m = 0
x = 0
y = []
text.each_char {|char|
if char == '{'
i.push m
end
if char == '}'
j.push m
end
m = m + 1
}
while x < i.size
y[x] = text[i[x]+1...j[x]]
x = x + 1
end
return y
end
def self.getindex (text)
i = ""
m = 0
text.each_char {|char|
if char == '#'
i =text[0..m]
return i
end
m = m + 1
}
return "0"
end
##=============================================================================
def self.getattri (text,tag1,tag2)
i = 0
m = 0
n = 0
l = ""
text.each_char {|char|
if char == tag1
m = i
end
if char == tag2
n = i
end
i = i + 1
}
return text[m+1...n]
end
##=============================================================================
def self.setup
@@interpret = [Hash.new]
s = []
i = 0
li = 0
p = 0
l = ""
lt = ""
c = ""
o = ""
con = ""
text = $text
s = Dialog.getsentence(text)
for f in s
i = Dialog.getindex(f).to_i
l = Dialog.getattri(f,'#','@')
c = Dialog.getattri(f,'@','&')
o = Dialog.getattri(f,'&','*')
p = Dialog.getattri(f,'*','$')
con = Dialog.getattri(f,'$','<')
lt = Dialog.getattri(f,'<','>')
$dialog[i].push(Dialog.new(i,l,c,o,p,con,lt))
$dialog[i].compact!
li = $dialog[i].size - 1
@@interpret[i] = Hash.new if @@interpret[i] == nil
@@interpret[i][l] = li
end
end
def initialize(i,l,c,o,p,con,lt)
@index = i
@label = l
@label_target = lt
@condition = c
@option = o
@picid = p
@content = con
end
end
$dialog = Array.new(72,Array.new)
$text = '{1#2@3&4*5$我爱你<6>}'
##暂时用全局变量代替输入数据,io类我还在学习中
#=============================================================================
class Dialog
attr_accessor :index
attr_accessor :label
attr_accessor :label_target
attr_accessor :condition
attr_accessor :option
attr_accessor :picid
attr_accessor :content
@@interpret = [Hash.new]
##============================================================================
##============================================================================
def self.getsentence (text)
i = []
j = []
m = 0
x = 0
y = []
text.each_char {|char|
if char == '{'
i.push m
end
if char == '}'
j.push m
end
m = m + 1
}
while x < i.size
y[x] = text[i[x]+1...j[x]]
x = x + 1
end
return y
end
def self.getindex (text)
i = ""
m = 0
text.each_char {|char|
if char == '#'
i =text[0..m]
return i
end
m = m + 1
}
return "0"
end
##=============================================================================
def self.getattri (text,tag1,tag2)
i = 0
m = 0
n = 0
l = ""
text.each_char {|char|
if char == tag1
m = i
end
if char == tag2
n = i
end
i = i + 1
}
return text[m+1...n]
end
##=============================================================================
def self.setup
@@interpret = [Hash.new]
s = []
i = 0
li = 0
p = 0
l = ""
lt = ""
c = ""
o = ""
con = ""
text = $text
s = Dialog.getsentence(text)
for f in s
i = Dialog.getindex(f).to_i
l = Dialog.getattri(f,'#','@')
c = Dialog.getattri(f,'@','&')
o = Dialog.getattri(f,'&','*')
p = Dialog.getattri(f,'*','$')
con = Dialog.getattri(f,'$','<')
lt = Dialog.getattri(f,'<','>')
$dialog[i].push(Dialog.new(i,l,c,o,p,con,lt))
$dialog[i].compact!
li = $dialog[i].size - 1
@@interpret[i] = Hash.new if @@interpret[i] == nil
@@interpret[i][l] = li
end
end
def initialize(i,l,c,o,p,con,lt)
@index = i
@label = l
@label_target = lt
@condition = c
@option = o
@picid = p
@content = con
end
end
现在我是在想使用Windows base还是message来显示文本,message我现在还没搞懂怎么用。
作者: 6rp 时间: 2013-4-20 16:42
本帖最后由 6rp 于 2013-4-20 17:59 编辑
建议你学习使用load方法。
练习:
在游戏根目录下存入文本文件try.txt
$name='npc张三'
$text='玩家你好,我是张三!'
$label=2013
$faceid=0 #不知道
# 总之一切都是按照ruby中的规则写文本。
$name='npc张三'
$text='玩家你好,我是张三!'
$label=2013
$faceid=0 #不知道
# 总之一切都是按照ruby中的规则写文本。
然后在游戏脚本中设定一个函数 loadtext
def loadtext(filename='try.txt')
load filename
p $name
p $text
end
def loadtext(filename='try.txt')
load filename
p $name
p $text
end
用这样的方法就可以把外部的文件导入游戏脚本中,不用自己设定什么{}%@#之类的古怪符号。
至于输出,一般就简单的使用$message这个变量就行了,当你函数运行完毕后,message中的文字就会自动刷新到屏幕窗口中了。
作者: 6rp 时间: 2013-4-20 17:37
本帖最后由 6rp 于 2013-4-20 17:39 编辑
6rp 发表于 2013-4-20 16:42
建议你学习使用load方法。
练习:
message就是这样使用的:
$game_message.add('hello')
$game_message.add('hello')
所有文本要使用utf-8格式(有BOM)
而且变量传递不能就那么简单的写,可以用全局变量传递。
文本中
$data=[]
load 'try.txt'
p $data[1]
$game_message.add($data[1])
$data=[]
load 'try.txt'
p $data[1]
$game_message.add($data[1])
这样你试试看吧。
顺便说一下,load 方法使用,好像要忌讳出现中文目录名,否则出错!
作者: 沉滞的剑 时间: 2013-4-20 19:16
6rp 发表于 2013-4-20 17:37
message就是这样使用的:
$game_message.add('hello')[/pre]
感谢已经成功读取文件了
突然发现可以用Excel 批量转换txt 效率提高一大截
唯一遗憾就是不知道如何在类内部使用
不过暂且用类方法解决了
$dialog = Array.new(72,Array.new)
#=============================================================================
class Dialog
attr_accessor :index
attr_accessor :label
attr_accessor :label_target
attr_accessor :condition
attr_accessor :option
attr_accessor :picid
attr_accessor :content
@@interpret = [Hash.new]
##============================================================================
##============================================================================
def self.intercreate(i)
@@interpret[i] = Hash.new
end
def self.intercrease(i,l,li)
@@interpret[i][l] = li
end
def self.interpret(i)
return @@interpret[i]
end
def self.setup
@@interpret = [Hash.new]
load('book.etc')
end
def initialize(i,l,c,o,p,con,lt)
@index = i
@label = l
@label_target = lt
@condition = c
@option = o
@picid = p
p @content = con
end
end
$dialog = Array.new(72,Array.new)
#=============================================================================
class Dialog
attr_accessor :index
attr_accessor :label
attr_accessor :label_target
attr_accessor :condition
attr_accessor :option
attr_accessor :picid
attr_accessor :content
@@interpret = [Hash.new]
##============================================================================
##============================================================================
def self.intercreate(i)
@@interpret[i] = Hash.new
end
def self.intercrease(i,l,li)
@@interpret[i][l] = li
end
def self.interpret(i)
return @@interpret[i]
end
def self.setup
@@interpret = [Hash.new]
load('book.etc')
end
def initialize(i,l,c,o,p,con,lt)
@index = i
@label = l
@label_target = lt
@condition = c
@option = o
@picid = p
p @content = con
end
end
转换成txt以后 Excel 会自动给所有带括号的部分添加双引号,还会插入大量tab,用查找替换一次性删除勉强算是弄掉了def run(i,l,c,o,p,con,lt)
$dialog[i].push Dialog.new(i,l,c,o,p,con,lt)
$dialog[i].compact!
li = $dialog[i].size - 1
p Dialog.interpret(i)
Dialog.intercreate(i) if Dialog.interpret(i) == nil
Dialog.intercrease(i,l,li)
end
i = 1
l = ' 2 '
c = ' 3 '
o = ' 4 '
con = ' 5 '
lt = ' 6 '
run(i,l,c,o,p,con,lt)
def run(i,l,c,o,p,con,lt)
$dialog[i].push Dialog.new(i,l,c,o,p,con,lt)
$dialog[i].compact!
li = $dialog[i].size - 1
p Dialog.interpret(i)
Dialog.intercreate(i) if Dialog.interpret(i) == nil
Dialog.intercrease(i,l,li)
end
i = 1
l = ' 2 '
c = ' 3 '
o = ' 4 '
con = ' 5 '
lt = ' 6 '
run(i,l,c,o,p,con,lt)
大概就生成这么个东西
测试结果还算满意,但是不能在类内使用还是问题,这些变量难道都被当成main函数的局部变量了么?
作者: 6rp 时间: 2013-4-20 19:31
是啊,我也发现是成为main的临时变量了。
所以建议你先弄个全局变量作容器,在文本中调用容器函数给它赋值,回到游戏中再读出来。这样可能更合理一些。
class Mydata
attr_accessor :name,:text,:lable
end
$mydata=Mydata.new
######################
class Mystory
def run
load 'a.txt'
p $mydata.text
end
end
class Mydata
attr_accessor :name,:text,:lable
end
$mydata=Mydata.new
######################
class Mystory
def run
load 'a.txt'
p $mydata.text
end
end
$mydata.text='hello,world'
$mydata.text='hello,world'
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |