注册会员 登录
Project1 返回首页

亿万星辰的深邃空间 https://rpg.blue/?62841 [收藏] [复制] [分享] [RSS]

日志

RGSS窗口类Window详解(二)

已有 516 次阅读2011-9-13 20:43 |个人分类:坑爹的RGSS教程

第二讲 静态窗口的图片绘制

这次讲解的内容依然是以静态窗口Window_Base类为基础,上一讲中已经介绍了如何在Window_Base类的对象中写字,这一讲,我们来说说怎样画图。

在介绍绘图之前,先介绍几个我们要常常使用到的语句,或者说是函数、方法。
self.content.clear
这一句在第一讲里已经见过了,是把整个self.contents清理为干干净净的空白画纸的功能,相当于是个大橡皮吧。


self.content.fill_rect(0, 0, 100, 100, Color.new(0, 0, 0, 0))
这一句是第一次见,它本身是用于为一个矩形范围进行颜色的填充,前四个参数依次是矩形范围的x坐标、y坐标、矩形宽度、高度,第五个参数则是用于填充的颜色。
这里要提一下RGSS中Bitmap类对象中的描绘规则,很简单,颜色(或者说图片)是一层一层盖上去的,也就是越靠后描绘的内容,越出现在上头,同时也就是这挡住了底下先描绘的内容。
但由于RGSS中Bitmap类对象的一个特殊之处,使得这个fill_rect方法有了另外的作用。
一般情况下,我们设想,如果在一张已经画满图画的纸上再涂上一层透明的颜色,应该是相当于做了一次无用操作,涂个透明的颜色上去岂不是等于没涂么?但RGSS中则不是这样,当你尝试再为某个区域涂上一层透明的颜色,也就是刚才写到的Color.new(0, 0, 0, 0)时,这个区域中的所有颜色都会被清除,换言之,你下达的涂上透明颜色的操作,其实是用橡皮擦给这个区域做了清除操作,而这个区域也就理所应当的成为了干净的画纸。


bitmap = Bitmap.new("Graphics/Battlers/001-Fighter.png")
与这个类似地方法我们在创建画纸的时候见过,不同的是,当时括号里是有两个数字,而这次则是一个文件名,这是Bitmap类对象创建的另一种方式,而且它对于载入图片等操作更为便捷。如代码中所写的,现在bitmap这个对象直接就是一张图片,而图片的内容就是工程Graphics目录下的Battlers目录下的001-Fighter.png这张图片。当我们需要描绘一张图片时,就需要先做这样的操作,而与此功能相同的还有下面这个操作:
bitmap = RPG::Cache.battler("001-Fighter", 50)
这个使用的是RGSS中的RPG::Cache模块中的一个函数来实现的,具体实现的功能大体上与上面所述的无异,不过函数可以允许附带一个hue值使得整个图片的色调发生一定的变化。


self.contents.blt(0, 0, bitmap, Rect.new(0, 0, 100, 100))
这个方法就是将一张已经做好载入工作的图片bitmap描绘到制定的位置去,至于它其中的几个参数的意义,下面我们提到的时候再来做解释。




这次的讲解,我们选用自行编写一小段代码来进行。先来整个看一下代码部分。

class Window_Gold < Window_Base
def initialize
super(160, 120, 320, 240)
self.z = 999
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.size = 18
refresh
end
def refresh
self.contents.clear
for i in 0...$game_party.actors.size
draw_actor(i)
end
end
def draw_actor(index)
actor = $game_party.actors[index]
self.contents.fill_rect(72 * index, 0, 72, 208, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
x = (bitmap.width - 72) / 2
y = (bitmap.height - 108) / 2
self.contents.blt(72 * index, 0, bitmap, Rect.new(x, y, 72, 108))
self.contents.font.color = normal_color
self.contents.draw_text(72 * index, 112, 72, 32, actor.name, 1)
self.contents.draw_text(72 * index, 144, 72, 32, actor.hp.to_s, 2)
self.contents.draw_text(72 * index, 176, 72, 32, "#{actor.sp}", 2)
self.contents.font.color = system_color
self.contents.draw_text(72 * index, 144, 72, 32, $data_system.words.hp)
self.contents.draw_text(72 * index, 176, 72, 32, $data_system.words.sp)
end
end

想看效果的朋友可以复制到F11的脚本中,插到Main前面,运行进入游戏,按ESC打开菜单应该就可以看到效果。

下面我们逐字逐句来分析。还是老规矩,带有■为脚本内容。

■class Window_Gold < Window_Base
■ def initialize
■ super(160, 120, 320, 240)
■ self.z = 999
这里只解释一下这句,目的是为了让窗口处于最前端,方便查看。


■ self.contents = Bitmap.new(width - 32, height - 32)
■ self.contents.font.size = 18
还记得这句的功能么,放在这里是为了方便。


■ refresh
■ end
■ def refresh
■ self.contents.clear

■ for i in 0...$game_party.actors.size
■ draw_actor(i)
■ end
上面这三行执行的是一个循环过程,是连续多次调用下面定义的draw_actor方法。调用的次数是根据队伍中的角色数量而定的。


■ end
■ def draw_actor(index)
■ actor = $game_party.actors[index]
首先获取当前角色的信息。



■ self.contents.fill_rect(72 * index, 0, 72, 208, Color.new(0, 0, 0, 0))
这里用到开头介绍的fill_rect方法,正是当成橡皮功能来用了。



■ bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
这句也是开头介绍过的,载入了当前角色的战斗图。



■ x = (bitmap.width - 72) / 2
■ y = (bitmap.height - 108) / 2
这两句先记着,下面说。


■ self.contents.blt(72 * index, 0, bitmap, Rect.new(x, y, 72, 108))
依然是这次新加入的知识,现在来具体说说这个blt方法的使用。首先前两个参数是坐标,这就不废话了;紧接着的是要描绘的图片,我这里叫他样图,可以看到,样图是在刚才通过RPG::Cache方法载入的;最后一个参数是一个矩形,这个参数往往是最让人迷茫的。
很多朋友刚接触Bitmap的图片描绘时,前面的坐标、样图都好理解,那么这个矩形该如何理解呢?我来试着做一下解释。
我们依然把整个描绘过程叙述的实体化。
我们要把样图画到画纸上的话,画纸有了、样图也有了、要画的位置也确定了,感觉上已经都具备了,那么还需要什么呢?……如果说,要求你把一整张图都画到画纸上,那么的确,这些东西足够了,但如果我只让你画样图的左半边上去呢?没错,我们还需要一个用于控制样图的范围,而最后那个矩形参数,就是做这个的。
以RMXP的默认行走图为例(假设宽度128,高度192)
当我们需要把整个4*4的行走图都描绘到画纸上的时候,我们就可以把矩形的大小设置为从行走图图左上角原点(0,0)开始,宽度为行走图宽度128,高度为行走图高度192的这样一个矩形,其实也就是整个行走图的大小了。
当我们只需要最上面一行的时候,我们可以设置这个矩形为从行走图图左上角原点(0,0)开始,宽度为行走图宽度128,高度为行走图高度的1/4也就是48的一个矩形。
那么请大家想想,如果我想取最左边的一列呢?还有取最右边的一列呢? 如果能想明白的话那说明这部分你已经理解了 O(∩_∩)O
结合上面的x、y两个坐标的运算,不知道大家能不能想明白这个绘制是怎么选取区域的呢?


■ self.contents.font.color = normal_color
■ self.contents.draw_text(72 * index, 112, 72, 32, actor.name, 1)
■ self.contents.draw_text(72 * index, 144, 72, 32, actor.hp.to_s, 2)
■ self.contents.draw_text(72 * index, 176, 72, 32, "#{actor.sp}", 2)
这里用于描绘角色名称以及HP和SP使用的两种方法,也正式第一讲中提到的字符串类型的多种表达方式。首先actor.name这个属性本身就是字符串类型,所以可以直接放在这里;而角色的HP和SP值则为数字,必须经过一次转换以得到一个字符串类型的值才可放在这里使用,角色的HP,我使用了to_s方法来进行转换,它可以返回一个数字对应的一个字符串,如2009转换为“2009”;而对于角色的SP,我使用了隐式转换的方法,也就是在引号内部进行转换,通过#{}包围一个变量,使得输出时自动执行一次字符串类型的转换。


■ self.contents.font.color = system_color
■ self.contents.draw_text(72 * index, 144, 72, 32, $data_system.words.hp)
■ self.contents.draw_text(72 * index, 176, 72, 32, $data_system.words.sp)
■ end
■end


第二讲在这里也就结束了,希望大家能根据前两讲所学的内容去读解一下默认工程中几个Window_Base类的子类的代码,看看能不能把大部分看明白,如Window_Help Window_Gold Window_PlayTime Window_Stemps Window_EquipLeft 等等等等

鸡蛋

鲜花

评论 (0 个评论)

facelist doodle 涂鸦笔

您需要登录后才可以评论 登录 | 注册会员

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-27 01:13

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部