设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 99|回复: 0

[制作教程] All you need to know about Windowskins

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    前天 04:10
  • 签到天数: 209 天

    连续签到: 2 天

    [LV.7]常住居民III

    4472

    主题

    864

    回帖

    2万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    22951
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    28317

    灌水之王

    发表于 7 天前 | 显示全部楼层 |阅读模式
    On this tutorial, I will talk in detail about the Windowskins in RPG maker XP.

    The Windowskin is the graphic used to draw the windows that appear in the game.





    PART 1. Parts of the Windowskin

    Here you can see the limits of each part of the graphic







    A. This part is the back of the windowskin.
    B. This part is the frame of the window.
    C. Those are the scroll arrows that appear on item lists.
    D. This part is the cursor.
    E. Those little squares are each one of the 4 frames of that little icon that appears at the bottom of the message window. That icon is called pause.
    F. Those are the 2 frames of the battle arrow that appears over the sprites when you pick them.

    The display of most of those parts (A-E) is defined in the internal class Window, and that means you can't access the code that controls how they're displayed, but don't lose your hope; you can overwrite that class with a RGSS script, paste it over Main and customize that one instead.

    The last arrows (F) have their own non-internal class called Arrow_Base. Even if they are on the same graphic, it may be easier to consider they're not part of the window themselves.

    Something I want to highlight about the template is that, as you can see, the cursor actually has a small border around it that is not stretched, unlike the central part. I'll talk a bit more about this later.

    Spoiler: Cursor's border
    It doesn't matter how big the cursor is, the border mantains its thickness.
    PART 2. Windowskin properties

    The window has some properties that define how those parts are displayed.
    Some can be modified (for example the window's opacity), but others are internal.

    Modifiable:





    Non modifiable:





    PART 3. Stretch and tiling

    When the window is bigger that the graphic, some parts of the graphic are stretched and some tile until they fill all that plane.





    Spoiler: Example
    [/quote]

    On this example, the parts I painted with green blinds aren't stretched, but those with grey blinds are.

    You can change the back stretch mode with a little script over Main, that changes the "stretch" variable commented before. That means you can also change that on each window independly or based on the current windowskin.

                    Ruby:        
    class Window   alias stretch_mode_ini initialize unless $@   def initialize(*args)     stretch_mode_ini(*args)     self.stretch = false   end end


    In summary, the back has no border and its stretch depends on a variable, frames have a 16px border and don't stretch, and the cursor has a 2px border and stretches.

    Spoiler: Example of windowskins with tiling background[quote]Here are some windowskins that will only look good with the stretch mode disabled.

    PART 4. RGSS Rewrite of the Window Class

    In order to modify some of the window properties more freely, you can use a script that overwrites the window methods in RGSS. That makes their displaying a bit more slow, but we have much more control over them. There are many scripts that overwrite that class, but since I'm as cool as a cucumber I've made one specially for this tutorial, free to use. I used Selwyn's rewrite as a reference.

                    Ruby:        
    #============================================================================== # ** [XP] Window - Hidden RGSS Class #------------------------------------------------------------------------------ # Author: Wecoc (no credits required) #------------------------------------------------------------------------------ # I used Selwyn's Window rewrite as reference. #==============================================================================  #============================================================================== # * Bitmap #==============================================================================  class Bitmap   #--------------------------------------------------------------------------   # * Erase   #--------------------------------------------------------------------------   def erase(*args)     if args.size == 1       rect = args[0]     elsif args.size == 4       rect = Rect.new(*args)     end     fill_rect(rect, Color.new(0, 0, 0, 0))   end   #--------------------------------------------------------------------------   # * Cut   #--------------------------------------------------------------------------   def cut(*args)     case args.size     when 1 # (rect)       rect = args[0]       x, y, width, height = *rect.size     when 4 # (x, y, width, height)       x, y, width, height = *args     end     return Bitmap.new(1, 1) if width <= 0 or height <= 0     bitmap = Bitmap.new(width, height)     bitmap.blt(0, 0, self, Rect.new(x, y, width, height))     return bitmap   end end  #============================================================================== # * Tiled_Sprite #==============================================================================  class Tiled_Sprite   attr_reader :bitmap, :skin, :margin, :stretch   #--------------------------------------------------------------------------   # * Initialize   #--------------------------------------------------------------------------   def initialize(bitmap, m=1, stretch=true)     w = bitmap.width     h = bitmap.height     @margin = m     @stretch = stretch     @skin = {}     @skin[7] = bitmap.cut(  0,   0, m, m)     @skin[9] = bitmap.cut(w-m,   0, m, m)     @skin[1] = bitmap.cut(  0, h-m, m, m)     @skin[3] = bitmap.cut(w-m, h-m, m, m)     @skin[8] = bitmap.cut(  m,   0, w-(m*2), m)     @skin[4] = bitmap.cut(  0,   m, m, h-(m*2))     @skin[6] = bitmap.cut(w-m,   m, m, h-(m*2))     @skin[2] = bitmap.cut(  m, h-m, w-(m*2), m)     @skin[5] = bitmap.cut(  m,   m, w-(m*2), h-(m*2))   end end  #============================================================================== # * Bitmap #==============================================================================  class Bitmap   #--------------------------------------------------------------------------   # * Draw Tiled Sprite   #--------------------------------------------------------------------------   def draw_tiled(sprite)     for i in 1..9       draw_tiled_part(sprite, i)     end   end   #--------------------------------------------------------------------------   # * Draw Tiled Sprite (each part)   #--------------------------------------------------------------------------   def draw_tiled_part(sprite, id)     src_bitmap = sprite.skin[id]     m = sprite.margin     bx = (self.width - m * 2).to_f / src_bitmap.width     by = (self.height - m * 2).to_f / src_bitmap.height     dx = (src_bitmap.width * (bx.ceil.to_f - bx)).floor     dy = (src_bitmap.height * (by.ceil.to_f - by)).floor     case id     when 1       blt(0, self.height - m, src_bitmap, src_bitmap.rect)     when 3       blt(self.width - m, self.height - m, src_bitmap, src_bitmap.rect)     when 7       blt(0, 0, src_bitmap, src_bitmap.rect)     when 9       blt(self.width - m, 0, src_bitmap, src_bitmap.rect)     when 2       if sprite.stretch == false         for i in 0..bx.ceil           rect = src_bitmap.rect           rect.width = dx if i == bx.ceil           blt(m + i * src_bitmap.width, self.height - m, src_bitmap, rect)         end       else         dest_rect = Rect.new(m, self.height - m, self.width - m * 2, m)         stretch_blt(dest_rect, src_bitmap, src_bitmap.rect)       end     when 4       if sprite.stretch == false         for i in 0..by.ceil           rect = src_bitmap.rect           rect.height = dy if i == by.ceil           blt(0, m + i * src_bitmap.height, src_bitmap, rect)         end       else         dest_rect = Rect.new(0, m, m, self.height - m * 2)         stretch_blt(dest_rect, src_bitmap, src_bitmap.rect)       end     when 6       if sprite.stretch == false         for i in 0..by.ceil           rect = src_bitmap.rect           rect.height = dy if i == by.ceil           blt(self.width - m, m + i * src_bitmap.height, src_bitmap, rect)         end       else         dest_rect = Rect.new(self.width - m, m, m, self.height - m * 2)         stretch_blt(dest_rect, src_bitmap, src_bitmap.rect)       end     when 8       if sprite.stretch == false         for i in 0..bx.ceil           rect = src_bitmap.rect           rect.width = dx if i == bx.ceil           blt(m + i * src_bitmap.width, 0, src_bitmap, rect)         end       else         dest_rect = Rect.new(m, 0, self.width - m * 2, m)         stretch_blt(dest_rect, src_bitmap, src_bitmap.rect)       end     when 5       if sprite.stretch == false         for iy in 0..by.ceil           for ix in 0..bx.ceil             rect = src_bitmap.rect             rect.width  = dx if ix == bx.ceil             rect.height = dy if iy == by.ceil             blt(m + ix * src_bitmap.width, m + iy * src_bitmap.height,             src_bitmap, rect)           end         end       else         dest_rect = Rect.new(m, m, self.width - m * 2, self.height - m * 2)         stretch_blt(dest_rect, src_bitmap, src_bitmap.rect)       end     end   end end  #============================================================================== # * Cursor_Rect #==============================================================================  class Cursor_Rect < ::Sprite   attr_reader :width, :height, :skin, :margin, :sprite   #--------------------------------------------------------------------------   # * Initialize   #--------------------------------------------------------------------------   def initialize(viewport)     super(viewport)     @width = 0     @height = 0     @margin = 16     @skin = nil     @sprite = nil   end   #--------------------------------------------------------------------------   # * Margin   #--------------------------------------------------------------------------   def margin=(margin)     @margin = margin     get_cursor_sprite     set(x, y, width, height)   end   #--------------------------------------------------------------------------   # * Skin   #--------------------------------------------------------------------------   def skin=(skin)     @skin = skin     get_cursor_sprite   end   #--------------------------------------------------------------------------   # * Get Cursor Sprite   #--------------------------------------------------------------------------   def get_cursor_sprite     return if @skin == nil     src_bitmap = @skin.cut(128, 64, 32, 32)     @sprite = Tiled_Sprite.new(src_bitmap, 2, true)   end   #--------------------------------------------------------------------------   # * Set Width   #--------------------------------------------------------------------------   def width=(width)     return if @width == width     @width = width     if @width == 0 and self.bitmap != nil       self.bitmap.dispose       self.bitmap = nil     end     draw_rect   end   #--------------------------------------------------------------------------   # * Set Height   #--------------------------------------------------------------------------   def height=(height)     return if @height == height     @height = height     if @height == 0 and self.bitmap != nil       self.bitmap.dispose       self.bitmap = nil     end     draw_rect   end   #--------------------------------------------------------------------------   # * Set Coords   #--------------------------------------------------------------------------   def set(x, y, width, height)     self.x = x + @margin     self.y = y + @margin     if @width != width or @height != height       @width = width       @height = height       if width > 0 and height > 0         draw_rect       end     end   end   #--------------------------------------------------------------------------   # * Clear cursor   #--------------------------------------------------------------------------   def empty     self.x = 0     self.y = 0     self.width = 0     self.height = 0   end   #--------------------------------------------------------------------------   # * Draw cursor   #--------------------------------------------------------------------------   def draw_rect     return if @skin == nil or @sprite == nil     if @width > 0 and @height > 0       self.bitmap = Bitmap.new(@width, @height)       self.bitmap.draw_tiled(@sprite)     end   end end  #============================================================================== # * Window #==============================================================================  class Window   attr_reader :x, :y, :z, :width, :height, :ox, :oy   attr_reader :opacity, :back_opacity, :contents_opacity   attr_reader :stretch, :visible, :pause, :margin   attr_accessor :active   #--------------------------------------------------------------------------   # * Initialize   #--------------------------------------------------------------------------   def initialize     @viewport = Viewport.new(0, 0, 0, 0)     @cr_vport = Viewport.new(0, 0, 0, 0)     @width = 0     @height = 0     @ox = 0     @oy = 0     @opacity = 255     @back_opacity = 255     @contents_opacity = 255     @margin = 16     @frame   = Sprite.new     @bg      = Sprite.new     @window  = Sprite.new(@viewport)     @pause_s = Sprite.new     @arrows = []     for i in 0...4       @arrows.push(Sprite.new(@cr_vport))       @arrows.bitmap = Bitmap.new(16, 16)       @arrows.visible = false     end     @cursor_rect = Cursor_Rect.new(@cr_vport)     @cursor_fade = true     @pause_s.visible = false     @pause = false     @active = true     @stretch = true     @visible = true     self.x = 0     self.y = 0     self.z = 100     self.windowskin = RPG::Cache.windowskin($game_system.windowskin_name)   end   #--------------------------------------------------------------------------   # * Set Contents   #--------------------------------------------------------------------------   def contents=(bmp)     @window.bitmap = bmp     if bmp != nil       if bmp.width > @viewport.rect.width or bmp.height > @viewport.rect.height         draw_arrows       end     end   end   #--------------------------------------------------------------------------   # * Get Contents   #--------------------------------------------------------------------------   def contents     return @window.bitmap   end   #--------------------------------------------------------------------------   # * Dispose   #--------------------------------------------------------------------------   def dispose     @bg.dispose     @frame.dispose     @window.dispose     @cursor_rect.dispose     @viewport.dispose     @pause_s.dispose     @cr_vport.dispose     for arrow in @arrows       arrow.dispose     end   end   #--------------------------------------------------------------------------   # * Update   #--------------------------------------------------------------------------   def update     @window.update     @cursor_rect.update     @viewport.update     @cr_vport.update     update_pause     update_visible     update_arrows     update_cursor   end   #--------------------------------------------------------------------------   # * Update Pause   #--------------------------------------------------------------------------   def update_pause     id = (Graphics.frame_count / 8) % 4     rect = Rect.new(160, 64, 16, 16)     src_bitmap = Bitmap.new(rect.width, rect.height)     px = rect.x + (id % 2) * rect.width     py = rect.y + (id.to_f / 2).floor * rect.height     src_bitmap.blt(0, 0, @skin, Rect.new(px, py, rect.width, rect.height))     @pause_s.bitmap = src_bitmap     @pause_s.update   end   #--------------------------------------------------------------------------   # * Update Visible   #--------------------------------------------------------------------------   def update_visible     @frame.visible = @visible     @bg.visible = @visible     @window.visible = @visible     @cursor_rect.visible = @visible     if @pause       @pause_s.visible = @visible     else       @pause_s.visible = false     end   end   #--------------------------------------------------------------------------   # * Set Pause Mode   #--------------------------------------------------------------------------   def pause=(pause)     @pause = pause     update_visible   end   #--------------------------------------------------------------------------   # * Update Arrows   #--------------------------------------------------------------------------   def update_arrows     if @window.bitmap == nil or @visible == false       for arrow in @arrows         arrow.visible = false       end     else       @arrows[0].visible = @oy > 0       @arrows[1].visible = @ox > 0       @arrows[2].visible = (@window.bitmap.width - @ox) > @viewport.rect.width       @arrows[3].visible = (@window.bitmap.height - @oy) > @viewport.rect.height     end   end   #--------------------------------------------------------------------------   # * Update Cursor   #--------------------------------------------------------------------------   def update_cursor     if self.active == true       if @cursor_fade         @cursor_rect.opacity -= 10         @cursor_fade = false if @cursor_rect.opacity <= 100       else         @cursor_rect.opacity += 10         @cursor_fade = true if @cursor_rect.opacity >= 255       end     else       @cursor_rect.opacity = 100       @cursor_fade = false     end   end   #--------------------------------------------------------------------------   # * Set Visible   #--------------------------------------------------------------------------   def visible=(visible)     @visible = visible     update_visible     update_arrows   end   #--------------------------------------------------------------------------   # * Set X   #--------------------------------------------------------------------------   def x=(x)     @x = x     @bg.x = x + 2     @frame.x = x     @viewport.rect.x = x + @margin     @cr_vport.rect.x = x     @pause_s.x = x + (@width / 2) - 8     set_arrows   end   #--------------------------------------------------------------------------   # * Set Y   #--------------------------------------------------------------------------   def y=(y)     @y = y     @bg.y = y + 2     @frame.y = y     @viewport.rect.y = y + @margin     @cr_vport.rect.y = y     @pause_s.y = y + @height - @margin     set_arrows   end   #--------------------------------------------------------------------------   # * Set Z   #--------------------------------------------------------------------------   def z=(z)     @z = z     @bg.z = z - 1     @frame.z = z     @cr_vport.z = z + 2     @viewport.z = z + 3     @pause_s.z = z + 4   end   #--------------------------------------------------------------------------   # * Set OX   #--------------------------------------------------------------------------   def ox=(ox)     return if @ox == ox     @ox = ox     @viewport.ox = ox     update_arrows   end   #--------------------------------------------------------------------------   # * Set OY   #--------------------------------------------------------------------------   def oy=(oy)     return if @oy == oy     @oy = oy     @viewport.oy = oy     update_arrows   end   #--------------------------------------------------------------------------   # * Set Width   #--------------------------------------------------------------------------   def width=(width)     @width = width     @viewport.rect.width = width - @margin * 2     @cr_vport.rect.width = width     draw_window if @width > 0 and @height > 0     self.x = @x     self.y = @y   end   #--------------------------------------------------------------------------   # * Set Height   #--------------------------------------------------------------------------   def height=(height)     @height = height     @viewport.rect.height = height - @margin * 2     @cr_vport.rect.height = height     draw_window if @height > 0 and @width > 0     self.x = @x     self.y = @y   end   #--------------------------------------------------------------------------   # * Set Opacity   #--------------------------------------------------------------------------   def opacity=(opacity)     value = [[opacity, 255].min, 0].max     @opacity = value     @contents_opacity = value     @back_opacity = value     @frame.opacity = value     @bg.opacity = value     @window.opacity = value   end   #--------------------------------------------------------------------------   # * Set Back Opacity   #--------------------------------------------------------------------------   def back_opacity=(opacity)     value = [[opacity, 255].min, 0].max     @back_opacity = value     @bg.opacity = value   end   #--------------------------------------------------------------------------   # * Set Contents Opacity   #--------------------------------------------------------------------------   def contents_opacity=(opacity)     value = [[opacity, 255].min, 0].max     @contents_opacity = value     @window.opacity = value   end   #--------------------------------------------------------------------------   # * Get Cursor Rect   #--------------------------------------------------------------------------   def cursor_rect     return @cursor_rect   end   #--------------------------------------------------------------------------   # * Set Cursor Rect   #--------------------------------------------------------------------------   def cursor_rect=(rect)     @cursor_rect.x = rect.x     @cursor_rect.y = rect.y     if @cursor_rect.width != rect.width or @cursor_rect.height != rect.height       @cursor_rect.set(@cursor_rect.x, @cursor_rect.y, rect.width, rect.height)     end   end   #--------------------------------------------------------------------------   # * Get Windowskin   #--------------------------------------------------------------------------   def windowskin     return @skin   end   #--------------------------------------------------------------------------   # * Set Windowskin   #--------------------------------------------------------------------------   def windowskin=(windowskin)     return if windowskin == nil     if @skin != windowskin       @skin = windowskin       @cursor_rect.skin = windowskin       draw_window       draw_arrows     end   end   #--------------------------------------------------------------------------   # * Set Margin   #--------------------------------------------------------------------------   def margin=(margin)     if @margin != margin       @margin = margin       self.x = @x       self.y = @y       temp = @height       self.height = 0       self.width = @width       self.height = temp       @cursor_rect.margin = margin       set_arrows     end   end   #--------------------------------------------------------------------------   # * Set Stretch   #--------------------------------------------------------------------------   def stretch=(stretch)     if @stretch != stretch       @stretch = stretch       draw_window     end   end   #--------------------------------------------------------------------------   # * Set Arrow Positions   #--------------------------------------------------------------------------   def set_arrows     @arrows[0].x = @width / 2 - 8     @arrows[0].y = 8     @arrows[1].x = 8     @arrows[1].y = @height / 2 - 8     @arrows[2].x = @width - 16     @arrows[2].y = @height / 2 - 8     @arrows[3].x = @width / 2 - 8     @arrows[3].y = @height - 16   end   #--------------------------------------------------------------------------   # * Draw Window Basics   #--------------------------------------------------------------------------   def draw_window     return if @skin == nil     return if @width == 0 or @height == 0     draw_back     draw_frame   end   #--------------------------------------------------------------------------   # * Draw Back   #--------------------------------------------------------------------------   def draw_back     @bg.bitmap = Bitmap.new(@width - 4, @height - 4)     src_bitmap = @skin.cut(0, 0, 128, 128)     sprite = Tiled_Sprite.new(src_bitmap, 0, @stretch)     @bg.bitmap.draw_tiled(sprite)   end   #--------------------------------------------------------------------------   # * Draw Frame   #--------------------------------------------------------------------------   def draw_frame     @frame.bitmap = Bitmap.new(@width, @height)     m = 16     src_bitmap = @skin.cut(128, 0, 64, 64)     src_rect = Rect.new(m, m, 64 - m * 2, 64 - m * 2)     src_bitmap.fill_rect(src_rect, Color.new(0, 0, 0, 0))     sprite = Tiled_Sprite.new(src_bitmap, m, false)     @frame.bitmap.draw_tiled(sprite)   end   #--------------------------------------------------------------------------   # * Draw Arrows   #--------------------------------------------------------------------------   def draw_arrows     return if @skin == nil     @arrows[0].bitmap = @skin.cut(152, 16, 16, 8)     @arrows[1].bitmap = @skin.cut(144, 24, 8, 16)     @arrows[2].bitmap = @skin.cut(168, 24, 8, 16)     @arrows[3].bitmap = @skin.cut(152, 40, 16, 8)     update_arrows   end end


    PART 5. Script adaptations

    The Window script posted above defines in a single method the drawing of the sprites (used as a shortcut), this way it's easier to customize it taking into account both the border and the stretch mode.
    That property is defined in Back, Frames, Cursor, and finally in Blind if you're using the Window Blind Add-On (see below).

    It's also possible to change the cursor's windowskin independently, using cursor_rect.skin = name

    Examples:
    self.cursor_rect.skin = "001-Blue01"
    @window.cursor_rect.skin = "Dark_Skin"


    This dynamic cursor skin can be useful if you want to change it based on a condition (for example, when the current choice is disabled).

    Therefore, we can make other basic changes, implemented as "AddOns" below this base script.
    The method update_pause defines how the pause graphic is loaded. There you can change it easily so that graphic is loaded using an independent graphic instead, for example this one. This way it can be as big as you want, and have more frames.

                    Ruby:        
    #============================================================================== # ** Window - Pause Frame Edit #==============================================================================  class Window   def update_pause     #------------------------------------------------------------------------     # Number of frames per frame     frames = 8     # Graphic used     pause_bmp = RPG::Cache.picture("pause")     #------------------------------------------------------------------------     h = pause_bmp.height     i = pause_bmp.width / h     id = (Graphics.frame_count / frames) % i     rect = Rect.new(0, 0, h, h)     src_bitmap = Bitmap.new(rect.width, rect.height)     px = rect.x + id * rect.width     src_bitmap.blt(0, 0, pause_bmp, Rect.new(px, 0, rect.width, rect.height))     @pause_s.bitmap = src_bitmap     @pause_s.update   end end


    The method update_cursor defines the blinking of the cursor and its opacity when it's disabled. Disabling its blinking is very simple.

                    Ruby:        
    #============================================================================== # ** Window - Cursor Fade Fix #==============================================================================  class Window   def update_cursor     if self.active == true       @cursor_rect.opacity = 255     else       @cursor_rect.opacity = 100     end   end end


    You could also make a cursor with multiple frames as in RM2k/3, to do that you can use the previous script for pause as a reference. Similarly, on the method draw_arrows you can change how the scroll arrows are displayed, in case you want them bigger, or animated, etc.

    Inside the methods that define X and Y, you can find these:
    @pause_s.x = x + (@width / 2) - 8
    @pause_s.y = y + @height - @margin


    That controls the position of the pause, so you can easily change it as well, like this:

                    Ruby:        
    #============================================================================== # ** Window - Pause position #==============================================================================  class Window   alias pause_pos_x x= unless $@   alias pause_pos_y y= unless $@   def x=(x)     pause_pos_x(x)     # Set Pause X     @pause_s.x = x + @width - 24   end   def y=(y)     pause_pos_y(y)     # Set Pause Y     @pause_s.y = y + @height - 20   end end


    Now margin is a modifiable property too, but I recommend not changing that.
    The method set_arrows defines the position of the scroll arrows, which I don't recommend changing either.





    The method draw_back defines how the background is displayed.
    It gets the graphic with the rect (0, 0, 128, 128) from the windowskin and then uses this
    sprite = Tiled_Sprite.new(src_bitmap, 0, @stretch)

    That 0 is the margin, which means changing it you can make things like this image.





                    Ruby:        
    #============================================================================== # ** Window - Back margin #==============================================================================  class Window   def draw_back     @bg.bitmap = Bitmap.new(@width - 4, @height - 4)     src_bitmap = @skin.cut(0, 0, 128, 128)     sprite = Tiled_Sprite.new(src_bitmap, 24, @stretch)     @bg.bitmap.draw_tiled(sprite)   end end


    Right after that, the Frame is defined in a very similar way inside the method draw_frame, where m = 16 is the margin.
    sprite = Tiled_Sprite.new(src_bitmap, m, false)

    Changing that to true allows the borders of the frames to stretch, which may be interesting in some cases. You can check it here.

                    Ruby:        
    #============================================================================== # ** Window - Frame Stretch #==============================================================================  class Window   def draw_frame     @frame.bitmap = Bitmap.new(@width, @height)     m = 16     src_bitmap = @skin.cut(128, 0, 64, 64)     src_rect = Rect.new(m, m, 64 - m * 2, 64 - m * 2)     src_bitmap.fill_rect(src_rect, Color.new(0, 0, 0, 0))     sprite = Tiled_Sprite.new(src_bitmap, m, true)     @frame.bitmap.draw_tiled(sprite)   end end


    Finally (this is getting long), the last interesting method is get_cursor_sprite, which defines the display of the cursor. The default 2px border is very limiting, so you can now change it to something more wide. You can also make it tile.

    As before, all that is defined on this line:
    @sprite = Tiled_Sprite.new(src_bitmap, 2, true)

    Here's my version

                    Ruby:        
    #============================================================================== # ** Window - Cursor Sprite #==============================================================================  class Cursor_Rect < ::Sprite   def get_cursor_sprite     return if @skin == nil     src_bitmap = @skin.cut(128, 64, 32, 32)     @sprite = Tiled_Sprite.new(src_bitmap, 14, true)   end end






    Spoiler: AddOns - Window Blind
    More recent RPG maker versions have an extra part on the graphic with blinds, so you can define at once a tiling and a stretching part for the back of your windows. I've made a little AddOn for this script that allows doing that, but you'll need a Picture called blind.

                    Ruby:        
    #============================================================================== # ** Window Blind Add-On #------------------------------------------------------------------------------ #  This script requires the Window - Hidden RGSS Class by Wecoc #==============================================================================  class Window   alias blind_ini initialize unless $@   def initialize     @blind = Sprite.new     @blind.blend_type = 0     blind_ini   end     alias blind_dis dispose unless $@   def dispose     blind_dis     @blind.dispose   end     alias blind_visible update_visible unless $@   def update_visible     blind_visible     @blind.visible = @visible   end     alias blind_x x= unless $@   def x=(x)     blind_x(x)     @blind.x = x + 2   end     alias blind_y y= unless $@   def y=(y)     blind_y(y)     @blind.y = y + 2   end     def z=(z)     @z = z     @bg.z = z     @blind.z = z + 1     @frame.z = z + 2     @cr_vport.z = z + 3     @viewport.z = z + 4     @pause_s.z = z + 5   end     alias blind_opacity opacity= unless $@   def opacity=(opacity)     value = [[opacity, 255].min, 0].max     blind_opacity(value)     @blind.opacity = value   end     alias blind_back_opacity back_opacity= unless $@   def back_opacity=(opacity)     value = [[opacity, 255].min, 0].max     blind_back_opacity(value)     @blind.opacity = value   end     alias blind_draw_back draw_back   def draw_back     blind_draw_back     @blind.bitmap = Bitmap.new(@width - 4, @height - 4)     src_bitmap = RPG::Cache.picture("blind")     sprite = Tiled_Sprite.new(src_bitmap, 0, false)     @blind.bitmap.draw_tiled(sprite)   end end


    Spoiler: AddOns - Chrono Trigger Windowskin
    The windows of Chrono Trigger have two separated backs, similar to VX body and blind, but the other way around; the top part is the stretched one. You can see it here.

    You could try to modify the stretch modes in the Blind Addon, but it wouldn't look exactly the same, so I made it a separate AddOn instead.

                    Ruby:        
    #============================================================================== # ** Window Chrono Trigger #------------------------------------------------------------------------------ #  This script requires the Window - Hidden RGSS Class by Wecoc #==============================================================================  class Window   alias chrono_ini initialize unless $@   def initialize     @chrono_lighten = Sprite.new     @chrono_darken = Sprite.new     @chrono_lighten.blend_type = 1     @chrono_darken.blend_type = 2     chrono_ini     self.stretch = false   end     alias chrono_dis dispose unless $@   def dispose     chrono_dis     @chrono_lighten.dispose     @chrono_darken.dispose   end     alias chrono_visible update_visible unless $@   def update_visible     chrono_visible     @chrono_lighten.visible = @visible     @chrono_darken.visible = @visible   end     def update_cursor     if self.active == true       @cursor_rect.opacity = 255     else       @cursor_rect.opacity = 100     end   end     alias chrono_x x= unless $@   def x=(x)     chrono_x(x)     @bg.x = x     @chrono_lighten.x = x     @chrono_darken.x = x   end     alias chrono_y y= unless $@   def y=(y)     chrono_y(y)     @bg.y = y     @chrono_lighten.y = y     @chrono_darken.y = y   end     def z=(z)     @z = z     @bg.z = z     @frame.z = z + 1     @chrono_lighten.z = z + 2     @chrono_darken.z  = z + 2     @cr_vport.z = z + 3     @viewport.z = z + 4     @pause_s.z = z + 5   end     alias chrono_opacity opacity= unless $@   def opacity=(opacity)     value = [[opacity, 255].min, 0].max     chrono_opacity(value)     @chrono_lighten.opacity = value     @chrono_darken.opacity = value   end     def draw_back     @bg.bitmap = Bitmap.new(@width, @height)     src_bitmap = @skin.cut(0, 0, 128, 128)     sprite = Tiled_Sprite.new(src_bitmap, 16, @stretch)     @bg.bitmap.draw_tiled(sprite)     @chrono_lighten.bitmap = Bitmap.new(@width, @height)     src_bitmap = RPG::Cache.picture("chrono_lighten")     sprite = Tiled_Sprite.new(src_bitmap, 0, true)     @chrono_lighten.bitmap.draw_tiled(sprite)     @chrono_darken.bitmap = Bitmap.new(@width, @height)     src_bitmap = RPG::Cache.picture("chrono_darken")     sprite = Tiled_Sprite.new(src_bitmap, 0, true)     @chrono_darken.bitmap.draw_tiled(sprite)   end end


    In this case it requires two extra images in the Pictures folder; chrono_lighen and chrono_lighten. I also made a skin in case you want to try it (don't use it on your game, it's just for testing purposes).



    本贴来自国际rpgmaker官方论坛作者:Wecoc处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/all-you-need-to-know-about-windowskins.138315/

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-7-14 18:03 , Processed in 0.133839 second(s), 53 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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