#============================================================================== # * 총망라 해상도 조절 스크립트 (2), @cheapmunk.naver, 2014-10-19 #============================================================================== # 해상도 설정 # 너비 $WINDOW_WIDTH = 800 # 높이 $WINDOW_HEIGHT = 600 # 시작시 풀스크린 사용 여부 $WINDOW_FULL = false # Alt + Enter 사용 여부 $WINDOW_ALTENTER = true #============================================================================== # ** FullScreen (ChangeDisplaySettings), 发表于, 2010-09-17 #------------------------------------------------------------------------------ # http://bbs.66rpg.com/forum.php?mod=viewthread&tid=156438 #============================================================================== module Display #-------------------------------------------------------------------------- # ## API #-------------------------------------------------------------------------- GPS = Win32API.new('kernel32', 'GetPrivateProfileString', 'pppplp', 'l') FW = Win32API.new('user32', 'FindWindow', 'pp', 'l') GWR = Win32API.new('user32', 'GetWindowRect', 'lp', 'l') GSM = Win32API.new('user32', 'GetSystemMetrics', 'l', 'l') GAKS = Win32API.new('user32', 'GetAsyncKeyState', 'l', 'l') AWR = Win32API.new('user32', 'AdjustWindowRect', 'pll', 'l') GCR = Win32API.new('user32', 'GetClientRect', 'lp','i') CDS = Win32API.new('user32', 'ChangeDisplaySettingsW', 'pl', 'l') SWL = Win32API.new('user32', 'SetWindowLongA', 'pll', 'l') GWL = Win32API.new('user32', 'GetWindowLongA', 'll', 'l') SWP = Win32API.new('user32', 'SetWindowPos', 'lllllll', 'l') # 게임 핸들 def self.game_hwnd() if (hwnd = Win32API.new('user32', 'GetActiveWindow', 'v', 'l').call) == 0 GPS.call('Game', 'Title', '', val = '\0' * 256, 256, '.\\Game.ini') hwnd = FW.call('RGSS Player', val.delete!('\0')) return hwnd else return hwnd end end #-------------------------------------------------------------------------- # ## 상수 #-------------------------------------------------------------------------- GWL_STYLE = -16 WS_BORDER = 0x800000 SWP_SHOWWINDOW = 0x40 PELSHEIGHT = 0x100000 PEDTH = 0x80000 BITSPERPEL = 0x00040000 PELSWIDTH = 0x00080000 PELSHEIGHT = 0x00100000 # 풀 스크린 CDS_FULLSCREEN = 0x00000004 # 기본 스크린 CDS_RESET = 0x40000000 # 항상 위로 HWND_TOPMOST = -1 # 처음 위로 HWND_TOP = 0 # 핸들 HWND = game_hwnd() # 윈도우 초기값 WIN_STYLE = GWL.call(HWND, GWL_STYLE) WIN_RECT = GSM.call(0), GSM.call(1) # 작업표시줄 RECT GWR.call(FW.call('Shell_TrayWnd', 0), buf='\0'*8) buf = buf.unpack('l4') tw = (buf[2]-buf[0]).abs; th = (buf[3]-buf[1]).abs TASKSIZE = (tw >= WIN_RECT[0] ? 0 : tw), (th >= WIN_RECT[1] ? 0 : th) # 단축키 MOD_ALT = 0x0001 VK_RETURN = 0x0D KEY_LALT = 0xA4 KEY_RETURN = 0x0D # Alt + Enter 금지 Win32API.new('user32', 'RegisterHotKey', 'llll', 'l').call(HWND, 0, MOD_ALT, VK_RETURN) #-------------------------------------------------------------------------- # ## 스크린 상태 #-------------------------------------------------------------------------- def self.Defaultscreen(width, height) @width, @height = width, height # 윈도우 스타일 복귀 SWL.call(HWND, GWL_STYLE, WIN_STYLE) # 풀스크린 해제 CDS.call(get_devmode(@width, @height), CDS_RESET) # 위치 조정 SetWindowPos($WINDOW_WIDTH, $WINDOW_HEIGHT) @display = 0 end def self.FullScreen(width, height) @width, @height = width, height # 보더 삭제 SWL.call(HWND, GWL_STYLE, WS_BORDER) # 풀스크린 SWP.call(HWND, HWND_TOPMOST, 0, 0, @width, @height, SWP_SHOWWINDOW) CDS.call(get_devmode(@width, @height), CDS_FULLSCREEN) @display = 1 end #-------------------------------------------------------------------------- # ## DM 구조체 #-------------------------------------------------------------------------- def self.get_devmode(width,height) devmode = [ 0,0,0,0,0,0,0,0, # Q8 0, # L 220, # S 0, # S BITSPERPEL|PELSWIDTH|PELSHEIGHT,# L4 0,0, # Q2 0,0,0,0,0,#S5 0,0,0,0,0,0,0,0,#Q8 0,# S 32, # L 32비트 width,# L height,# L 0, # Q 0,0,0,0# Q4 ].pack('Q8LS2LQ2S5Q8SL3Q5') return devmode end # 윈도우 가운데 정렬 def self.SetWindowPos(w, h) AWR.call(rect=[0,0,w,h].pack('i4'), WIN_STYLE, 0) rect = rect.unpack('i4'); rect = rect[2]-rect[0], rect[3]-rect[1] SWP.call(HWND, HWND_TOP, (WIN_RECT[0]-rect[0]-TASKSIZE[0])/2, (WIN_RECT[1]-rect[1]-TASKSIZE[1])/2, rect[0], rect[1], SWP_SHOWWINDOW) @display = 0 end # Alt + Enter 누를 시 def self.alt_enter? if GAKS.call(KEY_LALT) != 0 if GAKS.call(KEY_RETURN) != 0 case @display when 0 # d => f FullScreen($WINDOW_WIDTH, $WINDOW_HEIGHT) when 1 # f => d Defaultscreen(WIN_RECT[0], WIN_RECT[1]) end end end end # 초기 세팅 if $WINDOW_FULL FullScreen($WINDOW_WIDTH, $WINDOW_HEIGHT) else SetWindowPos($WINDOW_WIDTH, $WINDOW_HEIGHT) end end module Input class << self alias :resolution_update :update def update(*args) resolution_update(*args) Display.alt_enter? if $WINDOW_ALTENTER end end end #============================================================================== # ** Tilemap (hidden class) #------------------------------------------------------------------------------ # This class handles the map data to screen processing #============================================================================== # # Yet another Tilemap Script (for any map size /w autotiles) # by Meâ €žÂ¢ / Derk-Jan Karrenbeld (me@solarsoft.nl) # version 1.0 released on 08 nov 08 # version 1.2 # #============================================================================== class Tilemap #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :tileset attr_reader :autotiles attr_reader :flash_data attr_reader :priorities attr_reader :visible attr_reader :ox, :oy attr_writer :autotiles #-------------------------------------------------------------------------- # * Constant Configuration #-------------------------------------------------------------------------- # Window Rect - the visible Area of the Map (default: 640 x 480) # Bitmap Rect - the active drawing Area of the Map (window tiles + 2 tiles) # BitmapWindow offset - the invisible tile count on one side WindowRect = Rect.new(0, 0, $WINDOW_WIDTH, $WINDOW_HEIGHT) BitmapRect = Rect.new(0, 0, $WINDOW_WIDTH + 160, $WINDOW_HEIGHT + 80) # Recommended BitmapWindowOffset = (BitmapRect.height-WindowRect.height)/2/32 # Length in frames of one frame showing from autotile AutotileLength = 10 # KillOutScreenSprite - Kills priority and autotile sprites out of screen # EnableFlashingData - If activated, enables updating flashing data KillOutScreenSprite = true EnableFlashingData = false # SingleFlashingSprite - Uses one Flashing sprite, instead of many # SinglePrioritySprite - Uses one Priority sprite, instead of many # SingleAutotileSprite - Uses one Autotile sprite, instead of many SingleFlashingSprite = true#false SinglePrioritySprite = true#false SingleAutotileSprite = true#false # This is the Autotile animation graphical index array. It contains numbers # that point to the graphic part of an animating autotile. Autotiles = [ [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27, 6, 33, 34], [ 5, 6, 33, 34], [27, 28, 33, 12], [ 5, 28, 33, 12], [27, 6, 33, 12], [ 5, 6, 33, 12] ], [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27, 6, 11, 34], [ 5, 6, 11, 34], [27, 28, 11, 12], [ 5, 28, 11, 12], [27, 6, 11, 12], [ 5, 6, 11, 12] ], [ [25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12], [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ], [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36], [39, 40, 45, 46], [ 5, 40, 45, 46], [39, 6, 45, 46], [ 5, 6, 45, 46] ], [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12], [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ], [ [37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44], [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1, 2, 7, 8] ] ] #-------------------------------------------------------------------------- # * Object Initialization # viewport : the drawing viewport # rpgmap : the rpgmap object #-------------------------------------------------------------------------- def initialize(viewport = nil, rpgmap = nil) # Autotiles Array @autotiles = Array.new(6, nil) @oldautotiles = Array.new(6, nil) # Tilemap Viewport @viewport = viewport ? viewport : Viewport.new(WindowRect) # Showing Region Rectangle @region = Rect.new(0,0,BitmapRect.width/32, BitmapRect.height/32) # Old Region Rect @oldregion = nil # Set TilemapSprite @sprite = Sprite.new(@viewport) # Set Bitmap on Sprite @sprite.bitmap = Bitmap.new(BitmapRect.width, BitmapRect.height) # Set FlashingSprite and bitmap if SingleFlashingSprite @flashsprite = Sprite.new(@viewport) @flashsprite.bitmap = Bitmap.new(BitmapRect.width, BitmapRect.height) end # Set Informational Arrays/Hashes @priority_ids = {} # Priority ids @normal_tiles = {} # Non-auto tile bitmaps @auto_tiles = {} # Autotile bitmaps @priority_sprites = [] # Priority Sprites @autotile_sprites = [] # Autotile Sprites @flashing_sprites = [] # Flashing Sprites # Disposal Boolean @disposed = false # Visibility Boolean @visible = true # Flashing Boolean @flashing = true # Disable Drawing Boolean @can_draw = true # Set Coords @ox, @oy = 0, 0 # Create TileMap if rpgmap is provided create_tilemap(rpgmap) if !rpgmap.nil? end #-------------------------------------------------------------------------- # * Get Bitmap Sprite #-------------------------------------------------------------------------- def sprite_bitmap return @sprite.bitmap end #-------------------------------------------------------------------------- # * Data Tileset Referer - loads if needed #-------------------------------------------------------------------------- def data_tilesets $data_tilesets ||= load_data('Data/Tilesets.rxdata') end #-------------------------------------------------------------------------- # * Check: Disposed? #-------------------------------------------------------------------------- def disposed? @disposed end #-------------------------------------------------------------------------- # * Dispose #-------------------------------------------------------------------------- def dispose # Dispose all sprites (and cached bitmaps for quick memory clearing) for sprite in [@sprite] + @normal_tiles.values + @auto_tiles.values + @priority_sprites + @autotile_sprites + (SingleFlashingSprite ? [@flashsprite] : @flashing_sprites) sprite = sprite[0] if sprite.is_a?(Array) sprite.dispose if sprite.is_a?(Bitmap) end # Set Informational Arrays/Hashes @priority_ids = {} # Priority ids @normal_tiles = {} # Non-auto tile bitmaps @priority_sprites = [] # Priority Sprites @autotile_sprites = [] # Autotile Sprites @flashing_sprites = [] # Flashing Sprites # I am disposed @disposed = true end #-------------------------------------------------------------------------- # * Checking: Drawing Allowed #-------------------------------------------------------------------------- def drawing? @can_draw end #-------------------------------------------------------------------------- # * Enable Drawing #-------------------------------------------------------------------------- def enable_drawing @can_draw = true end #-------------------------------------------------------------------------- # * Disable Drawing #-------------------------------------------------------------------------- def disable_drawing @can_draw = true end #-------------------------------------------------------------------------- # * Enable Flashing #-------------------------------------------------------------------------- def enable_flashing @flashing = true end #-------------------------------------------------------------------------- # * Disable Flashing #-------------------------------------------------------------------------- def disable_flashing @flashing = false end #-------------------------------------------------------------------------- # * Check: Flashing #-------------------------------------------------------------------------- def flashing? EnableFlashingData and @flashing and @flashing_sprites.size end #-------------------------------------------------------------------------- # * Check: Visible #-------------------------------------------------------------------------- def visible? @visible end #-------------------------------------------------------------------------- # * Check: Autotiles Changed #-------------------------------------------------------------------------- def autotiles_changed? @oldautotiles != @autotiles end #-------------------------------------------------------------------------- # * Set Visibility # value: new value #-------------------------------------------------------------------------- def visible=(value) # Set Visibility value @visible = value # Update all sprites for sprite in [@sprite] + @priority_sprites + @autotile_sprites + (SingleFlashingSprite ? [@flashsprite] : @flashing_sprites) sprite = sprite[0] if sprite.is_a?(Array) sprite.visible = value end end #-------------------------------------------------------------------------- # * Set Tileset # value : new RPG::Tileset, String or Bitmap #-------------------------------------------------------------------------- def tileset=(value) # Return on equal data return if @tileset == value # Set TilesetName value = value.tileset_name if value.is_a?(RPG::Tileset) # Cache Tileset @tileset = RPG::Cache.tileset(value) if value.is_a?(String) # Set Tileset @tileset = value if value.is_a?(Bitmap) # Draw Tileset redraw_tileset if @can_draw end #-------------------------------------------------------------------------- # * Set Priorities # value : new value #-------------------------------------------------------------------------- def priorities=(value) # Return on equal data return if @priorities == value # Set Priorities @priorities = value # Draw Tileset redraw_priorities if @can_draw end #-------------------------------------------------------------------------- # * Set flash data # coord[0] : x # coord[1] : y # value : Color or Hex #-------------------------------------------------------------------------- def flash_data=(*coord, &value) # Return on equal data return if @flash_data[coord[0],coord[1]] == value # Already Flashing this tile? flashing = !@flash_data[x,y].nil? # Set Flash Data @flash_data[x,y] = value return if !EnableFlashingData # Take action and remove/change/add flash if value.nil? remove_flash(x,y) elsif flashing change_flash(x,y,value) else add_flash(x,y,value) end end #-------------------------------------------------------------------------- # * Map Data referer #-------------------------------------------------------------------------- def map_data @map_data end #-------------------------------------------------------------------------- # * Set Map Data # value : new Table value #-------------------------------------------------------------------------- def map_data=(value) # Return on equal data return if @map_data == value # Set New Map Data @map_data = value # Flash Data Table @flash_data = Table.new(@map_data.xsize, @map_data.ysize) # Redraw Current Region draw_region if @can_draw and @priorities and @tileset end #-------------------------------------------------------------------------- # * Get Map width (in tiles) #-------------------------------------------------------------------------- def map_tile_width map_data.xsize end #-------------------------------------------------------------------------- # * Get Map height (in tiles) #-------------------------------------------------------------------------- def map_tile_height map_data.ysize end #-------------------------------------------------------------------------- # * Create Tilemap # rpgmap : base object #-------------------------------------------------------------------------- def create_tilemap(rpgmap) # Return on invalid data return if rpgmap.is_a?(RPG::Map) == false # Restrict drawing @can_draw = false # Set Local Tileset Object (RPG::Tileset) _tileset = data_tilesets[rpgmap.tileset_id] # Return on invalid data return if _tileset.is_a?(RPG::Tileset) == false # Set Informational Arrays/Hashes @priority_ids = {} # Priority ids @normal_tiles = {} # Non-auto tile bitmaps @priority_sprites = [] # Priority Sprites @autotile_sprites = [] # Autotile Sprites @flashing_sprites = [] # Flashing Sprites # Set Tileset tileset = _tileset.tileset_name # Set AutoTiles (0..6).each { |i| autotiles[i] = _tileset.autotile_names[i] } # Set Priorities priorities = _tileset.priorities # Set Mapdata map_data = rpgmap.map_data # Reset drawing @can_draw = true # Reset disposed (need to reinit info variables) @disposed = false # Draw Region draw_region end #-------------------------------------------------------------------------- # * Get Tile id # x : x tile coord # y : y tile coord # z : z layer coord #-------------------------------------------------------------------------- def tile_id(x, y, z) return map_data[x, y, z] end #-------------------------------------------------------------------------- # * Get Priority # args (1) : tile_id # args (3) : x, y, z coord #-------------------------------------------------------------------------- def priority(*args) return @priorities[args[0]] if args.size == 1 return @priorities[tile_id(args[0], args[1], args[2])] end #-------------------------------------------------------------------------- # * Redraw Tileset (on change) #-------------------------------------------------------------------------- def redraw_tileset # Kill current bitmap sprite_bitmap.clear # Get rid of tile bitmaps @normal_tiles.clear # Get rid of autotile bitmaps @auto_tiles.clear # Dispose current tiles in screen (@autotile_sprites + @priority_sprites).each { |sprite| sprite[0].dispose if !sprite[0].disposed? } # Clear disposed graphics @autotile_sprites.clear; @priority_sprites.clear # Draw if allowed draw_region if @can_draw and @priorities and @tileset end #-------------------------------------------------------------------------- # * Redraw Priorities (on change) #-------------------------------------------------------------------------- def redraw_priorities # Dispose current tiles in screen (@autotile_sprites + @priority_sprites).each { |sprite| sprite[0].dispose if !sprite[0].disposed? } # Clear disposed graphics @priority_sprites.clear; @autotile_sprites.clear # Clear Priority id information @priority_ids.clear # Do a one time check for all priorities (can't do @tileset.priorities # because RPG::Tilemap is normally not passed trough, but if it were, you # can do the following - just uncomment this part and command the next for # loop: ## for tile_id in 0...@tileset.priorities.xsize ## next if @tileset.priorities[tile_id] == 0 ## @priority_ids[tile_id] = @tileset.priorities[tile_id] ## end # But because we don't have that data, just iterate trough the map and # get seperate priority data for each tile, and save if there is one. for z in 0...3 for y in 0...map_tile_height for x in 0...map_tile_width next if (id = tile_id(x, y, z)) == 0 next if (p = priority(id)) == 0 @priority_ids[id] = p end end end # Draw if allowed draw_region if @can_draw and @priorities and @tileset end #-------------------------------------------------------------------------- # * Redraw autotiles (on change) #-------------------------------------------------------------------------- def redraw_autotiles # Clear autotile bitmaps @auto_tiles.clear # Dispose current autotiles on screen @autotile_sprites.each { |sprite| sprite[0].dispose if !sprite[0].disposed? } # Get rid of disposed sprites @autotile_sprites.clear # Save changes aka don't call this method again @oldautotiles = @autotiles # Draw if allowed draw_region if @can_draw and @priorities and @tileset end #-------------------------------------------------------------------------- # * Draw new Visible region #-------------------------------------------------------------------------- def draw_current_region # Determine x and y coords for tile top left left_x = @ox / 32 top_y = @oy / 32 # Set origin for bitmap @sprite.ox = @ox % 32 + BitmapWindowOffset * 32 @sprite.oy = @oy % 32 + BitmapWindowOffset * 32 # Set New Region @region.x, @region.y = left_x, top_y # Set New Sprite Positions (pray for non disposed sprites: checking = cpu cost) (@priority_sprites + @autotile_sprites).each { |sprite| sprite[0].x = (sprite[1] - left_x) * 32 ; sprite[0].ox = @ox % 32; sprite[0].y = (sprite[2] - top_y) * 32; sprite[0].oy = @oy % 32; unless (priority = @priority_ids[tile_id(sprite[1], sprite[2], sprite[3])]).nil? then sprite[0].z = @viewport.z + sprite[0].y + priority * 32 + 32 end} # Return on old data return if @oldregion == @region # Draw complete region if new? return draw_region if @oldregion.nil? # Determine missing rect first_drawing_x = [((left_x - @oldregion.x) >= 0 ? @region.width : 0) - (left_x - @oldregion.x)].max drawing_rect_x = Rect.new(first_drawing_x, 0, ((left_x - @oldregion.x).abs), @region.height) first_drawing_y = [((top_y - @oldregion.y) >= 0 ? @region.height : 0) - (top_y - @oldregion.y)].max drawing_rect_y = Rect.new(0, first_drawing_y, @region.width, ((top_y - @oldregion.y).abs)) # Determine Rect that is still visible stay_rect = Rect.new([(left_x-@oldregion.x) * 32,0].max, [(top_y-@oldregion.y) * 32,0].max, (@region.width - (left_x-@oldregion.x).abs) * 32,(@region.height - (top_y-@oldregion.y).abs) * 32) # Dumplicate bitmap and clear Original dump_bitmap = sprite_bitmap.dup; sprite_bitmap.clear # Place Old bitmap on screen sprite_bitmap.blt([(@oldregion.x-left_x) * 32, 0].max, [(@oldregion.y-top_y) * 32, 0].max,dump_bitmap, stay_rect) # Remove Out of Range Sprites if KillOutScreenSprite _prio, _auto = @priority_sprites.dup, @autotile_sprites.dup; @priority_sprites, @autotile_sprites = [], [] for sprite in _prio do if (sprite[1]) < @region.x - BitmapWindowOffset or (sprite[1] - BitmapWindowOffset) > @region.width + @region.x or sprite[2] < @region.y - BitmapWindowOffset or (sprite[2] - BitmapWindowOffset) > @region.height + @region.y then sprite[0].dispose else @priority_sprites << sprite end end for sprite in _auto do if (sprite[1]) < @region.x - BitmapWindowOffset or (sprite[1] - BitmapWindowOffset) > @region.width + @region.x or sprite[2] < @region.y - BitmapWindowOffset or (sprite[2] - BitmapWindowOffset) > @region.height + @region.y then sprite[0].dispose else @autotile_sprites << sprite end end # Remove nil elements (error prevention) @priority_sprites.compact!; @autotile_sprites.compact!; end # Draw New Columns for x in 0...drawing_rect_x.width for y in 0...drawing_rect_x.height for z in 0..2 draw_tile(drawing_rect_x.x + x , drawing_rect_x.y + y, tile_id(left_x + drawing_rect_x.x + x - BitmapWindowOffset, top_y + y - BitmapWindowOffset, z), left_x + drawing_rect_x.x + x - BitmapWindowOffset, top_y + y - BitmapWindowOffset, z) end end end # Draw New Rows for x in 0...drawing_rect_y.width for y in 0...drawing_rect_y.height for z in 0..2 draw_tile(drawing_rect_y.x + x , drawing_rect_y.y + y, tile_id(left_x + x - BitmapWindowOffset, top_y + drawing_rect_y.y + y - BitmapWindowOffset, z), left_x + x - BitmapWindowOffset, top_y + drawing_rect_y.y + y - BitmapWindowOffset, z) end end end # Set region sprite coords @oldregion = Rect.new(left_x, top_y, @region.width, @region.height) end #-------------------------------------------------------------------------- # * Draw complete visible region #-------------------------------------------------------------------------- def draw_region # Clear Sprites sprite_bitmap.clear (@priority_sprites + @autotile_sprites).each { |sprite| sprite[0].dispose } @priority_sprites.clear; @autotile_sprites.clear # Determine x and y coords for tile top left left_x = @ox / 32 top_y = @oy / 32 # Set Sprite ox/oy @sprite.ox = BitmapWindowOffset * 32 @sprite.oy = BitmapWindowOffset * 32 # Set New Region @region.x, @region.y = left_x, top_y # Iterate through new xses for x in 0...(@region.width) for y in 0...(@region.height) for z in 0..2 # Draw new tiles draw_tile(x, y , tile_id(x + left_x - BitmapWindowOffset,y + top_y - BitmapWindowOffset,z), x + left_x - BitmapWindowOffset , y + top_y - BitmapWindowOffset, z) end end end # Set oldregion (sprite coords) @oldregion = Rect.new(left_x, top_y, @region.width, @region.height) # Update Sprite @sprite.update # Prevent Frame Skipping Graphics.frame_reset end #-------------------------------------------------------------------------- # * Draw a tile # x : x coord in tiles on screen # y : y coord in tiles on screen # tile_id : tile id # tx : x coord in tiles on map # ty : y coord in tiles on map # tx : z layer on map # src_... : bitmap to draw on #-------------------------------------------------------------------------- def draw_tile(x, y, tile_id, tx, ty, tz, src_bitmap = nil) # Return on invalid data #return if @region.x < x or @region.y < y #return if @region.width + @region.x > x or @region.height + @region.y > y return if x < 0 or y < 0 return if tile_id == nil return draw_autotile(x, y, tile_id, tx, ty, tz, bitmap = bitmap) if tile_id < 384 # First, Get Bitmap if (src_bitmap = @normal_tiles[tile_id]).nil? # Get Bitmap src_bitmap = Bitmap.new(32, 32) src_rect = Rect.new((tile_id - 384) % 8 * 32, (tile_id - 384) / 8 * 32,32,32) src_bitmap.blt(0, 0, @tileset, src_rect) # Save Bitmap @normal_tiles[tile_id] = src_bitmap end # Now, if tile is not a priority tile... if @priority_ids[tile_id].nil? sprite_bitmap.blt(x * 32, y * 32, src_bitmap, Rect.new(0,0,32,32)) else # ... Set Sprite and bitmap sprite = Sprite.new(@viewport) sprite.visible = visible sprite.bitmap = src_bitmap sprite.x, sprite.y = (tx - (@ox/32)) * 32, (ty - (@oy/32)) * 32 sprite.ox, sprite.oy = @ox % 32, @oy % 32 # Priority matches 32 (above normal) + value * 32 (priority) + tile y * 32 sprite.z = @viewport.z + y * 32 + @priority_ids[tile_id] * 32 + 32 # Add to sprites Array @priority_sprites << [sprite, tx, ty, tz] end end #-------------------------------------------------------------------------- # * Draw an autotile # x : x coord in tiles on screen # y : y coord in tiles on screen # tile_id : tile id # tx : x coord in tiles on map # ty : y coord in tiles on map # tx : z layer on map # src_... : bitmap to draw on #-------------------------------------------------------------------------- def draw_autotile(x, y, tile_id, tx, ty, tz, src_bitmap = nil) # Kill invalid calls return if x < 0 or y < 0 return if tile_id == nil or tile_id >= 384 return if tile_id == 0 # Get AutotileGraphic autotile = @autotiles[tile_id/48-1] return if autotile.nil? or autotile.disposed? # Get Frame Data frames = (autotile.height == 32 ? autotile.width / 32 : autotile.width / 96) current_frame = (Graphics.frame_count/AutotileLength) % frames # First Get Bitmap if (src_bitmap_array = @auto_tiles[tile_id]).nil? @auto_tiles[tile_id] = [] # If autotile is weird... :P if autotile.height == 32 # Just iterate trough frames for i in 0...frames # Create a bitmap for this frame this_frame_bitmap = Bitmap.new(32,32) src_rect = Rect.new(i * 32, 0, 32, 32) this_frame_bitmap.blt(0, 0, autotile, src_rect) # Save this frame's bitmap @auto_tiles[tile_id] << this_frame_bitmap end # Set the bitmap array to the created one src_bitmap_array = @auto_tiles[tile_id] else # If autotile is normal, iterate for i in 0...frames # Create a new bitmap for this frame this_frame_bitmap = Bitmap.new(32,32) # Get the tiles from the Autotiles Array (tile_id corresponds # to the autotile graphic, so left_top is different to center tiles = Autotiles[(tile_id % 48)>>3][(tile_id % 48)&7] # Iterate trough 0, 1, 2 and 3 for j in 0...4 # Get tile_position (to get from the graphic) tile_position = tiles[j] - 1 src_rect = Rect.new(tile_position % 6 * 16 + i * 96, tile_position / 6 * 16, 16, 16) this_frame_bitmap.blt(j % 2 * 16, j / 2 * 16 , autotile, src_rect) end @auto_tiles[tile_id][i] = this_frame_bitmap end src_bitmap_array = @auto_tiles[tile_id] end end # Now Get Frame Bitmap src_bitmap = src_bitmap_array[current_frame] return if src_bitmap.nil? # Now, if tile is not a priority tile... if @priority_ids[tile_id].nil? and autotile.width == 32 sprite_bitmap.blt(x * 32, y * 32, src_bitmap, Rect.new(0,0,32,32)) else priority = (@priority_ids[tile_id] or 0) # ... Set Sprite and bitmap sprite = Sprite.new(@viewport) sprite.visible = visible sprite.bitmap = src_bitmap sprite.x, sprite.y = (tx - (@ox/32)) * 32, (ty - (@oy/32)) * 32 sprite.ox, sprite.oy = @ox % 32, @oy % 32 # Priority matches 32 (above normal) + value * 32 (priority) + tile y * 32 # Because this sprite is created later then the normal base sprite, it # has a higher internal z value. We fix this by setting the z value to # minus 2 + z value of this tile. This results in that a autotile is below # minus 2 + z value of this tile. This results in that a autotile is below # a normal sprite on the same priority sprite.z = @viewport.z - 1 + tz # Fix for ltr drwn. unless @priority_ids[tile_id].nil? sprite.z = @viewport.z + y * 32 + @priority_ids[tile_id] * 32 + 32 end # Add to sprites Array @autotile_sprites << [sprite, tx, ty, tz] end end #-------------------------------------------------------------------------- # * Get new autotile Bitmap # tile_id : tile id #-------------------------------------------------------------------------- def get_update_autotile(tile_id) # Kill invalid Data return if tile_id == nil or tile_id >= 384 return if tile_id == 0 # Get AutotileGraphic autotile = @autotiles[tile_id/48-1] return if autotile.nil? or autotile.disposed? # Get Frame Data frames = (autotile.height == 32 ? autotile.width / 32 : autotile.width / 96) current_frame = (Graphics.frame_count/AutotileLength) % frames # Now Get Frame Bitmap src_bitmap = @auto_tiles[tile_id][current_frame] return src_bitmap end #-------------------------------------------------------------------------- # * Set x origin value # value : new value #-------------------------------------------------------------------------- def ox=(value) # Next line is needed if you want to do complex things if ox changes return unless @ox != value @ox = value end #-------------------------------------------------------------------------- # * Set y origin value # value : new value #-------------------------------------------------------------------------- def oy=(value) # Next line is needed if you want to do complex things if oy changes return unless @oy != value @oy = value end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Redraw autotiles if changed redraw_autotiles if autotiles_changed? # Cancel updating if invisible return if not visible? # Flash Tiles update_flashing if flashing? # Update autotiles update_autotiles if (Graphics.frame_count % AutotileLength) == 0 # Draw Region draw_current_region end #-------------------------------------------------------------------------- # * Update (flashing) #-------------------------------------------------------------------------- def update_flashing # To be released end #-------------------------------------------------------------------------- # * Update (autotiles) #-------------------------------------------------------------------------- def update_autotiles # Determine x and y coords for tile top left left_x = @ox / 32 top_y = @oy / 32 # Iterate trough sprites for sprite in @autotile_sprites # Get Data from Array real_sprite, tx, ty, tz = sprite tile_id = tile_id(tx, ty, tz) # Replace Bitmap (can't clear the bitmap, for some reason - don't try to) real_sprite.bitmap = get_update_autotile(tile_id) # We do not need to update the positions already, because it will be done # the next method call (below update_autotiles, there is draw_current_...) # so it will be 'fixed' there. No need to call something twice, right? end end end #============================================================================== # ** Plane, ForeverZer0, 2010-12-18, 0.93 #------------------------------------------------------------------------------ # http://www.gdunlimited.net/forums/topic/7024-custom-resolution/ #=============================================================================== class Plane < Sprite def z=(z) # Change the Z value of the viewport, not the sprite. super(z * 1000) end def ox=(ox) return if @bitmap == nil # Have viewport stay in loop on X-axis. super(ox % @bitmap.width) end def oy=(oy) return if @bitmap == nil # Have viewport stay in loop on Y-axis. super(oy % @bitmap.height) end def bitmap # Return the single bitmap, before it was tiled. return @bitmap end def bitmap=(tile) @bitmap = tile # Calculate the number of tiles it takes to span screen in both directions. xx = 1 + ($WINDOW_WIDTH.to_f / tile.width).ceil yy = 1 + ($WINDOW_HEIGHT.to_f / tile.height).ceil # Create appropriately sized bitmap, then tile across it with source image. plane = Bitmap.new(@bitmap.width * xx, @bitmap.height * yy) (0..xx).each {|x| (0..yy).each {|y| plane.blt(x * @bitmap.width, y * @bitmap.height, @bitmap, @bitmap.rect) }} # Set the bitmap to the sprite through its super class (Sprite). super(plane) end # Redefine methods dealing with coordinates (defined in super) to do nothing. def x; end def y; end def x=(x); end def y=(y); end end class Game_Player CENTER_X = ($WINDOW_WIDTH / 2 - 16) * 4 CENTER_Y = ($WINDOW_HEIGHT / 2 - 16) * 4 def center(x, y) max_x = ($game_map.width - ($WINDOW_WIDTH / 32.0).round) * 128 max_y = ($game_map.height - ($WINDOW_HEIGHT / 32.0).round) * 128 $game_map.display_x = [0, [x * 128 - CENTER_X, max_x].min].max $game_map.display_y = [0, [y * 128 - CENTER_Y, max_y].min].max end end class Spriteset_Map alias :resolution_initialize :initialize def initialize resolution_initialize @viewport1.rect = Rect.new(0, 0, $WINDOW_WIDTH, $WINDOW_HEIGHT) @viewport2.rect = Rect.new(0, 0, $WINDOW_WIDTH, $WINDOW_HEIGHT) @viewport3.rect = Rect.new(0, 0, $WINDOW_WIDTH, $WINDOW_HEIGHT) end end class Game_Map def scroll_down(distance) if self.height * 32.0 <= $WINDOW_HEIGHT.to_f @display_y = [@display_y + distance, (self.height - 15) * 128].min else @display_y = [@display_y + distance, (32 * self.height - $WINDOW_HEIGHT) / 32 * 128].min end end def scroll_right(distance) if self.width * 32.0 <= $WINDOW_WIDTH.to_f @display_x = [@display_x + distance, (self.width - 20) * 128].min else @display_x = [@display_x + distance, (32 * self.width - $WINDOW_WIDTH) / 32 * 128].min end end end module RPG class Weather def update return if @type == 0 for i in 1..@max sprite = @sprites[i] if sprite == nil break end if @type == 1 sprite.x -= 2 sprite.y += 16 sprite.opacity -= 8 end if @type == 2 sprite.x -= 8 sprite.y += 16 sprite.opacity -= 12 end if @type == 3 sprite.x -= 2 sprite.y += 8 sprite.opacity -= 8 end x = sprite.x - @ox y = sprite.y - @oy if sprite.opacity < 64 or x < -50 or x > $WINDOW_WIDTH + 110 or y < -300 or y > $WINDOW_HEIGHT + 20 sprite.x = rand($WINDOW_WIDTH + 160) - 50 + @ox sprite.y = rand($WINDOW_HEIGHT + 320) - 200 + @oy sprite.opacity = 255 end end end end end #------------------------------------------------------------------------------ # 버그 픽스 (1), 2014-10-02 # 장소 이동시 맵 밖 검은부분 나오는 버그 # 날씨의 표현이 어색했던 버그 #------------------------------------------------------------------------------ # 버그 픽스 (2), 2014-10-19 # 시작 시 창화면 상태에서 Alt + Enter 누르면 전체화면이 안되는 버그