/// <summary> /// Steps the movement of the parent entity by the controller logic. /// </summary> public override void Move() { if (_falling || !FallOnce) { _ysp += Gravity * _varService.DeltaTime; var position = _parent.Position; var size = _parent.CollisionBox.GetSize(); var tq = new TraceQuery() { Line = new Line(position.X, position.Y, position.X, position.Y + size.Y / 2.0), Ignore = _parent, CollisionPath = _parent.CollisionPath, Options = TraceLineOptions.SolidOnly }; if (TerrainOnly) { tq.Options |= TraceLineOptions.IgnoreEntities; } var tr = _collisionService.TraceLine(tq); if (!tr.Hit) { _falling = true; _ysp = Math.Min(_ysp, MaxFallSpeed); } else { _ysp = 0.0; _parent.Position = new Point(position.X, tr.ContactPoint.Y - size.Y / 2.0); _falling = false; } } base.Move(); }
/// <summary> /// Steps the movement of the parent entity by the controller logic. /// </summary> public override void Move() { var position = _parent.Position; var size = _parent.CollisionBox.GetSize(); _ysp += Gravity * _varService.DeltaTime; if (_ysp < 0.0) { var tr = _collisionService.TraceLine(GetTraceQuery(new Line(position.X, position.Y, position.X, position.Y - size.Y / 2.0))); if (tr.Hit) { _ysp *= -VerticalBounceFactor; } } else if (_ysp > 0.0) { var tr = _collisionService.TraceLine(GetTraceQuery(new Line(position.X, position.Y, position.X, position.Y + size.Y / 2.0))); if (tr.Hit) { _ysp *= -VerticalBounceFactor; } } if (_xsp < 0.0) { var tr = _collisionService.TraceLine(GetTraceQuery(new Line(position.X, position.Y, position.X - size.X / 2.0, position.Y))); if (tr.Hit) { _xsp *= -HorizontalBounceFactor; } } else if (_xsp > 0.0) { var tr = _collisionService.TraceLine(GetTraceQuery(new Line(position.X, position.Y, position.X + size.X / 2.0, position.Y))); if (tr.Hit) { _xsp *= -HorizontalBounceFactor; } } // clamp speed if (_ysp > 0.0) { _ysp = Math.Min(_ysp, MaxSpeed); } else if (_ysp < 0.0) { _ysp = Math.Max(_ysp, -MaxSpeed); } if (_xsp > 0.0) { _xsp = Math.Min(_xsp, MaxSpeed); } else if (_xsp < 0.0) { _xsp = Math.Max(_xsp, -MaxSpeed); } base.Move(); }
/// <summary> /// Performs a jump. /// </summary> private void Jump() { if (_falling) { // cant jump whilst in the air return; } var position = _player.Position; var size = _player.Size; _jumping = true; double deltaX, deltaY; switch (_movementMode) { case PlayerMovementMode.Floor: deltaX = 0.0; deltaY = -((size.Y / 2) + 5.0); break; case PlayerMovementMode.Ceiling: deltaX = 0.0; deltaY = ((size.Y / 2) + 5.0); break; case PlayerMovementMode.RightWall: deltaX = -((size.Y / 2) + 5.0); deltaY = 0.0; break; case PlayerMovementMode.LeftWall: deltaX = ((size.Y / 2) + 5.0); deltaY = 0.0; break; default: deltaX = 0.0; deltaY = 0.0; break; } var tq = new TraceQuery { Line = new Line(position.X, position.Y, position.X + deltaX, position.Y + deltaY), CollisionPath = _player.CollisionPath, Options = TraceLineOptions.IgnoreJumpThrough | TraceLineOptions.SolidOnly, Ignore = _player }; var tr = _collisionService.TraceLine(tq); if (tr.Hit) { // relative ceiling too low, nowhere to jump return; } _movementMode = PlayerMovementMode.Floor; _falling = true; _rolling = true; _player.SetBoundingBox(Player.RollingBox); var rad = _groundAngle * (Math.PI / 180.0); _xsp -= JumpSpeed * -Math.Sin(rad); _ysp -= JumpSpeed * -Math.Cos(rad); if (_ysp < JumpSpeed) { _ysp = JumpSpeed; } if (JumpSound != 0) { _audioService.PlaySoundEffect(JumpSound); } }
/// <summary> /// Called each frame. /// </summary> protected override void OnStep() { if (_logs == null) { return; } // determine if player is standing on a log by firing a trace across it var start = new Point(Position.X, Position.Y - 12.0); var end = new Point(Position.X + _logs[0].Size.X * Length, Position.Y - 12.0); var tq = new TraceQuery { Line = new Line(start, end), Ignore = this, EntityType = typeof(Player), Options = TraceLineOptions.IgnoreTiles }; var tr = _collisionService.TraceLine(tq); var idx = -1; if (tr.Hit) { var player = tr.Entity as Player; if ((player != null) && !player.MoveController.Falling) { // is any log being stood on? for (var i = 0; i < _logs.Length; i++) { var log = _logs[i]; if (Math.Abs(player.Position.X - log.Position.X) <= (log.Size.X / 2.0)) { idx = i; break; } } } } if (idx != -1) { _standIndex = idx; } // step the depression factor _depressionFactor = Utils.Lerp(_depressionFactor, (idx != -1) ? 1.0 : 0.0, 4.0, _variableService.DeltaTime); var maxDepression = _maxDepressions[_standIndex]; for (var i = 0; i <= _standIndex; i++) { var log = _logs[i]; var x = i + 1.0; var y = _standIndex + 1.0; log.Position = new Point(log.Position.X, Position.Y + maxDepression * Math.Sin(x / y) * _depressionFactor); } for (var i = _logs.Length - 1; i > _standIndex; i--) { var log = _logs[i]; var x = _logs.Length - (double)i; var y = _logs.Length - (double)_standIndex; log.Position = new Point(log.Position.X, Position.Y + maxDepression * Math.Sin(x / y) * _depressionFactor); } base.OnStep(); }