This was basically my try on this, but rounding the value has an obvious collateral problem; you lose "movement resolution"; 3.1 = 3.2, 3.4 = 3.5 ...
Here an example; these charas are walking (Move up) in frequence 6, and their speed is 3.0, 3.2, 3.4, 3.5, 3.6, 3.8 and 4.0
You can see the difference between rounding the value or not.
One possible fix for that would be to round only the player's distance, but the player would still have that lack of "movement resolution".
Someone said me rounding the distance also has some problems on camera if you are using a "smooth-movement" script, but sincerely I didn't check that.
The other possible way to fix this would be to work always with distances directly controlling it's integer instead of the speed as a float. Anyway, I don't like so much this idea...
The character I used on the first image:
http://s9.postimg.org/7i2mp9hzv/character.png==============================
Anyway, I think I already fixed this on my game some months ago, I didn't post it here because I'm not 100% sure but I'll tell what I found ;D
All this fixes try to fit the charas movement with the current screen movement, but the one which is delayed is the screen.
Once, on my game, I tried to display a bitmap layer or a picture over the map and scroll it via script call on parallel process to fit with the map (changing display_x and display_y). The result was laggy, and because of the
3.6 speed of the player, I had the same problem. It had nothing to do with character speed, so I decided to modificate the Game_Map converting to some sort of a smooth-movement script, but "not so smooth". The result is a map scroll practically identical as the default but the picture is displayed well and lag decreases. The annoying bug also disappears. The only problem is the new script is not perfect. For example, on diagonal movement the map is too slow now...
This is the script. I'm pretty sure correcting its bugs, we would fix the problem definitelly:
#==============================================================================
# ** 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_accessor :tileset_name # tileset file name
attr_accessor :autotile_names # autotile file name
attr_accessor :panorama_name # panorama file name
attr_accessor :panorama_hue # panorama hue
attr_accessor :fog_name # fog file name
attr_accessor :fog_hue # fog hue
attr_accessor :fog_opacity # fog opacity level
attr_accessor :fog_blend_type # fog blending method
attr_accessor :fog_zoom # fog zoom rate
attr_accessor :fog_sx # fog sx
attr_accessor :fog_sy # fog sy
attr_accessor :battleback_name # battleback file name
attr_accessor :display_x # display x-coordinate * 128
attr_accessor :display_y # display y-coordinate * 128
attr_accessor :need_refresh # refresh request flag
attr_reader :passages # passage table
attr_reader :priorities # prioroty table
attr_reader :terrain_tags # terrain tag table
attr_reader :events # events
attr_reader :fog_ox # fog x-coordinate starting point
attr_reader :fog_oy # fog y-coordinate starting point
attr_reader :fog_tone # fog color tone
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@map_id = 0
@display_x = 0
@display_y = 0
end
#--------------------------------------------------------------------------
# * Setup
# map_id : map ID
#--------------------------------------------------------------------------
def setup(map_id)
# Put map ID in @map_id memory
@map_id = map_id
# Load map from file and set @map
@map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
# set tile set information in opening instance variables
tileset = $data_tilesets[@map.tileset_id]
@tileset_name = tileset.tileset_name
@autotile_names = tileset.autotile_names
@panorama_name = tileset.panorama_name
@panorama_hue = tileset.panorama_hue
@fog_name = tileset.fog_name
@fog_hue = tileset.fog_hue
@fog_opacity = tileset.fog_opacity
@fog_blend_type = tileset.fog_blend_type
@fog_zoom = tileset.fog_zoom
@fog_sx = tileset.fog_sx
@fog_sy = tileset.fog_sy
@battleback_name = tileset.battleback_name
@passages = tileset.passages
@priorities = tileset.priorities
@terrain_tags = tileset.terrain_tags
# Initialize displayed coordinates
@display_x = 0
@display_y = 0
@scroll_remain_x = 0
@scroll_remain_y = 0
@scroll_take_x = 0
@scroll_take_y = 0
# Clear refresh request flag
@need_refresh = false
# Set map event data
@events = {}
for i in @map.events.keys
@events[i] = Game_Event.new(@map_id, @map.events[i])
end
# Set common event data
@common_events = {}
for i in 1...$data_common_events.size
@common_events[i] = Game_CommonEvent.new(i)
end
# Initialize all fog information
@fog_ox = 0
@fog_oy = 0
@fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0
@fog_opacity_duration = 0
@fog_opacity_target = 0
# Initialize scroll information
@scroll_direction = 2
@scroll_rest = 0
@scroll_speed = 4
end
#--------------------------------------------------------------------------
# * Get Map ID
#--------------------------------------------------------------------------
def map_id
return @map_id
end
#--------------------------------------------------------------------------
# * Get Width
#--------------------------------------------------------------------------
def width
return @map.width
end
#--------------------------------------------------------------------------
# * Get Height
#--------------------------------------------------------------------------
def height
return @map.height
end
#--------------------------------------------------------------------------
# * Get Encounter List
#--------------------------------------------------------------------------
def encounter_list
return @map.encounter_list
end
#--------------------------------------------------------------------------
# * Get Encounter Steps
#--------------------------------------------------------------------------
def encounter_step
return @map.encounter_step
end
#--------------------------------------------------------------------------
# * Get Map Data
#--------------------------------------------------------------------------
def data
return @map.data
end
#--------------------------------------------------------------------------
# * Automatically Change Background Music and Backround Sound
#--------------------------------------------------------------------------
def autoplay
if @map.autoplay_bgm
$game_system.bgm_play(@map.bgm)
end
if @map.autoplay_bgs
$game_system.bgs_play(@map.bgs)
end
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
# If map ID is effective
if @map_id > 0
# Refresh all map events
for event in @events.values
event.refresh
end
# Refresh all common events
for common_event in @common_events.values
common_event.refresh
end
end
# Clear refresh request flag
@need_refresh = false
end
#--------------------------------------------------------------------------
# * Scroll Down
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_down(distance)
if distance > (self.height - 15) * 128 - @display_y - @scroll_remain_y
distance = (self.height - 15) * 128 - @display_y - @scroll_remain_y
end
if scrolling?
@scroll_take_y = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_y = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_y = distance.ceil - distance.ceil % 4
else
@scroll_take_y = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_y += distance
end
#--------------------------------------------------------------------------
# * Scroll Left
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_left(distance)
if distance > @display_x - @scroll_remain_x
distance = @display_x - @scroll_remain_x
end
if scrolling?
@scroll_take_x = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_x = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_x = distance.ceil - distance.ceil % 4
else
@scroll_take_x = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_x -= distance
end
#--------------------------------------------------------------------------
# * Scroll Right
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_right(distance)
if distance > (self.width - 15) * 128 - @display_x - @scroll_remain_x
distance = (self.width - 15) * 128 - @display_x - @scroll_remain_x
end
if scrolling?
@scroll_take_x = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_x = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_x = distance.ceil - distance.ceil % 4
else
@scroll_take_x = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_x += distance
end
#--------------------------------------------------------------------------
# * Scroll Up
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_up(distance)
if distance > @display_y - @scroll_remain_y
distance = @display_y - @scroll_remain_y
end
if scrolling?
@scroll_take_y = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_y = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_y = distance.ceil - distance.ceil % 4
else
@scroll_take_y = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_y -= distance
end
#--------------------------------------------------------------------------
# * Determine Valid Coordinates
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def valid?(x, y)
return (x >= 0 and x < width and y >= 0 and y < height)
end
#--------------------------------------------------------------------------
# * Determine if Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# self_event : Self (If event is determined passable)
#--------------------------------------------------------------------------
def passable?(x, y, d, self_event = nil)
# If coordinates given are outside of the map
unless valid?(x, y)
# impassable
return false
end
# Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
bit = (1 << (d / 2 - 1)) & 0x0f
# Loop in all events
for event in events.values
# If tiles other than self are consistent with coordinates
if event.tile_id >= 0 and event != self_event and
event.x == x and event.y == y and not event.through
# If obstacle bit is set
if @passages[event.tile_id] & bit != 0
# impassable
return false
# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f
# impassable
return false
# If priorities other than that are 0
elsif @priorities[event.tile_id] == 0
# passable
return true
end
end
end
# Loop searches in order from top of layer
for i in [2, 1, 0]
# Get tile ID
tile_id = data[x, y, i]
# Tile ID acquistion failure
if tile_id == nil
# impassable
return false
# If obstacle bit is set
elsif @passages[tile_id] & bit != 0
# impassable
return false
# If obstacle bit is set in all directions
elsif @passages[tile_id] & 0x0f == 0x0f
# impassable
return false
# If priorities other than that are 0
elsif @priorities[tile_id] == 0
# passable
return true
end
end
# passable
return true
end
#--------------------------------------------------------------------------
# * Determine Thicket
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def bush?(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & 0x40 == 0x40
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# * Determine Counter
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def counter?(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & 0x80 == 0x80
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# * Get Terrain Tag
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def terrain_tag(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return 0
elsif @terrain_tags[tile_id] > 0
return @terrain_tags[tile_id]
end
end
end
return 0
end
#--------------------------------------------------------------------------
# * Get Designated Position Event ID
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def check_event(x, y)
for event in $game_map.events.values
if event.x == x and event.y == y
return event.id
end
end
end
#--------------------------------------------------------------------------
# * Start Scroll
# direction : scroll direction
# distance : scroll distance
# speed : scroll speed
#--------------------------------------------------------------------------
def start_scroll(direction, distance, speed)
@scroll_direction = direction
@scroll_speed = speed
@scroll_rest = distance.ceil * 128
case @scroll_direction
when 2 # Down
scroll_down(@scroll_rest)
when 4 # Left
scroll_left(@scroll_rest)
when 6 # Right
scroll_right(@scroll_rest)
when 8 # Up
scroll_up(@scroll_rest)
end
end
#--------------------------------------------------------------------------
# * Determine if Scrolling
#--------------------------------------------------------------------------
def scrolling?
return @scroll_rest > 0
end
#--------------------------------------------------------------------------
# * Start Changing Fog Color Tone
# tone : color tone
# duration : time
#--------------------------------------------------------------------------
def start_fog_tone_change(tone, duration)
@fog_tone_target = tone.clone
@fog_tone_duration = duration
if @fog_tone_duration == 0
@fog_tone = @fog_tone_target.clone
end
end
#--------------------------------------------------------------------------
# * Start Changing Fog Opacity Level
# opacity : opacity level
# duration : time
#--------------------------------------------------------------------------
def start_fog_opacity_change(opacity, duration)
@fog_opacity_target = opacity * 1.0
@fog_opacity_duration = duration
if @fog_opacity_duration == 0
@fog_opacity = @fog_opacity_target
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Refresh map if necessary
if $game_map.need_refresh
refresh
end
# If scrolling
if @scroll_rest > 0
@scroll_rest -= 2 ** @scroll_speed
end
if @scroll_remain_x > 0
old_display_x = @display_x
distance = [@scroll_take_x, 4].max
unless @display_x + distance > (self.width - 15) * 128
@display_x += distance
end
@scroll_remain_x += old_display_x - @display_x
if @scroll_remain_x < 0
@scroll_remain_x = 0
end
elsif @scroll_remain_x < 0
old_display_x = @display_x
distance = [@scroll_take_x, 4].max
unless @display_x - distance < 0
@display_x -= distance
end
@scroll_remain_x += old_display_x - @display_x
if @scroll_remain_x > 0
@scroll_remain_x = 0
end
end
if @scroll_remain_y > 0
old_display_y = @display_y
distance = [@scroll_take_y, 4].max
unless @display_y + distance > (self.height - 15) * 128
@display_y += distance
end
@scroll_remain_y += old_display_y - @display_y
if @scroll_remain_y < 0
@scroll_remain_y = 0
end
elsif @scroll_remain_y < 0
old_display_y = @display_y
distance = [@scroll_take_y, 4].max
unless @display_y - distance < 0
@display_y -= distance
end
@scroll_remain_y += old_display_y - @display_y
if @scroll_remain_y > 0
@scroll_remain_y = 0
end
end
# Update map event
for event in @events.values
event.update
end
# Update common event
for common_event in @common_events.values
common_event.update
end
# Manage fog scrolling
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
# Manage change in fog color tone
if @fog_tone_duration >= 1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d
@fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d
@fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d
@fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
# Manage change in fog opacity level
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
end
end
end