Today, 05:25 AM
(This post was last modified: Today, 05:41 AM by DerVVulfman.)
Poccil's Tilemap Rewrite
Version: 1.0
The Re-Envisioned Game Set
Version: 1.0
The Re-Envisioned Game Set
Introduction
This script is a replacement for the default code within the RPGMaker engine that generates the visible map within your game. Just as the default tilemap system, it uses the tilesets applied to your maps.
As a script, it still renders the map slower than the default system. But it works with screen resolution scripts that increase/decrease the screen size and may work with other scripts that work with the tilemap.
Features
- Automatically adjusts based on the viewport's dimensions
- Adaptable
Screenshots
None.
Demo
BOX.COM LINK Look for the Download link in the top right of the screen
Script
The Script
Code:
#==============================================================================
# ** Poccil's Tilemap Rewrite
# A rewrite of Poccil's Tilemap found in HBGames.
#------------------------------------------------------------------------------
# Version 1.0
# Edit by DerVVulfman
# 02-21-2025 (MM-DD-YYYY)
# RGSS / RPGMaker XP / RUBY 2.7 Compliant
#==============================================================================
#
#
# INTRODUCTION:
# =============
# This script is a replacement for the default code within the RPGMaker engine
# that generates the visible map within your game. Just as the default tilemap
# system, it uses the tilesets applied to your maps.
#
# As a script, it still renders the map slower than the default system. But it
# works with screen resolution scripts that increase/decrease the screen size
# and may work with other scripts that work with the tilemap.
#
#
# INSTALLTION:
# ============
# Place below Scene_Debug and above Main. Place it below any resolution script
# if one is in use.
#
#
# CONFIGURATION:
# ==============
# Generally, you don't touch it. But it allows you to set the refresh rate of
# autotiles, the opacity level of flash effects, and how many map layers you
# can display assuming you have a compatible map editor.
#
#
# ORIGINAL SOURCE:
# ================
# The 3rd post in (Jan 19, 2008):
# https://www.arpgmaker.com/threads/tilemap-script-needed-some-feedback.37433/
# - or (with the Internet Archive) -
# http://www.hbgames.org/forums/viewtopic.php?f=11&t=37433&start=2
#
#
#==============================================================================
#==============================================================================
# ** Poccil's Tilemap Settings
#------------------------------------------------------------------------------
# This module just allows you to adjust the three settings in the script.
#==============================================================================
module PoccilTilemap
# Animated Autotiles Frames Reset
# ===============================
# Defines the speed where the autotiles repaint and refresh within the map.
# (DEFAULT: 15)
#--------------------------------------------------------------------------
#
AUTOTILES_SPEED = 15
# Map Layers
# ==========
# Defines how many layers are used to draw the rendered map. It will require
# the map editor to be compatible with the number of layers possible.
# (DEFAULT: 3 typical RMXP layers)
#--------------------------------------------------------------------------
#
LAYERS = 3
# Flash Opacity per Stage
# =======================
# The flash effect is generated in six stages, each of the six stages ren-
# dering the colorized effet with its own opacity intensity. It is here
# where you set the intensity (range 0-255) for each of the six stages.
# (DEFAULT: [100,90,80,70,80,90]
#--------------------------------------------------------------------------
#
FLASH_OPACITY = [100,90,80,70,80,90]
end
#==============================================================================
# ** Custom Tilemap Autotiles
#------------------------------------------------------------------------------
# This class handles the autotiles
#==============================================================================
class CustomTilemapAutotiles
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :changed # autotiles changed flag
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
#
@changed = true
@tiles = [nil,nil,nil,nil,nil,nil,nil]
#
end
#--------------------------------------------------------------------------
# * Set tiles
# value : tiles
#--------------------------------------------------------------------------
def []=(i,value)
#
@tiles[i] = value
@changed = true
#
end
#--------------------------------------------------------------------------
# * Get tiles
#--------------------------------------------------------------------------
def [](i)
#
return @tiles[i]
#
end
end
#==============================================================================
# ** Tilemap (hidden class)
#------------------------------------------------------------------------------
# This class handles the map data to screen processing
#==============================================================================
class Tilemap
#--------------------------------------------------------------------------
# * Configured values
# - Animated Autotiles Frames Reset
# - Map Layer System (default for 3 - typical RMXP layers)
# - Flash Opacity (with 6 opacity stages for a single flash)
#--------------------------------------------------------------------------
Animated_Autotiles_Frames = PoccilTilemap::AUTOTILES_SPEED
Map_Layers = PoccilTilemap::LAYERS
FlashOpacity = PoccilTilemap::FLASH_OPACITY
#--------------------------------------------------------------------------
# * Auto-Tiles
# Auto-Tile 48 : First Auto-Tile, Constructed of tiles 27, 28, 33, 34
#--------------------------------------------------------------------------
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] ]
]
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :tileset # tileset
attr_accessor :autotiles # autotiles
attr_accessor :map_data # map data
attr_accessor :priorities # map priorities
attr_accessor :flash_data # flash data
attr_reader :visible # visible
attr_accessor :ox # ox
attr_accessor :oy # oy
attr_reader :viewport # viewport
#--------------------------------------------------------------------------
# * Object Initialization
# viewport : viewport
#--------------------------------------------------------------------------
def initialize(viewport)
#
@viewport = viewport
@tileset = nil
@autotiles = CustomTilemapAutotiles.new
@map_data = nil
@flash_data = nil
@priorities = nil
@visible = true
@ox = 0
@oy = 0
@plane = false
@tiles = []
@autotileInfo = []
@regularTileInfo = []
@oldOx = 0
@oldOy = 0
@layer0 = Sprite.new(viewport)
@layer0.visible = true
@nowshown = false
vrw = @viewport.rect.width*2
vrh = @viewport.rect.height*2
@layer0.bitmap = Bitmap.new(vrw, vrh)
@flash = nil
@layer0.ox = 0
@layer0.oy = 0
@zoom_x = $game_map.tilemap_zoom_x
@zoom_y = $game_map.tilemap_zoom_y
@layer0.zoom_x = @zoom_x
@layer0.zoom_y = @zoom_y
@oxLayer0 = 0
@oyLayer0 = 0
@oxFlash = 0
@oyFlash = 0
@layer0.z = 0
@priotiles = []
@prioautotiles = []
@autosprites = []
@framecount = []
@need_refresh = true
@flashChanged = false
@firsttime = true
@disposed = false
@usedsprites = false
@layer0clip = true
@firsttimeflash = true
@fullyrefreshed = false
@fullyrefreshedautos = false
@priority_need_refresh = false
#
end
#--------------------------------------------------------------------------
# * Set Tileset and confirm change with refresh
# value : tileset data
#--------------------------------------------------------------------------
def tileset=(value)
#
@tileset = value
@need_refresh = true
#
end
#--------------------------------------------------------------------------
# * Set X-Coordinate Starting point and confirm for update
# value : revised y coordinate starting value
#--------------------------------------------------------------------------
def ox=(value)
#
value = (value * $game_map.tilemap_zoom_x).to_i
value = (value / $game_map.tilemap_zoom_x).to_i
wasshown = self.shown?
@ox = value.floor
@nowshown = (!wasshown && self.shown?)
#
end
#--------------------------------------------------------------------------
# * Set Y-Coordinate Starting point and confirm for update
# value : revised y coordinate starting value
#--------------------------------------------------------------------------
def oy=(value)
#
value = (value * $game_map.tilemap_zoom_y).to_i
value = (value / $game_map.tilemap_zoom_y).to_i
wasshown = self.shown?
@oy = value.floor
@nowshown = (!wasshown && self.shown?)
#
end
#--------------------------------------------------------------------------
# * Acquire number of horizontal tiles on the screen
# value : revised y coordinate starting value
#--------------------------------------------------------------------------
def tiles_width
#
(@viewport.rect.width / 32)
#
end
#--------------------------------------------------------------------------
# * Acquire number of horizontal tiles on the screen
# value : revised y coordinate starting value
#--------------------------------------------------------------------------
def tiles_height
#
(@viewport.rect.height / 32)
#
end
#--------------------------------------------------------------------------
# * Refresh
# autotiles : autotile flag
#--------------------------------------------------------------------------
def refresh(autotiles=false)
#
@oldOx = @ox
@oldOy = @oy
usesprites = false
#
if @layer0
@layer0.visible = @visible
usesprites =! refreshLayer0(autotiles)
return if autotiles && !usesprites
else
usesprites = true
end
#
refreshFlashSprite
vpx = @viewport.rect.x
vpy = @viewport.rect.y
vpr = @viewport.rect.width+vpx
vpb = @viewport.rect.height+vpy
xsize = @map_data.xsize
ysize = @map_data.ysize
minX = (@ox/32)-1
maxX = ((@ox+@viewport.rect.width)/32)+1
minY = (@oy/32)-1
maxY = ((@oy+@viewport.rect.height)/32)+1
minX = 0 if minX<0
minX = xsize-1 if minX>=xsize
maxX = 0 if maxX<0
maxX = xsize-1 if maxX>=xsize
minY = 0 if minY<0
minY = ysize-1 if minY>=ysize
maxY = 0 if maxY<0
maxY = ysize-1 if maxY>=ysize
#
count = 0
if (minX < maxX) && (minY < maxY)
@usedsprites=usesprites || @usedsprites
if @layer0
@layer0.visible=false if usesprites
end
if @priority_need_refresh = true
for prio in @priotiles
next if (prio[0] < minX) || (prio[0] > maxX)
next if (prio[1] < minY) || (prio[1] > maxY)
id = prio[3]
xpos = (prio[0]<<5)-@ox
ypos = (prio[1]<<5)-@oy
count = addTile(@tiles, count, xpos, ypos, id, true)
end
@priority_need_refresh = false
end
#
if @fullyrefreshed
for prio in @priotiles
next if (prio[0] < minX) || (prio[0] > maxX)
next if (prio[1] < minY) || (prio[1] > maxY)
id = prio[3]
xpos = (prio[0]<<5)-@ox
ypos = (prio[1]<<5)-@oy
count = addTile(@tiles, count, xpos, ypos, id, true)
end
else
for z in 0...@map_data.zsize
for y in minY..maxY
for x in minX..maxX
id = @map_data[x, y, z]
next if (id == 0) || !@priorities[id]
next if @priorities[id] == 0
xpos = (x << 5) - @ox
ypos = (y << 5) - @oy
count = addTile(@tiles, count, xpos, ypos, id)
end
end
end
end
end
if count < @tiles.length
bigchange = (count <= (@tiles.length*2/3)) && (@tiles.length*2/3)>25
j = count
len = @tiles.length
while j<len
sprite = @tiles[j]
@tiles[j+1] =- 1
if bigchange
sprite.dispose
@tiles[j] = nil
@tiles[j+1] = nil
elsif !@tiles[j].disposed?
sprite.visible = false if sprite.visible
end
j += 2
end
@tiles.compact! if bigchange
end
#
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
def dispose
#
return if disposed?
@help.dispose if @help
@help=nil
i=0;len=@autotileInfo.length;while i<len
if @autotileInfo[i]
@autotileInfo[i].dispose
@autotileInfo[i]=nil
end
i+=1
end
i=0;len=@regularTileInfo.length;while i<len
if @regularTileInfo[i]
@regularTileInfo[i].dispose
@regularTileInfo[i]=nil
end
i+=1
end
i=0;len=@tiles.length;while i<len
@tiles[i].dispose
@tiles[i]=nil
i+=2
end
i=0;len=@autosprites.length;while i<len
@autosprites[i].dispose
@autosprites[i]=nil
i+=2
end
if @layer0
@layer0.bitmap.dispose if !@layer0.disposed?
@layer0.bitmap=nil if !@layer0.disposed?
@layer0.dispose
@layer0=nil
end
if @flash
@flash.bitmap.dispose if !@flash.disposed?
@flash.bitmap=nil if !@flash.disposed?
@flash.dispose
@flash=nil
end
for i in 0...7
self.autotiles[i]=nil
end
@tiles.clear
@autosprites.clear
@autotileInfo.clear
@regularTileInfo.clear
@tilemap=nil
@tileset=nil
@priorities=nil
@disposed=true
#
end
#--------------------------------------------------------------------------
# * Get if disposed
#--------------------------------------------------------------------------
def disposed?
#
return @disposed
#
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
#
# Refresh and repaint autotiles if changed
if @autotiles.changed
refresh_autotiles
repaintAutotiles
end
#
# Get current zoom settings from Game Map
z_x = $game_map.tilemap_zoom_x
z_y = $game_map.tilemap_zoom_y
#
# Apply zoom settings to layers if zoom settings changed
if @zoom_x != z_x || @zoom_y != z_y
@zoom_x = z_x
@zoom_y = z_y
@layer0.zoom_x = @zoom_x
@layer0.zoom_y = @zoom_y
@priority_need_refresh = true
refresh
end
#
# Refresh the flash and tileset if needed
refresh_flash if @flashChanged
refresh_tileset if @need_refresh
#
# Handle flash opacity if flash present
if @flash
@flash.opacity = FlashOpacity[(Graphics.frame_count/2) % 6]
end
#
# Refresh if anything changed
if !(@oldOx==@ox && @oldOy==@oy && !@need_refresh && !@autotiles.changed)
refresh
end
# Repaint autotiles and refresh based on timed autotiles system
if (Graphics.frame_count % Animated_Autotiles_Frames == 0) || @nowshown
repaintAutotiles
refresh(true)
end
#
# Clear refresh/redraw values
@nowshown = false
@autotiles.changed = false
@need_refresh = false
#
end
#--------------------------------------------------------------------------
# * Set Flash Data
# value : flash data value
#--------------------------------------------------------------------------
def flash_data=(value)
#
@flash_data = value
@flashChanged = true
#
end
#--------------------------------------------------------------------------
# * Set Priorities
# value : priority value
#--------------------------------------------------------------------------
def priorities=(value)
#
@priorities = value
@need_refresh = true
#
end
#--------------------------------------------------------------------------
# * Get if shown
#--------------------------------------------------------------------------
def shown?
#
return false if !@visible
ysize = @map_data.ysize
xsize = @map_data.xsize
xStart = (@ox / 32) - 1
xEnd = ((@ox + @viewport.rect.width) / 32) + 1
yStart = (@oy / 32) - 1
yEnd = ((@oy + @viewport.rect.height) / 32) + 1
xStart = 0 if xStart < 0
xStart = xsize - 1 if xStart >= xsize
xEnd = 0 if xEnd < 0
xEnd = xsize - 1 if xEnd >= xsize
yStart = 0 if yStart < 0
yStart = ysize - 1 if yStart >= ysize
yEnd = 0 if yEnd < 0
yEnd = ysize - 1 if yEnd >= ysize
return (xStart < xEnd && yStart < yEnd)
#
end
#--------------------------------------------------------------------------
# Blit Autotile
# bitmap :
# x :
# y :
# id :
# frame :
#--------------------------------------------------------------------------
def bltAutotile(bitmap,x,y,id,frame)
#
return if frame < 0
autotile = @autotiles[id / 48 - 1]
return if !autotile
if autotile.height == 32
anim = frame * 32
src_rect=Rect.new(anim, 0, 32, 32)
bitmap.blt(x, y, autotile, src_rect)
else
anim = frame * 96
id %= 48
tiles = Autotiles[id>>3][id&7]
src = Rect.new(0,0,0,0)
for i in 0...4
tile_position = tiles[i] - 1
src.set(tile_position % 6 * 16 + anim, tile_position / 6 * 16, 16, 16)
bitmap.blt(i % 2 * 16 + x, i / 2 * 16 + y, autotile, src)
end
end
#
end
#--------------------------------------------------------------------------
# * Autotile Number of Frames
# id : Tile ID
#--------------------------------------------------------------------------
def autotileNumFrames(id)
#
# Acquire autotile
autotile = @autotiles[id/48-1]
# Exit if no autotile or autotile disposed
return 0 if !autotile || autotile.disposed?
# Set frames
frames = 1
# Reset frames based on autotile height
frames = (autotile.height==32) ? (autotile.width/32) : (autotile.width/96)
# Exit method with number of frames
return frames
#
end
#--------------------------------------------------------------------------
# * Autotile Frame (count/rate used in display)
# id : Tile ID
#--------------------------------------------------------------------------
def autotileFrame(id)
#
# Acquire autotile
autotile = @autotiles[id/48-1]
# Exit if no autotile or autotile disposed
return -1 if !autotile || autotile.disposed?
# Set frames
frames = 1
# Reset frames based on autotile height
frames = (autotile.height==32) ? (autotile.width/32) : (autotile.width/96)
# Exit method with autotile frame
return (Graphics.frame_count/Animated_Autotiles_Frames)%frames
#
end
#--------------------------------------------------------------------------
# * Repaint Autotiles
#--------------------------------------------------------------------------
def repaintAutotiles
#
# Cycle through autotile information
for i in 0...@autotileInfo.length
next if !@autotileInfo[i] # Skip if no autotile data
frame = autotileFrame(i) # Acquire frame
bltAutotile(@autotileInfo[i],0,0,i,frame) # Blit current autotile
end
#
end
#--------------------------------------------------------------------------
# * Get Autotile Tile
# sprite : Map sprite
# id : Tile ID
#--------------------------------------------------------------------------
def getAutotile(sprite,id)
#
# Get Autotile data
anim = autotileFrame(id) # Get if it is animated
return if anim < 0 # Exit if anim flag below 0
bitmap = @autotileInfo[id] # Get bitmap from autotile data
#
# If no autotile bitmap
if !bitmap
bitmap = Bitmap.new(32,32) # Define a 32x32 bitmap
bltAutotile(bitmap, 0, 0, id, anim) # Blit the autotile
@autotileInfo[id] = bitmap # Apply to autotile data
end
#
# Set the bitmap to the sprite if sprite bitmap doesn't match
sprite.bitmap=bitmap if !sprite.equal?(bitmap) || sprite.bitmap!=bitmap
#
end
#--------------------------------------------------------------------------
# * Get Regular Tile
# sprite : Map sprite
# id : Tile ID
#--------------------------------------------------------------------------
def getRegularTile(sprite, id)
#
if false
# Get empty sprite if bitmap doesn't match tileset
if !sprite.equal?(@tileset) || sprite.bitmap != @tileset
sprite.bitmap
end
# Get the sprite tile
sprite.src_rect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
#
else
#
# Get the bitmap for a tile
bitmap = @regularTileInfo[id]
# If there's no bitmap
if !bitmap
# Creae an empty 32x32 bitmap
bitmap = Bitmap.new(32,32)
# Define which tile from the tileset to use
rect = Rect.new((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
# Apply the tileset tile to the bitmap
bitmap.blt(0,0,@tileset,rect)
# Set the bitmap
@regularTileInfo[id] = bitmap
end
# Set the bitmap to the sprite if sprite bitmap doesn't match
sprite.bitmap=bitmap if !sprite.equal?(bitmap) || sprite.bitmap!=bitmap
#
end
#
end
#--------------------------------------------------------------------------
# * Add the tiles
# tiles :
# count :
# xpos :
# y_pos :
# id :
# prio_star :
#--------------------------------------------------------------------------
def addTile(tiles, count, xpos, ypos, id, prio_star = false)
#
#
tile_z = 32 * @zoom_y
#
# As lon
if id >= 384
#
if count >= tiles.length
sprite = Sprite.new(@viewport)
tiles.push(sprite,0)
else
sprite=tiles[count]
tiles[count+1] = 0
end
# Adjust position by zcale and position sprite
xpos *= @zoom_x
ypos *= @zoom_y
sprite.x = xpos
sprite.y = ypos
# Increase by 1/20th beyond scale for odd tile separation
sprite.zoom_x = (@zoom_x + 0.05)
sprite.zoom_y = (@zoom_y + 0.05)
#
# Get Priority from ID
prio = @priorities[id]
getRegularTile(sprite,id)
#
# Define z-Depth based on pririty
spriteZ = (prio==0||!prio) ? 0 : ypos + prio * tile_z + tile_z
sprite.z = spriteZ
# Make Visible
sprite.visible = @visible
# Add to count
count += 2
#
# If
else
#
if count >= tiles.length
sprite = Sprite.new(@viewport)
tiles.push(sprite,1)
else
sprite = tiles[count]
tiles[count+1] = 1
end
# Adjust position by zcale and position sprite
xpos *= @zoom_x
ypos *= @zoom_y
sprite.x = xpos
sprite.y = ypos
# Increase by 1/20th beyond scale for odd tile separation
sprite.zoom_x = (@zoom_x + 0.05)
sprite.zoom_y = (@zoom_y + 0.05)
#
# Get Priority from ID
prio = @priorities[id]
#
getAutotile(sprite,id)
#
# Define z-Depth based on pririty
spriteZ = (prio==0||!prio) ? 0 : ypos + prio * tile_z + tile_z
sprite.z = spriteZ
# Make Visible
sprite.visible = @visible
# Add to count
count += 2
#
end
#
# Exit with count
return count
#
end
#--------------------------------------------------------------------------
# * Refresh the tileset
#--------------------------------------------------------------------------
def refresh_tileset
#
# Initialize the sort index and length of tile data
i = 0
len = @regularTileInfo.length
#
# Sort throught and dispose all tilemap data
while i < len
if @regularTileInfo[i]
@regularTileInfo[i].dispose
@regularTileInfo[i]=nil
end
# Increase index by 1
i+=1
end
#
# Clear tiledata
@regularTileInfo.clear
@priotiles.clear
#
# Get map dimensions
ysize = @map_data.ysize
xsize = @map_data.xsize
zsize = @map_data.zsize
#
# Exit with no refresh if x or y sizes exceed 100
return @fullyrefreshed = false if xsize > 100 || ysize > 100
#
# Cycle through all map dimensions
for z in 0...zsize # 0 1 2 layer
for y in 0...ysize
for x in 0...xsize
# Get tile ID
id = @map_data[x, y, z]
# Skip if no tile no valid priority above 0
next if id == 0 || !@priorities[id]
next if @priorities[id] == 0
# Push Priority for map data
@priotiles.push( [x, y, z, id] )
end
end
end
#
# Set refresh tilemap flag
@fullyrefreshed = true
#
end
#--------------------------------------------------------------------------
# * Refresh Flash
#--------------------------------------------------------------------------
def refresh_flash
#
# If flash data exists but no flash
if @flash_data && !@flash
#
@flash = Sprite.new(viewport) # Create the sprite
@flash.visible = true # Show the sprite
@flash.z = 1 # Set its depth
@flash.blend_type = 1 # Set its blend
bm_width = @viewport.rect.width * 2 # Calc the bitmap size
bm_height = @viewport.rect.height * 2 #
@flash.bitmap = Bitmap.new(bm_width, bm_height) # Make the bitmap
@flash.zoom_x = @zoom_x # Set the flash scale
@flash.zoom_y = @zoom_y #
@firsttimeflash = true # Set the flash flag
#
# Or if flash but no flash data
elsif !@flash_data && @flash
#
@flash.bitmap.dispose if @flash.bitmap # Clear the bitmap
@flash.dispose # Erase the sprite
@flash = nil # Nil the sprite
@firsttimeflash = false # Clear the flag
#
end
#
end
#--------------------------------------------------------------------------
# * Refresh Autotiles
#--------------------------------------------------------------------------
def refresh_autotiles
#
# Initialize the sort index and length of autotile data
i = 0
len = @autotileInfo.length
#
# Sort throught and dispose all autotile data
while i < len
if @autotileInfo[i]
@autotileInfo[i].dispose
@autotileInfo[i] = nil
end
# Increase index by 1
i += 1
end
#
# Initialize the sort index and length of autotile sprites
i = 0
len = @autosprites.length
#
# Sort throught and dispose all autotile sprites
while i<len
if @autosprites[i]
@autosprites[i].dispose
@autosprites[i] = nil
end
# Increase index by 2
i += 2
end
#
# Clear autotile data
@autosprites.clear
@autotileInfo.clear
@prioautotiles.clear
#
# Set animated flag false
hasanimated = false
#
# Cycle through the 8 autotiles
for i in 0...7
numframes = autotileNumFrames(48*(i+1))
hasanimated = true if numframes >= 2
@framecount[i] = numframes
end
#
# Exit with test for autotile search if animated
return refresh_autotiles_search if hasanimated
# Set refresh autotile flag
@fullyrefreshedautos=true
#
end
#--------------------------------------------------------------------------
# * Refresh Autotiles Map Search
#--------------------------------------------------------------------------
def refresh_autotiles_search
#
# Get map dimensions
ysize = @map_data.ysize
xsize = @map_data.xsize
zsize = @map_data.zsize
#
# Exit with autotile refresh flag if x or y sizes exceed 100
if xsize > 100 || ysize > 100
@fullyrefreshedautos = false
return
end
#
# Cycle through flat map
for y in 0...ysize
for x in 0...xsize
# Assume no autotile
haveautotile = false
# Cycle through map depths
for z in 0...zsize
# Get tile ID
id = @map_data[x, y, z]
# Skip if no autotile or no valid 0 priority
next if id==0 || id>=384 || @priorities[id] != 0 || !@priorities[id]
# Skip based on frame count
next if @framecount[id/48-1] < 2
# Set autotile flag and break from depth loop
haveautotile = true
break
end
# Push into priority autotile array if found
@prioautotiles.push([x,y]) if haveautotile
end
end
# Set refresh autotile flag
@fullyrefreshedautos = true
#
end
#--------------------------------------------------------------------------
# * Set Map Data
# value : map data
#--------------------------------------------------------------------------
def map_data=(value)
#
@map_data = value # Apply new map data to tilemap
@need_refresh = true # Set refresh variaable
#
end
#--------------------------------------------------------------------------
# * Refresh Flash Sprite
#--------------------------------------------------------------------------
def refreshFlashSprite
#
# Exit if no flash or no flash data
return if !@flash || @flash_data.nil?
#
#
ptX = @ox - @oxFlash
ptY = @oy - @oyFlash
#
#
if !@firsttimeflash && !@usedsprites &&
ptX>=0 && ptX+@viewport.rect.width<=@flash.bitmap.width &&
ptY>=0 && ptY+@viewport.rect.height<=@flash.bitmap.height
@flash.ox = 0
@flash.oy = 0
@flash.src_rect.set(ptX.round,ptY.round,
@viewport.rect.width,@viewport.rect.height)
return
end
#
#
width = @flash.bitmap.width
height = @flash.bitmap.height
bitmap = @flash.bitmap
ysize = @map_data.ysize
xsize = @map_data.xsize
zsize = @map_data.zsize
@firsttimeflash = false
@oxFlash = @ox - (width>>2)
@oyFlash = @oy - (height>>2)
@flash.ox = 0
@flash.oy = 0
#
#
@flash.src_rect.set(width>>2,height>>2,
@viewport.rect.width,@viewport.rect.height)
@flash.bitmap.clear
#
@oxFlash = @oxFlash.floor
@oyFlash = @oyFlash.floor
xStart = (@oxFlash>>5)
yStart = (@oyFlash>>5)
xStart = 0 if xStart < 0
yStart = 0 if yStart < 0
xEnd = xStart + (width>>5)+1
yEnd = yStart + (height>>5)+1
xEnd = xsize if xEnd >= xsize
yEnd = ysize if yEnd >= ysize
#
# As long as ranges increase from start to end
if xStart < xEnd && yStart < yEnd
# Get the ranges
yrange = yStart...yEnd
xrange = xStart...xEnd
tmpcolor = Color.new(0,0,0,0)
# Sort through ranges and get x/y positions
for y in yrange
ypos = (y<<5) - @oyFlash
for x in xrange
xpos = (x<<5) - @oxFlash
# Get data
id = @flash_data[x, y, 0]
# process RGB and fill flash bitmap with color
r = (id>>8) & 15
g = (id>>4) & 15
b = (id) & 15
tmpcolor.set(r*16, g*16, b*16)
bitmap.fill_rect(xpos, ypos, 32, 32, tmpcolor)
end
end
end
#
end
#--------------------------------------------------------------------------
# * Refresh Layer 0
# autotiles : autotile flag
#--------------------------------------------------------------------------
def refreshLayer0(autotiles=false)
#
# acquire x/y position based on origin and layer
ptX = @ox - @oxLayer0
ptY = @oy - @oyLayer0
#
# if no autotiles,
if !autotiles && !@firsttime && !@usedsprites &&
ptX >= 0 && ptX+@viewport.rect.width <= @layer0.bitmap.width &&
ptY >= 0 && ptY+@viewport.rect.height <= @layer0.bitmap.height
# Blit into the layer based on the clip
if @layer0clip
@layer0.ox=0
@layer0.oy=0
@layer0.src_rect.set(ptX.round,ptY.round,
@viewport.rect.width,@viewport.rect.height)
else
@layer0.ox=ptX.round
@layer0.oy=ptY.round
@layer0.src_rect.set(0,0,@layer0.bitmap.width,@layer0.bitmap.height)
end
# Exit the method true
return true
end
#
# Get map dimensions and bitmap
width = @layer0.bitmap.width
height = @layer0.bitmap.height
bitmap = @layer0.bitmap
ysize = @map_data.ysize
xsize = @map_data.xsize
zsize = @map_data.zsize
#
# If autotiles
if autotiles
# Exit if autotiles refreshed, priority length at 0 and not shown
return true if @fullyrefreshedautos && @prioautotiles.length == 0
return true if !shown?
# Set start and end ranges
xStart = (@oxLayer0>>5)
xStart = 0 if xStart<0
yStart = (@oyLayer0>>5)
yStart = 0 if yStart<0
xEnd = xStart+(width>>5)+1
yEnd = yStart+(height>>5)+1
xEnd = xsize if xEnd>xsize
yEnd = ysize if yEnd>ysize
#
# Exit true based on start/end range
return true if xStart>=xEnd || yStart>=yEnd
#
# Get transparencey colorand set rectacle areas
trans = Color.new(0,0,0,0)
temprect = Rect.new(0,0,0,0)
tilerect = Rect.new(0,0,32,32)
#
# Set range and reset counts
range = 0...zsize
overallcount = 0
count = 0
# If auto not fully refreshed
if !@fullyrefreshedautos
# Sort through x and y ranges
for y in yStart..yEnd
for x in xStart..xEnd
# Assume no autotile
haveautotile=false
# Sort through depth
for z in range
# Get tile ID
id = @map_data[x, y, z]
# skip if (take your choice!!!!)
next if id < 48 || id >= 384
next if @priorities[id] != 0 || !@priorities[id]
next if @framecount[id/48-1] < 2
# Break after finding autotile
haveautotile = true
break
end
# skip if still no autotile
next if !haveautotile
# increase overall count
overallcount += 1
# Get area range
xpos = (x<<5) - @oxLayer0
ypos = (y<<5) - @oyLayer0
# Fill the area if count is less than 2000
bitmap.fill_rect(xpos, ypos, 0, 0, trans) if overallcount <= 2000
# Sort within range
for z in range
# Get map data
id = @map_data[x,y,z]
next if id<48 || @priorities[id]!=0 || !@priorities[id]
if overallcount>2000
count=addTile(@autosprites, count, xpos, ypos, id)
next
elsif id>=384
temprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
bitmap.blt(xpos,ypos,@tileset,temprect)
else
# get the bitmap
tilebitmap = @autotileInfo[id]
# If it does not exist
if !tilebitmap
# determine animation
anim = autotileFrame(id)
# Exit if no animation
next if anim < 0
# create a blank tile bitmap
tilebitmap = Bitmap.new(32,32)
# blit into position
bltAutotile(tilebitmap, 0, 0, id, anim)
# Save the bitmap into the autotile
@autotileInfo[id] = tilebitmap
end
# blit in area range
bitmap.blt(xpos, ypos, tilebitmap, tilerect)
#
end
end
end
end
else
#
# Cycle through tiles in autotile priorities
for tile in @prioautotiles
# get tile coordinates
x = tile[0]
y = tile[1]
# Skip if out of range
next if x < xStart || x > xEnd
next if y < yStart || y > yEnd
#
# Increase overall count
overallcount+=1
#
# Calculate position
xpos = (x<<5) - @oxLayer0
ypos = (y<<5) - @oyLayer0
#
# Fill the are transparent if count not yet reached 2000
bitmap.fill_rect(xpos,ypos,0,0,trans) if overallcount <= 2000
#
for z in range
# Get map data
id = @map_data[x,y,z]
#
next if id < 48 || @priorities[id] != 0 || !@priorities[id]
# Define count and break from depth loop if count exceeds 2000
if overallcount > 2000
count = addTile(@autosprites, count, xpos, ypos, id)
next
# Or blit tile if not an autotile
elsif id >= 384
temprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
bitmap.blt(xpos,ypos,@tileset,temprect)
# Otherwise handle autotile
else
tilebitmap = @autotileInfo[id]
if !tilebitmap
anim = autotileFrame(id)
next if anim<0
tilebitmap = Bitmap.new(32,32)
bltAutotile(tilebitmap,0,0,id,anim)
@autotileInfo[id] = tilebitmap
end
# Blit into the bitmap
bitmap.blt(xpos, ypos, tilebitmap, tilerect)
end
end
end
#
end
#
# Frame update when count reaches 2000
Graphics.frame_reset if overallcount>2000
# Reset flag and exit method
@usedsprites = false
return true
#
end
#
# Exit method false if
return false if @usedsprites
#
@firsttime = false
@oxLayer0 = @ox - (width>>2)
@oyLayer0 = @oy - (height>>2)
if @layer0clip
@layer0.ox = 0
@layer0.oy = 0
@layer0.src_rect.set(width>>2,height>>2,
@viewport.rect.width,@viewport.rect.height)
else
@layer0.ox = (width>>2)
@layer0.oy = (height>>2)
end
#
# Clear the layer bitmap
@layer0.bitmap.clear
# Re-acquire layer ranges
@oxLayer0 = @oxLayer0.floor
@oyLayer0 = @oyLayer0.floor
xStart = (@oxLayer0>>5)
yStart = (@oyLayer0>>5)
xStart = 0 if xStart < 0
yStart = 0 if yStart < 0
xEnd = xStart + (width>>5) + 1
yEnd = yStart + (height>>5) + 1
xEnd = xsize if xEnd >= xsize
yEnd = ysize if yEnd >= ysize
#
# As long as a valid range from start to end
if xStart < xEnd && yStart < yEnd
#
# reset the temp rectangle and set ranges
tmprect = Rect.new(0,0,0,0)
yrange = yStart...yEnd
xrange = xStart...xEnd
#
# Cycle through depth
for z in 0...zsize
for y in yrange
ypos = (y<<5) - @oyLayer0
for x in xrange
xpos = (x<<5) - @oxLayer0
# Get the tile data
id = @map_data[x, y, z]
# Skip if no valid data or not at 0 priority
next if id==0 || @priorities[id] != 0 || !@priorities[id]
# If a normal tile
if id >= 384
# Set and blit the proper tile in place
tmprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
bitmap.blt(xpos,ypos,@tileset,tmprect)
# otherwise handle autotile
else
frame=autotileFrame(id)
bltAutotile(bitmap,xpos,ypos,id,frame)
end
end
end
end
#
Graphics.frame_reset
end
#
return true
#
end
#--------------------------------------------------------------------------
# * Get Resize Factor
# -- Depreciated (Not used in script at time of acquisition)
#--------------------------------------------------------------------------
def getResizeFactor
#return $game_map.tilemap_zoom_x
##return $ResizeFactor ? $ResizeFactor : 1.0
end
#--------------------------------------------------------------------------
# * Set Visibility
# val : value
#--------------------------------------------------------------------------
def visible=(val)
#
wasshown = @visible
@visible = val
@nowshown = (!wasshown && val)
#
end
end
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles the map. It includes scrolling and passable determining
# functions. Refer to "$game_map" for the instance of this class.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :map # Current tile
attr_accessor :tilemap_tone # Current tone
attr_accessor :tilemap_plane # Current plane
attr_accessor :tilemap_zoom_x # Current scale (allows x stretching)
attr_accessor :tilemap_zoom_y # Current scale (allows y stretching)
attr_accessor :tilemap_tile_width # Current tile width (usually 32px)
attr_accessor :tilemap_tile_height # Current tile height (usually 32px)
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias seph_orig_game_map_tilemapnew_initialize initialize
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
#
# Perform the original method
seph_orig_game_map_tilemapnew_initialize
#
# Add new values for tilemap zoom
@tilemap_tone = nil
@tilemap_plane = false
@tilemap_zoom_x = 1.0
@tilemap_zoom_y = 1.0
@tilemap_tile_width = 32
@tilemap_tile_height = 32
#
end
end
Instructions
Plenty, and in the script.
FAQ
Made in conjunction with Screen Size for RMXP and Poccil's Map Zoom.
I was looking for a Tilemap script that could be adapted with a Zoom Map script... any zoom map script. And this one was the most complete that could cover all three map layers and properly worked with tilemap priorities.
The original script can be found in the 3rd post of (THIS) thread.
Compatibility
Designed for RPGMaker XP. RUBY 2.7 Compliant
Credits and Thanks
Obviously, thanks to Poccil for the original work.
Terms and Conditions
Free for use, even in commercial work. However, due credit to both Poccil and myself is required.
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)
Above are clickable links