07-05-2011, 09:59 PM
The New Mode 7 script doesn't handle zoom features, mainly because it may lag more than with NeoM7 and HM7 scripts.
But if you really want to try it, I made a small add-on :
- first upgrade your NM7 script to the latest version (24/04/2008) : New Mode 7
- then paste the following script below :
To apply a new zoom level (in percentage - default = 100), use in an event :
$scene.spriteset.tilemap.set_zoom(new value)
Or you can zoom progressively into a new zoom level with :
$scene.spriteset.tilemap.to_zoom(value, speed)
But if you really want to try it, I made a small add-on :
- first upgrade your NM7 script to the latest version (24/04/2008) : New Mode 7
- then paste the following script below :
script
Code:
#============================================================================
# Add-on for the New Mode 7 script (24/04/08), to handle zoom in and zoom out
# V.1.0 - 05/07/2011
# Author : MGC
# Must be pasted below the New Mode 7 script and above main
#============================================================================
#- To set a new zoom level (in percentage - default = 100) :
# $scene.spriteset.tilemap.set_zoom(new value)
#- To slide progressively into a new zoom level :
# $scene.spriteset.tilemap.to_zoom(value, speed)
#============================================================================
#============================================================================
# ** Game_System
#============================================================================
class Game_System
attr_accessor :zoom
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_nm7_zoom
alias initialize_nm7_zoom_game_system initialize
@already_aliased_nm7_zoom = true
end
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
self.zoom = 1.0
initialize_nm7_zoom_game_system
end
end
#============================================================================
# ** Tilemap_mode7
#============================================================================
class Tilemap_mode7
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_nm7_zoom
alias initialize_nm7_zoom_tilemap initialize
@already_aliased_nm7_zoom = true
end
#--------------------------------------------------------------------------
# * Object Initialization
# viewport : viewport
#--------------------------------------------------------------------------
def initialize(viewport, spriteset)
@sprites = [] # list of the scanlines sprites (Sprite)
@sprites_loop_x = [] # list of the additionnal sprites (for X-looping)
@target_value = 100 * $game_system.zoom
@target_speed = 20
initialize_nm7_zoom_tilemap(viewport, spriteset)
end
#--------------------------------------------------------------------------
# * Increase (or decrease) the zoom level
#--------------------------------------------------------------------------
def increase_zoom(speed)
speed = speed.to_f / 100
$game_system.zoom = ([[100 * $game_system.zoom *
(2 ** speed), 500].min, 1].max).to_f / 100
init_sprites(@angle)
end
#--------------------------------------------------------------------------
# * Set the zoom level
#--------------------------------------------------------------------------
def set_zoom(value)
$game_system.zoom = ([[value, 500].min, 1].max).to_f / 100
@target_value = 100 * $game_system.zoom
init_sprites(@angle)
end
#--------------------------------------------------------------------------
# * Launch the slide from the current zoom level into the target value
#--------------------------------------------------------------------------
def to_zoom(value, speed)
@target_value = [[value, 500].min, 1].max
@target_speed = speed
end
#--------------------------------------------------------------------------
# * Update the slide from the current zoom level into the target value
#--------------------------------------------------------------------------
def update_zoom
if @target_value > 100 * $game_system.zoom
increase_zoom(@target_speed)
if @target_value < 100 * $game_system.zoom
set_zoom(@target_value)
end
elsif @target_value < 100 * $game_system.zoom
increase_zoom(-@target_speed)
if @target_value > 100 * $game_system.zoom
set_zoom(@target_value)
end
end
end
#--------------------------------------------------------------------------
# * Increase slant angle
#--------------------------------------------------------------------------
def increase_angle
if @angle == 88 then return end
@angle = [@angle + 2, 88].min # angle value between 0 and 88 degrees
init_sprites(@angle) # reinitialize screenlines sprites
end
#--------------------------------------------------------------------------
# * Decrease slant angle
#--------------------------------------------------------------------------
def decrease_angle
if @angle == 0 then return end
@angle = [@angle - 2, 0].max # angle value between 0 and 88 degrees
init_sprites(@angle) # reinitialize screenlines sprites
end
#--------------------------------------------------------------------------
# * Redraw the map instantaneously with the new slant angle value
# value : target angle value (in degree)
#--------------------------------------------------------------------------
def mode7_set(value)
@angle = [[value, 0].max, 89].min
init_sprites(@angle) # reinitialize screenlines sprites
update
Graphics.update
end
#--------------------------------------------------------------------------
# * Reinitialize screenlines sprites
#--------------------------------------------------------------------------
def mode7_redraw
init_sprites(@angle) # reinitialize scanlines
update
Graphics.update
end
#--------------------------------------------------------------------------
# * Create sprites equivalent to scanlines
# value : target angle value (in degree)
#--------------------------------------------------------------------------
def init_sprites(angle)
(@sprites + @sprites_loop_x).each{|sprite| sprite.dispose}
@sprites.clear
@sprites_loop_x.clear
@horizon = ($game_system.horizon * $game_system.zoom).to_i
angle_rad = (Math::PI * angle) / 180 # angle in radian
cos_angle = Math.cos(angle_rad)
sin_angle = Math.sin(angle_rad)
# save values in $game_temp
$game_temp.distance_h = @distance_h
$game_temp.pivot = @pivot
$game_temp.cos_angle = cos_angle
$game_temp.sin_angle = sin_angle
# h0, z0 : intermediate values
h0 = (- @distance_h * @pivot * cos_angle).to_f /
(@distance_h + @pivot * sin_angle) + @pivot
z0 = @distance_h.to_f / (@distance_h + @pivot * sin_angle)
$game_temp.slope_value = (1.0 - z0) / (@pivot - h0)
$game_temp.corrective_value = 1.0 - @pivot * $game_temp.slope_value
last_line = - @pivot - @horizon # last_line : the highest line that is drawn
height_limit = (@distance_h * last_line * cos_angle).to_f /
(@distance_h - last_line * sin_angle) + @pivot # the line corresponding to
# the last_line in the warped reference = horizon's line
$game_temp.height_limit = height_limit
# constant to handle gradual opacity
k2lim = ((@distance_h * last_line).to_f /
(@distance_h * cos_angle + last_line * sin_angle)).to_i
# one sprite is created for each screenline
for j in 0..479
next if j < height_limit # if the line is further than the horizon's line,
# no sprite is created
i = j - @pivot # y-reference is the pivot's line
sprite = Sprite.new(@viewport)
sprite.x = 320 # x-reference is the vertical line in the middle of the screen
sprite.y = j
sprite.z = - 99999 # map must not mask vertical elements
sprite.y_origin_bitmap = (@distance_h * i).to_f /
((@distance_h * cos_angle + i * sin_angle) * $game_system.zoom) + @pivot
sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap + 0.5).to_i
sprite.y_origin_bitmap_i %= @height if $game_system.loop_y
sprite.zoom_x = ($game_temp.slope_value * j + $game_temp.corrective_value) * $game_system.zoom
sprite.length = 2 + (640.to_f / sprite.zoom_x).to_i
sprite.x_origin_bitmap_i = ((642 - sprite.length) / 2)
sprite.x_origin_bitmap_i %= @width if $game_system.loop_x
sprite.x_origin_bitmap = (sprite.x_origin_bitmap_i).to_f
sprite.ox = sprite.length / 2
sprite.bitmap = @map
# horizontal translation to center around the hero
if @disp_x != 0
sprite.x_origin_bitmap += @disp_x / 4
sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i
sprite.x_origin_bitmap_i %= @width if $game_system.loop_x
end
# vertical translation to center around the hero
if @disp_y != 0
sprite.y_origin_bitmap += @disp_y / 4
sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap + 0.5).to_i
sprite.y_origin_bitmap_i %= @height if $game_system.loop_y
end
# handle opacity and tone
k2 = ((@distance_h * i).to_f /
(@distance_h * cos_angle + i * sin_angle)).to_i
k2 = 0 if k2 > 0
k_red = (- k2.to_f/k2lim * $game_system.map_gradual_tone.red).to_i
k_green = (- k2.to_f/k2lim * $game_system.map_gradual_tone.green).to_i
k_blue = (- k2.to_f/k2lim * $game_system.map_gradual_tone.blue).to_i
k_gray = (- k2.to_f/k2lim * $game_system.map_gradual_tone.gray).to_i
k2 = (- k2.to_f/k2lim * $game_system.map_gradual_opacity).to_i
sprite.tone = Tone.new(k_red, k_green, k_blue, k_gray)
sprite.opacity = 255 - k2
sprite.opacity *= ($game_system.map_opacity).to_f / 255
sprite.color = $game_system.map_tone
# white horizon's line
k = j - height_limit
k = 500 / k
if $game_system.white_horizon
tone_red = sprite.tone.red + k
tone_green = sprite.tone.green + k
tone_blue = sprite.tone.blue + k
tone_gray = sprite.tone.gray + k
sprite.tone = Tone.new(tone_red, tone_green, tone_blue, tone_gray)
end
@tone_values[j] = sprite.tone
@opacity_values[j] = sprite.opacity
# set sprite's graphics
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
@sprites.push(sprite)
if $game_system.loop_x and j < @pivot
# additional sprite to handle horizontal looping
sprite2 = Sprite.new(@viewport)
sprite2.x = 320
sprite2.y = j
sprite2.z = - 99999
sprite2.y_origin_bitmap = sprite.y_origin_bitmap
sprite2.y_origin_bitmap_i = sprite.y_origin_bitmap_i
sprite2.zoom_x = sprite.zoom_x
sprite2.length = sprite.length
sprite2.x_origin_bitmap_i = sprite.x_origin_bitmap_i - @width
sprite2.x_origin_bitmap = sprite.x_origin_bitmap_i - @width
sprite2.ox = sprite.ox
sprite2.bitmap = @map
sprite2.opacity = sprite.opacity
sprite2.color = sprite.color
sprite2.tone = sprite.tone
sprite2.src_rect.set(sprite2.x_origin_bitmap_i, sprite2.y_origin_bitmap_i,
sprite2.length, 1)
@sprites_loop_x.push(sprite2)
end
end
end
#--------------------------------------------------------------------------
# * Update the screenlines sprites and the vertical sprites
# compare tilemap's display with map's display
#--------------------------------------------------------------------------
def update
update_zoom
# update screenlines sprites
if @disp_y < $game_map.display_y
difference = $game_map.display_y - @disp_y
@disp_y += difference
for sprite in @sprites + @sprites_loop_x
sprite.y_origin_bitmap += difference.to_f / 4
sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap+0.5).to_i
sprite.y_origin_bitmap_i %= @height if $game_system.loop_y
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
end
end
if @disp_y > $game_map.display_y
difference = @disp_y - $game_map.display_y
@disp_y -= difference
for sprite in @sprites + @sprites_loop_x
sprite.y_origin_bitmap -= difference.to_f / 4
sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap+0.5).to_i
sprite.y_origin_bitmap_i %= @height if $game_system.loop_y
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
end
end
if @disp_x < $game_map.display_x
difference = $game_map.display_x - @disp_x
@disp_x += difference
for sprite in @sprites
sprite.x_origin_bitmap += difference.to_f / 4
sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i
sprite.x_origin_bitmap_i %= @width if $game_system.loop_x
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
end
for sprite in @sprites_loop_x
sprite.x_origin_bitmap += difference.to_f / 4
sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i
sprite.x_origin_bitmap_i %= @width
sprite.x_origin_bitmap_i -= @width
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
end
end
if @disp_x > $game_map.display_x
difference = @disp_x - $game_map.display_x
@disp_x -= difference
for sprite in @sprites
sprite.x_origin_bitmap -= difference.to_f / 4
sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i
sprite.x_origin_bitmap_i %= @width if $game_system.loop_x
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
end
for sprite in @sprites_loop_x
sprite.x_origin_bitmap -= difference.to_f / 4
sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i
sprite.x_origin_bitmap_i %= @width
sprite.x_origin_bitmap_i -= @width
sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,
sprite.length, 1)
end
end
# update vertical sprites
for sprite in @sprites_V
sprite.update
end
end
end
#============================================================================
# ** Sprite_Character
#============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update
if !$game_system.mode7
update_mode7_sprite_character
return
end
if @flat_indicator
if (!@character.flat or @character.moving? or
@tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue)
@flat_indicator = @character.flat
# redraw the original ground
maps_list = $scene.spriteset.tilemap.maps_list
map_ground = $scene.spriteset.tilemap.map_ground
rect = Rect.new(@flat_x_map, @flat_y_map, @flat_width, @flat_height)
for map in maps_list
map.blt(@flat_x_map, @flat_y_map, map_ground, rect)
if $game_system.loop_x and @flat_x_map.between?(0, 19 * 32)
map.blt(@flat_x_map + 32 * $game_map.width, @flat_y_map, map_ground,
rect)
end
end
else
return
end
end
super
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
# pivot correction (intersection between the map and this sprite)
self.oy -= 4
end
end
self.visible = (not @character.transparent)
if @tile_id == 0
sx = @character.pattern * @cw
sy = (@character.direction - 2) / 2 * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
if @character.flat # event must be flat drawn
return if $scene.spriteset == nil
if @tile_id == 0
@flat_x_map = @character.real_x / 4 - (@cw - 32) / 2
@flat_y_map = @character.real_y / 4 - @ch + 32
@flat_x0 = sx
@flat_y0 = sy
@flat_width = @cw
@flat_height = @ch
else
@flat_x_map = @character.real_x / 4
@flat_y_map = @character.real_y / 4
@flat_x0 = 0
@flat_y0 = 0
@flat_width = 32
@flat_height = 32
end
# modify the maps graphics
maps_list = $scene.spriteset.tilemap.maps_list
rect = Rect.new(@flat_x0, @flat_y0, @flat_width, @flat_height)
for map in maps_list
map.blt(@flat_x_map, @flat_y_map, bitmap, rect, @character.opacity)
if $game_system.loop_x and @flat_x_map.between?(0, 19 * 32)
map.blt(@flat_x_map + 32 * $game_map.width, @flat_y_map, bitmap, rect,
@character.opacity)
end
end
@flat_indicator = true
self.opacity = 0
return
end
x_intermediate = @character.screen_x
y_intermediate = @character.screen_y
y_intermediate -= $game_temp.pivot + 4 if $game_system.mode7
# if vertical looping
if $game_system.loop_y
h = 32 * $game_map.height
y_intermediate = (y_intermediate + h / 2) % h - h / 2
end
# coordinates in a mode7 map
self.y = (($game_temp.distance_h * y_intermediate *
$game_temp.cos_angle * $game_system.zoom).to_f / ($game_temp.distance_h - y_intermediate *
$game_temp.sin_angle * $game_system.zoom) + $game_temp.pivot)
self.zoom_x = ($game_temp.slope_value * y + $game_temp.corrective_value) * $game_system.zoom
self.zoom_y = zoom_x
self.x = 320 + zoom_x * (x_intermediate - 320)
# if horizontal looping
if $game_system.loop_x
offset = ($game_map.width >= 24 ? 64 * zoom_x : 0)
l = 32 * $game_map.width * zoom_x
self.x = (x + offset) % l - offset
end
if @character.is_a?(Game_Player)
# Overworld Sprite Resize
if $game_system.ov
self.zoom_x *= $game_system.ov_zoom
self.zoom_y *= $game_system.ov_zoom
end
end
self.z = @character.screen_z(@ch)
# hide the sprite if it is beyond the horizon's line
self.opacity = (y < $game_temp.height_limit ? 0 : @character.opacity)
self.y -= 32 * @character.height * zoom_y # height correction
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
end
#============================================================================
# ** Sprite_V (Vertical Sprites)
#============================================================================
class Sprite_V < Sprite
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update
square_y_corrected = square_y
y_intermediate = 32 * y_map - $game_temp.pivot - $game_map.display_y / 4
y_intermediate_reference = y_intermediate
# if vertical looping
if $game_system.loop_y
y_intermediate = (y_intermediate + $game_temp.height / 2) %
$game_temp.height - $game_temp.height / 2
if y_intermediate_reference < y_intermediate
square_y_corrected = square_y + $game_map.height
elsif y_intermediate_reference > y_intermediate
square_y_corrected = square_y - $game_map.height
end
end
self.y = ($game_temp.distance_h * y_intermediate *
$game_temp.cos_angle * $game_system.zoom).to_f / ($game_temp.distance_h - y_intermediate *
$game_temp.sin_angle * $game_system.zoom) + $game_temp.pivot
if y < $game_temp.height_limit
# hide the sprite if it is beyond the horizon's line
self.opacity = 0
return
end
self.opacity = 255
if $scene.spriteset != nil and $scene.spriteset.tilemap.is_a?(Tilemap_mode7)
opacity_values = $scene.spriteset.tilemap.opacity_values
tone_values = $scene.spriteset.tilemap.tone_values
if opacity_values.has_key?(y)
self.opacity = opacity_values[y]
self.tone = tone_values[y]
end
end
self.zoom_x = ($game_temp.slope_value * y + $game_temp.corrective_value) * $game_system.zoom
self.zoom_y = zoom_x
x_intermediate = 32 * x_map - $game_map.display_x / 4
self.x = 320 + (zoom_x * (x_intermediate - 320))
# if horizontal looping
if $game_system.loop_x
offset = ($game_map.width >= 24 ? 64 * zoom_x : 0)
l = 32 * $game_map.width * self.zoom_x
self.x = (self.x + offset) % l - offset
end
self.z = (128 * square_y_corrected - $game_map.display_y + 3) / 4 +
32 + 32 * priority
return
end
end
To apply a new zoom level (in percentage - default = 100), use in an event :
$scene.spriteset.tilemap.set_zoom(new value)
Or you can zoom progressively into a new zoom level with :
$scene.spriteset.tilemap.to_zoom(value, speed)
Some scripts :
[XP] H-Mode7
[XP] ASBC for ATCBS
[XP] Neo Mode 7 / Neo Mode 7 + / [VX] Import NeoM7 maps
[XP] FPLE / [VX] Import FPLE maps
[Old][XP] Moving Platforms
[Old][XP] New Mode 7
[Old][XP] 2D ISO
[XP] ASBC for ATCBS
[XP] Neo Mode 7 / Neo Mode 7 + / [VX] Import NeoM7 maps
[XP] FPLE / [VX] Import FPLE maps
[Old][XP] Moving Platforms
[Old][XP] New Mode 7
[Old][XP] 2D ISO
Working on :
- H-Mode7 Engine v.1.4
- FPLE 2
- MGC_ISO Engine
- VP Engine
- MKBS
- FPLE 2
- MGC_ISO Engine
- VP Engine
- MKBS