/// <summary> /// _confirmDamage callback. Optionally override this in a child class to only deal damage to specific actors. Returns true by default /// (i.e. deals damage to any Actor). /// </summary> /// <param name="ourObject">The scene object this HazardComponent is on.</param> /// <param name="theirObject">The scene object the ActorComponent is on.</param> /// <param name="actor">The ActorComponent on the scene object that entered the trigger.</param> /// <returns>True if the HazardComponent should deal damage to the Actor.</returns> protected virtual bool _confirmDamage(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor) { // this should be overridden by derived classes // a return value of false will result in the damage not being applied // a return value of true will result in the damage being applied return true; }
protected override bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor) { base._confirmPickup(ourObject, theirObject, actor); if(actor is PlayerActorComponent) { if(ourObject.TestObjectType(PlatformerData.SpawnedObjectType)) { CheckpointSystemSpawnedObjectComponent spawnedComp = ourObject.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>(); if(spawnedComp != null) spawnedComp.Recover = false; } // Play sound effect here! SoundManager.Instance.PlaySound("sounds", "checkpoint"); CheckpointManager.Instance.CheckpointReached(); // set the new respawn position of the actor if (SceneObject != null) actor.RespawnPosition = SceneObject.Position; else actor.RespawnPosition = actor.Actor.Position; //GUICanvas.Instance.SetContentControl(new Checkpoint_GUI(SceneObject.Position + new Vector2(0, -5))); effect.Spawn(SceneObject.Position); // true = yes, i was picked up. delete me! return true; } // false = no, this guy didn't pick me up. return false; }
/// <summary> /// Constructor. Stores the ActorComponent that this animation manager is associated with and calls _registerAnimStates. /// </summary> /// <param name="actorComponent">The ActorComponent associated with this animation manager.</param> public ActorAnimationManager(ActorComponent actorComponent) { // get a reference to the actor component _actorComponent = actorComponent; // register animation states _registerAnimStates(); }
public override void ActorSpawned(ActorComponent actor) { base.ActorSpawned(actor); this.actor = actor as IEnemyActor; // make sure all the actors are in the idle state when they spawn //CurrentState = FSM.Instance.GetState(this, "idle"); }
/// <summary> /// Decides whether or not the Actor should be allowed to pick this collectible up. Override this /// in derived classes. Default always returns true. /// </summary> /// <param name="ourObject">The scene object this CollectibleComponent is on.</param> /// <param name="theirObject">The scene object the ActorComponent is on.</param> /// <param name="actor">The ActorComponent that's trying to pick up this collectible.</param> /// <returns>True if the Actor should be allowed to pick up the collectible.</returns> protected virtual bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor) { if(theirObject.TestObjectType(PlatformerData.PlayerObjectType)) if(effect != null) effect.Spawn(SceneObject.Position); // this should be overridden by derived classes // a return value of false will result in the collectible remaining in the scene // a return value of true will result in the collectible being removed from the scene return true; }
protected override bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor) { base._confirmPickup(ourObject, theirObject, actor); if(actor is PlayerActorComponent) { if (ourObject.TestObjectType(PlatformerData.SpawnedObjectType)) { CheckpointSystemSpawnedObjectComponent spawnedObject = ourObject.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>(); if (spawnedObject != null) spawnedObject.Recover = false; } actor.HealDamage(healingValue, ourObject); SoundManager.Instance.PlaySound("sounds", "health"); // true = yes, i was picked up. delete me! return true; } // false = no, this guy didn't pick me up. return false; }
protected override bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor) { base._confirmPickup(ourObject, theirObject, actor); PlayerActorComponent player = actor as PlayerActorComponent; if (player != null) { if (ourObject.TestObjectType(PlatformerData.SpawnedObjectType)) { CheckpointSystemSpawnedObjectComponent spawnedObject = ourObject.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>(); if (spawnedObject != null) spawnedObject.Recover = false; } player.AddGoldCrystal(); SoundManager.Instance.PlaySound("sounds", "gold_crystal"); return true; } return false; }
/// <summary> /// Called from an actor possessed by this controller each time it spawns. /// </summary> /// <param name="actor">The possessed ActorComponent that spawned.</param> public virtual void ActorSpawned(ActorComponent actor) { }
/// <summary> /// Called from an actor possessed by this controller each time it lands on a valid platform. /// A valid platform is a scene object with either a PlatformComponent or a SolidPlatformComponent. /// </summary> /// <param name="actor">The possessed ActorComponent that landed on a platform.</param> /// <param name="platform">The scene object that the Actor landed on.</param> public virtual void ActorLanded(ActorComponent actor, T2DSceneObject platform) { }
/// <summary> /// Called from an actor possessed by this controller each time it collides with a wall or ceiling. /// (as defined on a per-actor basis by the ActorComponent's _maxSurfaceNormalY field). /// </summary> /// <param name="actor">The possessed ActorComponent that hit a wall.</param> /// <param name="info">The collision info for the collision that lead to this callback.</param> /// <param name="dot">Dot product of the velocity and the normal.</param> public virtual void ActorHitWall(ActorComponent actor, T2DCollisionInfo info, float dot) { }
/// <summary> /// Called from an actor possessed by this controller each time it dies. /// </summary> /// <param name="actor">The possessed ActorComponent that died.</param> /// <param name="damage">The amount of damage that was taken the instant of death. This should always be reliable /// because the default Kill method on the ActorComponent deals damage via the same methods as anything else.</param> /// <param name="sourceObject">The scene object related to the damage transaction. In most cases, the owner /// of the component that dealt the damage).</param> public virtual void ActorDied(ActorComponent actor, float damage, T2DSceneObject sourceObject) { }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { if (actor.PreviousState.Equals("inAir")) actor._jump = false; // update ground force based on the ground surface normal actor._groundForceVector = Vector2.Multiply(new Vector2(-actor._groundSurfaceNormal.Y, actor._groundSurfaceNormal.X), actor._groundSurfaceForce); // set desired ground velocity if (actor._GroundObject == null || actor._GroundObject.Physics == null) actor._groundVelocity = actor._groundForceVector; else actor._groundVelocity = actor._groundForceVector + actor._GroundObject.Physics.Velocity; // modify movement and increment inherited velocity actor._moveAccel = actor._groundAccel * elapsed * (float)Math.Pow(actor._groundFriction, 1.5); actor._moveDecel = actor._groundDecel * elapsed * (float)Math.Pow(actor._groundFriction, 1.5); // inherit ground velocity if (actor._inheritedVelocity != actor._groundVelocity) { float incrementX = (actor._groundVelocity.X - actor._inheritedVelocity.X) * (float)Math.Pow(actor._groundFriction, 2); float incrementY = (actor._groundVelocity.Y - actor._inheritedVelocity.Y) * (float)Math.Pow(actor._groundFriction, 2); actor._inheritedVelocity.X += incrementX; actor._inheritedVelocity.Y += incrementY; if (Math.Abs(actor._groundVelocity.X - actor._inheritedVelocity.X) < actor._groundAccel * actor._groundFriction) actor._inheritedVelocity.X = actor._groundVelocity.X; if (Math.Abs(actor._groundVelocity.Y - actor._inheritedVelocity.Y) < actor._groundAccel * actor._groundFriction) actor._inheritedVelocity.Y = actor._groundVelocity.Y; } // move in the direction specified, or slow to a stop based on damping if (actor._moveLeft) { actor._moveSpeed.X -= actor._moveAccel; } else if (actor._moveRight) { actor._moveSpeed.X += actor._moveAccel; } else { if (Math.Abs(actor._moveSpeed.X) > actor._moveDecel) { int dirMod; if (actor._moveSpeed.X < 0) dirMod = -1; else dirMod = 1; actor._moveSpeed.X -= actor._moveDecel * dirMod; } else { actor._moveSpeed.X = 0; } } // clamp move speed to maxMoveSpeed actor._moveSpeed.X = MathHelper.Clamp(actor._moveSpeed.X, -actor._maxMoveSpeed, actor._maxMoveSpeed); // get the modified movement vector if (actor._groundObject != null && !actor._groundSurfaceNormal.Equals(new Vector2(0, -1))) { // angled ground object: find walk vector actor._moveVector = Vector2.Multiply(new Vector2(-actor._groundSurfaceNormal.Y, actor._groundSurfaceNormal.X), actor._moveSpeed.X); } else { // no ground object or flat ground object: zero "Y walk" actor._moveVector = new Vector2(actor._moveSpeed.X, 0); } // apply move vector to actor velocity actor._actor.Physics.Velocity = actor._moveVector; // apply ground force actor._actor.Physics.Velocity += actor._inheritedVelocity; // do jumping if (actor._JumpingDown && actor._groundObjectComponent is OneWayPlatformComponent) { // clear the active platforms list so we stop colliding with these platforms actor._activePlatforms.Clear(); // set the animation state FSM.Instance.SetState(actor._animationManager, "fall"); // manually override the 'on ground' state actor._onGround = false; // use the jump-down event and any regular jump event // (this is to specifically allow for pushy controllers to just send both jump // events when a jump-down condition is met on the controller side and // not have to worry about what kind of platform the actor is on. // See PlayerController in the PlatformerDemo) actor._jumpDown = false; actor._jump = false; // record this as the last time we jumped down actor._lastJumpDownTime = TorqueEngineComponent.Instance.TorqueTime; } else if (actor._Jumping && !actor.IsMaxJumpTime()) { actor.jumpDuration += (elapsed / 100); // jump up actor._actor.Physics.VelocityY = actor._groundVelocity.Y - (actor._jumpForce * ((float)Math.Exp(actor.jumpDuration) / 2)); // set the appropriate animation state for jumping if (Math.Abs(actor._moveSpeed.X) < 0.01f) FSM.Instance.SetState(actor._animationManager, "jump"); else FSM.Instance.SetState(actor._animationManager, "runJump"); // override the 'on ground' state manually // (this allows the animation manager, among other things // to react to jumping properly) actor._onGround = false; // set actor's jump flag to false // (we used the jump 'event' - let's turn it off so it's not used again) // (without this, it's possible to launch yourself up crazy distances // by jumping off the ground through a ladder.. or 'something') // (we also want to cancel the jump-down flag in case a lazy // controller sent both events) actor._jump = false; actor._jumpDown = false; actor.isJumping = true; } else { actor._jump = false; actor.isJumping = false; actor.jumpDuration = 0.0f; } }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { base.UpdatePhysics(actor, elapsed); PlayerActorComponent playerActor = actor as PlayerActorComponent; if (playerActor == null) return; if (playerActor.spawning) { playerActor._actor.Physics.Velocity = Vector2.Zero; return; } // we wanna wait for the animated sprite to disappear after animation if (!playerActor.AnimatedSprite.Visible) { if (playerActor.Lives > 0) playerActor._respawn(); } // apply gravity to allow for the "jumpyness" playerActor._actor.Physics.VelocityX = 0; playerActor._actor.Physics.VelocityY += actor.Gravity * elapsed; }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { actor._actor.Physics.Velocity = Vector2.Zero; }
/// <summary> /// Confirms whether or not an Actor should be allowed to use this checkpoint at the moment. /// </summary> /// <param name="actor">The Actor that's currently trying to use the checkpoint.</param> /// <returns>True if the Actor should be allowed to use the checkpoint at the moment.</returns> protected virtual bool _confirmCheckpoint(ActorComponent actor) { // this should be overridden by derived classes // a return value of false will result in the checkpoint not being counted // a return value of true will result in the checkpoint being counted and progress being saved return true; }
public override void ActorDied(ActorComponent actor, float damage, T2DSceneObject sourceObject) { }
/// <summary> /// This is called when an Actor stops using this platform as its GroundObject. /// </summary> /// <param name="actor">The actor that left this platform.</param> public virtual void ActorLeft(ActorComponent actor) { foreach (TorqueComponent comp in _platform.Components) if (comp as PlatformBehavior != null) (comp as PlatformBehavior).ActorLeft(actor); if (_actorsCarrying.Contains(actor)) _actorsCarrying.Remove(actor); }
/// <summary> /// This is called whenever an Actor stops using this platform as its GroundObject. /// </summary> /// <param name="actor">The Actor that left on this platform.</param> public virtual void ActorLeft(ActorComponent actor) { }
/// <summary> /// This is called whenever an Actor begins using this platform as its GroundObject. /// </summary> /// <param name="actor">The Actor that landed on this platform.</param> public virtual void ActorLanded(ActorComponent actor) { }
protected override bool _OnRegister(TorqueObject owner) { if (!base._OnRegister(owner)) return false; // record our scene object _sceneObject = owner as T2DAnimatedSprite; // make sure this component is being used properly // (this might be too strict, but better safe than sorry) if (_sceneObject == null || _sceneObject.MountedTo == null) { Assert.Fatal(false, "ActorPuppetComponent must be used on a T2DAnimatedSprite that's mounted to a T2DSceneObject that has an ActorComponent. \n\nThe owner of the ActorPuppetComponent will be deleted if this message is ignored."); owner.MarkForDelete = true; return false; } // find the actor component of the object we're mounted to if (_sceneObject.MountedTo.TestObjectType(PlatformerData.ActorObjectType)) _master = _sceneObject.MountedTo.Components.FindComponent<ActorComponent>(); // make sure there is a valid actor if (_master == null) { Assert.Fatal(false, "ActorPuppetComponent must be used on a T2DAnimatedSprite that's mounted to a T2DSceneObject that has an ActorComponent. \n\nThe owner of the ActorPuppetComponent will be deleted if this message is ignored."); owner.MarkForDelete = true; return false; } // create the dummy pivot object _pivotObject = new T2DSceneObject(); _pivotObject.Size = _master.Actor.Size; _pivotObject.Position = _master.Actor.Position; _pivotObject.CreateWithLinkPoints = true; TorqueObjectDatabase.Instance.Register(_pivotObject); // get the current offset of the mounted puppet sprite _sceneObject.SnapToMount(); Vector2 offset = (_sceneObject.Position - _master.Actor.Position) / (_master.Actor.Size / 2); // account for flipped objects // (when the mount position is updated it will reverse this if it was supposed to be flipped) if (_master.Actor.FlipX) offset.X = -offset.X; if (_master.Actor.FlipY) offset.Y = -offset.Y; // do the big switcheroo // (mount pivot object offset by actorPivotOffset to the center of the master actor // scene object and offset by actorPivotOffset) _pivotObject.LinkPoints.AddLinkPoint("SpriteOffset", offset, 0); _master.Actor.LinkPoints.AddLinkPoint("Center", Vector2.Zero, 0); _pivotObject.Mount(_master.Actor, "Center", _actorPivotOffset, 0, true); _pivotObject.SnapToMount(); _sceneObject.Dismount(); _sceneObject.Mount(_pivotObject, "SpriteOffset", -_actorPivotOffset, 0, true); _sceneObject.SnapToMount(); // make sure we have the correct mounting settings // (it's only actually neccesary that TrackMountRotation be false if the // RotateToGroundSurface is enabled. // the other field values just make good sense) _sceneObject.TrackMountRotation = true; _sceneObject.IsOwnedByMount = true; _sceneObject.InheritMountFlip = true; _sceneObject.InheritMountVisibility = true; _sceneObject.UseMountForce = false; _pivotObject.TrackMountRotation = false; _pivotObject.IsOwnedByMount = true; _pivotObject.InheritMountFlip = true; _pivotObject.InheritMountVisibility = true; _pivotObject.UseMountForce = false; // set the master's AnimatedSprite property to this object // (note: it's possible that this overwrites another ActorPuppet on the master // object. as to why you would ever need two animated sprite puppets on the // same actor, i have no clue) _master.AnimatedSprite = _sceneObject; _master.ActorPuppet = this; // set the proper object type of this component's owner _sceneObject.SetObjectType(PlatformerData.ActorObjectType, true); return true; }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { // get desired inherited velocity if (actor._ladderObject == null || actor._ladderObject.Physics == null) actor._groundVelocity = Vector2.Zero; else actor._groundVelocity = actor._ladderObject.Physics.Velocity; // inherit groundVelocity directly if (actor._inheritedVelocity.X != actor._groundVelocity.X) actor._inheritedVelocity.X = actor._groundVelocity.X; // interpret vertical movement flags if (actor._moveUp) actor._moveSpeed.Y = -actor._climbUpSpeed; else if (actor._moveDown) actor._moveSpeed.Y = actor._climbDownSpeed; else actor._moveSpeed.Y = 0; // jump only when holding right or left if (actor._Jumping || actor._jumpDown) { if (actor._moveLeft || actor._moveRight) { actor._actor.Physics.VelocityY -= actor._jumpForce * actor._climbJumpCoefficient; if (actor._moveLeft) { actor._moveSpeed.X = -actor._maxMoveSpeed * actor._climbJumpCoefficient; actor._actor.Position = new Vector2(actor._actor.Position.X - actor._ladderAttachXThreshold, actor._actor.Position.Y); // set the appropriate animation state for jumping off a ladder FSM.Instance.SetState(actor._animationManager, "climbJump"); } else if (actor._moveRight) { actor._moveSpeed.X = actor._maxMoveSpeed * actor._climbJumpCoefficient; actor._actor.Position = new Vector2(actor._actor.Position.X + actor._ladderAttachXThreshold, actor._actor.Position.Y); // set the appropriate animation state for jumping off a ladder FSM.Instance.SetState(actor._animationManager, "climbJump"); } } // apply X inherited force from ladder actor._actor.Physics.VelocityX = actor._inheritedVelocity.X + actor._moveSpeed.X; actor._Climbing = false; // set actor's jump flag to false // (we used the jump 'event' - let's turn it off so it's not used again) // (without this, it's possible to launch yourself up crazy distances // by jumping off the ground through a ladder.. or something) actor._jump = false; } else { // apply ladder's vel to the player actor._actor.Physics.VelocityX = actor._groundVelocity.X; actor._actor.Physics.VelocityY = actor._groundVelocity.Y + actor._moveSpeed.Y; } }
public override void ActorLanded(ActorComponent actor) { base.ActorLanded(actor); T2DAnimatedSprite animSprite = Owner as T2DAnimatedSprite; if (animSprite != null && !_fallTriggered) { animSprite.PlayAnimation(_triggeredAnimation); animSprite.AnimationTimeScale = _timeout; } _fallTriggered = true; }
public override void ActorLanded(ActorComponent actor) { base.ActorLanded(actor); if (!actor.Actor.TestObjectType(PlatformerData.PlayerObjectType)) return; PlatformMoveComponent mover = _platform.Components.FindComponent<PlatformMoveComponent>(); if (mover == null) return; if (!mover.IsRunning) mover.Start(); }
public abstract void UpdatePhysics(ActorComponent actor, float elapsed);
public override void UpdatePhysics(ActorComponent actor, float elapsed) { base.UpdatePhysics(actor, elapsed); // cast the actor to a "player" actor PlayerActorComponent playerActor = actor as PlayerActorComponent; if (playerActor == null) return; }
/// <summary> /// Called from an actor possessed by this controller each time it picks up a collectible. Note that /// in many cases the collectible can be deleted before this code is reached, though by default the /// collectible is only made invisible by this point, and then deleted after this code has had a /// chance to run. /// </summary> /// <param name="actor">The possessed ActorComponent that got a collectible.</param> /// <param name="collectible">The CollectibleComponent for the item that was picked up.</param> public virtual void ActorCollectedItem(ActorComponent actor, CollectibleComponent collectible) { }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { base.UpdatePhysics(actor, elapsed); // cast actor to a "player" actor PlayerActorComponent playerActor = actor as PlayerActorComponent; if (playerActor == null) return; // set inherited velocity to 0 if we passed zero or we aren't moving if (!((playerActor._moveSpeed.X + playerActor._inheritedVelocity.X < 0) == (playerActor._previousTotalVelocityX < 0)) && playerActor._moveSpeed.X == 0) { playerActor._moveSpeed.X += playerActor._inheritedVelocity.X; playerActor._inheritedVelocity.X = 0; } }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { // air-based control actor._moveAccel = actor._airAccel * elapsed; actor._moveDecel = actor._airDecel * elapsed; // move in the direction specified, or slow to a stop based on damping if (actor._moveLeft) { actor._moveSpeed.X -= actor._moveAccel; } else if (actor._moveRight) { actor._moveSpeed.X += actor._moveAccel; } else { if (Math.Abs(actor._moveSpeed.X) > actor._moveDecel) { int dirMod; if (actor._moveSpeed.X < 0) dirMod = -1; else dirMod = 1; // only dampen moveSpeed if the resulting speed is not faster if (Math.Abs((actor._moveSpeed.X + actor._inheritedVelocity.X) - (actor._moveDecel * dirMod)) <= Math.Abs(actor._moveSpeed.X + actor._inheritedVelocity.X)) actor._moveSpeed.X -= actor._moveDecel * dirMod; } else { actor._moveSpeed.X = 0; } } // clamp move speed to maxMoveSpeed if (actor._inheritedVelocity.X > 0) actor._moveSpeed.X = MathHelper.Clamp(actor._moveSpeed.X, -actor._maxMoveSpeed - actor._inheritedVelocity.X, actor._maxMoveSpeed); else actor._moveSpeed.X = MathHelper.Clamp(actor._moveSpeed.X, -actor._maxMoveSpeed, actor._maxMoveSpeed - actor._inheritedVelocity.X); // apply x velocity to actor actor._actor.Physics.VelocityX = actor._moveSpeed.X; // apply X ground force actor._actor.Physics.VelocityX += actor._inheritedVelocity.X; // apply gravity actor._actor.Physics.VelocityY += actor.Gravity * elapsed; // do pressure sensitive jumping if (actor._Jumping && actor.isJumping) { actor.jumpDuration += (elapsed / 100); if (!actor.IsMaxJumpTime()) { actor._actor.Physics.VelocityY = actor._groundVelocity.Y - (actor._jumpForce * ((float)Math.Exp(actor.jumpDuration) / 2)); // set the appropriate animation state for jumping if (Math.Abs(actor._moveSpeed.X) < 0.01f) FSM.Instance.SetState(actor._animationManager, "jump"); else FSM.Instance.SetState(actor._animationManager, "runJump"); actor._jump = false; actor._jumpDown = false; actor._onGround = false; } } else { actor._jump = false; // this prevents the little bounce at the end of the jump actor.isJumping = false; actor.jumpDuration = 0.0f; } }