Project1
标题:
RGSS1的Window类试写
[打印本页]
作者:
沙漠点灰
时间:
2011-5-28 16:25
标题:
RGSS1的Window类试写
很多人都试写过Window类,不过很多地方没考虑到
F1中说Window类内部由大量精灵构成,所以试写如下,不过经过本人"鉴定",
Window类内部由大量精灵构成
是错的,因为这样太耗内存了...
好像有bug...
#==============================================================================
# ■ Window
#------------------------------------------------------------------------------
# 游戏中全部窗口的超级类。 伪.源代码
#==============================================================================
class Window
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_reader :stretch
attr_reader :windowskin
attr_reader :width
attr_reader :height
attr_reader :contents
attr_reader :active
attr_reader :pause
attr_reader :visible
attr_reader :opacity
attr_reader :back_opacity
attr_reader :contents_opacity
attr_reader :cursor_rect
attr_reader :x
attr_reader :y
attr_reader :ox
attr_reader :oy
attr_reader :z
#--------------------------------------------------------------------------
# ● 初始化对像
#--------------------------------------------------------------------------
def initialize(viewport=Viewport.new(0,0,640,480))
@disposed = false
@width = 64
@height = 64
@x = 0
@y = 0
@ox = 0
@oy = 0
@z = 0
@viewport1 = viewport
@_frame = Sprite.new(@viewport1)
@_back = Sprite.new(@viewport1)
@_cursor = Sprite.new(@viewport1)
@_pause = Sprite.new(@viewport1)
@viewport2 = Viewport.new(self.x+16,self.y+16,self.width-32,self.height-32)
@_content = Sprite.new(@viewport2)
@cursor_rect= Rect.new(0,0,0,0)
@active = true
self.stretch= true
@pause = false
@up_bitmap = Bitmap.new(16,16)
@dn_bitmap = Bitmap.new(16,16)
@lt_bitmap = Bitmap.new(16,16)
@rt_bitmap = Bitmap.new(16,16)
@_up = Sprite.new(@viewport1)
@_dn = Sprite.new(@viewport1)
@_lt = Sprite.new(@viewport1)
@_rt = Sprite.new(@viewport1)
@_up.bitmap = @up_bitmap
@_dn.bitmap = @dn_bitmap
@_lt.bitmap = @lt_bitmap
@_rt.bitmap = @rt_bitmap
@_up.visible= @_dn.visible = @_lt.visible = @_rt.visible = false
@_up.ox = @_dn.ox = @_lt.ox = @_rt.ox = 8
@_up.oy = @_dn.oy = @_lt.oy = @_rt.oy = 8
@opacity = 255
@back_opacity = 255
@contents_opacity = 255
#
@cursor_bitmap = Bitmap.new(32,32)
@pause_bitmap = (0..3).inject([]){|a,i|a<<Bitmap.new(16,16)}
#
@old_cursor_rect = @cursor_rect.dup
@_cursor.x = self.x + 16
@_cursor.y = @cursor_rect.y + self.y + 16
@pause_indes = 0
end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def update
# 避开不必要刷新...?
return if self.height <= 32 or self.width <= 32
# 窗口重要的光标设置...
if @old_cursor_rect.width != @cursor_rect.width or
@old_cursor_rect.height != @cursor_rect.height
@old_cursor_rect = @cursor_rect.dup
if cursor_explain
@_cursor.bitmap.dispose
@_cursor.bitmap = Bitmap.new(1,1)
end
end
@_cursor.x = self.x + 16
@_cursor.y = @cursor_rect.y + self.y + 16
# 光标闪烁
if self.active
if @_cursor.opacity < 100
@_plus = true
else
@_plus = false if @_cursor.opacity == 255
end
@_cursor.opacity += @_plus ? 5 : -5
end
# 暂停标志
@_pause.visible = @pause
@_pause.visible = false unless self.visible
if self.pause
# 坐标修正
@_pause.bitmap = @pause_bitmap[@pause_indes.to_i]
@pause_indes = (@pause_indes+0.25)%4
end
# 标志确定
logo_check
end
#--------------------------------------------------------------------------
# ● 上下左右标志坐标确定+可见性
#--------------------------------------------------------------------------
def logo_check
unless @_content.bitmap or self.visible
return @_up.visible = @_dn.visible = @_lt.visible = @_rt.visible = false
end
# 坐标修正...
@_up.x = self.x + self.width/2
@_up.y = self.y + 16
@_dn.x = @_up.x
@_dn.y = self.y + self.height - 16
@_lt.x = self.x + 16
@_lt.y = self.y + self.height/2
@_rt.x = self.x + self.width - 16
@_rt.y = @_lt.y
rect = @viewport2.rect
@_up.visible = @_content.oy > 0
@_dn.visible = (@_content.bitmap.height - @_content.oy) > rect.height
@_lt.visible = @_content.ox > 0
@_rt.visible = (@_content.bitmap.width - @_content.ox) > rect.width
end
#--------------------------------------------------------------------------
# ● 壁纸显示方法
#--------------------------------------------------------------------------
def stretch=(stretch)
if @disposed
raise(RGSSError,"disposed window")
else
@stretch = stretch
show_back
end
end
#--------------------------------------------------------------------------
# ● 壁纸显示方法 更换
# 为了严谨,窗口周围缩小了 2 像素大小。这是为了能自然地看见圆角形窗口。
#--------------------------------------------------------------------------
def show_back
skin_explain
return if self.height <= 32 or self.width <= 32 or !self.windowskin
if @stretch
@_back.bitmap.dispose if @_back.bitmap
@_back.bitmap = Bitmap.new(self.width-4,self.height-4)
dest_rect = Rect.new(0,0,self.width-4,self.height-4)
@_back.bitmap.stretch_blt(dest_rect, self.windowskin, Rect.new(0, 0, 128, 128))
else
@_back.bitmap.dispose if @_back.bitmap
@_back.bitmap = Bitmap.new(self.width-4,self.height-4)
(self.width/128.0).ceil.times{|x|
(self.height/128.0).ceil.times{|y|
@_back.bitmap.blt(128*x,128*y,self.windowskin, Rect.new(0, 0, 128, 128))
} }
end
end
#--------------------------------------------------------------------------
# ● 窗口皮肤
#--------------------------------------------------------------------------
def windowskin=(windowskin)
if @disposed
raise(RGSSError,"disposed window")
else
@windowskin = windowskin
show_back
skin_explain
end
end
#--------------------------------------------------------------------------
# ● 窗口皮肤 原Window没有(应该没有,就算有方法名也不一样,仅仅方便)
#--------------------------------------------------------------------------
def skin_explain
return unless @windowskin
4.times{|i|@pause_bitmap[i].blt(0,0,self.windowskin,Rect.new(160+i/2*16,64+i%2*16,16,16))}
@_frame.bitmap = Bitmap.new(self.width,self.height)
# 解析皮肤...左上解释
@_frame.bitmap.blt(0,0,self.windowskin,Rect.new(128, 0,16,16))
# 上边
(self.width/32).times{|i|
@_frame.bitmap.blt(i*32+16,0,self.windowskin,Rect.new(144, 0,32,16))}
@_frame.bitmap.fill_rect(self.width-2,0,2,2, Color.new(0,0,0,0))
# 右上角
@_frame.bitmap.blt(self.width-16,0,self.windowskin,Rect.new(176, 0,16,16))
# 左边
(self.height/32).times{|i|
@_frame.bitmap.blt(0,i*32+16,self.windowskin,Rect.new(128,16,16,32))}
@_frame.bitmap.fill_rect(0,self.height-2,2,2, Color.new(0,0,0,0))
# 左下角
@_frame.bitmap.blt(0,self.height-16,self.windowskin,Rect.new(128,48,16,16))
# 右边
(self.height/32).times{|i|@_frame.bitmap.blt(self.width-16,
i*32+16,self.windowskin,Rect.new(176,16,16,32))}
# 下边
(self.width/32).times{|i|@_frame.bitmap.blt(i*32+16,
self.height-16,self.windowskin,Rect.new(144,48,32,16))}
@_frame.bitmap.fill_rect(self.width-2,self.height-2,2,2, Color.new(0,0,0,0))
# 右下角
@_frame.bitmap.blt(self.width-16,self.height-16,self.windowskin,Rect.new(176,48,16,16))
@up_bitmap.blt(0,0,self.windowskin,Rect.new(152,16,16,16))
@dn_bitmap.blt(0,0,self.windowskin,Rect.new(152,32,16,16))
@lt_bitmap.blt(0,0,self.windowskin,Rect.new(144,24,16,16))
@rt_bitmap.blt(0,0,self.windowskin,Rect.new(160,24,16,16))
@cursor_bitmap.blt(0, 0, self.windowskin, Rect.new(128, 64, 32, 32))
cursor_explain
end
#--------------------------------------------------------------------------
# ● 光标解释
#--------------------------------------------------------------------------
def cursor_explain
return true if @cursor_rect.height == 0 or @cursor_rect.width == 0
@_cursor.bitmap.dispose if @_cursor.bitmap
h = @cursor_rect.height
w = @cursor_rect.width
@_cursor.bitmap = Bitmap.new(w, h)
# 解析皮肤...
@_cursor.bitmap.set_pixel(0 , 0, @cursor_bitmap.get_pixel( 0, 0))
@_cursor.bitmap.set_pixel(0 , h-1, @cursor_bitmap.get_pixel( 0,31))
@_cursor.bitmap.set_pixel(w-1, 0, @cursor_bitmap.get_pixel(31, 0))
@_cursor.bitmap.set_pixel(w-1, h-1, @cursor_bitmap.get_pixel(31,31))
# 上下左右边...
dest_rect = Rect.new(1, 0, w-2, 1)
src_rect = Rect.new(1, 0, 30, 1)
@_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
dest_rect = Rect.new(1, h-1, w-2, 1)
src_rect = Rect.new(1, 31, 30, 1)
@_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
dest_rect = Rect.new(0, 1, 1, h-2)
src_rect = Rect.new(0, 1, 1, 30)
@_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
dest_rect = Rect.new(w-1, 1, 1, h-2)
src_rect = Rect.new(31, 1, 1, 30)
@_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
# 中央
dest_rect = Rect.new(1, 1, w-2,h-2)
src_rect = Rect.new(1, 1, 30 , 30)
@_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
end
#--------------------------------------------------------------------------
# ● 内容不透明度
#--------------------------------------------------------------------------
def contents_opacity=(opacity)
if @disposed
raise(RGSSError,"disposed window")
else
@contents_opacity = [[0, opacity].max, 255].min
@_content.opacity = @contents_opacity
end
end
#--------------------------------------------------------------------------
# ● 背景不透明度
#--------------------------------------------------------------------------
def back_opacity=(opacity)
if @disposed
raise(RGSSError,"disposed window")
else
@back_opacity = [[0, opacity].max, 255].min
@_back.opacity = @back_opacity
end
end
#--------------------------------------------------------------------------
# ● 不透明度
#--------------------------------------------------------------------------
def opacity=(opacity)
if @disposed
raise(RGSSError,"disposed window")
else
@opacity = [[0, opacity].max, 255].min
@_frame.opacity = @opacity
@_back.opacity = @opacity
end
end
#--------------------------------------------------------------------------
# ● 选择光标
#--------------------------------------------------------------------------
def cursor_rect=(rect)
if @disposed
raise(RGSSError,"disposed window")
else
@cursor_rect = rect
end
end
#--------------------------------------------------------------------------
# ● 可见性
#--------------------------------------------------------------------------
def visible=(visible)
if @disposed
raise(RGSSError,"disposed window")
else
@visible = visible
@_frame.visible = visible
@_back.visible = visible
@_content.visible= visible
@_cursor.visible = visible
@_pause.visible = visible
@_pause.visible = false if @pause
@_up.visible = visible
@_dn.visible = visible
@_lt.visible = visible
@_rt.visible = visible
logo_check
end
end
#--------------------------------------------------------------------------
# ● 活动性
#--------------------------------------------------------------------------
def active=(active)
if @disposed
raise(RGSSError,"disposed window")
else
@active = active
end
end
#--------------------------------------------------------------------------
# ● 暂停
#--------------------------------------------------------------------------
def pause=(pause)
if @disposed
raise(RGSSError,"disposed window")
else
@pause = pause
end
end
#--------------------------------------------------------------------------
# ● 窗口内容
#--------------------------------------------------------------------------
def contents=(bitmap)
@contents = bitmap
if @disposed
raise(RGSSError,"disposed window")
else
@_content.bitmap = @contents
end
end
#--------------------------------------------------------------------------
# ● 高
#--------------------------------------------------------------------------
def height=(new_h)
if @disposed
raise(RGSSError,"disposed window")
else
@height = new_h
bitmap = @_content.bitmap.dup if @_content.bitmap
@_content.dispose
@_content.bitmap.dispose if @_content.bitmap
@viewport2.rect = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
@_content = Sprite.new(@viewport2)
self.contents = bitmap
show_back
@_pause.y = self.y + height - 32
end
end
#--------------------------------------------------------------------------
# ● 宽
#--------------------------------------------------------------------------
def width=(new_w)
if @disposed
raise(RGSSError,"disposed window")
else
@width = new_w
bitmap = @_content.bitmap.dup if @_content.bitmap
@_content.dispose
@_content.bitmap.dispose if @_content.bitmap
@viewport2.rect = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
@_content = Sprite.new(@viewport2)
self.contents = bitmap
show_back
@_pause.x = self.x + width/2
end
end
#--------------------------------------------------------------------------
# ● x 坐标
#--------------------------------------------------------------------------
def x=(x)
@_frame.x = x
@_back.x = x + 2
@_content.x = x + 16
@x = x
bitmap = @_content.bitmap.dup if @_content.bitmap
@_content.dispose
@_content.bitmap.dispose if @_content.bitmap
@viewport2.rect = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
@_content = Sprite.new(@viewport2)
self.contents = bitmap
@_pause.x = x + self.width/2
end
#--------------------------------------------------------------------------
# ● y 坐标
#--------------------------------------------------------------------------
def y=(y)
@_frame.y = y
@_back.y = y + 2
@_content.y = y + 16
@y = y
bitmap = @_content.bitmap.dup if @_content.bitmap
@_content.dispose
@_content.bitmap.dispose if @_content.bitmap
@viewport2.rect = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
@_content = Sprite.new(@viewport2)
self.contents = bitmap
@_pause.y = y + self.height - 32
end
#--------------------------------------------------------------------------
# ● z 坐标
#--------------------------------------------------------------------------
def z=(z)
@_frame.z = z + 1
@_back.z = z
@_content.z = z + 2
@z = z
@_cursor.z = z
@_pause.z = z
@_up.z = z + 1
@_dn.z = z + 1
@_lt.z = z + 1
@_rt.z = z + 1
end
#--------------------------------------------------------------------------
# ● ox 坐标
#--------------------------------------------------------------------------
def ox=(ox)
if @disposed
raise(RGSSError,"disposed window")
else
@_content.ox = ox
@ox = ox
end
end
#--------------------------------------------------------------------------
# ● oy 坐标
#--------------------------------------------------------------------------
def oy=(oy)
if @disposed
raise(RGSSError,"disposed window")
else
@_content.oy = oy
@oy = oy
end
end
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
def dispose
return if @disposed
@disposed = true
@viewport1.dispose
@viewport2.dispose
@_frame.dispose
@_frame.bitmap.dispose
@_back.dispose
@_back.bitmap.dispose
@_content.dispose
@_cursor.dispose
@_cursor.bitmap.dispose if @_cursor.bitmap
@_pause.dispose
@_pause.bitmap.dispose if @_pause.bitmap
@cursor_bitmap.dispose
@pause_bitmap.each{|i|i.dispose}
@_up.dispose
@_dn.dispose
@_lt.dispose
@_rt.dispose
@up_bitmap.dispose
@dn_bitmap.dispose
@lt_bitmap.dispose
@rt_bitmap.dispose
end
#--------------------------------------------------------------------------
# ● 释放?
#--------------------------------------------------------------------------
def disposed?
@disposed
end
end
复制代码
作者:
IamI
时间:
2011-5-28 17:03
大量精灵是肯定的,只不过在C类内部而已……另外以前其实许多人都写过……不妨参考
作者:
苏小脉
时间:
2011-5-28 22:38
通过钩住 Sprite 的接口可以知道 Window 的逻辑没有经过建立在 Ruby 包装 Sprite 后的抽象层上,在底层直接用本地代码的实现来控制精灵效率自然高一些。
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1