weird collision issues.

Mugi

Member
okay, I've now tried to figure this out for 2 days and im completely lost on what the **** is going on with this.
is this just an engine bug or is there something in my code that im completely not understanding and/or doing right ?

here's the deal, i made the wall grab code (code below) only check the top left or top right collision point of my player when she's grabbing the wall, to allow more accurate detection of the area where you're supposed to be able to grab.
this works extremely well, but it only works if there's no monsters or a maximum of 1 monster on screen along with the player. Any more and the collision check just dies. What gives.

in the vid i first kill of the monster and jump around on the wall, and later return to do the same while there are monsters being spawned to the sceeen.
as shown, once there's more than one monster, the performance of the script progressively goes worse, and i have no idea why.

https://youtu.be/oxiUPY4QEuY

the code for this is as follows:

Code:
    LDA gamepad
    AND #%00010000              ; is up pressed ?
    BEQ dontMessWithGravity

    ; LDA Object_physics_byte,x
    ; AND #%00000001              ; Are we in the air ?
    ; BNE dontMessWithGravity

    LDA Object_v_speed_hi,x
    BMI dontMessWithGravity

    LDA Object_movement,x
    CMP #%00000110
    BEQ checkLeftCollisionOnly
    
    LDA collisionPoint1,x
    BEQ dontMessWithGravity
    JMP doGrab
    
checkLeftCollisionOnly:
    LDA collisionPoint0,x
    BEQ dontMessWithGravity
doGrab:
    ChangeObjectState #$07, #$08

dontMessWithGravity:

what puzzles me the most here is that the whole script only runs when the player collides with this tile, so player is automatically in X, and in addition to that, while the collision part of the code breaks up, the tile itself
continues to function, meaning that player is still in X allowing it to work.

i've tried to do the CPX player1_object to ensure that player is indeed in X during this, and i've also tried adding LDX player1_object before each check, to further ensure that we are only comparing the player's values when doing this.
aside digging into the collision code in general, im just lost now, is this something really easy im just not seeing or is this an actual bug going on with the collision code ?
 

Mugi

Member
yeah, this is a tile script. i really dont get it how it does this, because this script is the one and only thing in my game that even can set the player to action state 07 (wall hang) so the fact that she still grabs the wall,
means that the code somehow passes the collision checks and sets the player action state, even though it's obviously shown that the collision check should not be passed, the player's top collision points are nowhere near
the tile.
 

dale_coop

Moderator
Staff member
Weird... even with a:
Code:
	CPX player1_object
	BNE dontMessWithGravity

it's still broken when monsters?
 

dale_coop

Moderator
Staff member
Have you made modifications in the Check For Vertical something Macro? or in the TileCollisions.asm script? That could have cause that?
 

dale_coop

Moderator
Staff member
Try with the:
Code:
	CPX player1_object
	BNE dontMessWithGravity
at the beginning and:
Code:
dontMessWithGravity:
	LDX currentObject
at the end of your script.
 

Mugi

Member
no change...
it looks like the object_movement,x is not working correctly, and it seems that it takes the face direction of the first slime that spawns to the screen as x instead of the player in this case.
doing LDX player1_object before that check doesnt do anything though...
 

dale_coop

Moderator
Staff member
How do you spawn your slime monsters? made specific code assigned to a tile? to another invisible monster?
I was thinking, maybe your monster is created BEFORE your player object? (that should not be... as the player is created first, as object 0, in the engine... except if you modified that)?
 

Mugi

Member
the monster spawner is an ai action ran by the monster that sits on the hole in the wall (the red eyes)

Code:
CountObjects #%00001000, #$00
    LDA monsterCounter
    CMP #$04
    BCS monsterLimitReached
    
doMonsterSpawn:    
    LDA Object_x_hi,x
    STA temp
    LDA Object_y_hi,x
    STA temp1
    
    LDA currentStage
    CMP #$02
    BEQ spawnStageBmonster
    RTS
spawnStageBmonster:    
    CreateObject temp, temp1, #$11, #$00, currentNametable

monsterLimitReached:
 

dale_coop

Moderator
Staff member
That looks correct for me.
Do you have the same issue, when you place manually the 4 monsters on the screen? (not spawn)
 

Mugi

Member
yeh, i just tested that too.
it appears that it only works when a monster is walking in a different direction than the player (im not sure if it's the first or the last monster, i placed 4 on the screen)

im starting to believe this is something that's messed up further deep in the collision code itself, because my code loads player in x and then checks for movements of X and collisions of X
so something messes X up somewhere down the road.

The red eyes monster doesnt seem to affect this because it never moves, it sits there and has ignore gravity ticked so that monster doesnt mess up the script. only things that move do.
 

dale_coop

Moderator
Staff member
But if your code loads the player object into X, you would have to put back the original pointer into X when your code is finished. Else you will mess up the collision code.
Because if I remember well, the tilecollision code is a loop on objects (it loads the current object in X)
 

Mugi

Member
i tried using
TXA
STA tempx
on the beginning and then ending the script with
LDX tempx

but it has no effect on this.

if i have 4 enemies on the screen, the first enemy is still used for the face direction instead of the player
 

Mugi

Member
that's what i said too.
the checks against X work perfectly (there's a check for vertical speed, to only make grabbing wall possible when you're falling) which never fails, you can only grab the wall when you're falling.
right below that is the check for object_movement,x which fails.
 

Mugi

Member
yeah.

the code checks if the player is facing left or right.
if facing left, it will check collision in collisionpoint0 (top left corner) and if the player is facing right, it will check collision on collisionpoint1 (top right corner).
if the collision check fails, she will not grab the wall.
this allows for extremely accurate detection of the wallgrab tiles so that you cant grab walls outside of them just because her legs are colliding with the tile.

as you see on the video, it works just fine without the monsters, it's only off by one or two pixels, which is fine enough for me, but the facedirection / collision point check stops working when the monsters are on screen making it behave as it was (it checks all collision points) thats why she grabs the wall much higher when the monsters are on screen (the legs are colliding with the tile.)

while that happens, the check for vertical speed is still working (object_v_speed,hi,x returns the players vspeed) but for whatever reason the object_movement,x doesnt respect X and just checks for the monster instead (i confirmed it checks for the last monster ID) Loading player1_object in X before the check doesnt work either, it still just loads the monster.

RTS'ing the entire script if it's not player1_object also has no effect.

and if you attempt to force push player1_object into stack with
LDX player1_object
TXA
PHA

it has no effect when done at the beginning of the script, and if you do it before the check for object_movement,x it will crash the game....
 

dale_coop

Moderator
Staff member
A better check would be:
Code:
	LDA Object_movement,x
	AND #%00000110
    BNE checkLeftCollisionOnly

What do you think?
 

Mugi

Member
and this is the point where i feel like a retard, haha
now it works, you're right.

(that said, im not sure why it even makes a difference since in the platformer it can only be one or the other, left or right so checking against a binary value should do. The more you know™)
i dunno what this community would do without you lol.

actually nevermind, it still occasionally fails for some reason.
It's definitely improved, but i'll have to dig further into what the hell is going on with it.

edit2: yeah, with this way, it actually does work...... until the monster changes direction, then it starts chekcing the monster again instead of the player
 
Top Bottom