Checking if player is moving. Bug?

● ARCHIVED · READ-ONLY
Started by Tsukihime 17 posts View original ↗
  1. I saw this method in Game_Player

    def update last_real_x = @real_x last_real_y = @real_y last_moving = moving? <------ move_by_input super update_scroll(last_real_x, last_real_y) update_vehicle update_nonmoving(last_moving) unless moving? <--------- @followers.updateendFirst, what is the point of this, and second, why is it written this way?Third, if I did this, would it change the logic?

    Code:
    def update  last_real_x = @real_x  last_real_y = @real_y    move_by_input         <------  last_moving = moving? <------ re-arrange  super  update_scroll(last_real_x, last_real_y)  update_vehicle  update_nonmoving(last_moving) unless moving?  @followers.updateend
  2. Would it have to relate to true or false statements? I mean reading this I'm seeing; every frame, determine movement flag, update non moving if false unless moving is true. Honestly though, I don't know why it would be written like this, there may be another reason behind it or just another way to cut corners and prevent a bug or something.
  3. Probably calling move by input modifies the value of moving? which is why they saved the previous moving? value first before calling move by input.

    So if you put move_by_input first, and the player moves, then you're saving the new moving? value instead of the old one.. and it's called last_moving for a reason. :)
  4. I'd say Engr. Adiktuzmiku is right here.

    move_by_input can enable moving? if the player starts a new move,

    super can disable moving? when the player finishes the current move within one update_move - call.

    So the code serves to check whether the player has stopped moving right now.

    Since move_by_input can only start a new move and update_nonmoving(last_moving) is suppressed when the player is moving exchanging these two lines should not make a difference as long as both lines stay above the super call.
  5. I assume move_by_input and/or super might change the moving? flag, so it wants to know if it has changed from moving to non-moving, or vice versa.


    Wish I had Ace with me now so I could look at those methods and see what it does in each situation, and also what update_nonmoving is all about.
  6. The issue I'm having is that now that I'm moving 4 pixels per step rather than 32 pixels, touch events no longer trigger when I'm dashing.

    This is because the way last moving is determined is to check whether @x != @real_x and @y != @real_y.

    The assumption with the default scripts is that because you're moving one tile at a time, your (x, y) coords are integers.

    When you move from (0,1) to (0,2), your real_y value looks like this during each update

    (0, 1.25) # move(0, 1.5) # move(0, 1.75) # move(0, 2) # doneNow, the update occurs every frame, so whenever you move, it will update.Once you're no longer moving, it will start updating nonmoving, which presumably means you're not moving (ie: standing still)

    So there is a very specific case where last_moving will be set to true, and it will be passed into update_nonmoving, and that is exactly when you WERE moving, but then you reached your destination. In my example, it is when you move from 1.75 to 2.

    So, the problem is not the order in which they are placed, it's the way "last_moving" is checked in the first place.

    At least for me, @x and @real_x are both equal when I'm dashing because each animation step moves 0.25 tiles per update, and I just happen to be moving at 0.25 tiles per step.

    Here are the relevant methods

    Code:
      def update    last_real_x = @real_x    last_real_y = @real_y    last_moving = moving?    move_by_input    super    update_scroll(last_real_x, last_real_y)    update_vehicle    update_nonmoving(last_moving) unless moving?    @followers.update  end  def moving?    @real_x != @x || @real_y != @y  end    def update_nonmoving(last_moving)    return if $game_map.interpreter.running?    if last_moving      $game_party.on_player_walk      return if check_touch_event    end    if movable? && Input.trigger?(:C)      return if get_on_off_vehicle      return if check_action_event    end    update_encounter if last_moving  end
    I'm just not sure if the specific case I mentioned is important to consider.
  7. so the problem only happens when ur dashing?

    anyway, since last_moving is only taking in the value of moving?, I guess it's better to say that it's because of how moving? is processed..

    Have you tried modifying moving? so that instead of @x/y and @real_x/y, it checks @last_real_x/y and @real_x/y instead?

    def moving? @real_x != @last_real_x || @real_y != @last_real_y end while editing the update to be like

    Code:
    def update  last_moving = moving? #Check first before re-setting the vars  #since we're now gonna use the @last_real to check for movement  @last_real_x = @real_x  @last_real_y = @real_y  move_by_input      super  update_scroll(@last_real_x, @last_real_y)  update_vehicle  update_nonmoving(last_moving) unless moving? <---------  @followers.updateend
    So now you're checking reals to reals.
  8. Not to throw this topic off or anything but, what is the bug issued with the definition? I'm just a little curious and figured I mine as well learn a little more like Tuskihime. Is it like the event glitch where it isn't lined with the grid as it calculates x & y rather then the last real x & y positions like Adik. mentioned?
  9. Well, if the player character moves fast enough to finish a move the same frame it was started, then you are right. In that case swapping the two lines you mentioned actually would also make a difference of course since the player never has to continue a move started in a previous update.

    Argh, I didn't think of that possibility...

    While I can't test it at the moment, I'm curious if swapping the two lines from the first post actually solved your problem.
  10. @Fen - if that's what's happening, then putting switching them won't matter. It will return false for both moving? calls since the movement was instant and because the game by default only checks the real_x/y and the x/y.

    Ace used real_x/y and x/y for comparison, but then when move_by_input is called, both real_x/y and x/y can change values. It relied on the fact that using just the default systems, whenever you stop, you'll always be in an exact place on the grid that is denotable by an integer.

    But, we're now dealing with pixel movement where it's possible to stop at a point in the grid that cannot be denoted by an integer. So now @real_x/y and @x/y can be equal even if ur moving. That is if the pixel per step (using normal Ace, pixel per step is always 32) is equal to the animation's pixel per step too. During that scenario, the game thinks that you didn't move even if you actually did, because it was "instant".

    So...

    To check for movement even if it's instant, we should really change moving? to use the last_real_x/y instead of simply x/y. After all, that's a more logical way right? If I changed positions, then I moved.

    I think we could do this

    def update last_moving = @last_moving @last_real_x = @real_x @last_real_y = @real_y move_by_input super update_scroll(@last_real_x, @last_real_y) update_vehicle #save it so that we can load it the next frame @last_moving = moving? update_nonmoving(last_moving) unless @last_moving @followers.update end def moving? @real_x != @last_real_x || @real_y != @last_real_y endSo let's say I'm at 0,0 and I move 4 pixels per step to the right from rest which happens in an instant. Assume just 1 steplast_moving = @last_moving = false

    @last_real_x = 0

    @last_real_y = 0

    move_by_input

    so now my real_x => 4

    real_y = 0

    moving? (@last_real_x = 0 != real_x = 4, so yes I'm moving!)

    Next frame:

    last_moving = @last_moving = true

    @last_real_x = 4

    @last_real_y = 0

    moving? (@last_real_x = 4 == real_x = 4 and both y variables are 0, so I'm not moving!)

    update_nonmoving(last_moving)

    => will now run, with last_moving equal to true so it will run the touch checking
  11. Technically, if it works with RTP and not with your script changes, it's not a bug ... it's just that it's not designed with your purpose in mind ;)
  12. Yeah, as I explained above, EB made sure that if ur just using the default scripts (and no usage of the Script event command to do some greater editing), that scenario can never happen.. But then we scripters do like to do stuff that breaks the safety nets placed by EB.


    Though really, checking for movement via position before and position now is more logical IMHO. and I don't think it will consume a considerably greater amount of power than their method.
  13. yeah, I just don't see the point in calling it a "bug" when it's doing exactly what it was designed to do perfectly well :) If we want to change the way things happen, we might have to change more than we initially expected, but it doesn't mean there was a flaw with the original.


    I do wish you luck in finding a good way around it though. I'm curious why you're making your own pixel movement script when there are already a number available - I can only imagine what extra things you're going to be putting in it. Looking forward to seeing you show it off :)
  14. Yeah, I wonder what additional things would Hime add into pixel movement.
  15. the one thing lacking in all existing pixel movement scripts, of course - pixel collision ;) Which would work perfectly with Hime's overlay map script (the one where you paint the collision areas - not sure if that's the correct name)
  16. Unfortunately, the snippet posted by storing last coordinates in an instance variable does not work.


    Try it out. With or without pixel movement the same issue occurs.

    Shaz said:
    Technically, if it works with RTP and not with your script changes, it's not a bug ... it's just that it's not designed with your purpose in mind ;)
    Lol that's true.


    Thinking about it some more, the logic is correct as Adik says: it just stores whether you're moving or not, before you move.


    It just doesn't work for me because I just happen to run into a case where the definition of whether you're moving or not fails.

    Shaz said:
    I do wish you luck in finding a good way around it though. I'm curious why you're making your own pixel movement script when there are already a number available - I can only imagine what extra things you're going to be putting in it. Looking forward to seeing you show it off :)
    I don't actually know what's available (beyond victor's pixel movement), and most of the comments I've seen say it's not very compatible with other scripts outside of his own.


    It's also more for educational purpose since people can see how it is put together from scratch rather than "here's a script that does what you want, now maybe you can read over it and figure out how it works". Because frankly I don't understand how victor's pixel movement script works.
  17. maybe we could put lots of debug messages in there to determine where it actually fails.

    Tested it, the touch works but the moving? check is buggy to the extent that my char moves to a random space somehow when I have it. Hmmmm..

    It seems like the game is also using moving? to actually determine if it needs to "move" the object. From what I understand up to know, the game will continue to move the object until it reaches it's destination which is the integer @x/@y which is also done via checking moving?. So since I changed moving? to use the reals instead, the game now continues to move the object until @real_x/y equals @last_real_x/y which doesn't happen often. Basically I assumed that the game will stop a character once it reaches the destination using a different check. But then I was wrong, it uses that exact same method to both check if the object is moving, and if it still needs to be moved.

    So I suggest that we modify the update so that only it will be using the modified moving? method

    basically this:

    def update last_moving = @last_moving @last_real_x = @real_x @last_real_y = @real_y move_by_input super update_scroll(@last_real_x, @last_real_y) update_vehicle #save it so that we can load it the next frame @last_moving = moved? update_nonmoving(last_moving) unless @last_moving @followers.update end def moved? @real_x != @last_real_x || @real_y != @last_real_y endSo now it will record the movement even if it's instantaneous, while also allowing the game to still recognize if the object reached it's destination or not since we leave the original moving? intacthopefully this works with the pixel movement. This pixel movement thingy is surely giving us lots to wonder about the designs of the default scripts and how to circumvent them.