Major headaches over door offset calculations

S

Spin Attaxx

Guest
So I asked this recently and it got largely ignored. I guess to be fair, I didn't thorougly define the problem, so let's try this again.

So I have a door object (32 x 256) that takes me to a different room when I touch it. It has an offset variable that puts me in the new room at a position relative to how I left it - so if I'm jumping, I'm in the same spot when I enter, and if I'm just running, that run goes uninterrupted. At least, in theory. What I've noticed is that for a lone frame, if I leave a room on the ground, I'm not considered "grounded". It's more noticeable when I have an idle and run sprite, since the idle sprite appears briefly.

After much headaches, I believe my offset calculations and/or the sprite origin of my door/collision mask (which is 60 x 147) are what's causing it. See, here's the code for my door object:
Code:
//NOTE: Door's origin is at 0 x 256 and player collision mask's is at 30 x 74
offset_y = other.bbox_bottom - y; //Player bottom minus door y equals offset
//These three vars are defined in instance creation code:
other.x = target_x; //Player goes to target X location
other.y = target_y + offset_y - 73; //Player goes to target Y location - minus 73 to account for collision mask's center
room_goto(target_r); //Game switches to target room
In creation code, I would (for example) put "607" for target_y, as that is the last area of free space before the ground starts. In addition, my door's sprite doesn't sink into/float above the ground.

Now ideally, running on the ground should mean offset_y equals 0, and thus nothing gets added, and thus I'm put into position directly on the ground. However, for some reason, I'm either instead put slightly higher, or I sink two pixels into the ground. Looking in the debug mode, apparently the game considers my doors' y to be 1 extra pixel down than what I put as my target_y (in other words, it's in the same line of pixels as my ground).

So I modify my offset calculations so it's "other.bbox_bottom - (y-1)" (so it'll be the same as making my door's origin one pixel higher)... and it doesn't work. Well, it does, but only on one door. And I for the life of me can't figure out why that door in particular works as intended, when it is unchanged from every other door.

So yeah. This has been a pretty big impasse, I don't know how to get around it, it's giving me headaches, and I'd like to avoid being greeted with dead air again now that I've outlined my problem more thoroughly. If you need more info, please ask.

EDIT: Oh, also, I don't know if this is a contributor, but apparently my (persistent) player appears before any other solid objects do for a VERY brief time (like, if I pause at exactly the right time, I'll get a screenshot of my character, but no level). I don't know what's causing this either.
 
Last edited by a moderator:

TheouAegis

Member
Why are you calculating the offset from the bottom of the players bounding box even though you say yourself that you need to account for the players y offset anyway? Why not just take it from the players offset to begin with? Maybe you really are having a math issue, but I don't know. But I mean, if the Target location is based on the door itself, and you need to move the player to the new location that is based on the door but account for the fact that the players offset is not the same as the doors, then really that is all you need.
 
S

Spin Attaxx

Guest
Why are you calculating the offset from the bottom of the players bounding box even though you say yourself that you need to account for the players y offset anyway? Why not just take it from the players offset to begin with? Maybe you really are having a math issue, but I don't know. But I mean, if the Target location is based on the door itself, and you need to move the player to the new location that is based on the door but account for the fact that the players offset is not the same as the doors, then really that is all you need.
Do forgive me if I misunderstand this - I'm not quite sure I understand what you mean. This image (made by someone when I asked about how to make this kind of door a while back) is the basic idea behind how it works:



If you're saying "why are you bothering with bbox_bottom when other.y is good enough", then... I'm not sure. Could've sworn it didn't work back then, but changing my code slightly it works exactly the same way as "other.y - y". Up to and including this bizarre problem of "you're not on the ground/you're very slightly in the ground except for this one door that's no different in code from all the others" that logically shouldn't exist and yet somehow does.
 

TheouAegis

Member
You didn't accidentally reverse your signs, did you?
Did you verify the position the door dumps the player at is the right position? Maybe you set the position based on the door's origin being elsewhere or changed the target room and forgot to change the position of the door.
 
S

Spin Attaxx

Guest
You didn't accidentally reverse your signs, did you?
Did you verify the position the door dumps the player at is the right position? Maybe you set the position based on the door's origin being elsewhere or changed the target room and forgot to change the position of the door.
No, the offset works 99% as intended, I've checked, rechecked, retweaked, rechecked and retweaked the target_y variables, and I haven't changed any target rooms. It's literally, "walking on the ground causes me to sink/jump up two pixels before going back into the proper position, except for this one specific door for some unfathomable reason". Said door's target_y is the position of the door sprite's bottom and works without incident, yet the same is true of every other door and the problem's still there. I even changed the target_y variables to be one extra than they already were. The exact same result happened; the one door worked a-ok, the others kept the problem. It's like the door refuses to recognise when offset is supposed to be 0.

EDIT: OK, I'm seriously stumped as to what the hell's going on. I changed my collision mask's origin so that it was at 30 x 146 (what counts as the very bottom for collisions - apparently if I have a 256 tall sprite, one of those pixels doesn't count). I changed my door's origin to be 255, not 256. I made target_y be the last line of empty space above the ground. I made it so that offset_y would always equal 0 if I touch a door by walking and not jumping. I used the debug mode - my player's y checked out, my offset_y checked out, basically, there was absolutely nothing that should make me sink/float ever so slightly above/below what I wanted, and I should always be grounded.

And yet despite ALL THAT... I'm not considered grounded for that one frame. All except for one door, no different from any other. I honestly don't know what is even going on. My only scrap of a clue is that my player object is persistent, and that if I pause the game at exactly the right time, for one frame when entering a room, no other objects exist. Is this it? What's causing it? How do I get around it? Please tell me; I haven't the foggiest.
 
Last edited by a moderator:

TheouAegis

Member
Did you try changing target_y to be 1 less, not "1 more"?

But.... I have no idea other than the doors would be dumping the player into the floor or above the floor... and I'm not seeing anything to cause that in the code. So I'm at a loss for now until I get an epiphany.
 
S

Spin Attaxx

Guest
I just edited my last post (didn't see this one), but I think I managed to achieve the same outcome with what I've described above anyway.

And trying that suggestion with that setup... sends me into the floor by two pixels.
 
A

anomalous

Guest
If you really want to debug that, you need to go and report every aspect of your calculation (on a single door, not multiple doors in a room), and chase it down. That's not really a "how to" it's just vanilla debug.

However I think the picture recommendation is better than whatever you are doing because it's not messing with bounding boxes, sprite origins, collision masks, all that stuff you mention.

player.y - door.y

Much easier to check and harder to screw up. If you are stumped, just change to that?

If you are randomly changing sprite offsets, messing with masks, etc, to "fix" things, your issues may never actually end (fix one, another breaks, in a loop). I know that feels wrong in your mind...listen to it.

It my experience it's good to develop a standard that ensures minimal need to mess or rely with sprite origins and collision masks, and that they are all ideally done in the same way. Consistency helps reduce errors. If you do need a single offset, fine, but set it up so all door sprites are always aligned to doors in precisely the same way or some other strict process that ensures its easy for you to draw doors without messing up other code.

And I sympathize, ironically it was my own doors that led to the lessons above, they became insanely complex and impossible to place pixel-perfect correctly until I changed it all.
 
S

Spin Attaxx

Guest
If you really want to debug that, you need to go and report every aspect of your calculation (on a single door, not multiple doors in a room), and chase it down. That's not really a "how to" it's just vanilla debug.

However I think the picture recommendation is better than whatever you are doing because it's not messing with bounding boxes, sprite origins, collision masks, all that stuff you mention.

player.y - door.y

Much easier to check and harder to screw up. If you are stumped, just change to that?
Already did; all that stuff I mentioned earlier was just for testing. However, I'm once again back at square one. If I change target_y to be two pixels less (to avoid sinking into the ground)... I wind up being on the correct area, yet for some reason I'm not seen as grounded for one frame before quickly reasserting itself.



See that 0 at the very top? That should be a 1. I'm not any number of pixels above or below where I should be (on the ground). So I'm guessing for some reason I'm not colliding with anything. Oh, and making target_y two pixels lower for that anomalous door (and that door alone) puts me two pixels above the ground briefly. So... yeah. This is still a thing.

EDIT: Oh also I should point out that I'm not using any real door sprites; it's basically just an invisible rectangle peeking in from a room edge.

EDIT EDIT: Here's the code I use to determine if grounded is true or false - maybe this is (one of) the real problem(s) here, and I shouldn't use y+1:
Code:
if (place_meeting(x,y+1,par_collide))
{
    grounded = true;
}
else grounded = false;
 
Last edited by a moderator:
Top