/// <summary> /// Updates the Character, checks for collision and handles input. /// This method has been verified! /// </summary> /// <param name="gameTime">The game time.</param> public void Update(Map map, ParticleManager particleManager, Character[] character) { if (Ai != null) Ai.Update(character, ID, map); PressedKey = PressedKeys.None; if (keyAttack) { PressedKey = PressedKeys.Attack; if (keyUp) PressedKey = PressedKeys.Lower; if (keyDown) PressedKey = PressedKeys.Upper; } if (keySecondary) { PressedKey = PressedKeys.Secondary; if (keyUp) PressedKey = PressedKeys.SecUp; if (keyDown) PressedKey = PressedKeys.SecDown; } if (PressedKey > PressedKeys.None) { if (GotoGoal[(int)PressedKey] > -1) { SetFrame(GotoGoal[(int)PressedKey]); if (keyLeft) Face = CharacterDirection.Left; if (keyRight) Face = CharacterDirection.Right; PressedKey = PressedKeys.None; for (int i = 0; i < GotoGoal.Length; i++) GotoGoal[i] = -1; frame = 0f; } } if (StunFrame > 0f) StunFrame -= RuinExplorersMain.FrameTime; #region update dying if (DyingFrame > -1f) { DyingFrame += RuinExplorersMain.FrameTime; } #endregion #region Update Animation if (DyingFrame < 0) { Animation animation = characterDefinition.Animations[Animation]; KeyFrame keyFrame = animation.KeyFrames[AnimationFrame]; frame += RuinExplorersMain.FrameTime * 30.0f; if (frame > (float)keyFrame.Duration) { int pframe = AnimationFrame; script.DoScript(Animation, AnimationFrame); CheckTrigger(particleManager); frame -= (float)keyFrame.Duration; if (AnimationFrame == pframe) AnimationFrame++; keyFrame = animation.KeyFrames[AnimationFrame]; if (AnimationFrame >= animation.KeyFrames.Length) AnimationFrame = 0; } if (keyFrame.FrameReference < 0) AnimationFrame = 0; if (AnimationName == "jhit") { if (Trajectory.Y > -100f) SetAnim("jmid"); } } #endregion #region Collision with other characters for (int i = 0; i < character.Length; i++) { if (i != ID) { if (character[i] != null) { if (!Ethereal && !character[i].Ethereal) { if (Location.X > character[i].Location.X - 90f * character[i].Scale && Location.X < character[i].Location.X + 90f * character[i].Scale && Location.Y > character[i].Location.Y - 120f * character[i].Scale && Location.Y < character[i].Location.Y + 10f * character[i].Scale) { float dif = (float)Math.Abs(Location.X - character[i].Location.X); dif = 180f * character[i].Scale - dif; dif *= 2f; if (Location.X < character[i].Location.X) { CollisionMove = -dif; character[i].CollisionMove = dif; } else { CollisionMove = dif; character[i].CollisionMove = -dif; } } } } } } if (CollisionMove > 0f) { CollisionMove -= 400f * RuinExplorersMain.FrameTime; if (CollisionMove < 0f) CollisionMove = 0f; } if (CollisionMove < 0f) { CollisionMove += 400f * RuinExplorersMain.FrameTime; if (CollisionMove > 0f) CollisionMove = 0f; } #endregion #region Update Location by Trajectory Vector2 previousLocation = new Vector2(Location.X, Location.Y); if (State == CharacterState.Ground || (State == CharacterState.Air && floating)) { if (Trajectory.X > 0f) { Trajectory.X -= RuinExplorersMain.Friction * RuinExplorersMain.FrameTime; if (Trajectory.X < 0f) Trajectory.X = 0f; } if (Trajectory.X < 0f) { Trajectory.X += RuinExplorersMain.Friction * RuinExplorersMain.FrameTime; if (Trajectory.X > 0f) Trajectory.X = 0f; } } Location.X += Trajectory.X * RuinExplorersMain.FrameTime; Location.X += CollisionMove * RuinExplorersMain.FrameTime; if (State == CharacterState.Air) { Location.Y += Trajectory.Y * RuinExplorersMain.FrameTime; } #endregion #region Collision detection if (State == CharacterState.Air) { #region Air State if (floating) { Trajectory.Y += RuinExplorersMain.FrameTime * RuinExplorersMain.Gravity * 0.5f; if (Trajectory.Y > 100f) Trajectory.Y = 100f; if (Trajectory.Y < -100f) Trajectory.Y = -100f; } else Trajectory.Y += RuinExplorersMain.FrameTime * RuinExplorersMain.Gravity; CheckXCollision(map, previousLocation); #region Land on ledge if (Trajectory.Y > 0.0f) { for (int i = 0; i < 16; i++) { if (map.Legdes[i].TotalNodes > 1) { int ts = map.GetLedgeSection(i, previousLocation.X); int s = map.GetLedgeSection(i, Location.X); float fY; float tfY; if (s > -1 && ts > -1) { tfY = map.GetLedgeYLocation(i, s, previousLocation.X); fY = map.GetLedgeYLocation(i, s, Location.X); if (previousLocation.Y <= tfY && Location.Y >= fY) { if (Trajectory.Y > 0.0f) { Location.Y = fY; ledgeAttach = i; Land(); } } else if (map.Legdes[i].isHardLedge == (int)LedgeFlags.Solid && Location.Y >= fY) { Location.Y = fY; ledgeAttach = i; Land(); } } } } } #endregion #region Land on col if (State == CharacterState.Air) { if (Trajectory.Y > 0f) { if (map.CheckCollision(new Vector2(Location.X, Location.Y + 15f))) { Location.Y = (float)((int)((Location.Y + 15f) / 64f) * 64); Land(); } } } #endregion #endregion } else if (State == CharacterState.Ground) { #region Grounded State if (ledgeAttach > -1) { if (map.GetLedgeSection(ledgeAttach, Location.X) == -1) { FallOff(); } else { Location.Y = map.GetLedgeYLocation(ledgeAttach, map.GetLedgeSection(ledgeAttach, Location.X), Location.X); } } else { if (!map.CheckCollision(new Vector2(Location.X, Location.Y + 15f))) FallOff(); } CheckXCollision(map, previousLocation); #endregion } #endregion #region Key input if (AnimationName == "idle" || AnimationName == "run" || (State == CharacterState.Ground && CanCancel)) { if (AnimationName == "idle" || AnimationName == "run") { if (keyLeft) { SetAnim("run"); Trajectory.X = -Speed; Face = CharacterDirection.Left; } else if (keyRight) { SetAnim("run"); Trajectory.X = Speed; Face = CharacterDirection.Right; } else { SetAnim("idle"); } } if (keyAttack) { SetAnim("attack"); } if (keySecondary) { SetAnim("second"); } if (keyJump) { SetAnim("jump"); } if (RightAnalog.X > 0.2f || RightAnalog.X < -0.2f) { SetAnim("roll"); if (AnimationName == "roll") { if (RightAnalog.X > 0f) Face = CharacterDirection.Right; else Face = CharacterDirection.Left; } } } if (AnimationName == "fly" || (State == CharacterState.Air && CanCancel)) { if (keyLeft) { Face = CharacterDirection.Left; if (Trajectory.X > -Speed) Trajectory.X -= 500f * RuinExplorersMain.FrameTime; } if (keyRight) { Face = CharacterDirection.Right; if (Trajectory.X < Speed) Trajectory.X += 500f * RuinExplorersMain.FrameTime; } if (keySecondary) { SetAnim("fsecond"); } if (keyAttack) { SetAnim("fattack"); } } #endregion }
/// <summary> /// Checks for x-based collisions. /// This method has been verified! /// </summary> /// <param name="map">The map.</param> /// <param name="pLoc">The previous location.</param> public void CheckXCollision(Map map, Vector2 pLocation) { if (Trajectory.X + CollisionMove > 0f) if (map.CheckCollision(new Vector2(Location.X + 25f, Location.Y - 15f))) Location.X = pLocation.X; if (Trajectory.X + CollisionMove < 0f) if (map.CheckCollision(new Vector2(Location.X - 25f, Location.Y - 15f))) Location.X = pLocation.X; }