[Scripter's Tool] Improved Window class, Tiled window backgrounds and more |
|
|
|
|
Dec 31 2008, 08:23 PM
|

No method: 'stupid_title' found for `nil:NilClass'

Group: Revolutionary
Posts: 1,829
Type: Scripter
RM Skill: Undisclosed

|
(Not Biged781's) Improved RGSS Window class PurposeFirst off, I did not write most of this code. I have tweaked it, made it more readable and a little more efficient, but this was written by a guy named "Peter O" at this site. I found this when looking around for the RGSS source code. I needed to edit the RGSS Window class (not the Window_Base class, the hidden Window class) so that I could change the way windowskins work. Well, I found this, and with a little editing it is working perfectly. Any scripter can look through the source to see what has been added, but the coolest thing imo is the tiled window option. The most powerful aspect of this code is that it shows you all of the source for the previously hidden "Window" RGSS/2 class. I have not found any compatibility issues yet, let me know of any bugs. This will also work in RMXP. Configuration / UseJust place it in the Materials section. this should go above any other script in that section because it alters the base class for all windows. Since this was the reason for it in the first place, here is all you have to do to set it to tiled mode; CODE window.stretch = false ScreenshotsWhile this example is ugly, this script will allow you do do something like this below. You can use any type of tile that you like. ScriptCODE class WindowCursorRect < Rect #-------------------------------------------------------------------- # * intialize #-------------------------------------------------------------------- def initialize(window) @window=window @x=0 @y=0 @width=0 @height=0 end attr_reader :x,:y,:width,:height #-------------------------------------------------------------------- # * empty #-------------------------------------------------------------------- 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 #-------------------------------------------------------------------- # * isEmpty #-------------------------------------------------------------------- def isEmpty? return @x==0 && @y==0 && @width==0 && @height==0 end #-------------------------------------------------------------------- # * set #-------------------------------------------------------------------- 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 #-------------------------------------------------------------------- # * height= #-------------------------------------------------------------------- def height=(value) @height=value; @window.width=@window.width end #-------------------------------------------------------------------- # * width= #-------------------------------------------------------------------- def width=(value) @width=value; @window.width=@window.width end #-------------------------------------------------------------------- # * x= #-------------------------------------------------------------------- def x=(value) @x=value; @window.width=@window.width end #-------------------------------------------------------------------- # * y= #-------------------------------------------------------------------- def y=(value) @y=value; @window.width=@window.width end end
#---------------------------------------------------------------------- # * Window Class #---------------------------------------------------------------------- class Window attr_reader :tone attr_reader :color attr_reader :blend_type attr_reader :contents_blend_type 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 attr_reader :openness #-------------------------------------------------------------------- # * windowskin #-------------------------------------------------------------------- def windowskin return @_windowskin end #-------------------------------------------------------------------- # * intialize #-------------------------------------------------------------------- def initialize(viewport=nil) @sprites={} @spritekeys= [ "back", "corner0","side0","scroll0", "corner1","side1","scroll1", "corner2","side2","scroll2", "corner3","side3","scroll3", "cursor","contents","pause" ] @sidebitmaps=[nil,nil,nil,nil] @cursorbitmap=nil @bgbitmap=nil @viewport=viewport @spritekeys.each { |key| @sprites[key]=Sprite.new(@viewport) } @disposed=false @tone=Tone.new(0,0,0) @color=Color.new(0,0,0,0) @blankcontents=Bitmap.new(1,1) # RGSS2 requires this @contents=@blankcontents @_windowskin=nil @rpgvx=false @x=0 @y=0 @width=0 @openness=255 @height=0 @ox=0 @oy=0 @z=0 @stretch=true @visible=true @active=true @blend_type=0 @contents_blend_type=0 @opacity=255 @back_opacity=255 @contents_opacity=255 @cursor_rect=WindowCursorRect.new(self) @cursorblink=0 @cursoropacity=255 @pause=false @pauseopacity=255 @pauseframe=0 privRefresh(true) end #-------------------------------------------------------------------- # * dispose #-------------------------------------------------------------------- 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 @blankcontents.dispose @cursorbitmap.dispose if @cursorbitmap @backbitmap.dispose if @backbitmap @sprites.clear @sidebitmaps.clear @_windowskin=nil @_contents=nil @disposed=true end end #-------------------------------------------------------------------- # * openness= #-------------------------------------------------------------------- def openness=(value) @openness=value @openness=0 if @openness<0 @openness=255 if @openness>255 privRefresh end #-------------------------------------------------------------------- # * strecth= #-------------------------------------------------------------------- def stretch=(value) @stretch=value privRefresh(true) end #-------------------------------------------------------------------- # * visible= #-------------------------------------------------------------------- def visible=(value) @visible=value privRefresh end #-------------------------------------------------------------------- # * viewposrt= #-------------------------------------------------------------------- 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 #-------------------------------------------------------------------- # * z= #-------------------------------------------------------------------- def z=(value) @z=value privRefresh end #-------------------------------------------------------------------- # * disposed? #-------------------------------------------------------------------- def disposed? return @disposed end #-------------------------------------------------------------------- # * contents= #-------------------------------------------------------------------- def contents=(value) @contents=value privRefresh end #-------------------------------------------------------------------- # * windowskin= #-------------------------------------------------------------------- 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 #-------------------------------------------------------------------- # * ox= #-------------------------------------------------------------------- def ox=(value) @ox=value privRefresh end #-------------------------------------------------------------------- # * active= #-------------------------------------------------------------------- def active=(value) @active=value privRefresh(true) end #-------------------------------------------------------------------- # * cursor_rect= #-------------------------------------------------------------------- def cursor_rect=(value) if !value @cursor_rect.empty else @cursor_rect.set(value.x,value.y,value.width,value.height) end end #-------------------------------------------------------------------- # * oy= #-------------------------------------------------------------------- def oy=(value) @oy=value privRefresh end #-------------------------------------------------------------------- # * width= #-------------------------------------------------------------------- def width=(value) @width=value privRefresh(true) end #-------------------------------------------------------------------- # * height= #-------------------------------------------------------------------- def height=(value) @height=value privRefresh(true) end #-------------------------------------------------------------------- # * pause= #-------------------------------------------------------------------- def pause=(value) @pause=value @pauseopacity=0 if !value privRefresh end #-------------------------------------------------------------------- # * x= #-------------------------------------------------------------------- def x=(value) @x=value privRefresh end #-------------------------------------------------------------------- # * y= #-------------------------------------------------------------------- def y=(value) @y=value privRefresh end #-------------------------------------------------------------------- # * opacity= #-------------------------------------------------------------------- def opacity=(value) @opacity=value @opacity=0 if @opacity<0 @opacity=255 if @opacity>255 privRefresh end #-------------------------------------------------------------------- # * back_opacity= #-------------------------------------------------------------------- def back_opacity=(value) @back_opacity=value @back_opacity=0 if @back_opacity<0 @back_opacity=255 if @back_opacity>255 privRefresh end #-------------------------------------------------------------------- # * contents_opacity= #-------------------------------------------------------------------- def contents_opacity=(value) @contents_opacity=value @contents_opacity=0 if @contents_opacity<0 @contents_opacity=255 if @contents_opacity>255 privRefresh end #-------------------------------------------------------------------- # * tone= #-------------------------------------------------------------------- def tone=(value) @tone=value privRefresh end #-------------------------------------------------------------------- # * color= #-------------------------------------------------------------------- def color=(value) @color=value privRefresh end #-------------------------------------------------------------------- # * blend_type= #-------------------------------------------------------------------- def blend_type=(value) @blend_type=value privRefresh end #-------------------------------------------------------------------- # * flash #-------------------------------------------------------------------- def flash(color,duration) return if disposed? @sprites.each {|sprite| sprite[1].flash(color,duration)} end def update return if disposed? mustchange=false if @active if @cursorblink==0 @cursoropacity-=8 @cursorblink = 1 if @cursoropacity<=128 else @cursoropacity+=8 @cursorblink=0 if @cursoropacity>=255 end mustchange=true if !@cursor_rect.isEmpty? else mustchange=true if @cursoropacity!=128 @cursoropacity=128 end if @pause @pauseframe=(Graphics.frame_count / 8) % 4 @pauseopacity=[@pauseopacity+64,255].min mustchange=true end privRefresh if mustchange for i in @sprites i[1].update end end #------------------ Private Methods ------------------# private #-------------------------------------------------------------------- # * ensureBitmap #-------------------------------------------------------------------- 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 #-------------------------------------------------------------------- # * tileBitmap #-------------------------------------------------------------------- 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 #-------------------------------------------------------------------- # * privRefresh #-------------------------------------------------------------------- def privRefresh(changeBitmap=false) return if self.disposed? backopac = self.back_opacity * self.opacity / 255 contopac = self.contents_opacity cursoropac = @cursoropacity * contopac / 255 @sprites["contents"].bitmap = @contents unless @_windowskin.nil? || @_windowskin.disposed? for i in 0...4 @sprites["corner#{i}"].bitmap = @_windowskin @sprites["corner#{i}"].opacity = @opacity @sprites["corner#{i}"].tone = @tone @sprites["corner#{i}"].color = @color @sprites["corner#{i}"].blend_type = @blend_type @sprites["corner#{i}"].visible = @visible @sprites["side#{i}"].opacity = @opacity @sprites["side#{i}"].tone = @tone @sprites["side#{i}"].color = @color @sprites["side#{i}"].blend_type = @blend_type @sprites["side#{i}"].visible = @visible @sprites["scroll#{i}"].bitmap = @_windowskin @sprites["scroll#{i}"].opacity = @opacity @sprites["scroll#{i}"].tone = @tone @sprites["scroll#{i}"].blend_type = @blend_type @sprites["scroll#{i}"].color = @color @sprites["scroll#{i}"].visible = @visible end @sprites["pause"].bitmap = @_windowskin for key in ["back", "cursor", "pause", "contents"] @sprites[key].color = @color @sprites[key].tone = @tone @sprites[key].blend_type = @blend_type end @sprites["contents"].blend_type = @contents_blend_type @sprites["contents"].opacity = contopac @sprites["contents"].visible = @visible && (@openness == 255) @sprites["cursor"].opacity = cursoropac @sprites["cursor"].visible = @visible && (@openness == 255) @sprites["pause"].visible = @visible && @pause @sprites["pause"].opacity = @pauseopacity @sprites["back"].opacity = backopac @sprites["back"].visible = @visible hascontents = (!@contents.nil? && !@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 && @openness==255 @sprites["contents"].color = @color @sprites["contents"].tone = @tone @sprites["contents"].blend_type = @contents_blend_type @sprites["contents"].opacity = contopac @sprites["back"].visible = false @sprites["pause"].visible = false @sprites["cursor"].visible = false end @sprites.each { |sprite| sprite[1].z = @z } if @rpgvx @sprites["cursor"].z = @z # For Compatibility @sprites["contents"].z = @z # For Compatibility @sprites["pause"].z = @z # For Compatibility trimX = 64 backRect = Rect.new(0,0,64,64) blindsRect = Rect.new(0,64,64,64) else @sprites["cursor"].z = @z + 1 # For Compatibility @sprites["contents"].z = @z + 2 # For Compatibility @sprites["pause"].z = @z + 2 # For Compatibility trimX = 128 backRect = Rect.new(0,0,128,128) blindsRect = nil end trimY = 0 @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.nil? && !@_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) @sidebitmaps[i].stretch_blt( @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 if @openness != 255 opn = @openness/255.0 for key in @spritekeys sprite = @sprites[key] ratio = (@height <= 0) ? 0 : (sprite.y - @y) * 1.0 / @height sprite.zoom_y = opn sprite.oy = 0 sprite.y = (@y + (@height / 2.0) + (@height * ratio * opn) - (@height / 2 * opn)).floor oldbitmap = sprite.bitmap oldsrcrect = sprite.src_rect.clone end else for key in @spritekeys sprite = @sprites[key] sprite.zoom_y = 1.0 end end # Ensure z order i = 0 for key in @spritekeys sprite = @sprites[key] y = sprite.y sprite.y = i sprite.oy = (sprite.zoom_y <= 0) ? 0 : (i - y) / sprite.zoom_y end end end
__________________________
` Give me teh codez!!! I am the master debator! 
|
|
|
|
|
|
|
|
 |
Replies
(1 - 4)
|
|
Dec 31 2008, 08:59 PM
|

L Did you know? Death gods... only eat apples

Group: +Gold Member
Posts: 2,976
Type: Scripter
RM Skill: Skilled

|
Interesting Scripter's Tool. Is this how it's suppose to look like when using the default window skin?
__________________________
My RMXP Project:  Farewell RRR. =]
|
|
|
|
|
|
|
|
|
Dec 31 2008, 09:03 PM
|

No method: 'stupid_title' found for `nil:NilClass'

Group: Revolutionary
Posts: 1,829
Type: Scripter
RM Skill: Undisclosed

|
It should only look like that if you set stretched = false. This option was good for my FF9 custom menu, because the windowskin in FF9 is tiled and looks like crap when stretched. So, if you have a windowskin that would look better tiled, you should use this. for most windowskins it will look like your example.
__________________________
` Give me teh codez!!! I am the master debator! 
|
|
|
|
|
|
|
|
|
Dec 31 2008, 09:10 PM
|

L Did you know? Death gods... only eat apples

Group: +Gold Member
Posts: 2,976
Type: Scripter
RM Skill: Skilled

|
QUOTE (BigEd781 @ Dec 31 2008, 09:03 PM)  It should only look like that if you set stretched = false. This option was good for my FF9 custom menu, because the windowskin in FF9 is tiled and looks like crap when stretched. So, if you have a windowskin that would look better tiled, you should use this. for most windowskins it will look like your example. Ah. I see. It's good that you got your FF9 menu tiled then. (and that's how you pulled your tiled status off. I thought you used an image or something.) I'm assuming that you can also set how much stretched the tile is. What other features are there? (Lol. I think I should just look at it for myself.) Thanks for this. I'm sure scripter's will find it useful. =D
__________________________
My RMXP Project:  Farewell RRR. =]
|
|
|
|
|
|
|
|
|
Dec 31 2008, 09:14 PM
|

No method: 'stupid_title' found for `nil:NilClass'

Group: Revolutionary
Posts: 1,829
Type: Scripter
RM Skill: Undisclosed

|
Actually, the status menu is made from images  . You can't set how stretched the image is in tiled mode because that would defeat the purpose of a tiled image. It just takes the 64x64 rectangle from the top left of the windowskin image and repeats it across the window. The most powerful aspect of this code is that it shows you all of the source for the previously hidden "Window" RGSS/2 class. As far as other features, it has a color property iof you want to paint the whole thing a single color and a few other little oddities like that, but the ability to change how the windowskin is drawn is the best new feature. I'll add an example to make it more clear as to what you can do.
__________________________
` Give me teh codez!!! I am the master debator! 
|
|
|
|
|
|
|
|
  |
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:
RPG RPG Revolution is an Privacy
Policy and Legal
|
|