幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3228|回复: 18

[原创]谈谈如何在RMXP打造自己游戏主菜单-->carol3转移

[复制链接]

8

主题

38

帖子

300

积分

④见习

三用陆行鸟

积分
300
QQ
发表于 2005-2-3 22:40:34 | 显示全部楼层 |阅读模式
首先,我要说明一下,这贴算不上教学贴,我还没有这个能力。我只是说说我做菜单的一点点的心得,有兴趣的一起来探讨一下,交流交流~~~[em07],还有就是,我第一次发这种贴,有不妥之处恳请原谅!

    说到XP,最令人称道的就是它的RGSS,有了它,基本上什么绚丽的效果都成为可能(有美工的基础上),只要有一定的编程基础(这就是有很多人望而却步的原因),Ruby语言其实不算是一种很难学的语言(本人认为)。

    接下来说的基本上都是能看懂RGSS代码的基础上的话,因为我的菜单就是在RGSS里动的大手术,对于不懂编程的人,我建议可以先学学编程,或者利用事件来做(其实这个反而我不大懂,XP到手后我只顾着搞代码),或者就是忍受RM本来的那简陋的菜单,再不是就拿高手们的代码贴上,起码可以改善一下。但我觉得要做有自己特色的游戏菜单,还得要下一番苦功的。俗话说得好,天下没有掉下来的馅饼。

现在就开始说说我制作【異世界の大冒険】里的菜单的一些经验:
1.要确定你的游戏需要一个怎样的菜单,有些什么基本功能。
    这个很重要,因为每个游戏都有自己的特色,什么宝石系统啊,炼化系统等等,这些都是很特别的,所以要确定要有些什么功能模块(我自己的就很简单,只有基本的几样,打算以后加上去)。

2.构图。
    这个对于我们程序员来说有点偏。可以找个美工来设计一下,要是没有就只有自己硬着头皮自己弄蔬菜,在PS里修修改改。每一个模块的构图和蔬菜都准备好以后就可以进行下一步

3.确定每个模块相互之间的联系
    就是每一个模块是怎么切换的,相互之间有些什么关系,这个一定要弄清楚,要不做到后面会很麻烦。

4.确定每个模块里有些什么的窗口,图片,动画等等
    这个确定下来以后就要看看,手头上的材料和数据齐不齐全,例如:一个窗口是显示某角色的基本数值的,还有就是人物图片的,那就找一下相关的数据来源,然后一个一个窗口去做。

5.寻找原系统代码中可以沿用的东西
    虽然说要对RGSS做大手术,但也不能把它弄得支离破碎。因为要找有用的东西,就必须理解原来的代码是什么意思,作用是什么,跟那些数据有关系(其实这里是最化时间和功夫的),然后结合一下自己的设计的菜单看看那些跟自己的菜单有共同点,有的就保留,或者是把代码借过来放进自己做的新类里面。

6.利用Window_Base和Window_Selectable作为超级类(父类)制作自己想要得窗口
    我觉得菜单都是窗口和窗口构成的,所以制作窗口就是硬道理(邓论读多了),一些只是显示数据的窗口,超级类就是Window_Base,要是要选择功能的就是Window_Selectable,这个应该不难看出。然后就是窗口要显示些什么啊,高多少阿,宽多少阿,都确定好。
这是我的菜单左边的人物列表的窗口的代码(注意:这个不是通用代码,我还没有水平写通用代码)
#==============================================================================
# ■ Window_Actor_list
#------------------------------------------------------------------------------
#  显示同伴列表的窗口。
#==============================================================================

class Window_Actor_list < Window_Selectable
  #--------------------------------------------------------------------------
  # ● 初始化目标
  #--------------------------------------------------------------------------
  
  def initialize
    super(-300, 65, 180, 295)
    self.contents = Bitmap.new(width - 32, height - 32)
    refresh
    self.active = false
    self.index = -1
    self.opacity = 0
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @back_ground = [Sprite.new]
    @item_max = $game_party.actors.size
    for i in 0...$game_party.actors.size
      x = 64
      y = i * 66
      actor = $game_party.actors
      #加载人物列表背景图
      @back_ground = Sprite.new
      @back_ground.bitmap = Bitmap.new("Graphics/pictures/status-back")
      @back_ground.x = self.x + 17
      @back_ground.y = 80 + y
      #数值的描绘
      draw_actor_graphic(actor, x - 50, y + 60)
      draw_actor_name(actor, x - 60, y - 10)
      
      draw_actor_hp(actor, x - 30 , y + 10 )
      draw_actor_sp(actor, x - 30 , y + 30 )
    end
    #加载以选择框
    @selectedf = Sprite.new
    @selectedf.bitmap = Bitmap.new("Graphics/pictures/selected")
    @selectedf.x = -300
    @selectedf.y = 59
    @selectedf.opacity = 255
  end
  #--------------------------------------------------------------------------
  # ● 数值的刷新
  #--------------------------------------------------------------------------
  def update_actor
    self.contents.clear
    @item_max = $game_party.actors.size
    for i in 0...$game_party.actors.size
      x = 64
      y = i * 66
      actor = $game_party.actors
      #加载人物列表背景图
      draw_actor_graphic(actor, x - 50, y + 60)
      draw_actor_name(actor, x - 60, y - 10)
      
      draw_actor_hp(actor, x - 30 , y + 10 )
      draw_actor_sp(actor, x - 30 , y + 30 )
    end
  end
  #--------------------------------------------------------------------------
  # ● 刷新光标矩形   and $itemaction == true
  #--------------------------------------------------------------------------
  def update_cursor_rect
    if ($indexselected == 2  and self.active == true) or (self.active == true and
      @selectedf.visible == false)
      # 光标位置 -1 为全选、-2 以下为单独选择 (使用者自身)
      if @index <= -2
        self.cursor_rect.set(0, (@index + 10) * 116, self.width - 32, 96)
      elsif @index == -1
        self.cursor_rect.set(0, 0, self.width - 32, 255)
      else
        self.cursor_rect.set(0, @index * 65, self.width - 32, 60)
      end
    else
      if @index < 0
        self.cursor_rect.empty
      else
        self.cursor_rect.set(0, @index * 65, self.width - 32, 60)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  def update
    super
    #人物列表飞入
    case $indexselected
    when 0..3
      if self.x < 0
        self.x += 30
      end
    when 4
      if self.x > -300
        self.x -= 30
      end
    end
    #背景跟随
    if @back_ground[0] != nil
      @back_ground[0].x = self.x + 17
    end
    if @back_ground[1] != nil
      @back_ground[1].x = self.x + 17
    end
    if @back_ground[2] != nil
      @back_ground[2].x = self.x + 17
    end
    if @back_ground[3] != nil
      @back_ground[3].x = self.x + 17
    end
    #以选择框跟随  
    @selectedf.x = self.x - 11
    #更新以选择框
    selected_update
  end
  #--------------------------------------------------------------------------
  # ● 更新以选择矩形
  #--------------------------------------------------------------------------
  def selected_update
    if $indexselected == 2 or $skillaction == true
      @selectedf.visible = false
    else
      @selectedf.visible = true
    end
    case $actorselected
    when 0
      @selectedf.y = 59
    when 1
      @selectedf.y = 59 + 66 * $actorselected
    when 2
      @selectedf.y = 59 + 66 * $actorselected
    when 3
      @selectedf.y = 59 + 66 * $actorselected
    end
  end
  #--------------------------------------------------------------------------
  # ● 释放窗口与图片
  #--------------------------------------------------------------------------
  def dispose
    dispose_picture
    super
  end
  #--------------------------------------------------------------------------
  # ● 释放图片
  #--------------------------------------------------------------------------
  def dispose_picture
    if @back_ground[0] != nil
      @back_ground[0].bitmap.dispose
      @back_ground[0].dispose
    end
    if @back_ground[1] != nil
      @back_ground[0].bitmap.dispose
      @back_ground[0].dispose
    end
    if @back_ground[2] != nil
      @back_ground[0].bitmap.dispose
      @back_ground[0].dispose
    end
    if @back_ground[3] != nil
      @back_ground[0].bitmap.dispose
      @back_ground[0].dispose
    end
    @selectedf.bitmap.dispose
    @selectedf.dispose
  end
  
end


7.自己写scene_menu
    这个其实很简单(但是我的scene_menu类里面的代码+注释就有1000多行)。为什么说很简单呢?其实在这个类里面就是定义窗体的对象,然后就是循环,图像刷新,输入刷新。我一个一个来说,定义窗体就是在自己的菜单里有些什么的窗体都在这里定义,都把窗体加载进来,像上面的人物列表窗口,就用一句@actor_list_window = Window_Actor_list.new 就定义了,其它窗口一样。然后就到基本循环了(我把它叫做基本循环):
    loop do
      # 刷新游戏画面
      Graphics.update
      # 刷新输入信息
      Input.update
      # 刷新画面
      update
      # 如果切换画面就中断循环
      if $scene != self
        break
      end
    end
这个循环牵及的东西就多了,Graphics.update这个可以不管他,input.update也可以不管他,就是update
这句调用的是scene_menu类里的一个update函数(方法),在这个函数里面都是都是窗体的刷新,还有就是调用活动窗口的输入处理。所以这个类就是控制窗口的中心了。这个可以参考一下原来的scene_menu,其实一步一步看,根本不难理解。

8.调整各部分窗体的位置
    做好窗体了,就用一个基本的scene_menu一个一个窗体的加载进去,然后测试,开始的时候可能不知道那个窗口该在什么位置,窗体先放在(0,0)点,然后再慢慢调窗体的位置,是否接受一些输入处理,慢慢的弄,其实这里比较轻松,只要是窗体大小和里面的内容都好了,这里就没什么难的。调整好以后就决定他该从什么地方出来等等,这个自己看着办

9.确保跟原来的游戏系统没有冲突
    在窗体都调整好以后就要测试了,看看会不会跟游戏系统冲突,或者是各个模块之间会不会出现什么问题,例如:先激活了一个功能,然后再激活另外一个,再激活其他的,不过的循环激活,看看会不会冲突,还有是跟XP的事件编辑器,还有就是跟数据库会不会冲突(这些一冲突就头大了,不过基本上不会有事的)

10.拿出来测试一下
    我的就是拿出来测试了,但好像没有什么人气。可能是什么剧情也没有,只有一个菜单什么的就拿出来说什么测试,才没人理睬的。其实说菜单是一个游戏吸引人的一个重要因素也不为过,我拿出来测试,就是要看看我做的菜单还有些什么不完善的地方,让大家举出来,然后再修正。


好了,说了一大堆的,也不知道有没有人看,高手们对这些不可能不知道,新手的看了也不大明白。。。。。。不过我还是那句我这个不是教学贴,只是交流贴,大家有些什么意见就尽管提吧。

ps.我的剧本正在加紧写,在下一测试版,我会把自制的战斗系统,还有就是把序幕送给大家(正在联系做CG的,希望他肯加入)。
没有最强,只有超越
回复

使用道具 举报

1

主题

24

帖子

123

积分

③业余

无静晴川(消失中)

积分
123
发表于 2005-2-3 22:58:05 | 显示全部楼层
看完了,我编程水平有待提高,等大体上能把握rgss后,这篇文章可能对我来说是收益非浅,先收下了,多谢!
甭理我,我消失了,大家继续。。。
回复 支持 反对

使用道具 举报

3

主题

27

帖子

1481

积分

⑥精研

积分
1481
发表于 2005-2-3 23:10:33 | 显示全部楼层
非常之好呀 ,顶一个
用楼主的方法,不断的循环判断窗口到没到指定座标,如果没到就按定量偏移。活用的话,还可以模拟一些物理效果
比如先定义一个 偏移量 f=0.5
然后循环判断窗口 并指定     _x+=(目标座标-目前座标)*f;       然后到一定程度后跳出循环并确定窗口座标 。这样可以 模拟缓冲的窗口效果。
不过不知道这样在gass里可不可以实现,就看有没有高手研究了。


[em01]
回复 支持 反对

使用道具 举报

8

主题

38

帖子

300

积分

④见习

三用陆行鸟

积分
300
QQ
 楼主| 发表于 2005-2-3 23:26:30 | 显示全部楼层
以下是引用solooni在2005-2-3 23:10:33的发言:

非常之好呀 ,顶一个

用楼主的方法,不断的循环判断窗口到没到指定座标,如果没到就按定量偏移。活用的话,还可以模拟一些物理效果

比如先定义一个 偏移量 f=0.5

然后循环判断窗口 并指定     _x+=(目标座标-目前座标)*f;       然后到一定程度后跳出循环并确定窗口座标 。这样可以 模拟缓冲的窗口效果。

不过不知道这样在gass里可不可以实现,就看有没有高手研究了。



[em01]


你的提议很好,当然可以实现啦
没有最强,只有超越
回复 支持 反对

使用道具 举报

0

主题

61

帖子

1609

积分

⑥精研

积分
1609
发表于 2005-2-4 00:03:01 | 显示全部楼层
强帖啊~ 感谢楼主,学习中。。。[em01]
回复 支持 反对

使用道具 举报

carol3 该用户已被删除
发表于 2005-2-4 00:47:38 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

13

主题

237

帖子

1452

积分

⑥精研

积分
1452
QQ
发表于 2005-2-4 09:22:29 | 显示全部楼层
--# 果然以现在的实力只能看懂楼主的意思……而不能去实施…………
等我手头这游戏完工开始咬RGSS……
我已经很老很老了...老到已经记不清RMXP是什么东西了....
回复 支持 反对

使用道具 举报

8

主题

38

帖子

300

积分

④见习

三用陆行鸟

积分
300
QQ
 楼主| 发表于 2005-2-4 10:08:51 | 显示全部楼层
以下是引用carol3在2005-2-4 0:47:38的发言:
明天转交流区。
啊!老大,不好意思,发错地方了~以后会注意的~
没有最强,只有超越
回复 支持 反对

使用道具 举报

8

主题

38

帖子

300

积分

④见习

三用陆行鸟

积分
300
QQ
 楼主| 发表于 2005-2-4 10:10:19 | 显示全部楼层
以下是引用rush在2005-2-4 9:22:29的发言:

--# 果然以现在的实力只能看懂楼主的意思……而不能去实施…………

等我手头这游戏完工开始咬RGSS……


呵呵,努力!也期待你的游戏
没有最强,只有超越
回复 支持 反对

使用道具 举报

13

主题

237

帖子

1452

积分

⑥精研

积分
1452
QQ
发表于 2005-2-4 11:42:31 | 显示全部楼层
以下是引用Choco在2005-2-4 10:10:19的发言:


呵呵,努力!也期待你的游戏

目前只有C语言的基础--#
其他语言都没碰过的……
我已经很老很老了...老到已经记不清RMXP是什么东西了....
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2025-5-3 17:40 , Processed in 0.013007 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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