Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Adding blinds to windows

Culex

Member

I'm sure you've all played that nifty new RPG Maker VX demo. Well, as you can tell, there are blinds overlapping the inside of the windows, as seen here:

http://www.geocities.com/ssj4jimbo/prob03.png[/img]

I know that RPG Maker VX draws blinds for its windowskin from the lower left corner of the windowskin, as seen here:

http://www.geocities.com/ssj4jimbo/prob04.png[/img]

I'm sure you could somehow script an entirely new way to read from windowskin files just as RPG Maker VX does, but my request is an edit to the current scripts (such as Window_Base) that could somehow tile, but not stretch, any picture over the inside of the the windows. Here's a picture that I tried to use:

http://www.geocities.com/ssj4jimbo/Blinds.png[/img]

I hope further clarification is unnecessary but please don't hesitate to ask for more. Thanks a lot!  :)
 

Culex

Member

No thanks. I figured somebody would do that too. :D That's the whole reason I created this topic. If you notice, the blinds in the windowskins are enlarged and it looks very sloppy. That did help to clarify why I created this topic in the first place, though, so thanks. Tiling is the key, not stretching. But in order to that in XP, one must either script a method in which XP reads windowskins like VX (which is way too much to ask for), or tile a picture (such as blinds) over the windowskin itself.
 

poccil

Sponsor

Here's a script I made that fulfills your request.  It's a rewritten version of the Window class that understands both RPG Maker XP and RPG Maker VX window formats.  Enjoy.

Code:
class WindowCursorRect < Rect
  def initialize(window)
    @window=window
    @x=0
    @y=0
    @width=0
    @height=0
  end
  attr_reader :x,:y,:width,:height
  def empty
    needupdate=@x!=0 || @y!=0 || @width!=0 || @height!=0
    if needupdate
     @x=0
     @y=0
     @width=0
     @height=0
     @window.width=@window.width
    end
  end
  def set(x,y,width,height)
    needupdate=@x!=x || @y!=y || @width!=width || @height!=height
    if needupdate
     @x=x
     @y=y
     @width=width
     @height=height
     @window.width=@window.width
    end
  end
  def height=(value)
    @height=value; @window.width=@window.width
  end
  def width=(value)
    @width=value; @window.width=@window.width
  end
  def x=(value)
    @x=value; @window.width=@window.width
  end
  def y=(value)
    @y=value; @window.width=@window.width
  end
end

class Window
 attr_reader :tone
 attr_reader :color
 attr_reader :viewport
 attr_reader :contents
 attr_reader :ox
 attr_reader :oy
 attr_reader :x
 attr_reader :y
 attr_reader :z
 attr_reader :width
 attr_reader :active
 attr_reader :pause
 attr_reader :height
 attr_reader :opacity
 attr_reader :back_opacity
 attr_reader :contents_opacity
 attr_reader :visible
 attr_reader :cursor_rect
 def windowskin
  @_windowskin
 end
 def initialize(viewport=nil)
  @sprites={}
  @spritekeys=[
   "back",
   "corner0","side0","scroll0",
   "corner1","side1","scroll1",
   "corner2","side2","scroll2",
   "corner3","side3","scroll3",
   "pause","cursor","contents"
  ]
  @sidebitmaps=[nil,nil,nil,nil]
  @cursorbitmap=nil
  @bgbitmap=nil
  @viewport=viewport
  for i in @spritekeys
   @sprites[i]=Sprite.new(@viewport)
  end
  @disposed=false
  @tone=Tone.new(0,0,0)
  @color=Color.new(0,0,0,0)
  @contents=nil
  @_windowskin=nil
  @rpgvx=false
  @x=0
  @y=0
  @width=0
  @height=0
  @ox=0
  @oy=0
  @z=0
  @stretch=true
  @visible=true
  @active=true
  @opacity=255
  @back_opacity=255
  @contents_opacity=255
  @cursor_rect=WindowCursorRect.new(self)
  @cursorblink=0
  @cursoropacity=255
  @pause=false
  @pauseframe=0
  privRefresh(true)
 end
 def dispose
  if !self.disposed?
   for i in @sprites
    i[1].dispose if i[1]
    @sprites[i[0]]=nil
   end
   for i in 0...@sidebitmaps.length
    @sidebitmaps[i].dispose if @sidebitmaps[i]
    @sidebitmaps[i]=nil
   end
   @cursorbitmap.dispose if @cursorbitmap
   @backbitmap.dispose if @backbitmap
   @sprites.clear
   @sidebitmaps.clear
   @_windowskin=nil
   @_contents=nil
   @disposed=true
  end
 end
 def stretch=(value)
  @stretch=value
  privRefresh(true)
 end
 def visible=(value)
  @visible=value
  privRefresh
 end
 def viewport=(value)
  @viewport=value
  for i in @spritekeys
   @sprites[i].dispose
   if @sprites[i].is_a?(Sprite)
    @sprites[i]=Sprite.new(@viewport)
   elsif @sprites[i].is_a?(Plane)
    @sprites[i]=Plane.new(@viewport)
   else
    @sprites[i]=nil
   end
  end
  privRefresh(true)
 end
 def z=(value)
  @z=value
  privRefresh
 end
 def disposed?
  return @disposed
 end
 def contents=(value)
  @contents=value
  privRefresh
 end
 def windowskin=(value)
  @_windowskin=value
  if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128
    @rpgvx=true
  else
    @rpgvx=false
  end
  privRefresh(true)
 end
 def ox=(value)
  @ox=value
  privRefresh
 end
 def active=(value)
  @active=value
  privRefresh(true)
 end
 def cursor_rect=(value)
  if !value
    @cursor_rect.empty
  else
    @cursor_rect.set(value.x,value.y,value.width,value.height)
  end
 end
 def oy=(value)
  @oy=value
  privRefresh
 end
 def width=(value)
  @width=value
  privRefresh(true)
 end
 def height=(value)
  @height=value
  privRefresh(true)
 end
 def pause=(value)
  @pause=value
  privRefresh
 end
 def x=(value)
  @x=value
  privRefresh
 end
 def y=(value)
  @y=value
  privRefresh
 end
 def opacity=(value)
  @opacity=value
  @opacity=0 if @opacity<0
  @opacity=255 if @opacity>255
  privRefresh
 end
 def back_opacity=(value)
  @back_opacity=value
  @back_opacity=0 if @back_opacity<0
  @back_opacity=255 if @back_opacity>255
  privRefresh
 end
 def contents_opacity=(value)
  @contents_opacity=value
  @contents_opacity=0 if @contents_opacity<0
  @contents_opacity=255 if @contents_opacity>255
  privRefresh
 end
 def tone=(value)
  @tone=value
  privRefresh
 end
 def color=(value)
  @color=value
  privRefresh
 end
 def flash(color,duration)
  return if disposed?
  for i in @sprites
   i[1].flash(color,duration)
  end
 end
 def update
  return if disposed?
  if @active
   if @cursorblink==0
    @cursoropacity-=5
    @cursorblink=1 if @cursoropacity<=180
   else
    @cursoropacity+=5
    @cursorblink=0 if @cursoropacity>=255
   end
  end
  if @pause
   @pauseframe=(Graphics.frame_count / 8) % 4
  end
  privRefresh
  for i in @sprites
   i[1].update
  end
 end

 private
 def ensureBitmap(bitmap,dwidth,dheight)
  if !bitmap||bitmap.disposed?||bitmap.width<dwidth||bitmap.height<dheight
   bitmap.dispose if bitmap
   bitmap=Bitmap.new([1,dwidth].max,[1,dheight].max)
  end
  return bitmap
 end
 def tileBitmap(dstbitmap,dstrect,srcbitmap,srcrect)
  return if !srcbitmap || srcbitmap.disposed?
  left=dstrect.x
  top=dstrect.y
  y=0;loop do break unless y<dstrect.height
   x=0;loop do break unless x<dstrect.width
    dstbitmap.blt(x+left,y+top,srcbitmap,srcrect)
    x+=srcrect.width
   end
   y+=srcrect.height
  end
 end
 def privRefresh(changeBitmap=false)
  return if self.disposed?
  backopac=self.back_opacity*self.opacity/255
  contopac=self.contents_opacity
  cursoropac=@cursoropacity*contopac/255
  for i in 0...4
   @sprites["corner#{i}"].bitmap=@_windowskin
   @sprites["scroll#{i}"].bitmap=@_windowskin
  end
  @sprites["pause"].bitmap=@_windowskin
  @sprites["contents"].bitmap=@contents
  if @_windowskin && !@_windowskin.disposed?
   for i in 0...4
    @sprites["corner#{i}"].opacity=@opacity
    @sprites["corner#{i}"].tone=@tone
    @sprites["corner#{i}"].color=@color
    @sprites["corner#{i}"].visible=@visible
    @sprites["side#{i}"].opacity=@opacity
    @sprites["side#{i}"].tone=@tone
    @sprites["side#{i}"].color=@color
    @sprites["side#{i}"].visible=@visible
    @sprites["scroll#{i}"].opacity=@opacity
    @sprites["scroll#{i}"].tone=@tone
    @sprites["scroll#{i}"].color=@color
    @sprites["scroll#{i}"].visible=@visible
   end
   for i in ["back","cursor","pause","contents"]
    @sprites[i].color=@color
    @sprites[i].tone=@tone
   end
   @sprites["back"].opacity=backopac
   @sprites["contents"].opacity=contopac
   @sprites["cursor"].opacity=cursoropac
   @sprites["pause"].opacity=@opacity
   @sprites["back"].visible=@visible
   @sprites["contents"].visible=@visible
   @sprites["pause"].visible=@visible && @pause
   @sprites["cursor"].visible=@visible && @active
   hascontents=(@contents && !@contents.disposed?)
   @sprites["scroll0"].visible = @visible && hascontents && @oy > 0
   @sprites["scroll1"].visible = @visible && hascontents && @ox > 0
   @sprites["scroll2"].visible = @visible && hascontents && (@contents.width - @ox) > @width-32
   @sprites["scroll3"].visible = @visible && hascontents && (@contents.height - @oy) > @height-32
  else
   for i in 0...4
    @sprites["corner#{i}"].visible=false
    @sprites["side#{i}"].visible=false
    @sprites["scroll#{i}"].visible=false
   end
   @sprites["contents"].visible=@visible
   @sprites["contents"].color=@color
   @sprites["contents"].tone=@tone
   @sprites["contents"].opacity=contopac
   @sprites["back"].visible=false
   @sprites["pause"].visible=false
   @sprites["cursor"].visible=false
  end
  for i in @sprites
   i[1].z=@z 
  end
  @sprites["cursor"].z=@z+1 # For Compatibility
  @sprites["contents"].z=@z+2 # For Compatibility
  @sprites["pause"].z=@z+2 # For Compatibility
  if @rpgvx
   trimX=64
   trimY=0
   backRect=Rect.new(0,0,64,64)
   blindsRect=Rect.new(0,64,64,64)
  else
   trimX=128
   trimY=0
   backRect=Rect.new(0,0,128,128)
   blindsRect=nil
  end
  @sprites["corner0"].src_rect.set(trimX,trimY+0,16,16);
  @sprites["corner1"].src_rect.set(trimX+48,trimY+0,16,16);
  @sprites["corner2"].src_rect.set(trimX,trimY+48,16,16);
  @sprites["corner3"].src_rect.set(trimX+48,trimY+48,16,16);
  @sprites["scroll0"].src_rect.set(trimX+24, trimY+16, 16, 8) # up
  @sprites["scroll3"].src_rect.set(trimX+24, trimY+40, 16, 8) # down
  @sprites["scroll1"].src_rect.set(trimX+16, trimY+24, 8, 16) # left
  @sprites["scroll2"].src_rect.set(trimX+40, trimY+24, 8, 16) # right
  cursorX=trimX
  cursorY=trimY+64
  sideRects=[
   Rect.new(trimX+16,trimY+0,32,16),
   Rect.new(trimX,trimY+16,16,32),
   Rect.new(trimX+48,trimY+16,16,32),
   Rect.new(trimX+16,trimY+48,32,16)
  ]
  if @width>32 && @height>32
   @sprites["contents"].src_rect.set(@ox,@oy,@width-32,@height-32)
  else
   @sprites["contents"].src_rect.set(0,0,0,0)
  end
  pauseRects=[
   trimX+32,trimY+64,
   trimX+48,trimY+64,
   trimX+32,trimY+80,
   trimX+48,trimY+80,
  ]
  pauseWidth=16
  pauseHeight=16
  @sprites["pause"].src_rect.set(
    pauseRects[@pauseframe*2],
    pauseRects[@pauseframe*2+1],
    pauseWidth,pauseHeight
  )
  @sprites["pause"].x=@x+(@width/2)-(pauseWidth/2)
  @sprites["pause"].y=@y+@height-16 # 16 refers to skin margin
  @sprites["contents"].x=@x+16
  @sprites["contents"].y=@y+16
  @sprites["corner0"].x=@x
  @sprites["corner0"].y=@y
  @sprites["corner1"].x=@x+@width-16
  @sprites["corner1"].y=@y
  @sprites["corner2"].x=@x
  @sprites["corner2"].y=@y+@height-16
  @sprites["corner3"].x=@x+@width-16
  @sprites["corner3"].y=@y+@height-16
  @sprites["side0"].x=@x+16
  @sprites["side0"].y=@y
  @sprites["side1"].x=@x
  @sprites["side1"].y=@y+16
  @sprites["side2"].x=@x+@width-16
  @sprites["side2"].y=@y+16
  @sprites["side3"].x=@x+16
  @sprites["side3"].y=@y+@height-16
  @sprites["scroll0"].x = @x+@width / 2 - 8
  @sprites["scroll0"].y = @y+8
  @sprites["scroll1"].x = @x+8
  @sprites["scroll1"].y = @y+@height / 2 - 8
  @sprites["scroll2"].x = @x+@width - 16
  @sprites["scroll2"].y = @y+@height / 2 - 8
  @sprites["scroll3"].x = @x+@width / 2 - 8
  @sprites["scroll3"].y = @y+@height - 16
  @sprites["back"].x=@x+2
  @sprites["back"].y=@y+2
  @sprites["cursor"].x=@x+16+@cursor_rect.x
  @sprites["cursor"].y=@y+16+@cursor_rect.y
  if changeBitmap && @_windowskin && !@_windowskin.disposed?
   width=@cursor_rect.width
   height=@cursor_rect.height
   if width > 0 && height > 0
      cursorrects=[
       # sides
       Rect.new(cursorX+2, cursorY+0, 28, 2),
       Rect.new(cursorX+0, cursorY+2, 2, 28),
       Rect.new(cursorX+30, cursorY+2, 2, 28),
       Rect.new(cursorX+2, cursorY+30, 28, 2),
       # corners
       Rect.new(cursorX+0, cursorY+0, 2, 2),
       Rect.new(cursorX+30, cursorY+0, 2, 2),
       Rect.new(cursorX+0, cursorY+30, 2, 2),
       Rect.new(cursorX+30, cursorY+30, 2, 2),
       # back
       Rect.new(cursorX+2, cursorY+2, 28, 28)
      ]
      margin=2
      fullmargin=4
      @cursorbitmap = ensureBitmap(@cursorbitmap, width, height)
      @cursorbitmap.clear
      @sprites["cursor"].bitmap=@cursorbitmap
      @sprites["cursor"].src_rect.set(0,0,width,height)
      rect = Rect.new(margin,margin, 
                       width - fullmargin, height - fullmargin)
      @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8])
      @cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4])# top left
      @cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right
      @cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6]) # bottom right
      @cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left
      rect = Rect.new(margin, 0, 
                       width - fullmargin, margin)
      @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0])
      rect = Rect.new(0, margin, 
                      margin, height - fullmargin)
      @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1])
      rect = Rect.new(width - margin, margin, 
                      margin, height - fullmargin)
      @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2])
      rect = Rect.new(margin, height-margin, 
                      width - fullmargin, margin)
      @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3])
   else
      @sprites["cursor"].visible=false
      @sprites["cursor"].src_rect.set(0,0,0,0)
   end
   for i in 0..3
    dwidth=(i==0||i==3) ? @width-32 : 16
    dheight=(i==0||i==3) ? 16 : @height-32
    @sidebitmaps[i]=ensureBitmap(@sidebitmaps[i],dwidth,dheight)
    @sprites["side#{i}"].bitmap=@sidebitmaps[i]
    @sprites["side#{i}"].src_rect.set(0,0,dwidth,dheight)
    @sidebitmaps[i].clear
    if sideRects[i].width>0 && sideRects[i].height>0
     tileBitmap(@sidebitmaps[i],@sprites["side#{i}"].src_rect,
      @_windowskin,sideRects[i])
    end
   end
   backwidth=@width-4
   backheight=@height-4
   if backwidth>0 && backheight>0
    @backbitmap=ensureBitmap(@backbitmap,backwidth,backheight)
    @sprites["back"].bitmap=@backbitmap
    @sprites["back"].src_rect.set(0,0,backwidth,backheight)
    @backbitmap.clear
    if @stretch
     @backbitmap.stretch_blt(@sprites["back"].src_rect,@_windowskin,backRect)
    else
     tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,backRect)
    end
    if blindsRect
     tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,blindsRect)
    end
   else
    @sprites["back"].visible=false
    @sprites["back"].src_rect.set(0,0,0,0)
   end
  end
 end
end

EDIT: Modified to improve performance.
 

poccil

Sponsor

I wasn't aware of the functionality of gradient text, and I was wondering what those colors were for, anyway.  Maybe I can try adding a function for gradient text.

EDIT:  Here's a function I wrote.  It draws gradient text on a bitmap.  It works rather well.

Code:
def drawGradientText(bitmap,color1,color2,x,y,width,height,text,align=0)
  return if width<=0 || height<=0
  tmp=Bitmap.new(width,height)
  tmp2=Bitmap.new(width,height)
  tmp.font.size=bitmap.font.size
  tmp.font.name=bitmap.font.name
  tmp.font.color=color2
  textsize=tmp.text_size(text)
  textheight=[textsize.height,1].max
  tmp.draw_text(0,0,width,height,text,align)
  textpos=(height/2)-(textheight/2)
  for i in 0...height
    if i<textpos
      opacity=0
    elsif i>=textpos+textheight
      opacity=255
    else
      ratio=((i-textpos)*1.0/textheight)
      ratio-=(0.5-ratio)*0.5
      opacity=ratio*255
      opacity=255 if opacity>255.0
      opacity=0 if opacity<0.0
    end
    tmp2.blt(0,i,tmp,Rect.new(0,i,width,1),opacity)
  end
  oldcolor=bitmap.font.color
  bitmap.font.color=color1
  bitmap.draw_text(x,y,width,height,text,align)
  bitmap.font.color=oldcolor
  bitmap.blt(x,y,tmp2,Rect.new(0,0,width,height))
  tmp.dispose
  tmp2.dispose
end

The next function retrieves a pair of colors from a Window_Base, similar to Window_Base#text_color, for use in drawGradientText above.

Code:
def getColorPair(window,pairnum)
  pairnum=0 if pairnum<0 || pairnum>=8
  if window.windowskin && !window.windowskin.disposed? &&
     window.windowskin.width==128
   # RPG Maker VX Windowskin
   x=64+pairnum*8
   color1=window.windowskin.get_pixel(x,96)
   color2=window.windowskin.get_pixel(x,104)
   return [color1,color2]
  else
   color=window.text_color(pairnum)
   return [color,color]
  end
end
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top