[XP][VXA] Drago Pixel Movement

Started by LiTTleDRAgo, May 07, 2013, 11:53:36 am

Previous topic - Next topic

LiTTleDRAgo

May 07, 2013, 11:53:36 am Last Edit: August 12, 2014, 06:05:22 am by LiTTleDRAgo
Drago Pixel Movement
Authors: LiTTleDRAgo
Version: 1.02
Type: Movement Add-on
Key Term: Movement Add-on



Introduction

Title explain everything


Features


  • Pixel movement on player




Screenshots




Script

XP Version

VXAce Version


Instructions

Only intended for player movement


Compatibility

Will cause problem with other movement script, especially ABS
Not compatible with Blizz ABS


Credits and Thanks


  • LiTTleDRAgo




Author's Notes

Enjoy ~

Zexion

May 07, 2013, 02:10:14 pm #1 Last Edit: May 20, 2013, 03:44:31 am by Zexion
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..?

LiTTleDRAgo

*slight update, fixes a glitch for passage correction*
*added VXA version*

Soulshaker3

Loved the screenshot best idea ever
Hellow?

Zexion

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

LiTTleDRAgo


MetalZelda

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 ?

LiTTleDRAgo

August 13, 2014, 10:44:13 pm #7 Last Edit: May 16, 2017, 06:27:25 am by LiTTleDRAgo
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).

Kise

June 23, 2017, 07:29:09 am #8 Last Edit: June 23, 2017, 08:34:44 am by Kise
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.

LiTTleDRAgo

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

Kise

June 23, 2017, 12:56:44 pm #10 Last Edit: June 23, 2017, 01:27:21 pm by Kise
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.

LiTTleDRAgo


Kise

June 23, 2017, 04:09:13 pm #12 Last Edit: June 24, 2017, 02:28:00 am by Kise
Here's demo, two maps show two mentioned issues - http://www13.zippyshare.com/v/dZOO92DU/file.html

LiTTleDRAgo

Sorry Kise, I'm currently in a remote village without my laptop and rmxp.
I'll be back in a week.

LiTTleDRAgo

Issue map 1 :

I edited all the trigger coordinates so the event will trigger even if player is in edge of tile.
Spoiler: ShowHide
#==============================================================================
# ** 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.

Spoiler: ShowHide

Kise

June 28, 2017, 10:58:09 am #15 Last Edit: June 28, 2017, 01:57:28 pm by Kise
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.

LiTTleDRAgo

June 28, 2017, 09:43:30 pm #16 Last Edit: June 28, 2017, 09:45:27 pm by LiTTleDRAgo
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 :
Spoiler: ShowHide


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.

Kise

June 29, 2017, 03:34:56 am #17 Last Edit: July 04, 2017, 04:35:20 pm by Kise
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.

KK20

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.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

LiTTleDRAgo

Thanks KK20, I forgot that I modified my RTP.
I'll edit the script now.

LiTTleDRAgo

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.

Zexion

Drago i'm also using it and i noticed that there are some issues with player touch aswell.
The event in question.
Spoiler: ShowHide

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.

LiTTleDRAgo

July 09, 2017, 10:57:07 pm #22 Last Edit: July 10, 2017, 01:04:53 am by LiTTleDRAgo
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.

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.
Spoiler: ShowHide


Btw script reuploaded to 1.11.
- Better coding.

Zexion

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!

LiTTleDRAgo

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.

Spoiler: ShowHide


The script is updated again.

Zexion


Kise

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 )

LiTTleDRAgo

July 14, 2017, 12:07:48 pm #27 Last Edit: July 17, 2017, 03:05:16 am by LiTTleDRAgo
For first problem, sorry it's my error. It should be $game_map.events[EVENT_ID].pixel_movement = true / false
Or if you using script command, you can use get_character(ID).pixel_movement = true / false
While 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.

LiTTleDRAgo

July 15, 2017, 06:43:50 am #28 Last Edit: July 17, 2017, 03:03:00 am by LiTTleDRAgo
ver 1.12b : *deleted*

Kise

July 16, 2017, 11:37:52 am #29 Last Edit: July 16, 2017, 01:23:02 pm by Kise
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.

Zexion

July 16, 2017, 04:33:56 pm #30 Last Edit: July 16, 2017, 05:04:52 pm by Zexion
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.

LiTTleDRAgo

July 16, 2017, 07:40:38 pm #31 Last Edit: July 17, 2017, 08:54:33 am by LiTTleDRAgo
ver 1.12c : *deleted*

Oh well, I had to overwrite passable? method this time....

Spoiler: ShowHide

  #--------------------------------------------------------------------------
  # * 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.

Zexion

Thanks again. take another level+ lol

LiTTleDRAgo


schmoggi

July 17, 2017, 06:20:59 am #34 Last Edit: July 17, 2017, 06:56:40 am by schmoggi
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

LiTTleDRAgo

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.

LiTTleDRAgo

July 17, 2017, 07:38:32 pm #36 Last Edit: July 19, 2017, 02:22:46 am by LiTTleDRAgo
I'll update pastebin later (after I fix new version).

Not recommended to use this:
Spoiler: ShowHide
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# 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.

Kise

July 18, 2017, 04:34:20 am #37 Last Edit: July 18, 2017, 03:32:35 pm by Kise
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

LiTTleDRAgo

Is that with new beta version or still previous version?

Kise

July 19, 2017, 02:53:04 am #39 Last Edit: July 19, 2017, 03:02:33 am by Kise
That happens on both versions.

LiTTleDRAgo

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.