Fangames > Programming Questions
GM 8.1 to Studio: colliding with playerKiller inside solid block
klazen108:
--- Quote from: Pigmess on April 23, 2015, 01:22:29 PM ---Unless we want to muddy up one of our draw events (gross!) the only way we can ensure one collision check happens before another is by performing the checks in one or more of the 3 Step events.
E.g., we could do both checks in End Step, or do one in Step and another in End Step.
The downside of this is, we incur overhead when we perform a collision check in a Step event instead of using a collision event. (We also might have to rewrite the collision logic due to the change in locale.)
--- End quote ---
I would say putting the collision checks in End Step would be fine. That way you can check block collision, rectify the kid's position, and then check for playerkillers in the new position. The slowdown you'll incur from that is negligible:
As you can see, using the collision event, the player spends 4% of the time handling collision. Using the step event, he spends 2% of the time handling the collision. Never do premature optimization!
I'll have to test to see if this performs identically; I just threw it together to profile it really quick.
Pigmess:
Thanks for your reply.
You're looking at the frame where the collision event fires, right? I wouldn't expect a big difference in the time the event takes, but in my understanding, the step event fires every frame, whereas the collision event fires only when collision is detected.
I don't know the way this is implemented; I'm just going by hearsay around the Internet.
Side note:
I have tried transplanting the code from collision events to the End Step event, as you describe, but have had difficulty reproducing the correct behavior.
When I work on this tomorrow I'll post code to illustrate the changes I made in transplanting it; maybe then we can debug the resultant behavior.
UPDATE:
This is the (relevant) code I'm currently using in the player's End Step event. It more or less produces the desired behavior, but I'd rather find a more optimized, more exact refactor (more on this below).
--- Code: ---var blockInstance = instance_place(x, y, block);
var collidingWithSolid = false;
while (blockInstance != noone)
{
if (blockInstance.solid)
{
collidingWithSolid = true;
break;
}
ds_stack_push(reactivationStack, blockInstance);
instance_deactivate_object(blockInstance);
blockInstance = instance_place(x, y, block);
}
while (!ds_stack_empty(reactivationStack))
{
instance_activate_object(ds_stack_pop(reactivationStack));
}
if (!collidingWithSolid)
{
if (place_meeting(x,y,playerKiller))
{
killPlayer();
}
}
--- End code ---
As you can see, I'm deactivating block instances in a loop (storing them on a stack for reactivation after the loop) so that successive calls to instance_place return unique instances IDs.
I've left the events for collision with block and platform alone.
The above is almost a true refactor, but completely ignores collision with a playerKiller on the frame where the player intersects a solid block. The original code running in GM 8.1 wouldn't ignore collision on this frame - instead, the end step code was running after x & y were set to xprevious & yprevious and after the collision events were processed (i.e., after the solid block had pushed the player out and the player had been moved up against the edge of the solid, and appropriate speeds zeroed). I've tried reproducing this in the End Step event with no success thus far; this is an approach I continue to consider.
Another possibility I'm considering (and will try next) is to wrap the end step logic to the next frame by putting it in the Begin Step event. This would guarantee it come after the collision events of the prior step, with the (small) downside that the player's death will occur one frame later, which I expect will be difficult to discern; I'll give it a go and see if it adversely affects the engine in other ways.
UPDATE:
Moving the playerKiller End Step logic (as it originally existed) into the Begin Step event, surprisingly, did not prevent the player from being killed by a spike embedded within a wall.
I had expected it would fix the issue, albeit perhaps creating new ones, since it would rectify the relative order of the position update, the block collision processing, and the playerKiller collision check.
Navigation
[0] Message Index
[*] Previous page
Go to full version