/// <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();
        }
Exemple #3
0
        /// <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);
            }
        }
Exemple #4
0
        /// <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();
        }