Drago Pixel Movement
Authors: LiTTleDRAgo
Version: 1.02
Type: Movement Add-on
Key Term: Movement Add-on
IntroductionTitle explain everything
Features
Screenshots(http://i.imgur.com/z9Tlc.png)
ScriptXP Version (http://littledrago.blogspot.com/2013/05/rgss-drg-pixel-movement.html)
VXAce Version (http://littledrago.blogspot.com/2014/08/rgss3-drg-pixel-movement-ace.html)
InstructionsOnly intended for player movement
CompatibilityWill cause problem with other movement script, especially ABS
Not compatible with Blizz ABS
Credits and Thanks
Author's NotesEnjoy ~
Thanks drago! I was trying to find a good clean base to look at and see if I could make it work with my script. I haven't actually looked at it yet, but your scripts are always top quality :D
Edit: Just looked at it, and it works without any modification! I'm wondering though if it will effect my event battle system..?
*slight update, fixes a glitch for passage correction*
*added VXA version*
Loved the screenshot best idea ever
Oh I don't think I ever noticed the bug, but I still use this so I'll update my script. Tis the best one out imo
*update again, added event pixel movement (http://pastebin.com/bUELkc1i) addon*
It causes some problem with XAS, you can go through some impassable tiles ... But it works !
So if I understant this pixel movement, it reduce the 32x32 tile walk by a 16x16 ?
Pixel movement for xas : http://littledrago.blogspot.com/2013/05/rgss-xas-391-ally-system-v112.html
Quote from: MetalZelda on August 13, 2014, 06:07:41 pmSo if I understant this pixel movement, it reduce the 32x32 tile walk by a 16x16 ?
Yes, this script mainly just reduce player step from 1 tile into half (0.5 tile).
I really like this script, it makes overall movement so much more enjoyable. I'm using also Event PM addon, and I have one problem with it. I have ingame events approaching player with event touch as trigger, and... they get confused when player stands on the edge of a tile. Is there be any way to fix that issue? I thought that adding 'through' option would work, but it didn't.
Try this
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Move toward Player
#--------------------------------------------------------------------------
def move_toward_player
abs_sx = (sx = @x - $game_player.x).abs
abs_sy = (sy = @y - $game_player.y).abs
if abs_sx < 1 && abs_sy < 1
move_away_from_player
turn_toward_player
end
if sx < -0.5 and sy > 0.5
move_upper_right
elsif sx > 0.5 and sy > 0.5
move_upper_left
elsif sx > 0.5 and sy < -0.5
move_lower_left
elsif sx < -0.5 and sy < -0.5
move_lower_right
elsif sx < -1.5
move_right
elsif sx > 1.5
move_left
elsif sy > 1.5
move_up
elsif sy < -1.5
move_down
end
end
end
Unfortunatly that didn't help. One more thing - I noticed, that when player just stands still in a way of 'through event' with on event touch nothing happens (not always). The event is triggered only (mostly) when player moves.
can you send a demo?
Here's demo, two maps show two mentioned issues - http://www13.zippyshare.com/v/dZOO92DU/file.html
Sorry Kise, I'm currently in a remote village without my laptop and rmxp.
I'll be back in a week.
Issue map 1 :
I edited all the trigger coordinates so the event will trigger even if player is in edge of tile.
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# This class handles the player. Its functions include event starting
# determinants and map scrolling. Refer to "$game_player" for the one
# instance of this class.
#==============================================================================
class Game_Player
#--------------------------------------------------------------------------
# * Same Position Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_here(triggers)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
#----------------------------------------------------------
if (event.x - @x).abs < 1 and (event.y - @y).abs < 1 and
triggers.include?(event.trigger)
#----------------------------------------------------------
# If starting determinant is same position event (other than jumping)
if not event.jumping? and event.over_trigger?
event.start
result = true
end
end
end
return result
end
#--------------------------------------------------------------------------
# * Front Envent Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_there(triggers)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# Calculate front event coordinates
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
#----------------------------------------------------------
if (event.x - new_x).abs < 1 and (event.y - new_y).abs < 1 and
triggers.include?(event.trigger)
#----------------------------------------------------------
# If starting determinant is front event (other than jumping)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
# If fitting event is not found
if result == false
# If front tile is a counter
if $game_map.counter?(new_x, new_y)
# Calculate 1 tile inside coordinates
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
#----------------------------------------------------------
if (event.x - new_x).abs < 1 and (event.y - new_y).abs < 1 and
triggers.include?(event.trigger)
#----------------------------------------------------------
# If starting determinant is front event (other than jumping)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
end
end
return result
end
#--------------------------------------------------------------------------
# * Touch Event Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
#----------------------------------------------------------
if (event.x - x).abs < 1 and (event.y - y).abs < 1 and
[1,2].include?(event.trigger)
#----------------------------------------------------------
# If starting determinant is front event (other than jumping)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
return result
end
end
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
# This class deals with events. It handles functions including event page
# switching via condition determinants, and running parallel process events.
# It's used within the Game_Map class.
#==============================================================================
class Game_Event
#--------------------------------------------------------------------------
# * Touch Event Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
# If event is running
if $game_system.map_interpreter.running?
return
end
# If trigger is [touch from event] and consistent with player coordinates
#----------------------------------------------------------
if @trigger == 2 and
(x - $game_player.x).abs < 1 and (y - $game_player.y).abs < 1
#----------------------------------------------------------
# If starting determinant other than jumping is front event
if not jumping? and not over_trigger?
start
end
end
end
#--------------------------------------------------------------------------
# * Automatic Event Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_auto
# If trigger is [touch from event] and consistent with player coordinates
#----------------------------------------------------------
if @trigger == 2 and
(x - $game_player.x).abs < 1 and (y - $game_player.y).abs < 1
#----------------------------------------------------------
# If starting determinant other than jumping is same position event
if not jumping? and over_trigger?
start
end
end
# If trigger is [auto run]
if @trigger == 3
start
end
end
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Move toward Player
#--------------------------------------------------------------------------
def move_toward_player
abs_sx = (sx = @x - $game_player.x).abs
abs_sy = (sy = @y - $game_player.y).abs
if abs_sx < 1 && abs_sy < 1
move_away_from_player
turn_toward_player
end
if sx < -0.5 and sy > 0.5
move_upper_right
elsif sx > 0.5 and sy > 0.5
move_upper_left
elsif sx > 0.5 and sy < -0.5
move_lower_left
elsif sx < -0.5 and sy < -0.5
move_lower_right
elsif sx < -1.5
move_right
elsif sx > 1.5
move_left
elsif sy > 1.5
move_up
elsif sy < -1.5
move_down
end
end
end
Issue map 2 :
Don't use Approach, use Custom > Move Toward Player instead.
(http://i.imgur.com/TLyXlKL.jpg)
Thank you, but there's still problem with second solution - events now don't get confused but event touch isn't as responsive. Now sometimes player can just go around it before it triggers.
One more little thing, I'm also using your smooth scroller script and for some reason camera always starts from lower right corner and then centers. It happens at the start of the game, or teleporting player. Oh, and it breaks Scroll Map command.
Hmm... for this problem I think you should thinker a bit with eventing.
As in checking the distance between event and player then make a custom scene / trigger instead relying on rtp's event touch.
Try insert this script.
class Game_Character
#--------------------------------------------------------------------------
# * adjust_follow_selfswitch
#--------------------------------------------------------------------------
def adjust_follow_selfswitch(selfswitch = 'A')
# Of course other self switch is also okay.
key = [$game_map.map_id, @id, selfswitch]
temp = $game_self_switches[key]
# Go ahead change this number with whatever distance you need.
if distance_from($game_player) < 1.75
# If distance from player is less than 1.75 tile
$game_self_switches[key] = true
else
# If distance from player is more or same than 1.75 tile
$game_self_switches[key] = false
end
if temp != $game_self_switches[key]
$game_map.need_refresh = true
end
end
end
And then you do this :
(http://i.imgur.com/0CIkXaX.jpg)
Now your event self switch will turn on whenever their distance with player is near.
Then, create a new page and do whatever you want in that page.
About smooth scroller script, not sure what your problem are.
Is the camera starts from the very corner right of the map every start / teleported?
I tested it in empty project and there are no such things.
I reuploaded the script and include a switch to activate / deactivate it now.
That solution didn't work. I just tried cogwheels pixel movement, and there're no such issues, event touch triggers without any problem and it events don't get confused - but... I still think yours feels better, isn't 'shaky' and is compatible with footsteps sounds script.
There's script - https://pastebin.com/eZztLTiC
Maybe you'll learn something from it, and improve your own? Of course if you have time. No need to rush.
BTW Drago, regarding the camera moving at the start of the game, I can reproduce it on clean XP too. If the map is, for example, 40x40 in size and the player start position is (12,12), the screen will move up and left upon the map loading. In the following
if ... (tile_y = ($BlizzABS ? CY : CENTER_Y)+ 64)
if ... (tile_x = ($BlizzABS ? CX : CENTER_X)+ 64)
if I remove the + 64, it no longer does this behavior.
Thanks KK20, I forgot that I modified my RTP.
I'll edit the script now.
Script updated (XP Version)
Now no issue for event triggers.
@Kise, if you redownload the script, please remove the event addon, as it also included in the new script.
Drago i'm also using it and i noticed that there are some issues with player touch aswell.
The event in question.
(https://puu.sh/wFMor/c9b4cb4a57.png)
I'm trying to just have the player move with direction fix here but it seems to work sometimes and other times i can just walk over it and nothing happens.
Quote from: Zexion on July 09, 2017, 09:10:45 pm
Drago i'm also using it and i noticed that there are some issues with player touch aswell.
The event in question.
https://puu.sh/wFMor/c9b4cb4a57.png
I'm trying to just have the player move with direction fix here but it seems to work sometimes and other times i can just walk over it and nothing happens.
For your problem, the reason is this line :
#--------------------------------------------------------------------------
# * Pixel Disable
#--------------------------------------------------------------------------
def pixel_disable?
return true unless self.pixel_movement
return true if @move_route_forcing # <<<<<<<
return false
end
That line disabling pixel movement when you use move route command.
Since your move route is just turn_up without any movement, it turned weird.
Solution :
1. Comment that line in the script, that means player will walk half a tile regardless in move route or not.
You probably need to readjust your entire move route event.
2. Add
$game_player.pixel_movement = false before move route command and then enable it again later.
3. Use script command instead move route command, that way you didn't have to disable pixel movement.
(http://i.imgur.com/mLJKKMP.png)
Btw script reuploaded to 1.11.
- Better coding.
Ahh that explains it, I'll be going with the 3rd option because it seems like the best work around for this case. Thanks for the quick reply drago!
Oh sorry, there are no 4.
4. Change that line in the script to:
return true if @move_route_forcing && @move_route.list.any? {|s| (1..14).include?(s.code)}
This way, the pixel movement will be disabled only if there are movement command in move route.
(http://i.imgur.com/Mlxxb6b.png)
The script is updated again.
Oh, nice fix. Thx
I've found two bugs with latest version. First one - I can't enable pixel movement for events because game throws NoMethodOccured while running script, undefined method '[]' for nil:NilClass.
The second one I captured on video, the script creates too early side movement or even makes it impossible to take a step forwad - one tile around any event. It's difficult for me to describe, so take a look at the video - https://youtu.be/uisJ8ROQY1I ( At the beginning I can't go forward, when it should be possible )
For first problem, sorry it's my error. It should be
$game_map.events[EVENT_ID].pixel_movement = true / falseOr if you using script command, you can use
get_character(ID).pixel_movement = true / falseWhile ID is :
- -1 (player),
- 0 (self event),
- 1.. (event with that ID)
For the second one I also noticed that, however I postponed it since to fix that bug, I need to recalculate everything again.
I'm sorry, I haven't got enough time right now, but I'll try to fix it later.
ver 1.12b : *deleted*
Thanks! I had to comment out sixth line to get it working ( it caused game to crash ). I tested it for a bit and didn't found any major problems so far.
I somehow managed to get on top of non-through event twice, but I'm not sure how I did it - just wanted to let you know about it.
The bug occurs by standing on the "second half" of the tile. Usually each step is about half a tile with pixel movement on, if you step only once and an event is walking to that square, they will ignore your collision. Also if the event is moving and you move at the same time it seems to cause the same problem. Honestly it doesn't bother me.
ver 1.12c : *deleted*
Oh well, I had to overwrite
passable? method this time....
#--------------------------------------------------------------------------
# * Overwriten method: passable?
#--------------------------------------------------------------------------
def passable?(x, y, d)
new_x = x_with_direction(x,d) # new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y_with_direction(y,d) # new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return false unless $game_map.valid?(new_x, new_y)
return true if @through
return false unless $game_map.passable?(x, y, d, self)
return false unless $game_map.passable?(new_x, new_y, 10 - d)
for event in $game_map.events.values
#----------------------------------------------------------
if ((event.x + event.revise_x) - new_x).abs < 1 and
((event.y + event.revise_y) - new_y).abs < 1
unless event.through || (self == event)
#----------------------------------------------------------
return false if self != $game_player
return false if event.character_name != ""
end
end
end
#----------------------------------------------------------
if self != (pl = $game_player) && ((pl.x + pl.revise_x) - new_x).abs < 1 &&
((pl.y + pl.revise_y) - new_y).abs < 1
#----------------------------------------------------------
return false if @character_name != "" && !$game_player.through
end
return true
end
I already marked my change on
passable? method.
If you have other scripts that aliases / overwrite that method, you should know what to do.
Thanks again. take another level+ lol
Update ver 1.14 : https://pastebin.com/U6AMbkwJ
Cleaned and aliased.
Helloo,
thank you very much for your effort LittleDrago! I love 16px Tile Movement, specially for Games with Zelda Style Battle Systems (ABS). It doesn't feel blocky like with the original 32px Movement and personally, i don't see the need for pixel Movement, not to mention that the need for collision maps is often present when using it. I've got one Question:
Is there a possibility, this Script can be made compatible with Heretics Modular Passable Script? I already made some Request one Year ago but sadly, didn't get an answer :/. Here is the Link
http://forum.chaos-project.com/index.php/topic,15436.0.html
Forget the mentioned Script in there, your Script is looking much better.
EDIT:
Woah .. i just thought "well, why not just test it anyway?". Guess what, i did not get any Errors *o*. It works pretty well actually, at least what i tested so far, i can't believe it. You are god.
Finally, it seems i can have 16px Movement and all the Advantages of Heretics Collection afterall!
Only the Moving Plattforms Script is buggy, but that was predictable. An easy Workaround would be, disable pixel Movement when entering/leaving a Plattform. Of course 16px Movement on a Plattform would be Cherry on the Cake!
greetz
I tried the script in clean project and have no problem with my pixel movement.
But I don't mind adjusting a little bit.
Update 1.15 (link same as post above).
Just put my pixel movement below modular passable script.
I'll update pastebin later (after I fix new version).
Not recommended to use this:
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# DRG - Pixel Movement
# Version: 1.15b
# Author : LiTTleDRAgo
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
($imported ||= {})[:drg_pixel_movement] = 1.15
#==============================================================================
#
# Introduction :
#
# This script makes player's movement became pixel movement.
# Event pixel movement turned off by default.
#
# To activate / deactivate pixel movement
# - $game_player.pixel_movement = true / false
# - $game_map.events[EVENT_ID].pixel_movement = true / false
#
# If used in Script call
# - get_character(ID).pixel_movement = true / false
# where ID : -1 (player),
# 0 (self event),
# 1.. (event ID)
#
#==============================================================================
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :pixel_movement, :direction_fix
attr_writer :revise_x, :revise_y
#--------------------------------------------------------------------------
# * Others
#--------------------------------------------------------------------------
define_method(:x_with_direction) {|x, d| x + (d==6 ? 1 : d==4 ? -1 : 0)}
define_method(:y_with_direction) {|y, d| y + (d==2 ? 1 : d==8 ? -1 : 0)}
define_method(:x_pixel_direction) {|x, d| x + (d==6 ? 0.5 : d==4 ? -0.5 : 0)}
define_method(:y_pixel_direction) {|y, d| y + (d==2 ? 0.5 : d==8 ? -0.5 : 0)}
define_method(:revise_x) { pixel_disable? ? 0 : @revise_x ||= 0 }
define_method(:revise_y) { pixel_disable? ? 0 : @revise_y ||= 0 }
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
ALIASING_PIXEL = lambda do |x|
[:move_down,:move_left,:move_right,:move_up, :move_lower_left,
:move_lower_right,:move_upper_left,:move_upper_right].each do |meth|
$@ || alias_method(:"#{meth}_unpixel_#{x}", :"#{meth}")
define_method(:"#{meth}") do |*args|
respond_to?(:"#{meth}_pixel") && !pixel_disable? ?
send(:"#{meth}_pixel",*args) :
reset_pixel && send(:"#{meth}_unpixel_#{x}",*args)
end
end
end
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_move_unpixel, :update_move)
$@ || alias_method(:moving_unpixel, :moving?)
$@ || alias_method(:passable_unpixel, :passable?)
#--------------------------------------------------------------------------
# * Aliased method: passable_conditions?
#--------------------------------------------------------------------------
if method_defined?(:passable_conditions?)
$@ || alias_method(:passable_conditions_unpixel, :"passable_conditions?")
def passable_conditions?(x, y, d, new_x, new_y, event, *args)
result = passable_conditions_unpixel(x, y, d, new_x, new_y, event, *args)
unless result
if ((event.x + event.revise_x) - new_x).abs < 1 and
((event.y + event.revise_y) - new_y).abs < 1 and
not event.through and event != self
return true
end
end
return result
end
#--------------------------------------------------------------------------
# * Aliased method: player_conditions?
#--------------------------------------------------------------------------
$@ || alias_method(:player_conditions_unpixel, :"player_conditions?")
def player_conditions?(x, y, d, *args)
result = player_conditions_unpixel(x, y, d, *args)
return true unless result || player_collition_passable?(x,y,d)
return result
end
end
#--------------------------------------------------------------------------
# * Aliased method: passable?
#--------------------------------------------------------------------------
def passable?(x, y, d)
result = passable_unpixel(x, y, d)
unless @through || !result
return false unless pixel_disable? || passable_pixel?(x, y, d)
end
return result
end
#--------------------------------------------------------------------------
# * Passable Pixel
#--------------------------------------------------------------------------
def passable_pixel?(x, y, d)
return tile_collition_passable?(x, y, d) if $Modular_Passable
event_collition_passable?(x, y, d) &&
player_collition_passable?(x, y, d) &&
tile_collition_passable?(x, y, d)
end
#--------------------------------------------------------------------------
# * Determine if Collided with Events
#--------------------------------------------------------------------------
def event_collition_passable?(x, y, d)
unless @through
new_x = x_with_direction(x, d)
new_y = y_with_direction(y, d)
for event in $game_map.events.values
#----------------------------------------------------------
unless event.through || (self == event)
if ((event.x + event.revise_x) - new_x).abs < 1 and
((event.y + event.revise_y) - new_y).abs < 1
#----------------------------------------------------------
return false if self != $game_player
return false if event.character_name != ""
end
end
end
end
return true
end
#--------------------------------------------------------------------------
# * Determine if Collided with Player
#--------------------------------------------------------------------------
def player_collition_passable?(x,y,d)
unless self == (pl = $game_player) || @through
new_x = x_with_direction(x,d)
new_y = y_with_direction(y,d)
#----------------------------------------------------------
if @character_name != "" && !pl.through &&
((pl.x + pl.revise_x) - new_x).abs < 1 &&
((pl.y + pl.revise_y) - new_y).abs < 1
#----------------------------------------------------------
return false
end
end
return true
end
#--------------------------------------------------------------------------
# * Determine if Collided with Tile
#--------------------------------------------------------------------------
def tile_collition_passable?(x, y, d)
nx = x_with_direction(x, d)
ny = y_with_direction(y, d)
if ((d == 2 || d == 8) && revise_x % 1 != 0)
unless $game_map.passable_pixel?((nx+revise_x).floor, ny, d)
return !(@revise_x = 0)
end
unless $game_map.passable_pixel?((nx+revise_x).ceil, ny, d)
return false
end
end
if ((d == 4 || d == 6) && revise_y % 1 != 0)
unless $game_map.passable_pixel?(nx, (ny+revise_y).floor, d)
return !(@revise_y = 0)
end
unless $game_map.passable_pixel?(nx, (ny+revise_y).ceil, d)
return false
end
end
return true
end
#--------------------------------------------------------------------------
# * Aliased method: update_move
#--------------------------------------------------------------------------
def update_move
if pixel_disable?
reset_pixel && update_move_unpixel
else
distance = 2 ** @move_speed
_x,_y = (@x + revise_x), (@y + revise_y)
@real_y = [@real_y + distance, _y * 128].min if _y * 128 > @real_y
@real_x = [@real_x - distance, _x * 128].max if _x * 128 < @real_x
@real_x = [@real_x + distance, _x * 128].min if _x * 128 > @real_x
@real_y = [@real_y - distance, _y * 128].max if _y * 128 < @real_y
@anime_count += @walk_anime ? 1.5 : @step_anime ? 1 : 0
end
end
#--------------------------------------------------------------------------
# * Aliased method: moving?
#--------------------------------------------------------------------------
def moving?
if pixel_disable?
moving_unpixel
else
(@real_x != (@x + revise_x) * 128 || @real_y != (@y + revise_y) * 128)
end
end
#--------------------------------------------------------------------------
# * xy_pixel_correction
#--------------------------------------------------------------------------
def xy_pixel_correction(direction)
_x, _y = (@x + revise_x), (@y + revise_y)
case direction
when 2
if revise_x % 1 != 0
unless passable?(_x.ceil,_y.floor, 2) or passable?(_x.ceil,_y.ceil, 2)
if passable?(_x.floor,_y.floor, 2) or passable?(_x.floor,_y.ceil, 2)
@revise_x = (_x = (@x += revise_x.floor)) * 0
end
end
end
if revise_x % 1 != 0
unless passable?(_x.floor,_y.floor, 2) or passable?(_x.floor,_y.ceil, 2)
if passable?(_x.ceil,_y.floor, 2) or passable?(_x.ceil,_y.ceil, 2)
@revise_x = (_x = (@x += revise_x.ceil)) * 0
end
end
end
when 4
if revise_y % 1 != 0
unless passable?(_x.ceil,_y.ceil, 4) or passable?(_x.floor,_y.ceil, 4)
if passable?(_x.ceil,_y.floor, 4) or passable?(_x.floor,_y.floor, 4)
@revise_y = (_y = (@y += revise_y.floor)) * 0
end
end
end
if revise_y % 1 != 0
unless passable?(_x.ceil,_y.floor, 4) or passable?(_x.floor,_y.floor, 4)
if passable?(_x.ceil,_y.ceil, 4) or passable?(_x.floor,_y.ceil, 4)
@revise_y = (_y = (@y += revise_y.ceil)) * 0
end
end
end
when 6
if revise_y % 1 != 0
unless passable?(_x.floor,_y.ceil, 6) or passable?(_x.ceil,_y.ceil, 6)
if passable?(_x.floor,_y.floor, 6) or passable?(_x.ceil,_y.floor, 6)
@revise_y = (_y = (@y += revise_y.floor)) * 0
end
end
end
if revise_y % 1 != 0
unless passable?(_x.floor,_y.floor, 6) or passable?(_x.ceil,_y.floor, 6)
if passable?(_x.floor,_y.ceil, 6) or passable?(_x.ceil,_y.ceil, 6)
@revise_y = (_y = (@y += revise_y.ceil)) * 0
end
end
end
when 8
if revise_x % 1 != 0
unless passable?(_x.ceil,_y.ceil, 8) or passable?(_x.ceil,_y.floor, 8)
if passable?(_x.floor,_y.ceil, 8) or passable?(_x.floor,_y.floor, 8)
@revise_x = (_x = (@x += revise_x.floor)) * 0
end
end
end
if revise_x % 1 != 0
unless passable?(_x.floor,_y.ceil, 8) or passable?(_x.floor,_y.floor, 8)
if passable?(_x.ceil,_y.ceil, 8) or passable?(_x.ceil,_y.floor, 8)
@revise_x = (_x = (@x += revise_x.ceil)) * 0
end
end
end
end
direction
end
#--------------------------------------------------------------------------
# * add_revise_coord
#--------------------------------------------------------------------------
def add_revise_coord
@revise_x % 1 == 0 && @revise_x = (@x += @revise_x.round) * 0
@revise_y % 1 == 0 && @revise_y = (@y += @revise_y.round) * 0
end
#--------------------------------------------------------------------------
# * Pixel Disable
#--------------------------------------------------------------------------
def pixel_disable?
return true unless self.pixel_movement
return true if @move_route_forcing && @move_route.list.any? do |s|
(1..14).include?(s.code)
end
return false
end
#--------------------------------------------------------------------------
# * reset_pixel
#--------------------------------------------------------------------------
def reset_pixel
return 0 if (@revise_x ||= 0) == 0 && (@revise_y ||= 0) == 0
xy_pixel_correction(@direction)
@revise_x = (@x += revise_x.floor) * 0
@revise_y = (@y += revise_y.floor) * 0
end
#--------------------------------------------------------------------------
# * Move Down
# turn_enabled : a flag permits direction change on that spot
#--------------------------------------------------------------------------
def move_down_pixel(turn_enabled = true)
@quarter = false
turn_enabled && turn_down
if passable?(@x, ((@y + revise_y).floor), xy_pixel_correction(2)) or
passable?(@x, ((@y + revise_y).ceil), 2)
turn_down
@revise_y = y_pixel_direction(@revise_y,2)
add_revise_coord
increase_steps
else
@revise_y = revise_y.ceil
add_revise_coord
check_event_trigger_touch(@x, y_with_direction(@y,2))
end
end
#--------------------------------------------------------------------------
# * Move Left
# turn_enabled : a flag permits direction change on that spot
#--------------------------------------------------------------------------
def move_left_pixel(turn_enabled = true)
@quarter = false
turn_enabled && turn_left
if passable?((@x + revise_x).ceil, @y, xy_pixel_correction(4)) or
passable?((@x + revise_x).floor, @y, 4)
turn_left
@revise_x = x_pixel_direction(@revise_x,4)
add_revise_coord
increase_steps
else
@revise_x = @revise_x.floor
add_revise_coord
check_event_trigger_touch(x_with_direction(@x,4), @y)
end
end
#--------------------------------------------------------------------------
# * Move Right
# turn_enabled : a flag permits direction change on that spot
#--------------------------------------------------------------------------
def move_right_pixel(turn_enabled = true)
@quarter = false
turn_enabled && turn_right
if passable?((@x + revise_x).floor, @y, xy_pixel_correction(6)) or
passable?((@x + revise_x).ceil, @y, 6)
turn_right
@revise_x = x_pixel_direction(@revise_x,6)
add_revise_coord
increase_steps
else
@revise_x = @revise_x.ceil
add_revise_coord
check_event_trigger_touch(x_with_direction(@x,6), @y)
end
end
#--------------------------------------------------------------------------
# * Move up
# turn_enabled : a flag permits direction change on that spot
#--------------------------------------------------------------------------
def move_up_pixel(turn_enabled = true)
@quarter = false
turn_enabled && turn_up
if passable?(@x, (@y + revise_y).ceil, xy_pixel_correction(8)) or
passable?(@x, (@y + revise_y).floor, 8)
turn_up
@revise_y = y_pixel_direction(@revise_y, 8)
add_revise_coord
increase_steps
else
@revise_y = revise_y.floor
add_revise_coord
check_event_trigger_touch(@x, y_with_direction(@y,8))
end
end
end
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# This class handles the player. Its functions include event starting
# determinants and map scrolling. Refer to "$game_player" for the one
# instance of this class.
#==============================================================================
class Game_Player
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
ALIASING_PIXEL.call(0)
#--------------------------------------------------------------------------
# * Alias Method
#--------------------------------------------------------------------------
$@ || alias_method(:pixel_initialize, :initialize)
#--------------------------------------------------------------------------
# * Pixel Movement
#--------------------------------------------------------------------------
def initialize(*args)
pixel_initialize(*args)
@pixel_movement = true
end
end
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
# This class deals with events. It handles functions including event page
# switching via condition determinants, and running parallel process events.
# It's used within the Game_Map class.
#==============================================================================
class Game_Event
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
ALIASING_PIXEL.call(1)
#--------------------------------------------------------------------------
# * Alias Method
#--------------------------------------------------------------------------
$@ || alias_method(:pixel_initialize, :initialize)
#--------------------------------------------------------------------------
# * Pixel Movement
#--------------------------------------------------------------------------
def initialize(*args)
pixel_initialize(*args)
@pixel_movement = false
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
#--------------------------------------------------------------------------
# * Tile not Passable
#--------------------------------------------------------------------------
unless method_defined?(:tile_not_passable?)
def tile_not_passable?(x, y, d, bit, tile_id, self_event = nil, result = nil)
return result if not result.nil?
if tile_id == nil
return true
elsif @passages[tile_id] & bit != 0
return true
elsif @passages[tile_id] & 0x0f == 0x0f
return true
end
end
end
#--------------------------------------------------------------------------
# * Tile Passable
#--------------------------------------------------------------------------
unless method_defined?(:tile_passable?)
def tile_passable?(x, y, d, bit, tile_id, self_event=nil, result=nil)
return result if not result.nil?
if @priorities[tile_id] == 0
return true
end
end
end
#--------------------------------------------------------------------------
# * Passable Pixel
#--------------------------------------------------------------------------
def passable_pixel?(x, y, d, self_event = nil)
case d
when 2, 8
bit_ex = (1 << (4 / 2 - 1)) & 0x0f
bit_ey = (1 << (6 / 2 - 1)) & 0x0f
when 4, 6
bit_ex = (1 << (2 / 2 - 1)) & 0x0f
bit_ey = (1 << (8 / 2 - 1)) & 0x0f
else
return true
end
for event in $game_map.events.values
if event.tile_id >= 0 and event != self_event and
((event.x + event.revise_x) - x).abs < 1 and
((event.y + event.revise_y) - y).abs < 1 and not event.through
if tile_not_passable?(x, y, d, bit_ex, event.tile_id, self_event)||
tile_not_passable?(x, y, d, bit_ey, event.tile_id, self_event)
return false
end
if tile_passable?(x, y, d, bit_ex, event.tile_id, self_event)||
tile_passable?(x, y, d, bit_ey, event.tile_id, self_event)
return true
end
end
end
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_not_passable?(x, y, d, bit_ex, tile_id, self_event) ||
tile_not_passable?(x, y, d, bit_ey, tile_id, self_event)
return false
end
if tile_passable?(x, y, d, bit_ex, tile_id, self_event) ||
tile_passable?(x, y, d, bit_ey, tile_id, self_event)
return true
end
end
return true
end
end
Unfortunately, to fix that I have to remove some step correction calculation.
You'll notice sometimes player will not dodge and stopped walking when faced unpassable tiles.
Yeah, movement definitly feels less fluid and less intuitive with this version. Honestly, I'd rather disable passability on tiles like these, and stick to the previous version. There're not that many of them anyway.
@Edit - I noticed that player can't step into second half of the tile, if the next one is impassable - is it done on purpose? here's screenshot. https://image.ibb.co/iDfrFQ/bugornot.jpg
Is that with new beta version or still previous version?
That happens on both versions.
Oh, I see what you mean...
Yes it's intentional, because if I didn't do that, player will just pass through that impassable tiles like it didn't exist.
Script updated (ACE)
* Fixed follower movement
https://littledrago.blogspot.com/2014/08/rgss3-drg-pixel-movement-ace.html