赞 | 1 |
VIP | 0 |
好人卡 | 11 |
积分 | 0 |
经验 | 26243 |
最后登录 | 2014-8-4 |
在线时间 | 841 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 48
- 在线时间
- 841 小时
- 注册时间
- 2010-8-11
- 帖子
- 1135
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 945127391 于 2013-3-9 00:39 编辑
一.本教程提供给一些已经有一点脚本基础的学习者们(至少你要知道变量啊函数啊什么的),如果你没有达到,那我希望你打开着VA的F1文档来看这篇教程;
二.如果你已经有一点脚本基础了,我也希望你打开着F1来看,因为我将在以下的教程中引用到许多F1里的内容;
三.本教程不会太多的说一些理论性的东西(比如浮点数是什么啊之类的),免得说多错多= =;
四.本人由于第一次写教程,所以有(fei)点(chang)乱,请多多包容;
五.如果有什么疑问或者发现了什么错误之处,又或者有什么意见或建议,欢迎回复,毕竟我也是个学习者而已。
如果你把上面的给看完了,就可以就绪看下去了。
好了,我们开始讲课……等等!
上次的课后作业还没有说呢,现在就把答案揭晓了吧!
①:
这个要在Window_MapStatus里新建一个方法,内容如下:- #----------------------------------------------------------------------------
- # * 描绘名称
- #----------------------------------------------------------------------------
- def draw_actor_name(actor, x, y, width = 112)
- color = Color.new(0, 0, 0)
- color = crisis_color if actor.hp < actor.mhp /
- color = knockout_color if actor.hp == 0
- change_color(color)
- draw_text(x, y, width, line_height, actor.name)
- end
复制代码 你写对了吗?
(PS:你直接写成以下的样子其实也没错:- #----------------------------------------------------------------------------
- # * 描绘名称
- #----------------------------------------------------------------------------
- def draw_actor_name(actor, x, y, width = 112)
- change_color(Color.new(0, 0, 0))
- draw_text(x, y, width, line_height, actor.name)
- end
复制代码 )
②:
嗯……其实这个作业不需要显示的,只用写出窗口的代码就行了,答案如下:- class Window_MapXY < Window_Base
- #----------------------------------------------------------------------------
- # * 初始化
- #----------------------------------------------------------------------------
- def initialize
- super(0, 0, 273, 72)
- refresh
- end
- #----------------------------------------------------------------------------
- # * 刷新画面
- #----------------------------------------------------------------------------
- def update
- super
- refresh
- end
- #----------------------------------------------------------------------------
- # * 更新内容
- #----------------------------------------------------------------------------
- def refresh
- self.contents.clear
- self.contents.draw_text(0, 0, self.contents.width, 24, "角色所在位置:")
- self.contents.draw_text(0, 24, self.contents.width, 24, "(#{$game_player.x},#{$game_player.y})", 2)
- end
- end
复制代码 好了,作业讲完了,我们就继续来讲课吧!
上次把头像名称和等级给描绘出来了,接下来我们就要描绘状态了。
想要描绘出状态的图标,我们首先要知道应该如何描绘图标,描绘图标一般使用draw_icon方法:
draw_icon(icon_index, x, y[, enabled])
在(x, y)处描绘icon_index号图标。
enabled是有效标志,可不填,默认为true。为false时半透明绘制。
这个东东的XY坐标计算和描绘头像的draw_face差不多,只不过它这里运用到了一个新的知识点:填充度。在draw_icon里有一句:- contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
复制代码 首先,我们看到contents,就要立刻想到它相当于self.contents,
然后,后面的那句enabled ? 255 : translucent_alpha,其实和- if enabled
- return 255
- else return translucent_alpha
- end
复制代码 的效果差不过,而第一句if enabled其实少掉了== true,但是也不会错,因为这是个偷懒方法(喂!)
然后在这里的话translucent_alpha其实是返回160,所以说当enabled为false时,描绘出来的图标的填充度就是160,也就造成了“半透明”的效果。
现在,你就知道了吧,填充度就相当于透明度。
然后我们知道了如何描绘图标,我们还要知道该如何获取对应的状态的图标ID。
其实每一个状态都由与其对应的一个RPG::State来管理,而在RPG::State里有一个叫icon_index的属性,来储存图标ID,而在游戏中,系统自动帮我们生成了一个叫$data_states的变量,这个变量其实是由许多RPG::State的实例组成的,所以我们使用以下脚本,就可以知道ID号状态的图标ID了:- $data_states[id].icon_index
复制代码 但是,我们这个状态的ID并不是没有目标的,而是可以从特定的地方获取的。
由于我们要描绘的是角色(领队)的状态,于是我们就要用以下的脚本来获取领队的状态的图标ID:- $game_party.members[0].state_icons + $game_party.members[0].buff_icons
复制代码 其实这句话的返回值其实是一个储存了$game_party.members[0](也就是领队)所有状态的图标ID的数组。
而我们要全部描绘,就要用到for...in...end这个循环了。
我们需要不断的循环描绘状态的图标,而且必须要有个只随着循环的次数而增加,那么最好的选择就是for...in...end了。
于是乎,先把以下的内容扔进refresh里:- icons = $game_party.members[0].state_icons + $game_party.members[0].buff_icons
- for i in 0...icons.size
- draw_icon(icons[i], i * 24, 72)
- end
复制代码 效果就会如下:
但是,这样就出现了一个问题:当状态数量大于4的时候,显示的图标就会超过头像的范围,如下:
但是旁边的那个地方我们要留着画血槽的啊泥煤!
所以我们要限定描绘的那个状态的数量,于是就要用到数组的一个方法:self[start, length]
self[start, length]
返回由从self[start]开始length个元素组成的数组。
F1里是这样说的:
返回从 start 算起,包含 length 个元素的数组。若 start 为负值,则从尾部开始算起(最后一个元素的索引为 -1)。若 length 超出从 start 算起的数组剩余长度,则忽略超出的部分。若 length 为负值则返回 nil。
于是,我们要知道现在能够描绘的数组有多少个。
其实这是个固定的量:头像宽度/图标宽度,也就是96/24=4。
所以我们要要在icons = $game_party.members[0].state_icons + $game_party.members[0].buff_icons下面新增这样一句话:很明显,这句话就获取了icons里开头的4个元素,然后再代入到icons这个变量里。
嗯……现在效果不错。
但其实描绘状态可以使用draw_actor_icons来描绘角色的状态。
draw_actor_icons(actor, x, y[, width])
在(x, y)处描绘actor的状态。
width是描绘的长度,可以不填,默认为96。
所以呢,我们把刚才写的那一堆全都换成:- draw_actor_icons($game_party.members[0], 0, 72)
复制代码 呐,状态就描绘完了。我们就要描绘HP、MP、TP和EXP槽了~
描绘HP、MP和TP槽都有自己专用的方法,下面就逐个介绍:
draw_actor_hp(actor, x, y[, width])
在(x, y)处描绘actor的HP槽。
width为宽度,可不填,默认为124。 | draw_actor_mp(actor, x, y[, width])
在(x, y)处描绘actor的MP槽。
width为宽度,可不填,默认为124。 | draw_actor_tp(actor, x, y[, width])
在(x, y)处描绘actor的TP槽。
width为宽度,可不填,默认为124。 | 所以我们在refresh里新增以下三句话:- draw_actor_hp($game_party.members[0], 101, 24, self.contents.width - 101)
- draw_actor_mp($game_party.members[0], 101, 48, self.contents.width - 101)
- draw_actor_tp($game_party.members[0], 101, 72, self.contents.width - 101)
复制代码 效果就会如下图所示:
唔……效果不错,但是不是太乏味了一点呢?
于是乎,我们接下来就要改造一下血槽了~~
首先,我们要知道,在draw_actor_hp、draw_actor_mp和draw_actor_tp里头都用到了同一个方法来描绘值槽,那就是draw_gauge,所以我首先要对draw_gauge这个方法动工。
首先,来个最基本的:在窗口的脚本里添加这样一个新的方法:- def draw_gauge(x, y, width, rate, color1, color2)
- end
复制代码 其实,在Window_Base里也定义了这个方法,只不过我们在这里把这个方法重新定义了一遍,所以在这个窗口内调用draw_gauge这个方法的时候,就会按照这里定义的来执行,而在其他地方调用这个方法的时候,就会按照Window_Base或者那里所定义的draw_gauge来执行。所以说,这样做是一个十分安全的方法。
然后,我们在draw_gauge里添加一句话:- fill_w = (width * rate).to_i
复制代码 其实这个是用来计算要填充的宽度的,但是这个rate是怎么计算出来的呢?
嗯……这是我们培优班的内容了,让我们推后再说。
然后,我们要添加这样两句话:- self.contents.gradient_fill_rect(x, y+12, fill_w, 6, color1, color2, true)
- self.contents.gradient_fill_rect(x, y+18, fill_w, 6, color2, color1, true)
复制代码 这里又有个新方法:gradient_fill_rect。其实这个是用来描绘渐变色的,介绍如下:
gradient_fill_rect(x, y, width, height, color1, color2[, vertical])
在(x, y)处描绘宽度为width,高度为height,由color1渐变到color2的渐变色。
vertical用于设定渐变方向,true为纵向,可不填。默认为横向。
F1里是这样说的:
将位图区域 (x, y, width, height) 或矩形(Rect 矩形类) 填满从颜色 color1(Color 色彩类) 至 color2(Color 色彩类)的渐层色彩。
将 vertical 设为 true 生成纵向的渐层色彩,预设为横向渐层。
然后呢,描绘出来的效果就是这样:
嗯……虽然比以前好很多了,但是看起来还是怪怪的啊……对了!我们不如描个边吧!
但是,要怎么画线呢?
其实,在RM里,每一个点都可以视为1像素*1像素的正方形,而线是由许多个点组成的,也就可以看成 (1*长度)像素*(1*宽度)像素 的长方形了。
理清了思路以后,我们就要开始描绘了。
首先,描绘第一条线:在self.contents.gradient_fill_rect(x, y+18, fill_w, 6, color2, color1, true)之后添加这样一句话:- self.contents.fill_rect(x, y+12, width, 2, Color.new(255, 255, 255))
复制代码 好了,这样就把第一条线给描绘出来了。我们先别急着看效果,先把这句话分析一下:
首先,通过前面的self.contents,我们能够知道fill_rect也是一个位图类的方法。
那这个方法具体的参数和说明是怎样的呢?让我来告诉大家吧!
fill_rect(x, y, width, height, color)
在(x, y)处描绘一个宽度为width,高度为height,填充了颜色color的矩形。
F1的说法是:
将位图区域 (x, y, width, height) 或矩形(Rect 矩形类 )填满指定的颜色 color (Color 色彩类 )。
于是乎,我们刚才写的那句话其实就是在(x, y)处描绘了一个 width * 2 的长方形。
(P.S请弄清楚上面的那一句x、y以及width和蓝字里的x、y、width其实是不同的两个变量,虽然名字相同。)
那剩下的三条线你们会画了吧,你们不如先自己写出来,再看答案吧!
答案如下:- self.contents.fill_rect(x, y+22, width, 2, Color.new(255, 255, 255))
- self.contents.fill_rect(x, y+14, 2, 8, Color.new(255, 255, 255))
- self.contents.fill_rect(x+width-2, y+14, 2, 8, Color.new(255, 255, 255))
复制代码 恩恩,这样子这些槽看起来就漂亮多了~~(众:有吗?)
最终预览图如下:
好了,这样子的话整个窗口就画完啦!
写到最后,窗口的代码就是这样啦~你写对了吗?- #==============================================================================
- # ** Window_MapStatus
- #==============================================================================
- class Window_MapStatus < Window_Base
- #----------------------------------------------------------------------------
- # * 初始化
- #----------------------------------------------------------------------------
- def initialize
- super(0, 0, 273, 144)
- refresh
- end
- #----------------------------------------------------------------------------
- # * 刷新画面
- #----------------------------------------------------------------------------
- def update
- super
- refresh
- end
- #----------------------------------------------------------------------------
- # * 更新内容
- #----------------------------------------------------------------------------
- def refresh
- self.contents.clear
- draw_actor_face($game_party.members[0], 0, 0)
- draw_actor_name($game_party.members[0], 0, 0)
- draw_actor_level($game_party.members[0], 101, 0)
- draw_actor_icons($game_party.members[0], 0, 72)
- draw_actor_hp($game_party.members[0], 101, 24, self.contents.width - 101)
- draw_actor_mp($game_party.members[0], 101, 48, self.contents.width - 101)
- draw_actor_tp($game_party.members[0], 101, 72, self.contents.width - 101)
- end
- #----------------------------------------------------------------------------
- # * 描绘值槽
- #----------------------------------------------------------------------------
- def draw_gauge(x, y, width, rate, color1, color2)
- fill_w = (width * rate).to_i
- self.contents.gradient_fill_rect(x, y+12, fill_w, 6, color1, color2, true)
- self.contents.gradient_fill_rect(x, y+18, fill_w, 6, color2, color1, true)
- self.contents.fill_rect(x, y+12, width, 2, Color.new(255, 255, 255))
- self.contents.fill_rect(x, y+22, width, 2, Color.new(255, 255, 255))
- self.contents.fill_rect(x, y+14, 2, 8, Color.new(255, 255, 255))
- self.contents.fill_rect(x+width-2, y+14, 2, 8, Color.new(255, 255, 255))
- end
- end
复制代码 同学甲(你终于出现了……):EXP条呢?
呐,EXP条就留给大家作为作业啦!(光速秒逃)
嗯……这节课我们学习了一些方法,包括:
名称 | LZ的说明 | F1/默认脚本里的说明 | self.contents.fill_rect(x, y, width, height, color) | 在(x, y)处描绘一个宽度为width,高度为height,填充了颜色color的矩形。 | 将位图区域 (x, y, width, height) 或矩形(Rect 矩形类 )填满指定的颜色 color (Color 色彩类 )。 | self.contents.gradient_fill_rect(x, y, width, height, color1, color2[, vertical]) | 在(x, y)处描绘宽度为width,高度为height,由color1渐变到color2的渐变色。 vertical用于设定渐变方向,true为纵向,可不填。默认为横向。 | 将位图区域 (x, y, width, height) 或矩形(Rect 矩形类) 填满从颜色 color1(Color 色彩类) 至 color2(Color 色彩类)的渐层色彩。
|
名称 | LZ的说明 | F1/默认脚本的说明 | draw_icon(icon_index, x, y[, enabled]) | 在(x, y)处描绘icon_index号图标。
enabled是有效标志,可不填,默认为true。为false时半透明绘制。 | ——
| draw_actor_hp(actor, x, y[, width]) | 在(x, y)处描绘actor的HP槽。 width为宽度,可不填,默认为124。 | —— | draw_actor_mp(actor, x, y[, width]) | 在(x, y)处描绘actor的MP槽。 width为宽度,可不填,默认为124。 | —— | draw_actor_tp(actor, x, y[, width]) | 在(x, y)处描绘actor的TP槽。 width为宽度,可不填,默认为124。 | —— |
对了,大家不觉得这一个窗口皮肤似乎太枯燥了吗?
我们可以给它放上个背景吧!
恩恩!我们下节课不仅要把窗口的显示转为“正式版”,还要给它许多人性化的功能呢!
所以下节课可能要说很多东西,大家注意喽~~
好了,可爱的作业又来了~
所谓的“必做”,不是指你一定要把答案告诉我,而是指你至少要在脑袋里把答案给想出来。
①(必做)draw_icon是在___________里定义的方法。
②这个作业就是要描绘EXP槽了。
你可以在Window_MapStatus里定义一个叫draw_actor_exp的方法,然后在refresh里调用哦!
这次是特别大酬宾= =,有预览图哦:
就是上面这样的效果啦~
提示:一.角色当前经验:actor.exp
升到下一级所需经验:actor.next_level_exp
二.比率的计算请看培优班;
三.范例里的颜色分别是Color.new(0, 255, 0)和Color.new(100, 255, 100)。
不会很难吧~
培优班要说什么来着?
啊,我想起来了~是要说描绘血槽的时候的rate(比率)是怎么算出来的吧。
其实很简单:在Game_BattlerBase里有一个叫hp_rate的方法(517~519),它的定义是这样滴:- def hp_rate
- @hp.to_f / mhp
- end
复制代码 头尾的那两句不用我说了吧,主要就在中间那一句:
他那里面的@hp和mhp我们可以理解为获取战斗着的HP和最大HP(MHP),而用HP除以MHP,就可以得到HP占MHP的多少,然后再乘上width,要描绘的宽度就出来了。
(P.S 实际上,Game_Actor,也就是掌管角色的类的父类的父类就是Game_BattlerBase,所以Game_BattlerBase里的方法都被继承到Game_Actor里去了。)
但是,那个to_f是啥呢?
我们都知道,在RM中,整数运算一定得整数。而HP永远小于或等于MHP(正常来说是这样滴),所以如果用整数来算(也就是HP和MHP都为整数)的话,得数永远只有两个数:0和1!
所以那句to_f就起到了一个很重要的作用:把整数转换为浮点数,这样算出来的数也会出现浮点数了。
同样的,也有mp_rate(523~525)和tp_rate(529~531)这两个方法,有兴趣的可以去看一下。
这里用来放一些读者在回复中提的问题以及我的回答。
暂时还没有,似乎。
花了几天,终于把这给写完了。
拖这么多天真是很抱歉,因为要上学了,所以也忙了起来。
以后的更新可能要等很久了,我尽量吧。
谢谢大家的支持 +^+ |
评分
-
查看全部评分
|