查看: 3639|回复: 2

[RMVA发布] [简单脚本]声望窗口

[复制链接]
梦石
0
星屑
105
在线时间
297 小时
注册时间
2009-1-7
回帖
155
发表于 2014-1-1 15:30:01 | 显示全部楼层 |阅读模式

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

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

×
  呵呵!一开始接触脚本就停不下脚步了,该说什么好呢?
  不得不说Ruby的语法实在太奇怪了。写法很自由,当然这样子的优点就是可以节省时间,提高效率,不过我觉得缺点就是可读性差。
  以上是我这两天入门脚本的一些心得。

  昨天实践了Ruby的基本语法,今天我们来看看跟Ruby语法不相干的内容。


  这个脚本所实现的功能如下:
1.jpg

  在菜单界面显示一个窗口,用来显示声望以及数值。
  声望数值在本例中用第15号变量表示:$game_variables[15]

  我就把实现这个功能的过程中,我脑袋所想的告诉大家。

1.我要实现一个窗口用来显示声望值。这个窗口非常简单,不要求任何的功能。凭空写一个的话对于新手来说是比较困难的,我们不妨参照默认脚本中已经存在的脚本进行修改,于是我看到了Window_Gold类。这个类是用来显示金钱的,也没有任何功能,拿来修改是再好不过了。

2.在main前面插入一个空的脚本,将Window_Gold类全部复制过来并且改名字。在本例中,声望窗口的名字为Window_Prestige。然后我们看看已经存在的方法,有哪些是有用的,有哪些是没用的,又有哪些是需要修改的:
    initialize:这个是窗口类的初始化方法。这个方法至关重要,所以不能删除,在本例中也没有进行修改。
    window_width:获取该窗口宽度的方法。由于声望窗口和金钱窗口的宽度是一致的,所以不用修改。
    refresh:刷新方法。这个方法至关重要,不能删除,但是可以修改。如果没有刷新方法,则即使数值改变,界面也不会体现,甚至不会有内容被绘制。
    value:获取金钱数目的方法。这个方法也很重要,稍作修改后可以实现获取声望的效果,不建议删除。
    currency_unit:获取金钱单位的方法。这个方法不重要,在本例中删除了。如果你的游戏中声望是有单位的,我建议在value方法里面进行实现。
    open:打开窗口方法。这个方法至关重要,不能删除,在当前状态下最好也别修改。

3.确定了Window_Gold类每个方法的功能后就可以开始进行修改了。从第一个方法开始:
@initialize
默认脚本如下:
[pre lang="ruby" line="1"]def initialize
    super(0, 0, window_width, fitting_height(1))
    refresh
end[/pre]
super:调用父类中的initialize方法并且传入一些参数。在父类(Window_Base)中,该方法的参数列表如下:(x, y, width, height)。传入的参数的含义如下:(x坐标,y坐标,该窗口宽度,当文字只有一行时该窗口的高度)。
refresh:调用这个类的refresh方法。
  可以看出这个initialize方法是不需要做任何修改的,因为该窗口的文字也是只有一行,所以高度和Window_Gold是一样的,而x坐标,y坐标,和窗口宽度也是和Window_Gold一样的。至于x坐标,y坐标是以哪个坐标系为参照物,我目前的理解如下,可能和实际有一些误差:窗口有一个载体,就好比是一个正方形箱子,我们把窗口看成正方形的木块什么的,故x坐标和y坐标就表示我们要将这个木块放置在这个箱子的位置,当然默认是放置在箱子的左上角以免造成空间浪费。而width和height就表示这个木块的大小。

@window_width
默认脚本如下:
[pre lang="ruby" line="1"]def window_width
    return 160
  end[/pre]
  return 160表示这个窗口的宽度是160,这个160包括可以看到的声望窗口的全部内容的宽度,包括白色边框。
  由于声望窗口的宽度和Window_Gold是一样的,所以这个方法也不用修改。

@refresh
默认脚本如下:
[pre lang="ruby" line="1"]def refresh
    contents.clear
    draw_currency_value(value, currency_unit, 4, 0, contents.width - 8)
  end[/pre]
  contents.clear:清除前一刻绘制的内容。这个contents在F1里面描述如下:引用作为窗口内容的位图。我的理解是:窗口本身。在刚才,我们把窗口看成是一个木块。很显然,要显示的东西(金钱,声望)就相当于用笔写在这一个木块上。所以大家还可以把contents理解为一个画板,一个和木块同样的画板。clear方法就是清除画板上的所有内容。如果不清除的话,新画上去的东西会和原来的进行重叠。
  draw_currency_value:这个方法在父类(Window_Base)中,意思是绘制当前的金钱数目和金钱单位。参数列表是:(value, unit, x, y, width),实际传入的参数如下:(金钱数目,金钱单位,绘制x坐标,绘制y坐标,绘制的宽度)。
  由默认脚本可知,这个refresh方法是用来绘制的,也就是说每一次调用refresh就会绘制一遍(事先清除)。由于《RMVA》的帧数太高了,所以我们感觉好像一直都显示在屏幕上,如果帧数低一点大家可以发现这个窗口是一闪一闪的。
  好!那么明白refresh方法的用途后我们就明白了,很显然默认脚本的内容不是我们想要的。开始修改吧。

第一:把draw_currency_value(value, currency_unit, 4, 0, contents.width - 8)这一行注释。因为我们不需要它。

第二:绘制“声望”二字。
  在本例中,声望二字的颜色采用的是系统颜色(蓝色),所以我们在绘制前应该先把颜色设置一下。在Window_Base找到draw_currency_value方法我们就很容易发现设置颜色的语句:change_color(system_color)。
  然后开始绘制“声望”二字,同样是在Window_Base找到draw_currency_value方法,我们发现有一个draw_text的方法。这个方法在Window_Base里的内容如下:
[pre lang="ruby" line="1"]def draw_text(*args)
    contents.draw_text(*args)
end[/pre]
  好,contents到底是什么东西?我们还得通过F1来获取答案。经过一番搜索,我发现contents在RGSS参考手册-游戏函数库-RGSS内建内-Window 窗口类中,是一个属性(描述:引用作为窗口内容的位图(Bitmap 位图类 ))。而draw_text正是这个属性的方法,位于同一个路径下的Bitmap 位图类。该方法的参数列表如下:(x, y, width, height, str[, align]) 分别代表如下含义(绘制的x坐标,绘制的y坐标,绘制的宽度,绘制的高度,绘制的内容,对齐方式(可以省略))。对于这个方法,我是这么理解的:箱子里有一个木块,木块上要写字,而写之前得先确定范围。当然,我们平时写字的时候在潜意识中已经确定好了范围,所以会出现一行写不下故意写得很挤的情况。计算机同理的,它也需要知道这个字要在木块的哪一个区域里写。如果内容太多当然就写不下。而对齐方式主要有以下几种情况:1:居中对齐;2:右对齐;默认:左对齐。如果省略这个参数则采用左对齐。
  理解了draw_text的用法后我们就开始绘制“声望”吧:draw_text(0, 0, contents.width - 8, line_height, "声望");这里我省略了对齐方式,所以默认是左对齐。那么这个脚本的意思如下:在窗口的(0,0)坐标上,绘制“声望”二字。这两个字的最大宽度不得超过窗口宽度的-8像素,最大高度不得超过一行文字的高度。我这么说大家可理解?

第三:绘制声望数值。
  在绘制之前要注意,在刚才已经把绘制的颜色变成system_color了,如果不再一次改变颜色的话,声望数值的颜色就会和“声望”文字的颜色一致,显得不美观。所以我们还需要改变一次颜色:change_color(normal_color)。
  改变好颜色后我们再来绘制:draw_text(0,0,contents.width - 8,line_height,value,2)。这条语句的含义和绘制声望文字的含义是一样的,只是多加了一个参数,表示右对齐。如果不加,则声望数值会覆盖在声望文字上。因为两个绘制区域是重叠的,而对齐方式也是一样的,所以就会重叠在一起。
  经过漫长的探索,已经绘制好了内容,但远远不够。我们继续。

@value
默认脚本如下:
[pre lang="ruby" line="1"]def value
    $game_party.gold
end[/pre]
  $game_party是一个实例(全局变量),存储的是队伍的各种信息,可以在默认脚本的Game_Party类中找到其定义。当然,这部分内容不在本帖的讨论范围内。gold是一个变量,存储队伍的金钱数目。
  那么很显然,这个方法的内容不是我们想要的,把$game_party.gold注释。然后,在本例中,声望的数值是用第15号变量来保存的,所以应该写:return $game_variables[15]。也可以省略return。
  如果你的游戏中声望是有单位的,例如单位是:个。那么这么写:return $game_variables[15].to_s + "个";由于“个”是个字符串,而$game_variables[15]是一个数字。我们必须先将数字转化为字符串,然后再跟“个”进行相加,就可以得到比如以下效果:15个,否则运行会出错。至于to_s,可以在F1的RGSS参考手册-Ruby语法-标准函数库-内建类-Numeric 数字类-Integer 整数类中找到,是一个方法。

@currency_unit
默认脚本如下:
[pre lang="ruby" line="1"]def currency_unit
    Vocab::currency_unit
end[/pre]
  Vocab就在默认脚本中,就是第一个,是一个模块。而currency_unit则表示Vocab中的方法。用来获取数据库设定的金钱的单位。
  那么对于无单位的声望,这个方法就可以完全注释不用了。有单位的声望也不用这个。

@open
默认脚本如下:
[pre lang="ruby" line="1"]def open
    refresh
    super
end[/pre]
  refresh:调用该类的refresh方法。这个方法刚才我们已经修改了,用来绘制声望文字和声望数字。所以这条语句不可变更。
  super:调用父类(Window_Base)的同名方法(open),是用来打开窗口的。跟update有关,不在本文的讨论范围内,可以保留也可以删除。

4.直到目前为止,总算把Window_Gold类的所有方法都按照我们的意愿修改完毕了,但是还远远不够。我们只是定义了这么一个窗口类,还没有对它进行实例化,没有对它进行显示什么的。那么开始吧。先是实例化。以Window_Gold类为例。找到其实例化的地方,位于Scene_Menu类的create_gold_window方法,然后Scene_Menu的start方法调用create_gold_window来实现实例化。我们依葫芦画瓢,在Scene_Menu类中新建一个方法:create_prestige_window。里面需要定义以下信息:实例化,x坐标,y坐标。
create_gold_window方法默认脚本如下:
[pre lang="ruby" line="1"]def create_gold_window
    @gold_window = Window_Gold.new
    @gold_window.x = 0
    @gold_window.y = Graphics.height - @gold_window.height
end[/pre]
  @gold_window是一个成员变量,我们的声望窗口也需要一个,就命名为@prestige_window。
  @gold_window = Window_Gold.new:进行金钱窗口的实例化。仿照这条语句的写法,声望窗口的实例化就为:@prestige_window = Window_Prestige.new。当进行实例化时,就会调用Window_Prestige类的initialize方法。
  @gold_window.x = 0:金钱窗口x坐标。声望窗口也是0,所以:@prestige_window.x = 0。0表示紧挨着游戏窗口的左侧。
  @gold_window.y = Graphics.height - @gold_window.height:金钱窗口的y坐标。由于金钱窗口紧挨着游戏窗口的下方,所以其计算的方法就是窗体高度减去金钱窗口的高度。而声望窗口又是紧挨着金钱窗口,所以我们还要减去声望窗口的高度:@prestige_window.y = Graphics.height - @gold_window.height - @prestige_window.height。Graphics的定义可以在F1中找到。height是一个方法,用来获取游戏窗口的高度,一般而言是416。

5.实例化的方法写好后,我们就在Scene_Menu的start方法加一句:create_prestige_window。
start经过修改的脚本如下:
[pre lang="ruby" line="1"]def start
    super
    create_command_window
    create_gold_window
    create_status_window
    create_prestige_window#新加的
end[/pre]

6.好!到目前为止,已经全部完成了。赶紧进游戏看看效果吧。

以下是脚本:
[pre lang="ruby" line="1"]#这是一个在主菜单显示声望的窗口类
#encoding:utf-8
#==============================================================================
# ■ Window_Prestige
#------------------------------------------------------------------------------
#  显示声望的窗口
#==============================================================================

class Window_Prestige < Window_Base
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, window_width, fitting_height(1))
    refresh
  end
  #--------------------------------------------------------------------------
  # ● 获取窗口的宽度
  #--------------------------------------------------------------------------
  def window_width
    return 160
  end
  #--------------------------------------------------------------------------
  # ● 刷新(在这里绘制内容)
  #--------------------------------------------------------------------------
  def refresh
    contents.clear#清除刚刚绘制的内容,以免造成内容重叠
    change_color(system_color)#改变绘制颜色为system_color(蓝色)
    #开始绘制“声望”二字,参数(x,y,w,h,v)
    #含义:
    #x:绘制内容的x坐标,相对于这个窗体
    #y:绘制内容的y坐标,相对于这个窗体
    #w:绘制内容的宽度,过短会显示不全
    #h:绘制内容的高度,同上
    #v:绘制的内容
    #int:对齐方式,1:居中;2:右对齐。省略:左对齐。
    draw_text(0, 0, contents.width - 8, line_height, "声望");
    change_color(normal_color);#改变绘制颜色为普通白色
    #开始绘制声望数值
    #line_height:位于父类中,表示一行文字占用的高度
    draw_text(0,0,contents.width - 8,line_height,value,2);
  end
  #--------------------------------------------------------------------------
  # ● 获取声望
  #--------------------------------------------------------------------------
  def value
    return $game_variables[15];
  end
  #--------------------------------------------------------------------------
  # ● 打开窗口
  #--------------------------------------------------------------------------
  def open
    refresh
    super
  end
end[/pre]

[pre lang="ruby" line="1"]class Scene_Menu < Scene_MenuBase
  #--------------------------------------------------------------------------
  # ● 开始处理
  #--------------------------------------------------------------------------
  alias start_old start;
  def start
    super
    create_command_window
    create_gold_window
    create_status_window
    create_prestige_window
  end
  #--------------------------------------------------------------------------
  # ● 生成声望窗口
  #--------------------------------------------------------------------------
  def create_prestige_window
    @prestige_window = Window_Prestige.new
    @prestige_window.x = 0
    @prestige_window.y = Graphics.height - @gold_window.height - @prestige_window.height
  end
end[/pre]

将以上2段脚本分别插入到main前面就可以实现功能了。效果在帖子的上方。

注:alias start_old start:表示将一个旧方法重新命名。格式如下:alias 新方法名称 旧方法名称。这样做的好处是避免脚本冲突。

呼!终于写完了。我自己都觉得很啰嗦。不过既然是类似于教程心得之类的东西,当然不能只贴脚本了事。详细的说明和思路还是很有必要的。因为我还是新人,所以也欢迎各位提出建议或者意见。

评分

参与人数 2星屑 +388 梦石 +1 收起 理由
lsu666666 + 38 塞糖
怪蜀黍 + 350 + 1 发布奖励!很详细的教程

查看全部评分

游戏群组:https://rpg.blue/forum.php?mod=group&fid=565在这里你可以看到我在制作游戏过程中分享的内容。
梦石
0
星屑
335
在线时间
1 小时
注册时间
2013-10-22
回帖
1
发表于 2014-1-9 14:54:13 | 显示全部楼层
回复

使用道具 举报

梦石
0
星屑
782
在线时间
3431 小时
注册时间
2011-6-10
回帖
6325
发表于 2014-1-9 15:25:10 | 显示全部楼层
有VX的吗?还有,LS存图片作死

点评

我现在专门搞VA。LS存的是什么图片啊?看不到。  发表于 2014-1-9 22:00
长名公主玩家群:372588926 攻略娱乐应有尽有
了解更多新RM游戏,游戏制作请加入RPGmaker支援群:113622890
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部