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

Project1

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

[原创发布] RGSS1的Window类试写

[复制链接]

Lv1.梦旅人

梦石
0
星屑
55
在线时间
323 小时
注册时间
2010-8-21
帖子
666
跳转到指定楼层
1
发表于 2011-5-28 16:25:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
很多人都试写过Window类,不过很多地方没考虑到
F1中说Window类内部由大量精灵构成,所以试写如下,不过经过本人"鉴定",
Window类内部由大量精灵构成
是错的,因为这样太耗内存了...
好像有bug...
  1. #==============================================================================
  2. # ■ Window
  3. #------------------------------------------------------------------------------
  4. #  游戏中全部窗口的超级类。 伪.源代码
  5. #==============================================================================

  6. class Window
  7.   #--------------------------------------------------------------------------
  8.   # ● 定义实例变量
  9.   #--------------------------------------------------------------------------
  10.   attr_reader                 :stretch
  11.   attr_reader                 :windowskin
  12.   attr_reader                 :width
  13.   attr_reader                 :height
  14.   attr_reader                 :contents
  15.   attr_reader                 :active
  16.   attr_reader                 :pause
  17.   attr_reader                 :visible
  18.   attr_reader                 :opacity
  19.   attr_reader                 :back_opacity
  20.   attr_reader                 :contents_opacity
  21.   attr_reader                 :cursor_rect
  22.   attr_reader                 :x
  23.   attr_reader                 :y
  24.   attr_reader                 :ox
  25.   attr_reader                 :oy
  26.   attr_reader                 :z
  27.   #--------------------------------------------------------------------------
  28.   # ● 初始化对像
  29.   #--------------------------------------------------------------------------
  30.   def initialize(viewport=Viewport.new(0,0,640,480))
  31.     @disposed   = false
  32.     @width      = 64
  33.     @height     = 64
  34.     @x          = 0
  35.     @y          = 0
  36.     @ox         = 0
  37.     @oy         = 0
  38.     @z          = 0
  39.     @viewport1  = viewport
  40.     @_frame     = Sprite.new(@viewport1)
  41.     @_back      = Sprite.new(@viewport1)
  42.     @_cursor    = Sprite.new(@viewport1)
  43.     @_pause     = Sprite.new(@viewport1)
  44.     @viewport2  = Viewport.new(self.x+16,self.y+16,self.width-32,self.height-32)
  45.     @_content   = Sprite.new(@viewport2)
  46.     @cursor_rect= Rect.new(0,0,0,0)
  47.     @active     = true
  48.     self.stretch= true
  49.     @pause      = false
  50.     @up_bitmap  = Bitmap.new(16,16)
  51.     @dn_bitmap  = Bitmap.new(16,16)
  52.     @lt_bitmap  = Bitmap.new(16,16)
  53.     @rt_bitmap  = Bitmap.new(16,16)
  54.     @_up        = Sprite.new(@viewport1)
  55.     @_dn        = Sprite.new(@viewport1)
  56.     @_lt        = Sprite.new(@viewport1)
  57.     @_rt        = Sprite.new(@viewport1)
  58.     @_up.bitmap = @up_bitmap
  59.     @_dn.bitmap = @dn_bitmap
  60.     @_lt.bitmap = @lt_bitmap
  61.     @_rt.bitmap = @rt_bitmap
  62.     @_up.visible= @_dn.visible = @_lt.visible = @_rt.visible = false
  63.     @_up.ox     = @_dn.ox = @_lt.ox = @_rt.ox = 8
  64.     @_up.oy     = @_dn.oy = @_lt.oy = @_rt.oy = 8
  65.     @opacity          = 255
  66.     @back_opacity     = 255
  67.     @contents_opacity = 255
  68.     #
  69.     @cursor_bitmap = Bitmap.new(32,32)
  70.     @pause_bitmap  = (0..3).inject([]){|a,i|a<<Bitmap.new(16,16)}
  71.     #
  72.     @old_cursor_rect = @cursor_rect.dup
  73.     @_cursor.x = self.x + 16
  74.     @_cursor.y = @cursor_rect.y + self.y + 16
  75.     @pause_indes = 0
  76.   end
  77.   #--------------------------------------------------------------------------
  78.   # ● 刷新
  79.   #--------------------------------------------------------------------------
  80.   def update
  81.     # 避开不必要刷新...?
  82.     return if self.height <= 32 or self.width <= 32
  83.     # 窗口重要的光标设置...
  84.     if @old_cursor_rect.width != @cursor_rect.width or
  85.      @old_cursor_rect.height != @cursor_rect.height
  86.      @old_cursor_rect = @cursor_rect.dup
  87.       if cursor_explain
  88.         @_cursor.bitmap.dispose
  89.         @_cursor.bitmap = Bitmap.new(1,1)
  90.       end
  91.     end
  92.     @_cursor.x = self.x + 16
  93.     @_cursor.y = @cursor_rect.y + self.y + 16
  94.     # 光标闪烁
  95.     if self.active
  96.       if @_cursor.opacity < 100
  97.         @_plus = true
  98.       else
  99.         @_plus = false if @_cursor.opacity == 255
  100.       end
  101.       @_cursor.opacity += @_plus ? 5 : -5
  102.     end
  103.     # 暂停标志
  104.     @_pause.visible = @pause
  105.     @_pause.visible = false unless self.visible
  106.     if self.pause
  107.       # 坐标修正
  108.       @_pause.bitmap = @pause_bitmap[@pause_indes.to_i]
  109.       @pause_indes = (@pause_indes+0.25)%4
  110.     end
  111.     # 标志确定
  112.     logo_check
  113.   end
  114.   #--------------------------------------------------------------------------
  115.   # ● 上下左右标志坐标确定+可见性
  116.   #--------------------------------------------------------------------------
  117.   def logo_check
  118.     unless @_content.bitmap or self.visible
  119.       return @_up.visible = @_dn.visible = @_lt.visible = @_rt.visible = false
  120.     end
  121.     # 坐标修正...
  122.     @_up.x = self.x + self.width/2
  123.     @_up.y = self.y + 16
  124.     @_dn.x = @_up.x
  125.     @_dn.y = self.y + self.height - 16
  126.     @_lt.x = self.x + 16
  127.     @_lt.y = self.y + self.height/2
  128.     @_rt.x = self.x + self.width - 16
  129.     @_rt.y = @_lt.y
  130.     rect = @viewport2.rect
  131.     @_up.visible = @_content.oy > 0
  132.     @_dn.visible = (@_content.bitmap.height - @_content.oy) > rect.height
  133.     @_lt.visible = @_content.ox > 0
  134.     @_rt.visible = (@_content.bitmap.width - @_content.ox) > rect.width
  135.   end
  136.   #--------------------------------------------------------------------------
  137.   # ● 壁纸显示方法
  138.   #--------------------------------------------------------------------------
  139.   def stretch=(stretch)
  140.     if @disposed
  141.       raise(RGSSError,"disposed window")
  142.     else
  143.       @stretch = stretch
  144.       show_back
  145.     end
  146.   end
  147.   #--------------------------------------------------------------------------
  148.   # ● 壁纸显示方法 更换
  149.   #    为了严谨,窗口周围缩小了 2 像素大小。这是为了能自然地看见圆角形窗口。
  150.   #--------------------------------------------------------------------------
  151.   def show_back
  152.     skin_explain
  153.     return if self.height <= 32 or self.width <= 32 or !self.windowskin
  154.     if @stretch
  155.       @_back.bitmap.dispose if @_back.bitmap
  156.       @_back.bitmap = Bitmap.new(self.width-4,self.height-4)
  157.       dest_rect = Rect.new(0,0,self.width-4,self.height-4)
  158.       @_back.bitmap.stretch_blt(dest_rect, self.windowskin, Rect.new(0, 0, 128, 128))
  159.     else
  160.       @_back.bitmap.dispose if @_back.bitmap
  161.       @_back.bitmap = Bitmap.new(self.width-4,self.height-4)
  162.       (self.width/128.0).ceil.times{|x|
  163.         (self.height/128.0).ceil.times{|y|
  164.         @_back.bitmap.blt(128*x,128*y,self.windowskin, Rect.new(0, 0, 128, 128))
  165.       } }
  166.     end
  167.   end
  168.   #--------------------------------------------------------------------------
  169.   # ● 窗口皮肤
  170.   #--------------------------------------------------------------------------
  171.   def windowskin=(windowskin)
  172.     if @disposed
  173.       raise(RGSSError,"disposed window")
  174.     else
  175.       @windowskin = windowskin
  176.       show_back
  177.       skin_explain
  178.     end
  179.   end
  180.   #--------------------------------------------------------------------------
  181.   # ● 窗口皮肤 原Window没有(应该没有,就算有方法名也不一样,仅仅方便)
  182.   #--------------------------------------------------------------------------
  183.   def skin_explain
  184.     return unless @windowskin
  185.     4.times{|i|@pause_bitmap[i].blt(0,0,self.windowskin,Rect.new(160+i/2*16,64+i%2*16,16,16))}
  186.     @_frame.bitmap = Bitmap.new(self.width,self.height)
  187.     # 解析皮肤...左上解释
  188.     @_frame.bitmap.blt(0,0,self.windowskin,Rect.new(128, 0,16,16))
  189.     # 上边
  190.     (self.width/32).times{|i|
  191.     @_frame.bitmap.blt(i*32+16,0,self.windowskin,Rect.new(144, 0,32,16))}
  192.     @_frame.bitmap.fill_rect(self.width-2,0,2,2, Color.new(0,0,0,0))
  193.     # 右上角
  194.     @_frame.bitmap.blt(self.width-16,0,self.windowskin,Rect.new(176, 0,16,16))
  195.     # 左边
  196.     (self.height/32).times{|i|
  197.     @_frame.bitmap.blt(0,i*32+16,self.windowskin,Rect.new(128,16,16,32))}
  198.     @_frame.bitmap.fill_rect(0,self.height-2,2,2, Color.new(0,0,0,0))
  199.     # 左下角
  200.     @_frame.bitmap.blt(0,self.height-16,self.windowskin,Rect.new(128,48,16,16))
  201.     # 右边
  202.     (self.height/32).times{|i|@_frame.bitmap.blt(self.width-16,
  203.     i*32+16,self.windowskin,Rect.new(176,16,16,32))}
  204.     # 下边
  205.     (self.width/32).times{|i|@_frame.bitmap.blt(i*32+16,
  206.     self.height-16,self.windowskin,Rect.new(144,48,32,16))}
  207.     @_frame.bitmap.fill_rect(self.width-2,self.height-2,2,2, Color.new(0,0,0,0))
  208.     # 右下角
  209.     @_frame.bitmap.blt(self.width-16,self.height-16,self.windowskin,Rect.new(176,48,16,16))
  210.     @up_bitmap.blt(0,0,self.windowskin,Rect.new(152,16,16,16))
  211.     @dn_bitmap.blt(0,0,self.windowskin,Rect.new(152,32,16,16))
  212.     @lt_bitmap.blt(0,0,self.windowskin,Rect.new(144,24,16,16))
  213.     @rt_bitmap.blt(0,0,self.windowskin,Rect.new(160,24,16,16))
  214.     @cursor_bitmap.blt(0, 0, self.windowskin, Rect.new(128, 64, 32, 32))
  215.     cursor_explain
  216.   end
  217.   #--------------------------------------------------------------------------
  218.   # ● 光标解释
  219.   #--------------------------------------------------------------------------
  220.   def cursor_explain
  221.     return true if @cursor_rect.height == 0 or @cursor_rect.width == 0
  222.     @_cursor.bitmap.dispose if @_cursor.bitmap
  223.     h = @cursor_rect.height
  224.     w = @cursor_rect.width
  225.     @_cursor.bitmap = Bitmap.new(w, h)
  226.     # 解析皮肤...
  227.     @_cursor.bitmap.set_pixel(0  ,   0, @cursor_bitmap.get_pixel( 0, 0))
  228.     @_cursor.bitmap.set_pixel(0  , h-1, @cursor_bitmap.get_pixel( 0,31))
  229.     @_cursor.bitmap.set_pixel(w-1,   0, @cursor_bitmap.get_pixel(31, 0))
  230.     @_cursor.bitmap.set_pixel(w-1, h-1, @cursor_bitmap.get_pixel(31,31))
  231.     # 上下左右边...
  232.     dest_rect = Rect.new(1, 0, w-2, 1)
  233.     src_rect  = Rect.new(1, 0,  30, 1)
  234.     @_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
  235.     dest_rect = Rect.new(1, h-1, w-2, 1)
  236.     src_rect  = Rect.new(1,  31,  30, 1)
  237.     @_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
  238.     dest_rect = Rect.new(0, 1, 1, h-2)
  239.     src_rect  = Rect.new(0, 1, 1, 30)
  240.     @_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
  241.     dest_rect = Rect.new(w-1, 1, 1, h-2)
  242.     src_rect  = Rect.new(31, 1, 1, 30)
  243.     @_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
  244.     # 中央
  245.     dest_rect = Rect.new(1, 1, w-2,h-2)
  246.     src_rect  = Rect.new(1, 1, 30 , 30)
  247.     @_cursor.bitmap.stretch_blt(dest_rect, @cursor_bitmap, src_rect)
  248.   end
  249.   #--------------------------------------------------------------------------
  250.   # ● 内容不透明度
  251.   #--------------------------------------------------------------------------
  252.   def contents_opacity=(opacity)
  253.     if @disposed
  254.       raise(RGSSError,"disposed window")
  255.     else
  256.       @contents_opacity = [[0, opacity].max, 255].min
  257.       @_content.opacity = @contents_opacity
  258.     end
  259.   end
  260.   #--------------------------------------------------------------------------
  261.   # ● 背景不透明度
  262.   #--------------------------------------------------------------------------
  263.   def back_opacity=(opacity)
  264.     if @disposed
  265.       raise(RGSSError,"disposed window")
  266.     else
  267.       @back_opacity  = [[0, opacity].max, 255].min
  268.       @_back.opacity  = @back_opacity
  269.     end
  270.   end
  271.   #--------------------------------------------------------------------------
  272.   # ● 不透明度
  273.   #--------------------------------------------------------------------------
  274.   def opacity=(opacity)
  275.     if @disposed
  276.       raise(RGSSError,"disposed window")
  277.     else
  278.       @opacity = [[0, opacity].max, 255].min
  279.       @_frame.opacity = @opacity
  280.       @_back.opacity  = @opacity
  281.     end
  282.   end
  283.   #--------------------------------------------------------------------------
  284.   # ● 选择光标
  285.   #--------------------------------------------------------------------------
  286.   def cursor_rect=(rect)
  287.     if @disposed
  288.       raise(RGSSError,"disposed window")
  289.     else
  290.       @cursor_rect = rect
  291.     end
  292.   end
  293.   #--------------------------------------------------------------------------
  294.   # ● 可见性
  295.   #--------------------------------------------------------------------------
  296.   def visible=(visible)
  297.     if @disposed
  298.       raise(RGSSError,"disposed window")
  299.     else
  300.       @visible         = visible
  301.       @_frame.visible  = visible
  302.       @_back.visible   = visible
  303.       @_content.visible= visible
  304.       @_cursor.visible = visible
  305.       @_pause.visible  = visible
  306.       @_pause.visible  = false  if @pause
  307.       @_up.visible     = visible
  308.       @_dn.visible     = visible
  309.       @_lt.visible     = visible
  310.       @_rt.visible     = visible
  311.       logo_check
  312.     end
  313.   end
  314.   #--------------------------------------------------------------------------
  315.   # ● 活动性
  316.   #--------------------------------------------------------------------------
  317.   def active=(active)
  318.     if @disposed
  319.       raise(RGSSError,"disposed window")
  320.     else
  321.       @active = active
  322.     end
  323.   end
  324.   #--------------------------------------------------------------------------
  325.   # ● 暂停
  326.   #--------------------------------------------------------------------------
  327.   def pause=(pause)
  328.     if @disposed
  329.       raise(RGSSError,"disposed window")
  330.     else
  331.       @pause = pause
  332.     end
  333.   end
  334.   #--------------------------------------------------------------------------
  335.   # ● 窗口内容
  336.   #--------------------------------------------------------------------------
  337.   def contents=(bitmap)
  338.     @contents = bitmap
  339.     if @disposed
  340.       raise(RGSSError,"disposed window")
  341.     else
  342.       @_content.bitmap = @contents
  343.     end
  344.   end
  345.   #--------------------------------------------------------------------------
  346.   # ● 高
  347.   #--------------------------------------------------------------------------
  348.   def height=(new_h)
  349.     if @disposed
  350.       raise(RGSSError,"disposed window")
  351.     else
  352.       @height = new_h
  353.       bitmap = @_content.bitmap.dup if @_content.bitmap
  354.       @_content.dispose
  355.       @_content.bitmap.dispose if @_content.bitmap
  356.       @viewport2.rect   = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
  357.       @_content   = Sprite.new(@viewport2)
  358.       self.contents = bitmap
  359.       show_back
  360.       @_pause.y = self.y + height - 32
  361.     end
  362.   end
  363.   #--------------------------------------------------------------------------
  364.   # ● 宽
  365.   #--------------------------------------------------------------------------
  366.   def width=(new_w)
  367.     if @disposed
  368.       raise(RGSSError,"disposed window")
  369.     else
  370.       @width = new_w
  371.       bitmap = @_content.bitmap.dup if @_content.bitmap
  372.       @_content.dispose
  373.       @_content.bitmap.dispose if @_content.bitmap
  374.       @viewport2.rect   = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
  375.       @_content   = Sprite.new(@viewport2)
  376.       self.contents = bitmap
  377.       show_back
  378.       @_pause.x = self.x + width/2
  379.     end
  380.   end
  381.   #--------------------------------------------------------------------------
  382.   # ● x 坐标
  383.   #--------------------------------------------------------------------------
  384.   def x=(x)
  385.     @_frame.x = x
  386.     @_back.x  = x + 2
  387.     @_content.x = x + 16
  388.     @x = x
  389.     bitmap = @_content.bitmap.dup if @_content.bitmap
  390.     @_content.dispose
  391.     @_content.bitmap.dispose if @_content.bitmap
  392.     @viewport2.rect   = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
  393.     @_content   = Sprite.new(@viewport2)
  394.     self.contents = bitmap
  395.     @_pause.x = x + self.width/2
  396.   end
  397.   #--------------------------------------------------------------------------
  398.   # ● y 坐标
  399.   #--------------------------------------------------------------------------
  400.   def y=(y)
  401.     @_frame.y = y
  402.     @_back.y  = y + 2
  403.     @_content.y = y + 16
  404.     @y = y
  405.     bitmap = @_content.bitmap.dup if @_content.bitmap
  406.     @_content.dispose
  407.     @_content.bitmap.dispose if @_content.bitmap
  408.     @viewport2.rect   = Rect.new(self.x+16,self.y+16,self.width-32,self.height-32)
  409.     @_content   = Sprite.new(@viewport2)
  410.     self.contents = bitmap
  411.     @_pause.y = y + self.height - 32
  412.   end
  413.   #--------------------------------------------------------------------------
  414.   # ● z 坐标
  415.   #--------------------------------------------------------------------------
  416.   def z=(z)
  417.     @_frame.z = z + 1
  418.     @_back.z  = z
  419.     @_content.z = z + 2
  420.     @z = z
  421.     @_cursor.z = z
  422.     @_pause.z = z
  423.     @_up.z = z + 1
  424.     @_dn.z = z + 1
  425.     @_lt.z = z + 1
  426.     @_rt.z = z + 1
  427.   end
  428.   #--------------------------------------------------------------------------
  429.   # ● ox 坐标
  430.   #--------------------------------------------------------------------------
  431.   def ox=(ox)
  432.     if @disposed
  433.       raise(RGSSError,"disposed window")
  434.     else
  435.       @_content.ox = ox
  436.       @ox = ox
  437.     end
  438.   end
  439.   #--------------------------------------------------------------------------
  440.   # ● oy 坐标
  441.   #--------------------------------------------------------------------------
  442.   def oy=(oy)
  443.     if @disposed
  444.       raise(RGSSError,"disposed window")
  445.     else
  446.       @_content.oy = oy
  447.       @oy = oy
  448.     end
  449.   end
  450.   #--------------------------------------------------------------------------
  451.   # ● 释放
  452.   #--------------------------------------------------------------------------
  453.   def dispose
  454.     return if @disposed
  455.     @disposed = true
  456.     @viewport1.dispose
  457.     @viewport2.dispose
  458.     @_frame.dispose
  459.     @_frame.bitmap.dispose
  460.     @_back.dispose
  461.     @_back.bitmap.dispose
  462.     @_content.dispose
  463.     @_cursor.dispose
  464.     @_cursor.bitmap.dispose if @_cursor.bitmap
  465.     @_pause.dispose
  466.     @_pause.bitmap.dispose if @_pause.bitmap
  467.     @cursor_bitmap.dispose
  468.     @pause_bitmap.each{|i|i.dispose}
  469.     @_up.dispose
  470.     @_dn.dispose
  471.     @_lt.dispose
  472.     @_rt.dispose
  473.     @up_bitmap.dispose
  474.     @dn_bitmap.dispose
  475.     @lt_bitmap.dispose
  476.     @rt_bitmap.dispose
  477.   end
  478.   #--------------------------------------------------------------------------
  479.   # ● 释放?
  480.   #--------------------------------------------------------------------------
  481.   def disposed?
  482.     @disposed
  483.   end
  484. end
复制代码
>>猛戳>>MetalSagaR游戏主页<<这里<<
欢迎提供您的意见

Lv3.寻梦者

孤独守望

梦石
0
星屑
3126
在线时间
1535 小时
注册时间
2006-10-16
帖子
4321

开拓者贵宾

2
发表于 2011-5-28 17:03:49 | 只看该作者
大量精灵是肯定的,只不过在C类内部而已……另外以前其实许多人都写过……不妨参考

点评

我貌似没说全对,我指的"大量精灵",指的是全为精灵类, 看来F1"大量精灵"是对的...  发表于 2011-5-28 17:37
菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
3
发表于 2011-5-28 22:38:22 | 只看该作者
通过钩住 Sprite 的接口可以知道 Window 的逻辑没有经过建立在 Ruby 包装 Sprite 后的抽象层上,在底层直接用本地代码的实现来控制精灵效率自然高一些。

点评

正是。实际上任何 Sprite 的接口都可以  发表于 2011-5-29 23:31
要知道是否从 Ruby 就要改写 Ruby Sprite 的 initialize (或self.new) 试试?  发表于 2011-5-29 15:25
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-5-14 09:38

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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