public override nfloat DistanceToWall(CGPoint pos0, CGPoint pos1)
        {
            var a = ConvertWorldPointToLevelMapPoint(pos0);
            var b = ConvertWorldPointToLevelMapPoint(pos1);

            var deltaX = b.X - a.X;
            var deltaY = b.Y - a.Y;
            var dist   = GraphicsUtilities.DistanceBetweenCGPoints(a, b);
            var inc    = 1f / dist;
            var p      = CGPoint.Empty;

            for (nfloat i = 0; i <= 1; i += inc)
            {
                p.X = a.X + i * deltaX;
                p.Y = a.Y + i * deltaY;

                DataMap point = levelMap.QueryLevelMap(p);
                if (point.Wall > 200)
                {
                    CGPoint wpos2 = ConvertLevelMapPointToWorldPoint(p);
                    return(GraphicsUtilities.DistanceBetweenCGPoints(pos0, wpos2));
                }
            }
            return(nfloat.MaxValue);
        }
        public override void DidSimulatePhysics()
        {
            base.DidSimulatePhysics();

            // Get the position either of the default hero or the hero spawn point.
            HeroCharacter defaultHero = DefaultPlayer.Hero;
            CGPoint       position;

            if (defaultHero != null && Heroes.Contains(defaultHero))
            {
                position = defaultHero.Position;
            }
            else
            {
                position = DefaultSpawnCGPoint;
            }

            // Update the alphas of any trees that are near the hero (center of the camera) and therefore visible or soon to be visible.
            foreach (Tree tree in trees)
            {
                if (GraphicsUtilities.DistanceBetweenCGPoints(tree.Position, position) < 1024)
                {
                    tree.UpdateAlphaWithScene(this);
                }
            }

            if (!WorldMovedForUpdate)
            {
                return;
            }

            // Show any nearby hidden particle systems and hide those that are too far away to be seen.
            foreach (SKEmitterNode particles in particleSystems)
            {
                bool particlesAreVisible = GraphicsUtilities.DistanceBetweenCGPoints(particles.Position, position) < 1024;

                if (!particlesAreVisible && !particles.Paused)
                {
                    particles.Paused = true;
                }
                else if (particlesAreVisible && particles.Paused)
                {
                    particles.Paused = false;
                }
            }

            // Update nearby parallax sprites.
            foreach (ParallaxSprite sprite in parallaxSprites)
            {
                if (GraphicsUtilities.DistanceBetweenCGPoints(sprite.Position, position) >= 1024)
                {
                    continue;
                }

                sprite.UpdateOffset();
            }
        }
Esempio n. 3
0
        public override void UpdateWithTimeSinceLastUpdate(double interval)
        {
            if (Character.Dying)
            {
                Target = null;
                return;
            }

            var position = Character.Position;
            MultiplayerLayeredCharacterScene scene = Character.CharacterScene;
            nfloat closestHeroDistance             = float.MaxValue;

            // Find the closest living hero, if any, within our alert distance.
            foreach (HeroCharacter hero in scene.Heroes)
            {
                var heroPosition = hero.Position;
                var distance     = GraphicsUtilities.DistanceBetweenCGPoints(position, heroPosition);
                if (distance < EnemyAlertRadius &&
                    distance < closestHeroDistance &&
                    !hero.Dying)
                {
                    closestHeroDistance = distance;
                    Target = hero;
                }
            }

            // If there's no target, don't do anything.
            if (Target == null)
            {
                return;
            }

            // Otherwise chase or attack the target, if it's near enough.
            var   heroPos     = Target.Position;
            float chaseRadius = ChaseRadius;

            if (closestHeroDistance > MaxAlertRadius)
            {
                Target = null;
            }
            else if (closestHeroDistance > ChaseRadius)
            {
                Character.MoveTowards(heroPos, interval);
            }
            else if (closestHeroDistance < ChaseRadius)
            {
                Character.FaceTo(heroPos);
                Character.PerformAttackAction();
            }
        }
Esempio n. 4
0
        public override void UpdateWithTimeSinceLastUpdate(double interval)
        {
            Cave cave = (Cave)Character;

            if (cave.Health <= 0)
            {
                return;
            }

            MultiplayerLayeredCharacterScene scene = cave.CharacterScene;

            nfloat closestHeroDistance = MinimumHeroDistance;
            var    closestHeroPosition = CGPoint.Empty;

            var cavePosition = cave.Position;

            foreach (SKNode hero in scene.Heroes)
            {
                var heroPosition = hero.Position;
                var distance     = GraphicsUtilities.DistanceBetweenCGPoints(cavePosition, heroPosition);
                if (distance < closestHeroDistance)
                {
                    closestHeroDistance = distance;
                    closestHeroPosition = heroPosition;
                }
            }

            var distScale = closestHeroDistance / MinimumHeroDistance;

            // Generate goblins more quickly if the closest hero is getting closer.
            cave.TimeUntilNextGenerate -= (float)interval;

            // Either time to generate or the hero is so close we need to respond ASAP!
            int goblinCount = cave.ActiveGoblins.Count;

            if (goblinCount < 1 ||
                cave.TimeUntilNextGenerate <= 0 ||
                (distScale < 0.35f && cave.TimeUntilNextGenerate > 5))
            {
                if (goblinCount < 1 || (goblinCount < 4 && closestHeroPosition != CGPoint.Empty) &&
                    scene.CanSee(closestHeroPosition, cave.Position))
                {
                    cave.Generate();
                }
                cave.TimeUntilNextGenerate = 4 * distScale;
            }
        }
        public void UpdateAlphaWithScene(MultiplayerLayeredCharacterScene scene)
        {
            if (scene == null)
            {
                throw new ArgumentNullException("scene");
            }

            if (!FadeAlpha)
            {
                return;
            }

            nfloat closestHeroDistance = nfloat.MaxValue;

            // See if there are any heroes nearby.
            var ourPosition = Position;

            foreach (SKNode hero in scene.Heroes)
            {
                var theirPos = hero.Position;
                var distance = GraphicsUtilities.DistanceBetweenCGPoints(ourPosition, theirPos);
                closestHeroDistance = (nfloat)Math.Min(distance, closestHeroDistance);
            }

            if (closestHeroDistance > OpaqueDistance)
            {
                // No heroes nearby.
                Alpha = 1;
            }
            else
            {
                // Adjust the alpha based on how close the hero is.
                var ratio = closestHeroDistance / OpaqueDistance;
                Alpha = 0.1f + ratio * ratio * 0.9f;
            }
        }
        public override bool CanSee(CGPoint pos0, CGPoint pos1)
        {
            var a = ConvertWorldPointToLevelMapPoint(pos0);
            var b = ConvertWorldPointToLevelMapPoint(pos1);

            var deltaX = b.X - a.Y;
            var deltaY = b.Y - a.Y;
            var dist   = GraphicsUtilities.DistanceBetweenCGPoints(a, b);
            var inc    = 1 / dist;
            var p      = CGPoint.Empty;

            for (nfloat i = 0; i <= 1; i += inc)
            {
                p.X = a.X + i * deltaX;
                p.Y = a.Y + i * deltaY;

                DataMap point = levelMap.QueryLevelMap(p);
                if (point.Wall > 200)
                {
                    return(false);
                }
            }
            return(true);
        }