Moving Platforms

30 views
Skip to first unread message

vecima

unread,
Sep 14, 2016, 11:48:20 PM9/14/16
to ReplicaIsland Coding Community
Hi RICC,

I'm struggling with implementing moving platforms & I'm hoping maybe someone around here has some insight.

I basically define the behavior of a "Moving Platform" with:
-MovementComponent
-SolidSurfaceComponent with 4 surfaces

^^those two are in the static data^^

-RenderComponent
-SpriteComponent
-DynamicCollisionComponent
-HitReactionComponent
-SimplePatrolComponent

and a new component
-MovingPlatformComponent

The behavior is basically that the the whole moving platform has a vulnerability volume of type DEPRESS over the surface of the platform (my player characters have a DEPRESS attack volume near their feet).  When the player stands on the platform the HitReactionComponent is triggered for the DEPRESS action.  I modified the HitReactionComponent to track multiple attackers (as I have 2 characters at once, both of which could be standing on the moving platform).  The update method of the MovingPlatformComponent fetches the HitReactionComponent, fetches the attackers from that, and adds to their position by the delta position of the parent object (the platform).  This works fine for platforms moving left/right and even down, but I have an issue with a platform moving up where the player characters are "popping" up a tiny bit then falling to the platform again as it moves upward.  I need them to stay on the platform and smoothly move upward with it.

Here is the update method in the MovingPlatformComponent:
public void update(float timeDelta, BaseObject parent)
{
   
GameObject parentObject = (GameObject) parent;

   
if (parentObject.getCurrentAction() == ActionType.HIT_REACT && parentObject.lastReceivedHitType == CollisionParameters.HitType.DEPRESS)
   
{
     
HitReactionComponent hitReact = parentObject.findByClass(HitReactionComponent.class);
     
if (hitReact != null)
     
{
         
Set<GameObject> attackers = hitReact.getLastAttackers();
         if (attackers != null && attackers.size() > 0) {

           
for (GameObject attacker : attackers) {
               
if (attacker != null) {
                 
float positionDeltaX = parentObject.getPosition().x - this.mLastPosX;
                 
float positionDeltaY = parentObject.getPosition().y - this.mLastPosY;

                  attacker
.getPosition().x += positionDeltaX;
                  attacker
.getPosition().y += positionDeltaY;
               
}
           
}
         
}
     
}
   
}

   
this.mLastPosX = parentObject.getPosition().x;
   
this.mLastPosY = parentObject.getPosition().y;
}

let me know if any other relevant code would help and I'll post it.

Thanks!
Eric

Chris Pruett

unread,
Sep 16, 2016, 12:25:24 AM9/16/16
to replica-island-...@googlegroups.com
This type of problem is pretty common with vertical platforms in all kinds of scrolling engines.  Usually the cause is gravity and order dependencies: the player falls a little bit into the platform, then is snapped up out of it, then the platform itself moves.  Or something like that.  Since Replica Island doesn’t enforce strict component execution ordering you probably want to solve this by accounting for gravity in your delta math, or by just turning it off completely.  I vaguely remember doing something similar for the orbital gravity around The Source.  

It might be sufficient to just turn gravity off when a moving platform has snagged another character and then carefully turn it back on when the connection is lost.

Chris



--
You received this message because you are subscribed to the Google Groups "ReplicaIsland Coding Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to replica-island-coding...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

vecima

unread,
Oct 2, 2016, 11:16:15 PM10/2/16
to ReplicaIsland Coding Community
Thanks for giving me some direction.  I had a problem when trying to cancel out gravity that my player would slowly sink through a platform moving up.

I've solved my original problem by doing an additional check that movement is happening in y+ direction and snapping player position to the top of the platform.  I also updated the HitReactionComponent to both track all current "attackers" and to be able to forget them when commanded.  I then updated the MovingPlatforrmComponent to direct the HitReactionComponent to forget each attacker if their background collision normal (y component) was 0.  Additionally I call attacker.setLastTouchedFloorTime(gameTime) for each attacker to be sure that the player can always jump to break contact with the moving platform.  This would be problematic if the vulnerability volume were much bigger than the actual SolidSurfaceComponent, but I only extend the volume a few pixels above the surface.

All this effort got me wondering:  I'm achieving "contact" by giving the player character an attack volume with HitType DEPRESS and the moving platform object a vulnerability volume with HitType DEPRESS (and a HitReactionComponent).  Is this even the best way?  Would it be better to just have the MovingPlatformComponent cast a few rays upward for one pixel and register anything it finds to be updated with the movement delta?  That would reduce complexity and allow me to remove the HitReactionComponent from this game object completely.  Failing the moving platform "finding" objects itself, is there a way for the BackgroundCollisionComponent to identify that the collision surface belongs to a game object?  ... I sort of thought the SolidSurfaceComponent registered some surfaces each frame and the collision system processed them without knowing where they came from.


To unsubscribe from this group and stop receiving emails from it, send an email to replica-island-coding-community+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages