设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 5395|回复: 11
打印 上一主题 下一主题

[原创发布] 日历的RGSS3入门教程 - 精灵与位图Lv2 初识位图与矩形

[复制链接]

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

跳转到指定楼层
1
发表于 2019-3-17 12:27:38 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

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

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

x
本帖最后由 KB.Driver 于 2019-5-24 18:11 编辑

上一课: 日历的RGSS3入门教程 - 精灵与位图Lv1 初识精灵


精灵与位图Lv2 初识位图与矩形
课程难度:★★☆☆☆ 沙包
涉及的RGSS知识:
类:Sprite,Bitmap,Rect, Color ,Font
模块:Graphics
其他:F1文档的基础使用
涉及的Ruby知识:实例方法



上一课中,我们认识了怎样从路径中读取图像到位图,再将位图交给精灵以显示在屏幕上。
与此同时,为了获得显示的效果,我们学习了精灵的不少属性。这次我们将开始进入位图与矩形的学习。
矩形(Rect)是RGSS中与精灵(Sprite)和位图(Bitmap)密不可分的一个数据对象。
正如它的名字所说,它所有的属性都是为了描述一个数学上的长方形而存在的。
在数学中要确定一个长方形有很多方法,例如确定长方形的三个点等,这里就不一一列举了。
RGSS中的矩形一共只有4个属性,分别是横纵坐标x与y和宽度width、高度height。
为了更好地理解矩形,让我们看一看矩形在Photoshop中的表现形式。


当我们用矩形工具随便一拉,信息就会显示四个数据,分别是矩形左上角那一点的x,y坐标和矩形的宽度高度。
在RGSS中,矩形也是靠这四个数据来吃饭的。

下一课:日历的RGSS3入门教程 - 精灵与位图Lv3 精灵更新与状态机

评分

参与人数 6+6 收起 理由
miantouchi + 1 精品文章
百里_飞柳 + 1 精品文章
真·可乐 + 1 精品文章
Mayaru + 1 精品文章
RMVXA + 1 精品文章
Nil2018 + 1 精品文章

查看全部评分

用头画头像,用脚写脚本

Lv3.寻梦者

梦石
0
星屑
4939
在线时间
489 小时
注册时间
2018-6-18
帖子
620
12
发表于 2019-3-17 15:11:43 | 只看该作者
PK之路走起来!
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
7570
在线时间
1157 小时
注册时间
2016-9-10
帖子
165

开拓者

11
发表于 2019-3-17 14:15:57 | 只看该作者
非常实用的教程,受益多多
支持KB大神
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

10
 楼主| 发表于 2019-3-17 12:52:52 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:56 编辑

课后练习:

利用本课所学知识,结合F1文档的Bitmap内容,绘制以下场景。

使用素材(RTP):
"Graphics/Battlebacks1/Clouds"
"Graphics/Battlebacks1/Sky"
"Graphics/Battlers/Wizard_m"
"Graphics/Battlers/Willowisp"


用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

9
 楼主| 发表于 2019-3-17 12:49:22 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:55 编辑

运行结果:


毫无疑问,这个“VS”实在是太小了。
通过查阅F1,我们得知Bitmap有字体font属性,我们可以在绘制前修改这个字体font的大小size。
不要忘记把绘制前测量大小的临时位图也赋予同样的字体。

# VS文字精灵
text_sprite = Sprite.new
fontsize = 64 # 字体大小
text_bitmap = Bitmap.new(1, 1) # 先生成一个最小的位图,用于调用text_size方法
text_bitmap.font.size = fontsize
text_size = text_bitmap.text_size("VS") # text_size是一个矩形(Rect)对象
...
text_bitmap = Bitmap.new(text_size.width, text_size.height) # 重新生成合适的位图
text_bitmap.font.size = fontsize
...
# 文字精灵居中
...


运行结果:


好了,到此我们回顾一下这堂课所讲的内容。

一、
        矩形(Rect)被广泛运用于精灵(Sprite)与位图(Bitmap)中,
它一共有x,y,宽度width,高度height四个属性。

二、
        一个位图(Bitmap)可以通过blt方法把其他位图src_bitmap上某个矩形src_rect内的数据
复制到自己以x,y为左上顶点的范围里。

三、
        除了读取文件路径,还可以通过指定宽度width与高度height用Bitmap.new(width,height)生成指定大小的空白位图。
这个空白位图需要我们自己调用位图的各种绘制方法来为它添加内容。

四、
        常见的位图的绘制方法包括blt(用其他位图填充),fill_rect(用纯色填充矩形),
gradient_fill_rect(用指定的两种颜色渐变填充矩形),draw_text(用文字填充矩形)。

五、
        RGSS的颜色类Color有RGBA四个属性,即红red,绿green,蓝blue,不透明度alpha。
用Color.new可以获得一个透明色,用Color.new(red, green, blue)可以获得一个指定RGB值的完全不透明的颜色。

六、
        位图(Bitmap)的字体font属性是一个字体(Font)对象,
字体(Font)有字号(size)等多种属性,这里不一一列举,可以通过F1文档查阅。
用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

8
 楼主| 发表于 2019-3-17 12:44:24 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:52 编辑

运行结果:


在这里,我们通过Bitmap.new(width, height)自己生成了一个宽度为width,高度为height的位图实例。
这个位图和前面我们从文件路径中读取的不一样,它的每个像素都是透明的,因此需要我们自己对它进行绘制。
我们把之前在back_bitmap上绘制失败的代码转移到这里,最后调整渐变精灵gradient_sprite的横坐标,就达到了我们需要的效果。

最后,让我们在画面中间增加一个“VS”的文字,让这场战斗更加白热化吧。
查过F1文档,draw_text方法可以满足我们的需要。
另外,为了知道这个自定义位图的大小,我们需要Bitmap实例的text_size方法。
两个方法的文档说明可以参考下图。



接下来,我们再生成一个文字精灵和一个文字位图,用来在渐变之上显示“VS”。

# 盖住中间的交界线
...
gradient_sprite.bitmap = gradient_bitmap
gradient_sprite.x = blt_rect.width - gradient_width
# VS文字精灵
text_sprite = Sprite.new
text_bitmap = Bitmap.new(1, 1) # 先生成一个最小的位图,用于调用text_size方法
text_size = text_bitmap.text_size("VS") # text_size是一个矩形(Rect)对象
text_size.width += 4
text_size.height += 4 # F1文档说明,测量的大小不包括文字边框,因此拓宽4像素备用
text_bitmap = Bitmap.new(text_size.width, text_size.height) # 重新生成合适的位图
text_bitmap.draw_text(text_size, "VS")
text_sprite.bitmap = text_bitmap
# 文字精灵居中
text_sprite.ox = text_sprite.width / 2
text_sprite.oy = text_sprite.height / 2
text_sprite.x = Graphics.width / 2
text_sprite.y = Graphics.height / 2


这里解释一下所做的工作。
位图在生成时必须指定大小,但是我们一开始并不知道绘制“VS”两个字母需要多大的位图。
而且即使我们知道了,万一以后更换了游戏字体,这个数值又会改变。
因此我们需要先通过生成一个Bitmap实例,调用它的text_size方法来知道我们需要多大的位图。

text_size方法会返回一个矩形,矩形的宽与高就是我们需要的位图大小,因此我们重新根据测量好的大小生成text_bitmap。
注意,F1文档已经说明这个测量的大小不包括轮廓,因此我们将矩形的宽与高事先拓展4像素以防万一。

生成位图后,draw_text就像之前fill_rect一样,我们要指定矩形与绘制内容。
只不过这次的绘制内容不是颜色,而是一个字符串”VS”。
最后,我们调整文字精灵的位置,将其置于画面的正中心。
将精灵的ox与oy调整为位图宽度与高度的一半后,精灵的原点就是位图的中心。
再把原点变化后的精灵的x与y分别设为画面宽度与高度的一半,这样位图的中心就到达了画面的中心。



用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

7
 楼主| 发表于 2019-3-17 12:41:07 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:50 编辑

好了,这样一来分界线就被遮住了。
然而,一道黑线在中线也不是特别美观,如果是往两边渐变的黑色,视觉效果可能更好。
我们找到F1文档中的gradient_fill_rect方法,它与fill_rect类似,只不过需要我们设置两种颜色以便产生渐变。


我们设置渐变的颜色分别为纯黑Color.new(0,0,0)与透明Color.new,修改之前的代码。

...
# 盖住中间的交界线
color = Color.new(0,0,0) # 纯黑
color1 = Color.new # 透明色
gradient_width = 20 # 渐变的单边宽度
rect = Rect.new(blt_rect.width - gradient_width, 0, gradient_width, blt_rect.height) # 左半边渐变的矩形
back_bitmap.gradient_fill_rect(rect, color1, color) # 左半边渐变是由透明到纯黑
rect.x += gradient_width # 调整起始x坐标,变为右半边渐变的矩形
back_bitmap.gradient_fill_rect(rect, color, color1) # 右半边渐变是由纯黑到透明
back_bitmap.fill_rect(blt_rect.width - 1, 0, 3, blt_rect.height, color)

back_sprite.bitmap = back_bitmap
# 女英雄精灵
...


运行结果:


咦,不应该是渐变吗?为什么是纯黑的呢?
大家还记得上一课我们一开始显示男神的时候吗,游戏的背景本来就是全黑的.
因此当我们给背景涂上哪怕是透明度很低的黑色,它与背景的黑色一结合就成了纯黑。
这时候,我们就需要增加一个新的精灵来承载这段渐变了,否则背景本身就会被破坏掉。

修改代码:

# 复制位图
back_bitmap.blt(0, 0, back_bitmap2, blt_rect)
# 盖住中间的交界线
#color = Color.new(0,0,0) # 纯黑
#color1 = Color.new # 透明
#gradient_width = 20 # 渐变的单边宽度
#rect = Rect.new(blt_rect.width - gradient_width, 0, gradient_width, blt_rect.height) # 左半边渐变的矩形
#back_bitmap.gradient_fill_rect(rect, color1, color) # 左半边渐变是由透明到纯黑
#rect.x += gradient_width # 调整起始x坐标,变为右半边渐变的矩形
#back_bitmap.gradient_fill_rect(rect, color, color1) # 右半边渐变是由纯黑到透明
# back_bitmap.fill_rect(blt_rect.width - 1, 0, 3, blt_rect.height, color)

back_sprite.bitmap = back_bitmap
# 黑色渐变精灵
gradient_sprite = Sprite.new
# 盖住中间的交界线
color = Color.new(0,0,0) # 纯黑
color1 = Color.new # 透明
gradient_width = 20 # 渐变的单边宽度
gradient_bitmap = Bitmap.new(gradient_width * 2, blt_rect.height)
rect = gradient_bitmap.rect
rect.width /= 2
gradient_bitmap.gradient_fill_rect(rect, color1, color) # 左半边渐变是由透明到纯黑
rect.x += rect.width
gradient_bitmap.gradient_fill_rect(rect, color, color1) # 右半边渐变是由纯黑到透明
gradient_sprite.bitmap = gradient_bitmap
gradient_sprite.x = blt_rect.width - gradient_width

# 女英雄精灵
...

用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

6
 楼主| 发表于 2019-3-17 12:38:35 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:43 编辑



回到运行结果上来。
虽然场地是隔开了,但是中间的交界处却有着明显的不协调感。
我们希望把中间的交界处给盖住。
这一次,我们可以从F1手册中寻找这样的方法。经过一番搜寻,我们发现了fill_rect方法。



fill_rect方法可以在调用它的位图的某个矩形内填满指定的颜色,我们要盖住中间的交界线,
可以选择把位图宽度一半的位置左边1像素开始,宽度为3像素,高度与位图相等的矩形填满黑色。
注意,fill_rect所能填充的范围不会超过位图的大小。
目前我们还不清楚怎样设置颜色为黑色,因此我们点进说明里蓝色的Color链接一看究竟。



在方法的括号后面,每一个单词是一个参数,调用方法时必须传入相应数量的参数。
注意最后一个用中括号包围的[, alpha],它表示不透明度alpha这个参数是可以省略的。
F1文档告诉我们,要生成一个颜色Color类的实例至少需要我们指定这个颜色的RGB值即红red、绿green、蓝blue。

黑色的RGB值均为0,而不透明度为255,所以我们要生成的Color就是Color.new(0,0,0)。
F1文档已经说了,只要指定了RGB值,省略不透明度时将使用255。

# 复制位图
back_bitmap.blt(0, 0, back_bitmap2, blt_rect)
# 盖住中间的交界线
color = Color.new(0,0,0) # 纯黑
back_bitmap.fill_rect(blt_rect.width - 1, 0, 3, blt_rect.height, color)
back_sprite.bitmap = back_bitmap

# 女英雄精灵
...


运行结果:

用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

5
 楼主| 发表于 2019-3-17 12:35:09 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:41 编辑

在详细解释位图Bitmap类的实例方法blt之前,我们来学一下怎样查看RGSS3的F1文档。
F1文档的中文翻译可以在VA讨论区的图书馆中找到。



打开F1文档,我们选择RGSS参考→游戏库→RGSS内建类→Bitmap



在Bitmap类中,我们可以在方法里找到文档中对于blt的说明是这样的:


这里解释一下如何看懂这一段文档。
blt出现在Bitmap的“方法”中,代表这是Bitmap的实例方法,只能在Bitmap的实例上调用。
blt后面的括号代表这个方法需要接受参数,并且这些参数分别是x,y,src_bitmap,src_rect还有一个中括号框起来的opacity。
中括号框起来的参数为可选参数,在使用该方法时可以提供也可以省略。
而前面的参数都是必须提供的,否则会导致参数错误(ArgumentError),使用时必须注意。

下面的说明告诉我们这个方法的用途,用大白话说就是:
把另一个位图src_bitmap中位于矩形src_rect里的部分复制到调用blt方法的位图上,放置的位置由前两个参数x,y决定。




怎么样,有没有感觉到矩形的重要用途?
用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
10
星屑
39587
在线时间
1920 小时
注册时间
2010-11-14
帖子
3320

R考场第七期纪念奖

4
 楼主| 发表于 2019-3-17 12:31:53 | 只看该作者
本帖最后由 KB.Driver 于 2019-3-17 12:38 编辑

不过,女英雄独自来到这种地方多危险啊,如果只是在城镇与郊外的交界处还好。
为了营造出交界线的效果,我们需要把女英雄所在的半边地板变回城镇的石头路。

在此之前,我们显示位图都是直接把整个位图搬上屏幕,现在要只把半边位图画出来,就不得不依靠前面所说的矩形了。
我们需要的效果是背景只有右半边变成以前的石头路,因此我们可以把石头路位图的右半边“复制”到郊外位图的右半边来。

这里我们第一次要用到实例方法,我先解释一下。
之前我们在学习精灵Sprite类时,都是通过设置Sprite的属性来达到目标。
实例方法顾名思义,就是在实例身上调用的方法。
相比于直接设置属性,方法的作用主要是通过方法内进行的计算帮助我们获取信息或者间接地设置属性。
这里我们使用Bitmap实例的blt方法,让我们输入下面的代码。

# 背景精灵
back_sprite = Sprite.new
back_bitmap = Bitmap.new("Graphics/Battlebacks1/Cobblestones1")
back_bitmap2 = Bitmap.new("Graphics/Battlebacks1/Ruins2")
# 准备复制的矩形
blt_rect = back_bitmap2.rect # 每个位图对象都有自己的矩形rect属性
blt_rect.width /= 2 # 将复制来的矩形rect的宽度减半
# 复制位图
back_bitmap.blt(0, 0, back_bitmap2, blt_rect)
back_sprite.bitmap = back_bitmap2 #删除这一行,改成下面的
back_sprite.bitmap = back_bitmap

# 女英雄精灵
...


运行结果:


这里我们用到了位图的矩形rect属性,这是一个x与y都为0,宽度width与高度height刚好与位图相同的矩形。
通过位图的rect属性我们可以快速地构建一个与位图相关的矩形,比如在这里,
我们将位图的矩形赋值给用于blt方法的blt_rect,然后将矩形的宽度变为一半,这样blt所复制过去的部分将只有src_bitmap的左半边。
用头画头像,用脚写脚本
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-15 15:27

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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