Example #1
0
        public void Draw(Renderer renderer, SpatialData spatial, float depth)
        {
            Point textureDim = TextureDim;

            if (textureDim == Point.Zero)
            {
                textureDim = Texture.Bounds.Size;
            }

            Rectangle sourceRect = new Rectangle
            {
                Location = TextureOffset,
                Size     = textureDim
            };

            renderer.DrawSprite(
                position: spatial.Position,
                rotation: spatial.Rotation,
                scale: Scale,
                depth: depth,
                texture: Texture,
                hotspot: Hotspot,
                sourceRectangle: sourceRect,
                tint: Tint,
                spriteEffects: SpriteEffects);
        }
        public override void Draw(Renderer renderer)
        {
            base.Draw(renderer);

            if (Health.IsAlive)
            {
                int         currentHP     = Health.CurrentHealth;
                int         cols          = Math.Min(currentHP, NumIconsPerRow);
                Vector2     healthIconDim = Conversion.ToMeters(HealthIcon.ScaledDim);
                Vector2     spacing       = healthIconDim + IconPadding;
                SpatialData anchor        = this.GetWorldSpatialData();
                anchor.Position.X -= 0.5f * (cols * spacing.X);
                float left    = anchor.Position.X;
                int   hpIndex = 0;
                while (true)
                {
                    for (int x = 0; x < cols; x++)
                    {
                        if (hpIndex++ >= currentHP)
                        {
                            goto DONE;
                        }

                        HealthIcon.Draw(renderer, anchor);
                        anchor.Position.X += spacing.X;
                    }
                    anchor.Position.X  = left;
                    anchor.Position.Y += spacing.Y;
                }

                DONE :;
            }
        }
Example #3
0
 public void CopyFrom(SpatialData other)
 {
     Parent    = other.Parent;
     Position  = other.Position;
     Rotation  = other.Rotation;
     LocalAABB = other.LocalAABB;
 }
Example #4
0
        public SpatialData GetCopy()
        {
            SpatialData result = new SpatialData();

            result.CopyFrom(this);
            return(result);
        }
Example #5
0
        /// <summary>
        /// Gets the world position and rotation for this spatial object.
        /// The result has the same LocalAABB, i.e. it is not inherited.
        /// The result will have no parent.
        /// </summary>
        public static SpatialData GetWorldSpatialData(this ISpatial self)
        {
            Vector2 position = Vector2.Zero;
            float   radians  = 0.0f;

            ISpatial parent = self;

            while (parent != null)
            {
                SpatialData spatial = parent.Spatial;
                position += spatial.Position;
                radians  += spatial.Rotation.Radians;

                Debug.Assert(spatial.Parent != parent);
                parent = spatial.Parent;
            }

            SpatialData result = new SpatialData
            {
                Position = position,
                Rotation = new Angle {
                    Radians = radians
                },
                LocalAABB = self.Spatial.LocalAABB,
            };

            return(result);
        }
Example #6
0
        public override void Initialize()
        {
            SpatialData spatial = this.GetWorldSpatialData();

            Body body = BodyFactory.CreateBody(
                world: Global.Game.World,
                position: spatial.Position,
                rotation: spatial.Rotation.Radians);

            FixtureFactory.AttachRectangle(
                body: body,
                offset: Conversion.ToMeters(0, -50),
                width: Conversion.ToMeters(330),
                height: Conversion.ToMeters(100),
                density: Global.OwliverDensity);
            FixtureFactory.AttachRectangle(
                body: body,
                offset: Conversion.ToMeters(0, -160),
                width: Conversion.ToMeters(280),
                height: Conversion.ToMeters(150),
                density: Global.OwliverDensity);

            BodyComponent.Body = body;

            base.Initialize();
        }
Example #7
0
        public float CalcDepth(SpatialData spatial, GameLayer layer)
        {
            // Note(manu): 0 means front, 1 means back.
            float maxY  = Level.SCREEN_DIMENSION * CurrentLevel.ScreenTileHeight;
            float y     = MathHelper.Clamp(spatial.Position.Y, 0, maxY);
            float alpha = y / maxY;

            float depth;

            switch (layer)
            {
            case GameLayer.CloseToTheScreen:
                depth = MathHelper.Lerp(0.0999f, 0.0f, alpha);
                break;

            case GameLayer.SomewhereInTheMiddle:
                depth = MathHelper.Lerp(0.9f, 0.1f, alpha);
                break;

            case GameLayer.Background:
                depth = 1.0f;
                break;

            default: throw new ArgumentException("layer");
            }

            return(depth);
        }
Example #8
0
        public override void Update(float deltaSeconds)
        {
            SpatialData s = this.GetWorldSpatialData();

            Body.SetTransform(ref s.Position, s.Rotation.Radians);

            base.Update(deltaSeconds);
        }
Example #9
0
        public override void Draw(Renderer renderer)
        {
            base.Draw(renderer);

            SpatialData worldSpatial = this.GetWorldSpatialData();

            Sprite.Draw(renderer, worldSpatial, RenderDepth);
        }
Example #10
0
        public override void Draw(Renderer renderer)
        {
            base.Draw(renderer);

            SpatialData worldSpatial = this.GetWorldSpatialData();

            ActiveAnimation.Draw(renderer, worldSpatial, RenderDepth, AdditionalScale, Tint);
        }
Example #11
0
        public override void Initialize()
        {
            Debug.Assert(Orientation != SpikeTrapOrientation.None);

            SpatialData s = this.GetWorldSpatialData();

            FixedOrigin.Spatial.CopyFrom(s);

            float halfThickness = 0.5f * SensorThickness;
            float halfReach     = 0.5f * SensorReach;

            switch (Orientation)
            {
            case SpikeTrapOrientation.Horizontal:
            {
                TargetSensor.RectangleSensorLocalAABB = new AABB
                {
                    LowerBound = new Vector2(-halfReach, -halfThickness),
                    UpperBound = new Vector2(halfReach, halfThickness),
                };
            }
            break;

            case SpikeTrapOrientation.Vertical:
            {
                TargetSensor.RectangleSensorLocalAABB = new AABB
                {
                    LowerBound = new Vector2(-halfThickness, -halfReach),
                    UpperBound = new Vector2(halfThickness, halfReach),
                };
            }
            break;

            default: throw new ArgumentException(nameof(Orientation));
            }

            {
                Body body = BodyFactory.CreateRectangle(
                    world: Global.Game.World,
                    bodyType: BodyType.Kinematic,
                    position: s.Position,
                    rotation: s.Rotation.Radians,
                    width: 1,
                    height: 1,
                    density: Global.OwliverDensity);

                body.FixedRotation       = true;
                body.CollisionCategories = CollisionCategory.Enemy | CollisionCategory.EnemyWeapon;
                body.OnCollision        += MovingBody_OnCollision;

                MovingBodyComponent.Body = body;
            }

            base.Initialize();

            TargetSensorAABB = TargetSensor.Body.ComputeAABB();
        }
Example #12
0
 public static void SetWorldRotation(this ISpatial self, Angle worldRotation)
 {
     if (self.Spatial.Parent != null)
     {
         SpatialData parent = self.Spatial.Parent.GetWorldSpatialData();
         self.Spatial.Rotation = worldRotation - parent.Rotation;
     }
     else
     {
         self.Spatial.Rotation = worldRotation;
     }
 }
Example #13
0
 public static void SetWorldPosition(this ISpatial self, Vector2 worldPosition)
 {
     if (self.Spatial.Parent != null)
     {
         SpatialData parent = self.Spatial.Parent.GetWorldSpatialData();
         self.Spatial.Position = worldPosition - parent.Position;
     }
     else
     {
         self.Spatial.Position = worldPosition;
     }
 }
Example #14
0
        public override void Initialize()
        {
            {
                SpatialData s    = this.GetWorldSpatialData();
                Body        body = new Body(
                    world: Global.Game.World,
                    position: s.Position,
                    rotation: s.Rotation.Radians,
                    bodyType: BodyType.Dynamic,
                    userdata: BodyComponent);

                float radius  = Conversion.ToMeters(80 * Global.SlurpScale.X);
                float density = Global.OwliverDensity;
                FixtureFactory.AttachCircle(
                    radius: radius,
                    density: density,
                    body: body,
                    offset: Conversion.ToMeters(0, -25) * Global.SlurpScale);
                FixtureFactory.AttachCircle(
                    radius: radius,
                    density: density,
                    body: body,
                    offset: Conversion.ToMeters(0, 25) * Global.SlurpScale);

                body.FixedRotation = true;
                body.LinearDamping = 5.0f;

                body.OnCollision        += OnCollision;
                body.CollisionCategories = CollisionCategory.Enemy;

                BodyComponent.Body = body;
            }

            base.Initialize();

            // Disable chasing when we are invincible.
            Health.OnInvincibilityGained += () =>
            {
                Homing.TargetSensor.Body.Enabled = false;
            };

            Health.OnInvincibilityLost += () =>
            {
                Homing.TargetSensor.Body.Enabled = true;
            };
        }
Example #15
0
        public override void Update(float deltaSeconds)
        {
            base.Update(deltaSeconds);

            if (DepthReference != null)
            {
                SpatialData spatial = DepthReference.GetWorldSpatialData();
                RenderDepth = Global.Game.CalcDepth(spatial, Owner.Layer);

                if (DebugDrawingEnabled)
                {
                    Global.Game.DebugDrawCommands.Add(view =>
                    {
                        view.DrawPoint(spatial.Position, Conversion.ToMeters(3), Color.Navy);
                    });
                }
            }
        }
Example #16
0
        public override void Initialize()
        {
            SpatialData s = BodyComponent.GetWorldSpatialData();

            BodyComponent.Body = BodyFactory.CreateCircle(
                world: Global.Game.World,
                radius: 0.2f,
                density: 0.5f * Global.OwliverDensity,
                position: s.Position);
            BodyComponent.Body.IsSensor     = true;
            BodyComponent.Body.CollidesWith = CollisionCategory.Friendly;

            SpriteAnimationType animType = SpriteAnimationType.Bonbon_Gold + (int)BonbonType;

            Animation.AnimationTypes.Add(animType);

            base.Initialize();
        }
Example #17
0
        /// <summary>
        /// Returns the SpatialData instance representing the offset.
        /// </summary>
        public static SpatialData AttachWithOffsetTo(this ISpatial self, ISpatial newParent,
                                                     Vector2 positionOffset, Angle rotationOffset)
        {
            SpatialData result = null;

            if (newParent != self)
            {
                result = new SpatialData()
                {
                    Position = positionOffset,
                    Rotation = rotationOffset
                };

                result.AttachTo(newParent);
                self.AttachTo(result);
            }

            return(result);
        }
Example #18
0
        public override void Initialize()
        {
            Debug.Assert(TargetCollisionCategories != 0, "You should have set target collision categories by now.");
            SpatialData s = this.GetWorldSpatialData();

            switch (SensorType)
            {
            case TargetSensorType.Unknown: throw new NotImplementedException();

            case TargetSensorType.Circle:
            {
                Debug.Assert(CircleSensorRadius > 0.0f);
                Body = BodyFactory.CreateCircle(
                    world: Global.Game.World,
                    bodyType: BodyType.Static,
                    position: s.Position,
                    radius: CircleSensorRadius,
                    density: 0);
            }
            break;

            case TargetSensorType.Rectangle:
            {
                Body = BodyFactory.CreateRectangle(
                    world: Global.Game.World,
                    bodyType: BodyType.Static,
                    position: RectangleSensorLocalAABB.Center,
                    width: RectangleSensorLocalAABB.Width,
                    height: RectangleSensorLocalAABB.Height,
                    density: 0);
            }
            break;

            default: throw new ArgumentException(nameof(SensorType));
            }

            base.Initialize();

            Body.IsSensor      = true;
            Body.CollidesWith  = TargetCollisionCategories;
            Body.OnCollision  += OnCollision;
            Body.OnSeparation += OnSeparation;
        }
Example #19
0
        public override void Update(float deltaSeconds)
        {
            base.Update(deltaSeconds);

            SpriteAnimationPlaybackState oldPlaybackState = ActiveAnimation.State.PlaybackState;

            ActiveAnimation.Update(deltaSeconds);
            SpriteAnimationPlaybackState newPlaybackState = ActiveAnimation.State.PlaybackState;

            if (newPlaybackState != oldPlaybackState)
            {
                OnAnimationPlaybackStateChanged?.Invoke(ActiveAnimationType, oldPlaybackState, newPlaybackState);
            }

            Global.Game.DebugDrawCommands.Add(view =>
            {
                SpatialData worldSpatial = this.GetWorldSpatialData();
                view.DrawAABB(worldSpatial.AbsoluteAABB, new Color(0xdd, 0x99, 0x44));
            });
        }
Example #20
0
        public override void Initialize()
        {
            SpatialData s = this.GetWorldSpatialData();

            MyBody = new Body(
                world: Global.Game.World,
                position: s.Position,
                rotation: s.Rotation.Radians,
                bodyType: BodyType.Dynamic,
                userdata: BodyComponent);

            float   radius       = Conversion.ToMeters(60) * Global.OwliverScale.X;
            float   density      = Global.OwliverDensity;
            Fixture lowerFixture = FixtureFactory.AttachCircle(
                radius: radius,
                density: density,
                body: MyBody);

            Fixture upperFixture = FixtureFactory.AttachCircle(
                radius: radius,
                density: density,
                body: MyBody,
                offset: Conversion.ToMeters(0, -70) * Global.OwliverScale);

            upperFixture.CollidesWith = CollisionCategory.EnemyWeapon;

            MyBody.CollisionCategories = CollisionCategory.Friendly | CollisionCategory.Owliver;
            MyBody.FixedRotation       = true;
            MyBody.SleepingAllowed     = false;
            MyBody.LinearDamping       = 15.0f;

            MyBody.OnCollision  += OnCollision;
            MyBody.OnSeparation += OnSeparation;

            BodyComponent.Body = MyBody;

            Animation.OnAnimationPlaybackStateChanged += OnAnimationLoopFinished;

            base.Initialize();
        }
Example #21
0
        public override void Initialize()
        {
            {
                float       halfWidth = Conversion.ToMeters(80) * Global.SingerScale.X;
                SpatialData s         = this.GetWorldSpatialData();
                Body        body      = BodyFactory.CreateCapsule(
                    world: Global.Game.World,
                    bodyType: BodyType.Dynamic,
                    position: s.Position,
                    rotation: s.Rotation.Radians,
                    height: Conversion.ToMeters(240) * Global.SingerScale.Y - 2.0f * halfWidth,
                    endRadius: halfWidth,
                    density: Global.OwliverDensity);
                body.LinearDamping       = 10.0f;
                body.FixedRotation       = true;
                body.CollisionCategories = CollisionCategory.Enemy;

                BodyComponent.Body = body;
            }

            base.Initialize();
        }
Example #22
0
        public override void Initialize()
        {
            SpatialData s    = this.GetWorldSpatialData();
            Body        body = BodyFactory.CreateCapsule(
                world: Global.Game.World,
                endRadius: Conversion.ToMeters(9),
                height: Conversion.ToMeters(50),
                position: s.Position,
                rotation: s.Rotation.Radians + new Angle {
                Degrees = 90.0f + new Random().NextBilateralFloat() * 2
            }.Radians,
                density: 1000 * Global.OwliverDensity,
                bodyType: BodyType.Dynamic);

            body.CollisionCategories = CollisionCategories;
            body.CollidesWith        = CollidesWith;
            body.IsBullet            = true;
            body.OnCollision        += OnCollision;
            BodyComponent.Body       = body;

            base.Initialize();
        }
Example #23
0
        public override void Initialize()
        {
            SpatialData s    = this.GetWorldSpatialData();
            Vector2     dim  = Conversion.ToMeters(350, 400) * Global.TanktonScale;
            Body        body = BodyFactory.CreateRoundedRectangle(
                world: Global.Game.World,
                position: s.Position,
                rotation: s.Rotation.Radians,
                bodyType: BodyType.Dynamic,
                width: dim.X,
                height: dim.Y,
                xRadius: 0.5f,
                yRadius: 0.5f,
                density: 2 * Global.OwliverDensity,
                segments: 0);

            body.FixedRotation       = true;
            body.LinearDamping       = 20.0f;
            body.CollisionCategories = CollisionCategory.Enemy;

            BodyComponent.Body = body;

            base.Initialize();
        }
Example #24
0
        public void Draw(Renderer renderer, float deltaSeconds)
        {
            CrossAnimation.Update(deltaSeconds);
            foreach (SpriteAnimationInstance anim in DigitAnimations)
            {
                anim.Update(deltaSeconds);
            }

            foreach (SpriteAnimationInstance anim in KeyAnimations)
            {
                anim.Update(deltaSeconds);
            }

            if (HealthIconAnimation != null)
            {
                HealthIconAnimation.Update(deltaSeconds);
                int         hp      = Owliver.Health.MaxHealth;
                SpatialData spatial = HealthIconAnchor.GetWorldSpatialData();
                const float spacing = 3;
                for (int healthIndex = 0; healthIndex < hp; healthIndex++)
                {
                    Color tint = healthIndex < Owliver.Health.CurrentHealth ? FullHealthTint : NoHealthTint;
                    HealthIconAnimation.Draw(renderer, spatial.GetWorldSpatialData(), tint: tint);
                    spatial.Position.X += HealthIconAnimation.ScaledDim.X + spacing;
                }
            }

            if (Owliver.MoneyBag != null)
            {
                MoneyBagIconAnimation.Update(deltaSeconds);

                SpatialData spatial = MoneyBagIconAnchor.GetWorldSpatialData();
                MoneyBagIconAnimation.Draw(renderer, MoneyBagIconAnchor);

                const float spacing           = 3;
                float       previousAnimWidth = MoneyBagIconAnimation.ScaledDim.X;

                spatial.Position.X -= 0.5f * CrossAnimation.ScaledDim.X + 0.5f * previousAnimWidth + spacing;
                CrossAnimation.Draw(renderer, spatial);
                previousAnimWidth = CrossAnimation.ScaledDim.X;

                int value = Owliver.MoneyBag.CurrentAmount;
                while (true)
                {
                    int digit = value % 10;
                    SpriteAnimationInstance digitAnim = DigitAnimations[digit];

                    spatial.Position.X -= 0.5f * previousAnimWidth + 0.5f * digitAnim.ScaledDim.X + spacing;
                    digitAnim.Draw(renderer, spatial);

                    value /= 10;
                    if (value == 0)
                    {
                        break;
                    }

                    previousAnimWidth = digitAnim.ScaledDim.X;
                }
            }

            if (Owliver.KeyRing != null)
            {
                SpatialData anchor = KeyRingAnchor.GetWorldSpatialData();
                for (int keyTypeIndex = 0; keyTypeIndex < (int)KeyType.COUNT; keyTypeIndex++)
                {
                    KeyType keyType   = (KeyType)keyTypeIndex;
                    int     keyAmount = Owliver.KeyRing[keyType];
                    SpriteAnimationInstance keyAnim = KeyAnimations[keyTypeIndex];
                    SpatialData             spatial = anchor.GetWorldSpatialData();
                    for (int keyIndex = 0; keyIndex < keyAmount; keyIndex++)
                    {
                        keyAnim.Draw(renderer, spatial);
                        spatial.Position.X += 0.6f * keyAnim.ScaledDim.X;
                    }

                    anchor.Position.Y += 0.8f * keyAnim.ScaledDim.Y;
                }
            }
        }
Example #25
0
        public override void Update(float deltaSeconds)
        {
            base.Update(deltaSeconds);

            switch (TrapState)
            {
            case SpikeTrapState.Searching:
            {
                Body target = TargetSensor.CurrentMainTarget;
                if (target != null)
                {
                    SpatialData originSpatial = FixedOrigin.GetWorldSpatialData();
                    Vector2     attackDir;
                    switch (Orientation)
                    {
                    case SpikeTrapOrientation.Horizontal:
                    {
                        float deltaX = target.Position.X - originSpatial.Position.X;
                        attackDir = new Vector2(Math.Sign(deltaX), 0);
                    }
                    break;

                    case SpikeTrapOrientation.Vertical:
                    {
                        float deltaY = target.Position.Y - originSpatial.Position.Y;
                        attackDir = new Vector2(0, Math.Sign(deltaY));
                    }
                    break;

                    default: throw new ArgumentException(nameof(Orientation));
                    }

                    MovingBody.LinearVelocity = attackDir * AttackSpeed;

                    EnterState(SpikeTrapState.Attacking);
                }
            }
            break;

            case SpikeTrapState.Attacking:
            {
                Vector2     movementDir    = MovingBody.LinearVelocity.GetNormalizedSafe();
                SpatialData originSpatial  = FixedOrigin.GetWorldSpatialData();
                Vector2     attackPosition = originSpatial.Position + movementDir * SensorReach;

                bool isAtEnd;
                switch (Orientation)
                {
                case SpikeTrapOrientation.Horizontal:
                {
                    if (movementDir.X > 0)
                    {
                        isAtEnd = MovingBody.Position.X >= attackPosition.X;
                    }
                    else
                    {
                        isAtEnd = MovingBody.Position.X <= attackPosition.X;
                    }
                }
                break;

                case SpikeTrapOrientation.Vertical:
                {
                    if (movementDir.Y > 0)
                    {
                        isAtEnd = MovingBody.Position.Y >= attackPosition.Y;
                    }
                    else
                    {
                        isAtEnd = MovingBody.Position.Y <= attackPosition.Y;
                    }
                }
                break;

                default: throw new ArgumentException(nameof(Orientation));
                }

                if (isAtEnd)
                {
                    EnterState(SpikeTrapState.WaitingAfterAttacking);
                    MovingBody.Position = attackPosition;
                }
            }
            break;

            case SpikeTrapState.WaitingAfterAttacking:
            {
                CurrentWaitTime += TimeSpan.FromSeconds(deltaSeconds);
                if (CurrentWaitTime >= DelayBeforeReturning)
                {
                    EnterState(SpikeTrapState.Returning);

                    Vector2 originDelta = FixedOrigin.GetWorldSpatialData().Position - MovingBody.Position;
                    Vector2 originDir   = originDelta.GetNormalizedSafe();
                    MovingBody.LinearVelocity = originDir * ReturnSpeed;
                }
            }
            break;

            case SpikeTrapState.Returning:
            {
                Vector2     movementDir   = MovingBody.LinearVelocity.GetNormalizedSafe();
                SpatialData originSpatial = FixedOrigin.GetWorldSpatialData();

                bool isAtEnd;
                switch (Orientation)
                {
                case SpikeTrapOrientation.Horizontal:
                {
                    if (movementDir.X > 0)
                    {
                        isAtEnd = MovingBody.Position.X >= originSpatial.Position.X;
                    }
                    else
                    {
                        isAtEnd = MovingBody.Position.X <= originSpatial.Position.X;
                    }
                }
                break;

                case SpikeTrapOrientation.Vertical:
                {
                    if (movementDir.Y > 0)
                    {
                        isAtEnd = MovingBody.Position.Y >= originSpatial.Position.Y;
                    }
                    else
                    {
                        isAtEnd = MovingBody.Position.Y <= originSpatial.Position.Y;
                    }
                }
                break;

                default: throw new ArgumentException(nameof(Orientation));
                }

                if (isAtEnd)
                {
                    EnterState(SpikeTrapState.Searching);
                    MovingBody.Position = originSpatial.Position;
                    MovingBody.Awake    = false;
                }
            }
            break;

            default: throw new ArgumentException(nameof(TrapState));
            }

            if (CurrentHitCooldown > TimeSpan.Zero)
            {
                CurrentHitCooldown -= TimeSpan.FromSeconds(deltaSeconds);
                if (CurrentHitCooldown <= TimeSpan.Zero)
                {
                    CurrentHitCooldown = TimeSpan.Zero;
                }
            }

            {
                Global.Game.DebugDrawCommands.Add(view =>
                {
                    view.DrawString(20, 400, $"{TrapState}");
                });
            }
        }
Example #26
0
        public override void Initialize()
        {
            float outerLeft     = Conversion.ToMeters(310);
            float innerLeft     = Conversion.ToMeters(79);
            float inner         = Conversion.ToMeters(80);
            float innerRight    = Conversion.ToMeters(79);
            float outerRight    = Conversion.ToMeters(222);
            float width         = Conversion.ToMeters(768);
            float height        = Conversion.ToMeters(128);
            float barrierHeight = Conversion.ToMeters(20);
            float density       = Global.OwliverDensity;

            //
            // Inner body
            //
            {
                // TODO(manu): Set InnerBodyComponent.Spatial.LocalAABB.
                SpatialData s = InnerBodyComponent.GetWorldSpatialData();
                InnerBodyComponent.Body = BodyFactory.CreateRectangle(
                    world: Global.Game.World,
                    width: innerLeft + inner + innerRight,
                    height: barrierHeight,
                    density: density,
                    position: s.Position + new Vector2(outerLeft + innerLeft + 0.5f * inner, 0.0f),
                    rotation: s.Rotation.Radians,
                    bodyType: BodyType.Static);
            }

            //
            // Outer body
            //
            {
                // TODO(manu): Set OuterBodyComponent.Spatial.LocalAABB.
                SpatialData s = OuterBodyComponent.GetWorldSpatialData();
                OuterBodyComponent.Body = BodyFactory.CreateBody(
                    world: Global.Game.World,
                    position: s.Position,
                    rotation: s.Rotation.Radians,
                    bodyType: BodyType.Static);

                Vector2 offsetRight = Conversion.ToMeters(300, 0);
                FixtureFactory.AttachRectangle(
                    body: OuterBodyComponent.Body,
                    width: outerLeft,
                    height: barrierHeight,
                    offset: new Vector2(0.5f * outerLeft, 0.0f),
                    density: density);
                FixtureFactory.AttachRectangle(
                    body: OuterBodyComponent.Body,
                    width: outerRight,
                    height: barrierHeight,
                    offset: new Vector2(width - 0.5f * outerRight, 0.0f),
                    density: density);
            }

            //
            // Trigger body
            //
            {
                Vector2 dim = Conversion.ToMeters(60, 80);
                Trigger.Spatial.LocalAABB = new AABB
                {
                    LowerBound = -0.5f * dim,
                    UpperBound = 0.5f * dim,
                };

                SpatialData s = Trigger.GetWorldSpatialData();
                s.Position.Y -= Conversion.ToMeters(20);
                //s.Position.Y -= Conversion.ToMeters((0.5f * 128) - 10);
                Trigger.Body = BodyFactory.CreateRectangle(
                    world: Global.Game.World,
                    width: s.LocalAABB.Width,
                    height: s.LocalAABB.Height,
                    density: 0,
                    position: s.Position,
                    rotation: s.Rotation.Radians,
                    bodyType: BodyType.Static);
                Trigger.Body.IsSensor     = true;
                Trigger.Body.CollidesWith = CollisionCategory.Friendly;
                Trigger.Body.OnCollision += OnCollisionWithTrigger;
            }

            base.Initialize();
        }
Example #27
0
        public void PerformChase(float deltaSeconds)
        {
            IsHoming = false;
            Body body = MyBody;

            if (Target != null)
            {
                SpatialData worldSpatial  = this.GetWorldSpatialData();
                SpatialData targetSpatial = Target.GetWorldSpatialData();
                Vector2     targetDelta   = targetSpatial.Position - worldSpatial.Position;
                targetDelta.GetDirectionAndLength(out Vector2 targetDir, out float targetDistance);

                if (targetDistance > TargetRange)
                {
                    // Don't do anything.
                }
                else if (targetDistance > TargetInnerRange)
                {
                    IsHoming = true;
                    Vector2 velocity = targetDir * Speed;

                    switch (HomingType)
                    {
                    case HomingType.ConstantSpeed:
                    {
                        if (body != null)
                        {
                            if (body.IsStatic)
                            {
                                Vector2 deltaPosition = velocity * deltaSeconds;
                                body.Position += deltaPosition;
                            }
                            else
                            {
                                body.LinearVelocity = velocity;
                            }
                        }
                        else
                        {
                            Vector2 deltaPosition = velocity * deltaSeconds;
                            Vector2 newPosition   = worldSpatial.Position + deltaPosition;
                            Spatial.SetWorldPosition(newPosition);
                        }
                    }
                    break;

                    case HomingType.ConstantAcceleration:
                    {
                        if (body != null)
                        {
                            Vector2 impulse = body.Mass * velocity;
                            body.ApplyLinearImpulse(ref impulse);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                    break;

                    default: throw new ArgumentException(nameof(HomingType));
                    }
                }
            }

            if (DebugDrawingEnabled)
            {
                Global.Game.DebugDrawCommands.Add(view =>
                {
                    Vector2 p = this.GetWorldSpatialData().Position;
                    view.DrawPoint(p, Conversion.ToMeters(3.0f), Color.Turquoise);
                    view.DrawCircle(p, TargetInnerRange, Color.Yellow);
                    view.DrawCircle(p, TargetRange, Color.Blue);
                });
            }
        }