查看: 2510|回复: 6

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

[复制链接]
梦石
0
星屑
1907
在线时间
1555 小时
注册时间
2013-4-13
回帖
783
发表于 2013-4-19 23:48:56 | 显示全部楼层 |阅读模式

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

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

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

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

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里
梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
回帖
575
发表于 2013-4-20 15:16:45 | 显示全部楼层
ruby 有load 方法,可以调入外部文本来执行的。
你的文本就设计成ruby认可的格式就行了,不用从新写编译器的。
怕鼠的猫
回复

使用道具 举报

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


我是打算从外部读取的,因为RM内部没有好的文字编辑器。
但是读入的只是字符串,这些字符串没法表示上下文的关系,
没法表示出现的条件。还得进行2次编辑成一个集合了对话元素的类才行。
就算我读入了对话,我最多也只能按行读取,然后编号,但是关键的是我没有方法调用。
读取的文字还得带上处理标签,然后实例化。头像是什么,什么条件出现,哪一句台词指向它,它指向哪一句台词或者选项等等
读取了文字没法变成对话还是无用。
这是我写的Dialog类
已经debug完毕无误。
[pre lang="ruby" line="1"]$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.push(Dialog.new(i,l,c,o,p,con,lt))
       $dialog.compact!
       li = $dialog.size - 1
     @@interpret = Hash.new if @@interpret == nil
       @@interpret[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[/pre]


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

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

使用道具 举报

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
回帖
575
发表于 2013-4-20 16:42:47 | 显示全部楼层
本帖最后由 6rp 于 2013-4-20 17:59 编辑

建议你学习使用load方法。

练习:

在游戏根目录下存入文本文件try.txt
[pre lang="txt" line="1" file="try.txt"]
$name='npc张三'
$text='玩家你好,我是张三!'
$label=2013
$faceid=0 #不知道
# 总之一切都是按照ruby中的规则写文本。[/pre]

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

[pre lang="ruby" line="1"]def loadtext(filename='try.txt')
  load filename
  p $name
  p $text
end[/pre]

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

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

点评

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

使用道具 举报

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
回帖
575
发表于 2013-4-20 17:37:49 | 显示全部楼层
本帖最后由 6rp 于 2013-4-20 17:39 编辑
6rp 发表于 2013-4-20 16:42
建议你学习使用load方法。

练习:


message就是这样使用的:
[pre lang="txt" line="1"]$game_message.add('hello')[/pre]

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

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

文本中[pre lang="txt" line="1"]$data[1]='hello'[/pre]

[pre lang="ruby" line="1"]
$data=[]
load 'try.txt'
p $data[1]
$game_message.add($data[1])[/pre]

这样你试试看吧。

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

点评

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

使用道具 举报

梦石
0
星屑
1907
在线时间
1555 小时
注册时间
2013-4-13
回帖
783
 楼主| 发表于 2013-4-20 19:16:43 | 显示全部楼层
6rp 发表于 2013-4-20 17:37
message就是这样使用的:
$game_message.add('hello')[/pre]

感谢已经成功读取文件了
突然发现可以用Excel 批量转换txt 效率提高一大截
唯一遗憾就是不知道如何在类内部使用
不过暂且用类方法解决了
[pre lang="ruby" line="1"]$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 = Hash.new
  end
  def self.intercrease(i,l,li)
    @@interpret[l] = li
  end
  def self.interpret(i)
    return @@interpret
  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[/pre]
1.jpg
转换成txt以后 Excel 会自动给所有带括号的部分添加双引号,还会插入大量tab,用查找替换一次性删除勉强算是弄掉了[pre lang="text" line="1"] def run(i,l,c,o,p,con,lt)         
$dialog.push Dialog.new(i,l,c,o,p,con,lt)         
$dialog.compact!        
li = $dialog.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)        
[/pre]
大概就生成这么个东西
测试结果还算满意,但是不能在类内使用还是问题,这些变量难道都被当成main函数的局部变量了么?
夏普的道具店

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

使用道具 举报

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
回帖
575
发表于 2013-4-20 19:31:57 | 显示全部楼层
是啊,我也发现是成为main的临时变量了。
所以建议你先弄个全局变量作容器,在文本中调用容器函数给它赋值,回到游戏中再读出来。这样可能更合理一些。
[pre lang="ruby" line="1"]class Mydata
    attr_accessor :name,:text,:lable
end

$mydata=Mydata.new
######################
class Mystory
    def run
      load 'a.txt'
      p $mydata.text
    end
end

[/pre]

[pre lang="txt" line="1" file="a.txt"]$mydata.text='hello,world'[/pre]
怕鼠的猫
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部