设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2007|回复: 6
打印 上一主题 下一主题

[讨论] 一个文字类游戏脚本的构思

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1882
在线时间
1552 小时
注册时间
2013-4-13
帖子
917
跳转到指定楼层
1
发表于 2013-4-19 23:48:56 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
打算在开工之前讨论一下可行性

特点:
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个,而且非常不好搞清楚脉络,所以打算采取这么个形式,不知道大家有什么看法。
夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里

Lv1.梦旅人

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
帖子
600
2
发表于 2013-4-20 15:16:45 | 只看该作者
ruby 有load 方法,可以调入外部文本来执行的。
你的文本就设计成ruby认可的格式就行了,不用从新写编译器的。
怕鼠的猫
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1882
在线时间
1552 小时
注册时间
2013-4-13
帖子
917
3
 楼主| 发表于 2013-4-20 15:35:14 | 只看该作者
本帖最后由 沉滞的剑 于 2013-4-20 15:41 编辑
6rp 发表于 2013-4-20 15:16
ruby 有load 方法,可以调入外部文本来执行的。
你的文本就设计成ruby认可的格式就行了,不用从新写编译器 ...


我是打算从外部读取的,因为RM内部没有好的文字编辑器。
但是读入的只是字符串,这些字符串没法表示上下文的关系,
没法表示出现的条件。还得进行2次编辑成一个集合了对话元素的类才行。
就算我读入了对话,我最多也只能按行读取,然后编号,但是关键的是我没有方法调用。
读取的文字还得带上处理标签,然后实例化。头像是什么,什么条件出现,哪一句台词指向它,它指向哪一句台词或者选项等等
读取了文字没法变成对话还是无用。
这是我写的Dialog类
已经debug完毕无误。
RUBY 代码复制
  1. $dialog = Array.new(72,Array.new)
  2. $text = '{1#2@3&4*5$我爱你<6>}'
  3. ##暂时用全局变量代替输入数据,io类我还在学习中
  4. #=============================================================================
  5. class Dialog
  6.   attr_accessor :index
  7.   attr_accessor :label
  8.   attr_accessor :label_target
  9.   attr_accessor :condition
  10.   attr_accessor :option
  11.   attr_accessor :picid
  12.   attr_accessor :content
  13.   @@interpret = [Hash.new]
  14. ##============================================================================
  15. ##============================================================================
  16.   def self.getsentence (text)
  17.   i = []
  18.   j = []
  19.   m = 0
  20.   x = 0
  21.   y = []
  22.   text.each_char {|char|
  23.     if char == '{'
  24.      i.push m
  25.     end
  26.     if char == '}'
  27.       j.push m
  28.     end
  29.     m = m + 1
  30.     }
  31.   while x < i.size
  32.   y[x] = text[i[x]+1...j[x]]
  33.   x = x + 1
  34.   end
  35.   return y
  36. end
  37.   def self.getindex (text)
  38.     i = ""
  39.     m = 0
  40.     text.each_char {|char|
  41.       if char == '#'
  42.         i =text[0..m]
  43.         return i
  44.       end
  45.       m = m + 1
  46.       }
  47.     return "0"
  48.   end
  49. ##=============================================================================
  50.   def self.getattri (text,tag1,tag2)
  51.     i = 0
  52.     m = 0
  53.     n = 0
  54.     l = ""
  55.     text.each_char {|char|
  56.       if char == tag1
  57.       m = i
  58.       end
  59.       if char == tag2
  60.       n = i
  61.       end
  62.       i = i + 1
  63.       }
  64.       return text[m+1...n]
  65.     end
  66. ##=============================================================================
  67.   def self.setup
  68.     @@interpret = [Hash.new]
  69.     s = []
  70.     i = 0
  71.     li = 0
  72.     p = 0
  73.     l = ""
  74.     lt = ""
  75.     c = ""
  76.     o = ""
  77.     con = ""
  78.     text = $text
  79.     s = Dialog.getsentence(text)
  80.     for f in s
  81.        i = Dialog.getindex(f).to_i
  82.        l = Dialog.getattri(f,'#','@')
  83.        c = Dialog.getattri(f,'@','&')
  84.        o = Dialog.getattri(f,'&','*')
  85.        p = Dialog.getattri(f,'*','$')
  86.        con = Dialog.getattri(f,'$','<')
  87.        lt = Dialog.getattri(f,'<','>')
  88.        $dialog[i].push(Dialog.new(i,l,c,o,p,con,lt))
  89.        $dialog[i].compact!
  90.        li = $dialog[i].size - 1
  91.      @@interpret[i] = Hash.new if @@interpret[i] == nil
  92.        @@interpret[i][l] = li
  93.     end
  94.   end
  95.   def initialize(i,l,c,o,p,con,lt)
  96.     @index = i
  97.     @label = l
  98.     @label_target = lt
  99.     @condition = c
  100.     @option = o
  101.     @picid = p
  102.     @content = con
  103.   end
  104. end



现在我是在想使用Windows base还是message来显示文本,message我现在还没搞懂怎么用。
夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
帖子
600
4
发表于 2013-4-20 16:42:47 | 只看该作者
本帖最后由 6rp 于 2013-4-20 17:59 编辑

建议你学习使用load方法。

练习:

在游戏根目录下存入文本文件try.txt
TXT 代码复制下载
  1. $name='npc张三'
  2. $text='玩家你好,我是张三!'
  3. $label=2013
  4. $faceid=0 #不知道
  5. # 总之一切都是按照ruby中的规则写文本。


然后在游戏脚本中设定一个函数 loadtext

RUBY 代码复制
  1. def loadtext(filename='try.txt')
  2.   load filename
  3.   p $name
  4.   p $text
  5. end


用这样的方法就可以把外部的文件导入游戏脚本中,不用自己设定什么{}%@#之类的古怪符号。

至于输出,一般就简单的使用$message这个变量就行了,当你函数运行完毕后,message中的文字就会自动刷新到屏幕窗口中了。

点评

还有一个问题,读取的时候字符编码错误怎么办?txt应该保存成什么编码?  发表于 2013-4-20 17:03
谢谢,能详细说说message的用法么?我找不到这个全局变量,也不知道实例方法是什么。  发表于 2013-4-20 16:49
怕鼠的猫
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
帖子
600
5
发表于 2013-4-20 17:37:49 | 只看该作者
本帖最后由 6rp 于 2013-4-20 17:39 编辑
6rp 发表于 2013-4-20 16:42
建议你学习使用load方法。

练习:


message就是这样使用的:
TXT 代码复制
  1. $game_message.add('hello')


所有文本要使用utf-8格式(有BOM)

而且变量传递不能就那么简单的写,可以用全局变量传递。

文本中
TXT 代码复制
  1. $data[1]='hello'


RUBY 代码复制
  1. $data=[]
  2. load 'try.txt'
  3. p $data[1]
  4. $game_message.add($data[1])


这样你试试看吧。

顺便说一下,load 方法使用,好像要忌讳出现中文目录名,否则出错!

点评

那么那个人物肖像是怎么做到的?有参数么?  发表于 2013-4-20 18:14
怕鼠的猫
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1882
在线时间
1552 小时
注册时间
2013-4-13
帖子
917
6
 楼主| 发表于 2013-4-20 19:16:43 | 只看该作者
6rp 发表于 2013-4-20 17:37
message就是这样使用的:
$game_message.add('hello')[/pre]

感谢已经成功读取文件了
突然发现可以用Excel 批量转换txt 效率提高一大截
唯一遗憾就是不知道如何在类内部使用
不过暂且用类方法解决了
RUBY 代码复制
  1. $dialog = Array.new(72,Array.new)
  2. #=============================================================================
  3. class Dialog
  4.   attr_accessor :index
  5.   attr_accessor :label
  6.   attr_accessor :label_target
  7.   attr_accessor :condition
  8.   attr_accessor :option
  9.   attr_accessor :picid
  10.   attr_accessor :content
  11.   @@interpret = [Hash.new]
  12. ##============================================================================
  13. ##============================================================================
  14.   def self.intercreate(i)
  15.     @@interpret[i] = Hash.new
  16.   end
  17.   def self.intercrease(i,l,li)
  18.     @@interpret[i][l] = li
  19.   end
  20.   def self.interpret(i)
  21.     return @@interpret[i]
  22.   end
  23.   def self.setup
  24.     @@interpret = [Hash.new]
  25.     load('book.etc')
  26.   end
  27.   def initialize(i,l,c,o,p,con,lt)
  28.     @index = i
  29.     @label = l
  30.     @label_target = lt
  31.     @condition = c
  32.     @option = o
  33.     @picid = p
  34.     p @content = con
  35.   end
  36. end


转换成txt以后 Excel 会自动给所有带括号的部分添加双引号,还会插入大量tab,用查找替换一次性删除勉强算是弄掉了
TEXT 代码复制
  1. def run(i,l,c,o,p,con,lt)         
  2. $dialog[i].push Dialog.new(i,l,c,o,p,con,lt)         
  3. $dialog[i].compact!        
  4. li = $dialog[i].size - 1         
  5. p Dialog.interpret(i)
  6. Dialog.intercreate(i) if Dialog.interpret(i) == nil        
  7. Dialog.intercrease(i,l,li)         
  8. end        
  9. i  =   1     
  10. l  = '  2 '   
  11. c  = '  3 '   
  12. o  = '  4 '   
  13. con  = '  5 '   
  14. lt  = '  6 '   
  15. run(i,l,c,o,p,con,lt)

大概就生成这么个东西
测试结果还算满意,但是不能在类内使用还是问题,这些变量难道都被当成main函数的局部变量了么?
夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
帖子
600
7
发表于 2013-4-20 19:31:57 | 只看该作者
是啊,我也发现是成为main的临时变量了。
所以建议你先弄个全局变量作容器,在文本中调用容器函数给它赋值,回到游戏中再读出来。这样可能更合理一些。
RUBY 代码复制
  1. class Mydata
  2.     attr_accessor :name,:text,:lable
  3. end
  4.  
  5. $mydata=Mydata.new
  6. ######################
  7. class Mystory
  8.     def run
  9.       load 'a.txt'
  10.       p $mydata.text
  11.     end
  12. end


TXT 代码复制下载
  1. $mydata.text='hello,world'
怕鼠的猫
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-28 22:02

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表