示例#1
0
        public override void _PhysicsProcess(float delta)
        {
            var d = 2f;

            if (_isBeingKnockedback)
            {
                if (LinearVelocity.Length() <= d)
                {
                    _isBeingKnockedback = false;
                }
                else
                {
                    return;
                }
            }

            if (!isChasing())
            {
                return;
            }

            try
            {
                var toTarget = GlobalPosition.DirectionTo(_chasing.GlobalPosition);
                LinearVelocity = toTarget.Normalized() * 100;
                PlayAnimation(DirectionService.VelocityToDirection(LinearVelocity));
            }
            catch (ObjectDisposedException e)
            {
                _chasing = null;
            }
        }
示例#2
0
    public void moveToward(Vector2 position, float delta)
    {
        Vector2 wanderDirection = GlobalPosition.DirectionTo(position);

        velocity             = velocity.MoveToward(wanderDirection * maxSpeed, acceleration * delta);
        animatedSprite.FlipH = velocity.x < 0;
    }
示例#3
0
    public void _OnHurtAreaEnter(Area2D hurtArea)
    {
        // Setup explosion
        if (++pierces >= maxPierces)
        {
            smokeTrailEmitter.Emitting       = false;
            smokeTrailEmitter.Scale          = new Vector2(0, 0);
            fireTrailEmitter.Emitting        = false;
            explosionEmitter.Emitting        = true;
            explosionEmitter.ProcessMaterial = explosionMaterial;
            explosionMaterial.Gravity        = new Vector3(velocity / 2, 0f, 0f);
            exploded       = true;
            sprite.Visible = false;
            hitArea.QueueFree();
            explosionCompleteTimer.Start();
            initialBoomVelocityTimer.Start();
        }

        // Affect target(s)
        foreach (Enemy target in GetTree().GetNodesInGroup("Enemies"))
        {
            if (Position.DistanceTo(target.Position) < effectRadius)
            {
                target.Damage(damage, GlobalPosition.DirectionTo(target.GlobalPosition) * knockbackStrength);
            }
        }
    }
示例#4
0
        private void AccelerateTowardsPoint(Vector2 point, float delta)
        {
            var direction = GlobalPosition.DirectionTo(point);

            _velocity             = _velocity.MoveToward(direction * _maxSpeed, _acceleration * delta);
            _animatedSprite.FlipH = _velocity.x < 0;
        }
示例#5
0
 public override void _PhysicsProcess(float delta)
 {
     Velocity = GlobalPosition.DirectionTo(Target) * Speed;
     if (GlobalPosition.DistanceTo(Target) > 5)
     {
         Velocity = MoveAndSlide(Velocity);
     }
 }
示例#6
0
    public void RotateToward(Vector2 location, float delta)
    {
        GlobalRotation = Mathf.LerpAngle(GlobalRotation, GlobalPosition.DirectionTo(location).Angle(), RotationSpeed * delta);
        Node2D weaponHolder = GetWeaponsHolder(Weapon.WeaponOrder.Right);

        weaponHolder.GlobalRotation = Mathf.LerpAngle(weaponHolder.GlobalRotation, weaponHolder.GlobalPosition.DirectionTo(location).Angle(), RotationSpeed * delta);

        weaponHolder = GetWeaponsHolder(Weapon.WeaponOrder.Left);
        weaponHolder.GlobalRotation = Mathf.LerpAngle(weaponHolder.GlobalRotation, weaponHolder.GlobalPosition.DirectionTo(location).Angle(), RotationSpeed * delta);
    }
示例#7
0
 public virtual void DamageNearby()
 {
     foreach (Enemy target in GetTree().GetNodesInGroup("Enemies"))
     {
         if (Position.DistanceTo(target.Position) < effectRadius)
         {
             target.Damage(damage, GlobalPosition.DirectionTo(target.GlobalPosition) * knockbackStrength);
         }
     }
 }
示例#8
0
        /// <summary>
        ///   Damages the body if it is damagable. Pushes the object back.
        /// </summary>
        /// <param name="rigidBody">The body to explode.</param>
        private void Explode(RigidBody2D body)
        {
            if (body is IDamageable damageable)
            {
                damageable.TakeDamage(this);
            }

            if (body is IKnockbackable knockbackable)
            {
                var dirToBody = GlobalPosition.DirectionTo(body.GlobalPosition).Normalized();
                knockbackable.Knockback(dirToBody * PushForce);
            }
        }
示例#9
0
 private void chaseState()
 {
     player = playerDetectionZone.player;
     if (player != null)
     {
         Direction = GlobalPosition.DirectionTo(player.GlobalPosition);
         Velocity  = Velocity.MoveToward(Direction * MaxSpeed, Acceleration);
     }
     else
     {
         state = pickRandomState(new Global.BehaviorState[] { Global.BehaviorState.STATE_IDLE, Global.BehaviorState.STATE_WANDER });
     }
 }
示例#10
0
    public override void _PhysicsProcess(float delta)
    {
        knockback = knockback.MoveToward(Vector2.Zero, 200 * delta);
        knockback = MoveAndSlide(knockback);

        Vector2 dir = Vector2.Zero;

        switch (state)
        {
        case AIState.IDLE:
            velocity = velocity.MoveToward(Vector2.Zero, 200 * delta);
            SeekPlayer();
            RestartWander();
            break;

        case AIState.WANDER:
            SeekPlayer();
            RestartWander();
            dir             = GlobalPosition.DirectionTo(wanderController.TargetPosition);
            velocity        = velocity.MoveToward(dir * maxSpeed, acceleration * delta);
            batSprite.FlipH = velocity.x < 0;
            if (GlobalPosition.DistanceTo(wanderController.TargetPosition) <= maxSpeed * delta)
            {
                state = PickRandomState(stateArray);
                wanderController.StartWanderTimer(rng.RandfRange(1, 3));
            }
            break;

        case AIState.CHASE:
            var player = playerZone.Player;
            if (player != null)
            {
                dir      = GlobalPosition.DirectionTo(player.GlobalPosition);
                velocity = velocity.MoveToward(dir * maxSpeed, acceleration * delta);
            }
            else
            {
                state = AIState.IDLE;
            }
            batSprite.FlipH = velocity.x < 0;
            break;

        default:
            break;
        }
        if (softCollision.isColliding())
        {
            velocity += softCollision.GetPushVector() * delta * 300;
        }
        velocity = MoveAndSlide(velocity);
    }
示例#11
0
    /// <summary>
    /// Move the body toward a <c>location</c>.
    /// </summary>
    public void MoveToward(Vector2 location)
    {
        var directionVelocity = GlobalPosition.DirectionTo(location) * SPEED;

        if (directionVelocity.Length() > 0)
        {
            _velocity = _velocity.LinearInterpolate(directionVelocity, ACCELERATION);
        }
        else
        {
            _velocity = _velocity.LinearInterpolate(Vector2.Zero, FRICTION);
        }
        _velocity = MoveAndSlide(_velocity);
    }
        protected void RandomizeDirection()
        {
            ChangeDirections = (GD.Randi() % 3) + 1;
            var player = GetTree().GetNodesInGroup("player").Cast <Player.Player>().FirstOrDefault();

            var delta = GetVariance();

            if (GD.Randi() % 2 == 0 && player != null)
            {
                Direction = GlobalPosition.DirectionTo(player.GlobalPosition).Rotated(delta);
            }
            else
            {
                Direction = GetRandomDirection().Rotated(delta);
            }
        }
示例#13
0
 public override void _Process(float delta)
 {
     base._Process(delta);
     if (state == EPlayerState.STATE_DYING || state == EPlayerState.STATE_STUNNED || state == EPlayerState.STATE_DODGING)
     {
         return;
     }
     if (_usePrimary)
     {
         abilityManager.Invoke(primary, GlobalPosition.DirectionTo(GetGlobalMousePosition()), GlobalPosition, 2);
     }
     if (_useSecondary)
     {
         abilityManager.Invoke(secondary, GlobalPosition.DirectionTo(GetGlobalMousePosition()), GlobalPosition, 2);
     }
 }
示例#14
0
        protected override void SpawnProjectiles()
        {
            var deltaAngle     = 360 / ProjectilesPerShot;
            var muzzleDistance = Position.DistanceTo(_muzzlePoint.Position);
            var direction      = GlobalPosition.DirectionTo(_muzzlePoint.GlobalPosition);

            for (int i = 0; i < ProjectilesPerShot; i++)
            {
                var bullet = InstanceBullet();

                bullet.Direction      = direction.Rotated(Mathf.Deg2Rad(i * deltaAngle));
                bullet.GlobalPosition = GlobalPosition + bullet.Direction * muzzleDistance;
                bullet.GlobalRotation = bullet.Direction.Angle();

                GetParent().GetParent().AddChild(bullet);
            }
        }
示例#15
0
    private void UpdateZap()
    {
        const int signCost = 50;

        int sign = Mathf.Sign(velocity.x);

        if (sign == 0)
        {
            sign = lastMoveSign;
        }
        else
        {
            lastMoveSign = sign;
        }

        protonLine.ClearPoints();
        closest = null;

        // A proton is only reachable if it's in range of the circle's area + any number
        float closestDist = Mathf.Pi * ZapDistance * ZapDistance + 0.69420f;

        foreach (Proton body in protonField.GetOverlappingAreas())
        {
            float dist = GlobalPosition.DistanceTo(body.GlobalPosition);

            // prioritize protons in the movement direction
            Vector2 dir = GlobalPosition.DirectionTo(body.GlobalPosition);
            if (dir.x * sign > 0)
            {
                dist -= signCost;
            }

            if (Mathf.Abs(dist) < closestDist && body != prevProton)
            {
                protonRay.CastTo = ToLocal(body.GlobalPosition);
                if (protonRay.IsColliding())
                {
                    continue;
                }
                closestDist = dist;
                closest     = body;
            }
        }
    }
示例#16
0
        public override void _PhysicsProcess(float delta)
        {
            var distance = GlobalPosition.DistanceTo(target.GlobalPosition);

            if (distance > activeDistance + 100)
            {
                return;
            }

            var direction = GlobalPosition.DirectionTo(target.GlobalPosition);

            if (distance > 300)
            {
                parent.MoveAndSlide(direction * speed);
            }
            else if (distance < 250)
            {
                parent.MoveAndSlide(-direction * speed);
            }
        }
示例#17
0
    private void wanderState()
    {
        seekPlayer();
        NewTargetPosition = wanderController.NewTargetPosition();
        if (wanderController.GetTimeLeft() == 0)
        {
            state = pickRandomState(new Global.BehaviorState[] { Global.BehaviorState.STATE_IDLE, Global.BehaviorState.STATE_WANDER });
            Random r = new Random();
            wanderController.StartWanderTimer(r.Next(1, 4));
            Direction = GlobalPosition.DirectionTo(NewTargetPosition);
        }

        Velocity = Velocity.MoveToward(Direction * MaxSpeed, Acceleration);
        if (GlobalPosition.DistanceTo(NewTargetPosition) <= 4)
        {
            state = pickRandomState(new Global.BehaviorState[] { Global.BehaviorState.STATE_IDLE, Global.BehaviorState.STATE_WANDER });
            Random r = new Random();
            wanderController.StartWanderTimer(r.Next(1, 4));
        }
    }
示例#18
0
        public override void _PhysicsProcess(float delta)
        {
            var distance = GlobalPosition.DistanceTo(target.GlobalPosition);

            if (distance < 300)
            {
                var direction = GlobalPosition.DirectionTo(target.GlobalPosition);
                directionCallback(direction);

                if (framesUntilAttack == 0)
                {
                    framesUntilAttack = (int)GD.RandRange(0, 60) + attackFrameFrequency;
                    Shoot(direction);
                }
                else
                {
                    framesUntilAttack = Math.Max(framesUntilAttack - 1, 0);
                }
            }
        }
示例#19
0
    //  // Called every frame. 'delta' is the elapsed time since the previous frame.
    public override void _PhysicsProcess(float delta)
    {
        lookDirection = GlobalPosition.DirectionTo(GetGlobalMousePosition());
        switch (state)
        {
        case AnimationState.MOVE:
            MoveState(delta);
            break;

        case AnimationState.ATTACK:
            AttackState(delta);
            break;

        case AnimationState.ROLL:
            RollState(delta);
            break;

        default:
            break;
        }
    }
示例#20
0
    public virtual void Explode()
    {
        onHitTween.Start();
        fireTrailEmitter.Emitting  = false;
        smokeTrailEmitter.Emitting = false;
        smokeTrailEmitter.Scale    = default(Vector2);
        explosionMaterial.Gravity  = new Vector3(velocity / 2, 0f, 0f);
        explosionEmitter.Emitting  = true;
        exploded               = true;
        sprite.Visible         = false;
        hitArea.CollisionLayer = 0;
        hitArea.CollisionMask  = 0;

        // Affect target(s)
        foreach (Enemy target in GetTree().GetNodesInGroup("Enemies"))
        {
            if (Position.DistanceTo(target.Position) < effectRadius)
            {
                target.Damage(damage, GlobalPosition.DirectionTo(target.GlobalPosition) * knockbackStrength);
            }
        }
    }
示例#21
0
        /// <summary>
        ///     Special function for the firemaster tower due to it shooting two parallel projectiles
        /// </summary>
        /// <param name="projectile">the projectile</param>
        /// <param name="enemy">the target enemy</param>
        /// <param name="xOffset">the x offset for the projectiles</param>
        /// <param name="yOffset">the y offset for the projectiles</param>
        /// <param name="isSecond">
        ///     used to set the angle of projectile depending on what side of the offset it is on (negative or
        ///     positive)
        /// </param>
        private void SetupProjectile(Projectile projectile, Node2D enemy, float xOffset, float yOffset,
                                     int isSecond = 1)
        {
            projectile.Setup(ProjectileCollateral);
            projectile.Lifetime = 0.2f;
            projectile.Source   = this;
            projectile.Damage   = AttackDamage;

            var enemyPos = enemy.GlobalPosition + new Vector2(xOffset, xOffset);
            // get direction and magnitude
            var direction = GlobalPosition.DirectionTo(enemyPos);

            var mag = (float)Math.Sqrt(direction.x * direction.x + direction.y * direction.y);


            // sets velocity of projectile
            projectile.SetVelocity(
                new Vector2(direction.x / mag * ProjectileSpeed, direction.y / mag * ProjectileSpeed));


            // turns sprite to look at enemy
            projectile.LookAt(new Vector2(enemy.GlobalPosition.x + xOffset * isSecond,
                                          enemy.GlobalPosition.y + xOffset * isSecond));
        }
示例#22
0
    /// <summary>
    /// Rotate the body toward a <c>location</c>.
    /// </summary>
    public void RotateToward(Vector2 location)
    {
        var angleToLocation = GlobalPosition.DirectionTo(location).Angle();

        Rotation = Mathf.LerpAngle(Rotation, angleToLocation, ROTATION_WEIGHT);
    }
示例#23
0
 public void SetDestination(Vector2 point)
 {
     LinearVelocity = GlobalPosition.DirectionTo(point) * Speed;
     Rotation       = GlobalPosition.AngleToPoint(point);
     LinearDamp     = 0;
 }
    public Bullet ShootAt(PackedScene bulletType, Vector2 position, Vector2 target)
    {
        Vector2 direction = GlobalPosition.DirectionTo(target);

        return(ShootAt(bulletType, position, direction.Angle()));
    }
示例#25
0
    public override void _PhysicsProcess(float delta)
    {
        base._PhysicsProcess(delta);

        wallL.GlobalRotation = wallR.GlobalRotation = 0;

        if (GetState() != State.Zap && GetState() != State.Hook)
        {
            UpdateZap();
            HookAndZap();
        }
        UpdateLine();

        switch (GetState())
        {
        case State.Idle:
            Move();
            if (velocity.x != 0)
            {
                SetState(State.Walk);
            }
            break;

        case State.Jump:
            Move(airAcceleration: 20, airFriction: 0.05f);
            if (!Input.IsActionPressed("Jump"))
            {
                if (velocity.y < -JumpSmooth)
                {
                    velocity.y = -JumpSmooth;
                }
            }

            if (velocity.y >= 0)
            {
                SetState(State.Fall);
            }
            break;

        case State.Walk:
            Move();
            if (velocity == new Vector2())
            {
                SetState(State.Idle);
            }
            break;

        case State.Fall:
            Move(airAcceleration: 20, airFriction: 0.05f);
            if (IsOnFloor())
            {
                SetState(State.Idle);
            }
            break;

        case State.Zap:
            prevProton = closest;

            if (closest == null)
            {
                SetState(State.Idle);
                return;
            }
            const int distanceThreshold = 64;

            velocity = GlobalPosition.DirectionTo(closest.GlobalPosition) * ZapSpeed;

            RotateTween(velocity.Angle() + Mathf.Pi / 2);

            // if inside of proton
            if (GlobalPosition.DistanceTo(closest.GlobalPosition) < distanceThreshold)
            {
                SetState(State.Bounce);

                protonLine.Width   = 1;
                protonLine.Texture = null;
            }

            break;

        case State.Bounce:
            Move(AirAcceleration, AirFriction, ZapSpeed);
            if (IsOnFloor() || IsOnWall() || IsOnCeiling())
            {
                SetState(State.Idle);
            }
            break;

        case State.Hook:
            Move(maxSpeed: 2000, friction: 0.02f, air: false, jump: IsOnFloor());

            Vector2 target = closest.GlobalPosition;
            Vector2 pos    = GlobalPosition;
            Vector2 prime  = pos + velocity * delta;

            if (prime.DistanceTo(target) >= hookDistance)
            {
                Vector2 v = velocity - velocity.Dot(pos - target) / pos.DistanceSquaredTo(target) * (pos - target);

                Vector2 prime2 = pos + v * delta;
                Vector2 newPos = target + (prime2 - target) * (pos.DistanceTo(target) / prime2.DistanceTo(target));
                velocity     = (newPos - pos) / delta;
                hookDistance = newPos.DistanceTo(target);
            }

            void ResetLine()
            {
                protonLine.Width   = 1;
                protonLine.Texture = null;
            }

            if (!Input.IsActionPressed("Grapple"))
            {
                SetState(State.Bounce);
                ResetLine();
            }
            break;

        case State.WallJump:
            Move();
            if (!Input.IsActionPressed("Jump"))
            {
                if (velocity.y < -JumpSmooth)
                {
                    velocity.y  = -JumpSmooth;
                    velocity.x -= 50 * Mathf.Sign(velocity.x);
                }
                SetState(State.Fall);
            }

            break;

        case State.WallSlide:
            Move(gravity: velocity.y > 0 ? 10 : Physics.Gravity);

            if (wallCurr == null || IsOnFloor() || !wallCurr.IsColliding())
            {
                SetState(State.Idle);
                break;
            }
            if (Input.IsActionJustPressed("Jump"))
            {
                SetState(State.WallJump);
            }

            sprite.FlipH = !wallCurr.Name.EndsWith('L');

            break;
        }

        velocity = MoveAndSlide(velocity, Vector2.Up);
        if (IsOnFloor())
        {
            sprite.RotationDegrees += velocity.x * delta;
            if (GetState() != State.Hook && GetState() != State.Zap)
            {
                prevProton = null;
            }
        }

        if (GlobalPosition.y > level.deathHeight)
        {
            Die();
        }

        if (Input.IsActionJustPressed("Quit") && !Pause.annoyingBug)
        {
            GetTree().Paused = true;
            Spawner.Node("res://UI/Pause.tscn", GetParent());
        }

        Pause.annoyingBug = false;
    }
示例#26
0
    public override void _Process(float delta)
    {
        base._Process(delta);

        if (CurrentState == State.Spawning || CurrentState == State.Dead)
        {
            return;
        }

        if (path.Count == 0)
        {
            CurrentState = State.Idle;
            ShootTimer.Stop();
            RecalculatePath();
            return;
        }

        if (GlobalPosition.DistanceTo(path[0]) < NextPathPoint || (IsInstanceValid(target) && GlobalPosition.DistanceTo(path[0]) < 32 && path[0].DistanceTo(target.GlobalPosition) > GlobalPosition.DistanceTo(target.GlobalPosition)))
        {
            path.RemoveAt(0);

            if (path.Count == 0)
            {
                return;
            }
        }

        MoveVec = GlobalPosition.DirectionTo(path[0]);

        Array overlappingBodies = TargetArea.GetOverlappingBodies();

        if (overlappingBodies.Count == 0)
        {
            CurrentState = State.Sprint;
            ShootTimer.Stop();
        }
        else if (PriorityTargetArea.GetOverlappingBodies().Contains(target))
        {
            CurrentState = State.Idle;
            if (ShootTimer.IsStopped())
            {
                ShootTimer.Start();
            }
        }
        else
        {
            CurrentState = State.Move;
            if (ShootTimer.IsStopped())
            {
                ShootTimer.Start();
            }
        }

        float rotateTarget;

        switch (CurrentState)
        {
        case State.Spawning:
            return;

        case State.Idle:
            AnimationPlayer.Play("Idle");
            rotateTarget = target.GlobalPosition.AngleToPoint(RotateGroup.GlobalPosition);
            Rotate(delta, rotateTarget);
            break;

        case State.Move:
            AnimationPlayer.Play("Move");
            var   closest         = (PhysicsBody2D)overlappingBodies[0];
            float closestDistance = GlobalPosition.DistanceTo(closest.GlobalPosition);
            foreach (PhysicsBody2D body in overlappingBodies)
            {
                float dist = GlobalPosition.DistanceTo(body.GlobalPosition);
                if (dist < closestDistance)
                {
                    closest         = body;
                    closestDistance = dist;
                }
            }
            rotateTarget = closest.GlobalPosition.AngleToPoint(RotateGroup.GlobalPosition);
            Rotate(delta, rotateTarget);

            break;

        case State.Sprint:
            AnimationPlayer.Play("Sprint");
            rotateTarget = MoveVec.Angle();
            Rotate(delta, rotateTarget);
            break;
        }
    }