- 注册时间
- 2004-8-27
- 最后登录
- 1970-1-1
|
就找这个清净的地方写吧,希望同志们不吝赐教,不要老做自己的哦~
前言:
能真正做出RPG的人实在太少了,而且随着LAVA等的出现,星迷们已经失去了自我研究的精神,可悲啊,看看现在,也就那么几个人在折腾了。。。为了能玩到更好的游戏,我写了点建议,希望能把新手们带入游戏制作的区域,仅此而已。
当然我没有那么多时间将所有的东西都写上,因为太多了,问题只有在实践时发现,如果遇上麻烦可以和我一起讨论,随时恭候!
“做游戏很辛苦,特别是图象方面,希望选择了的朋友能够坚持下去。没有好的图象的游戏是不具备震撼力的。”
下面讲解了一些RPG剧情处理方面的技巧。如果要精通的话一定要看编译原理(先懂数据结构。。。),好书啊!~~~~
从虚拟机到RPG剧情处理
这是一个很大的话题,如果要一个一个讲清楚,恐怕是很难的了,但是,作为文曲星上的新手们,了解下这方面的内容是很有必要的,如果要深入研究的话就要靠自己看书实践了。
虚拟机一词,我是在《编译原理》中看到的,不过在这之前也有所了解。象文曲星上的LAVA,GVB,甚或是神州引擎都用到了‘虚拟机’‘技术’。所以,它的重要性就不言而喻了,比如所做RPG,互动游戏的引擎啊什么的。。。多了去了。
先给虚拟机下个定义吧:
从字面上理解下虚拟二字的含义,也就是说这样的一个平台是模拟出来的。其所编译出来的代码是由另一个程序(解释器)来执行的,如GVB的解释器,LAVA解释器,神州的主程序......
虚拟机的文件中所包含的代码称为伪代码,即不能直接被硬件执行,而是依附于它所归属的解释器。
注意:虚拟机的针对性是很强的。
虚拟机由两部分组成: 编译器,解释器。
下面先来讲下解释器:
解释器就是实现伪代码对应的函数的过程,是一个大的循环,在这个循环中不断的读取文件中的伪指令执行,直到文件结束。可以总结为下图:
再来说下编译器-虚拟机的核心部分。
比之解释器,编译器占的比重很大,它的形态决定了虚拟机的种类,功能作用等全部的内容。要做一种语言,那么它的虚拟机绝对和RPG引擎的‘虚拟机’大不相同,因为RPG实现虚拟机是为了更方便的处理剧情。
看看编译器的组成:
编译器由几重要部分组成:词法分析,文法分析,代码生成。
词法分析:识别源文件中的单词(保留字,数字),换成一个或几个自己定义的字符表示,以便解释器解释。
文法分析:进行语法分析,包括表达式的分析
代码生成:为每个文法的句子生成代码,可以是伪代码,也可以是汇编代码(这样的话就不是虚拟机了),这部分程序可以在文法分析时调用,也可以在文法分析后调用,依情况而定。
------------------------------------------------------------------------------------------------
有了上面的基础,就可以开始研究自己的RPG了。
相信很多朋友曾尝试过自己制作一个RPG,但发现做不了多少就会思路大乱。下面来分析下原因:
一个RPG包含很多剧情,几乎每个NPC都有剧情,而且剧情之间往往又有很多联系,错杂成网,仅用几个IF...THEN...ELSE 是没办法搞定的。但是如果我们能把每个剧情归附到相应NPC上,而不是放在主程序里,那么处理起剧情来就会简单多了,原本需要一大堆的IF的程序,我们只用一个IF就可以搞定:获取相应的NPC编号,找到它所对应的剧情(即脚本文件)然后交给解释器执行,多么简洁啊~ 如此一来,我们的主程序只要一个脚本解释器和少数的界面处理函数就可以完成了。
看个图吧:
可以发现,上面的图和虚拟机解释器的图相当类似,其实一个RPG的剧情引擎就可以理解为一个虚拟机的解释器,至少在WQX上可以这么认为。
------------------------------------------------------------------------------------------------
首先强调一点,脚本是为特定的对象或事件所编写,具有一定的独立性,这有点象PC上的面向对象的思想编程,在有解释器的前提下,我们只要相对独立考虑每个NPC所具有的特性就可以完成RPG的设计了,而不会出现写的程序多了忘记这忘记那的情形,综上所述,在完成一个比较大的RPG时,我们首先做的是将框架做好,而不是去考虑某些小问题。
===================================================
一个RPG的简单结构设计(仅代表个人观点,如有新的想法一样可以)
数据文件:
MAPDATA。DAT 包含地图数据,已经编号
SCRIPT。DAT 剧情脚本,已经编号
SPEAK。DAT 对话存放在这里
主程序:
MAIN。XXX
将MAIN程序的结构说一下:
定义变量;
各个伪指令的实现;
脚本解释;
地图显示;
菜单的实现;
程序的进入口;
====================================================
构造脚本编译器:
想想看,要有哪些指令(这些指令是自己设计的)才能让NPC完美的‘讲述’剧情?
下面是我随便做的一个编译器。
支持的语句有:
if(n*n){}else
do{}while(n*n);
while(n*n){}
Let IDENT=N*N;
Battle #num/&add 跟某NPC或怪物战斗
Say #page,#id
Contalk #length,#page,#begin_id 连续说话
YesNoBox #page,#id
RndTalk #length,#page,#begin_id
tast #TASK_ID (what's the task depends on the ID)
KeyPause &add
EXChange 交易
bank 银行
图象处理指令:
SaveScreen
ShowScreen
UpdataScreen 刷新地图
Play Flash_ID 播放动画
剧情处理指令:
Give #Thing_ID,num (tow bytes) 给主教物品
Script #Sc_ID (this ID is a TWO bytes Num) 跳转执行另一个脚本文件
ChangeMap #Map_id(two bytes),x,y,b_isRefresh 切换地图
MagicFly #Map_id(two bytes),x,y,b_isRefresh 切换地图2
特殊指令:
CallSub #definedSub 调用主程序中的过程,做特殊用
=================================================
skill 学技能
shop 商店
上面的内容是比较具体点的脚本语言的定义,可以亲身体会下‘脚本’,有上面的指令后要让NPC完成剧情的
描述我想就不是很难了。可以看出,脚本就是另一种简单的语言,是为NPC描述剧情而量身定制的,这样,就
可以将没NPC从复杂交错的主程序中分离出来而不影响思路,因为我们可以先做主程序后再去设计剧情,这一
点是很重要的,而且可以重复使用某引擎,做新的游戏的时候只要将SCRIPT。DAT改动就可以了。
提示:当接触NPC时(对话,战斗,按输入键。。。)触发脚本的解释。
-----------------------------------------------------------------------------------------------
下面看看这个脚本编译程序是如何将指令编译成伪代码的:
语法:
每个脚本128字节 共 256 个
数据类型:
234 数字
#IDENT 数字
IDENT 地址
IDENT是标识符
支持的语句有:
if(n*n){}else
do{}while(n*n);
while(n*n){}
Let IDENT=N*N; //不支持表达式
必须是IDENT
//不支持表达式做参数,*为操作符号:+ - * / — | > < =
函数:
函数一律用 () 把参数扩起,有多个参数的用逗号隔开,末尾加; 如Say(1,0);
无参数的不需要括号,只要末尾加;就可以了
Battle #num/&add
Say #page,#id
Contalk #length,#page,#begin_id
YesNoBox #page,#id
RndTalk #length,#page,#begin_id
tast #TASK_ID (what's the task depends on the ID)
KeyPause &add
EXChange
bank
图象处理指令:
SaveScreen
ShowScreen
UpdataScreen
Play Flash_ID
剧情处理指令:
Give #Thing_ID,num (tow bytes)
Script #Sc_ID (this ID is a TWO bytes Num)
ChangeMap #Map_id(two bytes),x,y,b_isRefresh
MagicFly #Map_id(two bytes),x,y,b_isRefresh
特殊指令:
CallSub #definedSub
==============================
skill
shop
这两个指令较特殊指令:
shop { 2: 1,2 2,3}
项目数 项 1 项 2
且参数只能是数字。
shop{2: #Attack,2 2,3}
这样也可以的
下面是软件的截图:
改编译器支持自己定义宏参数,这样就可以用单词代替固定的数字,方便记忆了。
编译后我们可以在下面的编辑框中看到编译后的伪代码的16进制代码,这里解释一下关于IF 和WHILE的代码生
成,其余的函数都是 TOKEN+参数型的。
IF:
TOKEN(IF),参数1,关系运算,参数2,不成立时要跳转的字节,。。。(成立的代码)。。。不成立时的
代码。
WHILE:和IF相似。
DO{}WHILE() 只是要跳转的字节数放在DO的TOKEN后面了。
-----------------------------------------------------------------------------------------------
一个RPG在完成了上面的任务后,接下来的就是做解释器和图象处理了,这些也做好了后就是为NPC写脚本了。
所有工作都完成的紧紧有条。
这是脚本编译程序:
http://blogcup.com/doggy/worm/upload/34215627.rar
祝每个喜欢DIY游戏的朋友都做出自己喜欢的游戏,从此自力更生!
|
|