player doesn't walk to specified position

Started by HandsFree, Mon 15/03/2021 21:30:58

Previous topic - Next topic

HandsFree

Hi,

If I do:
Code: ags

player.Walk(player.x+10, player.y, eNoBlock, eAnywhere);
player.Walk(player.x-10, player.y, eNoBlock, eAnywhere);

The player's end position is not the same.
I checked this with display.

After 1st line: x=224, y=232
After 2nd line: x=218, y=232.

How can I force the player to walk exactly the specified amout of pixels?

Thanks.

Khris

#1
The first walk is non-blocking, so the 2nd command will immediately override the 1st.

Afaik AGS always puts the character exactly on the target position at the end of a walk, if possible.

It also sounds like you're using the wrong tool to achieve your goal. What do you want to accomplish?

morganw

Quote from: Khris on Mon 15/03/2021 23:14:43
Afaik AGS always puts the character exactly on the target position at the end of a walk, if possible.
I think this is only true if the mask resolution is set to 1:1, which is only selectable (and the default) on AGS 3.5.
https://adventuregamestudio.github.io/ags-manual/UpgradeTo35.html#room-sizes-and-mask-resolution

HandsFree

Yes sorry, it isn't exactly in the game like that.
When you click to the right of the player she walks 10 to the right.
When you click to the left, she walks 10 to the left.
I have safe regions en unsafe regions.
If you are safe and walking to the right makes you stand on an unsafe region, you should be able to click to the left and be back where you where before (safe).

But it turns out that (sometimes) you walk 10 to the right and then less to the left, so you are not back on a safe region.
Does this make sense?

@Morgan, are you saying this is expected behaviour? We are still in v3.3.

Khris

You could introduce a variable that stores the target x coordinate.
Clicking to the left/right of the player de/increases the variable by 10, then sends the player there. That way previous hiccups don't affect further clicks.

Still, the player should always reach the target coordinates, especially when using eAnywhere.

Laura Hunt

I actually have a somewhat related question, hope it's ok to ask it here.

If I send a character from, say, x=50 to x=100 with the walk command, will the character step on every single point/pixel between its origin and destination (x=51, x=52, x=53, etc etc), or does that depend on the character's walking speed?

In other words, can I always be sure that a 1-pixel wide region will always be stepped on, or does this change with the character speed? (so if the horizontal walking speed is 2, then he would step on x=52, x=54, x=56 and so on).

Khris

If .MovementLinkedToAnimation is true, then the character will always move roughly by .WalkingSpeed pixels. So yes, she will absolutely skip coordinates in between.
Detecting the passing of a one-pixel line is probably easier achieved with a coordinate check in rep_exe_always.

Laura Hunt

Quote from: Khris on Tue 16/03/2021 09:42:26
If .MovementLinkedToAnimation is true, then the character will always move roughly by .WalkingSpeed pixels. So yes, she will absolutely skip coordinates in between.

Ah, perfect, that's what it looked like. Thanks for confirming!

QuoteDetecting the passing of a one-pixel line is probably easier achieved with a coordinate check in rep_exe_always.

Except if that line is diagonal :) Basically, I'm trying to figure out the narrowest region I can get away with (in iso perspective) in order to ensure that it will always get stepped on because I've been probably making them much larger than needed. This helps a lot!

Khris

Assuming your line is between 100,100 and 400,200 you can turn that into y = x / 3 + 67.
Now let's say the player is at 200,150. When you insert the x coordinate into the equation, you'll get y = 200 / 3 + 67 = 134.
Compare the player's y of 150 to 134 to find out whether they're below or above. Basically:
Code: ags
  bool isBelow = player.y > player.x / 3 + 67;

If that value changes from true to false, they crossed the line while walking up and/or right.

Laura Hunt

#9
Very cool, thanks! I *did* consider using the general line equation, but I stupidly assumed it would be way more hassle to calculate than simply drawing a region, and never even bothered to give it a try. Thanks for proving me wrong :)

The thing is, how would I check for the exact moment when the value changes in order to trigger an event right at that moment? Using a second bool that I can compare isBelow to and that only gets updated when isBelow changes?

morganw

Quote from: HandsFree on Tue 16/03/2021 00:29:24
@Morgan, are you saying this is expected behaviour? We are still in v3.3.

Without the precise (1:1) mask for the walkable area the ability to move precisely won't be guaranteed, your results may vary depending on whether the result is an old or even number. Whether this is the problem or not I'm not sure because you also specify eAnywhere, but you also mention regions and these have their precision affected in the same way.

Outside of using AGS 3.5 I think you have to code/draw around these issues.

Khris

Quote from: Laura Hunt on Tue 16/03/2021 10:33:53The thing is, how would I check for the exact moment when the value changes in order to trigger an event right at that moment? Using a second bool that I can compare isBelow to and that only gets updated when isBelow changes?
Exactly; I always use this:

Code: ags
bool wasBelow;

function repeatedly_execute_always() {
  bool isBelow = ...;

  if (isBelow && !wasBelow) { ... }  // player crossed downwards

  if (wasBelow && !isBelow) { ... } // player crossed upwards

  wasBelow = isBelow;
}


HandsFree

I left it for now because in this scene it is not really gamebreaking, but now I'm getting worried.
We have this function that is in the game for years, and suddenly behaves strange.
So I put in two displays.
Code: ags

function enter_screen() {
  if (player.x<0) player.Walk(67, player.y, eBlock, eAnywhere); //enter from left
  else if (player.x>580) player.Walk(567, player.y, eBlock, eAnywhere); //enter from right
  else if (player.y>395){
    Display("walk to 350");
    player.Walk(player.x, 350, eBlock, eAnywhere); //enter from bottom
    Display("player.x = %d. player.y = %d.", player.x, player.y );
  }
  EnableRegions();
}

The result is:
"Walk to 350"
"player.x = 304.player.y = 372"

The function is called in room_AfterFadeIn()
What could be causing this?
Did something get broken?

Crimson Wizard

The difference between 350 and 372 is too large to be walkable mask problem (that would be 1-2 pixels in the worst case).
I don't remember if character may skip part of walk if steps are too large or it snaps to final destination.

Could you tell what version of AGS you are using and what's your game resolution?


Crimson Wizard

A sort of a blind shot, but you sure do not have any region event, or anything in repeatedly_execute_always (anywhere around your game scripts) that may stop player character?

HandsFree

Regions are disabled at this point.
The game is so big that it is hard to know for sure nothing is interfering.
It looks like it is something with walkable areas.
walking UP to y=350 she changes WA and stops there. That also happens just walking around the screen.
But walking DOWN does not make her stop. The WA's also have specific views assigned in the editor.

I can work around it bij changing the layout of the WA's a bit, but I'm still puzzled.

SMF spam blocked by CleanTalk