public Shop() { BodyComponent = new BodyComponent(this) { InitMode = BodyComponentInitMode.Manual, }; RootComponent = BodyComponent; ShopAnimation = new SpriteAnimationComponent(this) { AnimationTypes = new List <SpriteAnimationType> { SpriteAnimationType.Shop, }, }; ShopAnimation.AttachTo(BodyComponent); ShopkeeperAnimation = new SpriteAnimationComponent(this) { AnimationTypes = new List <SpriteAnimationType> { SpriteAnimationType.Shopkeeper_Idle_Front, }, }; ShopkeeperAnimation.Spatial.Position.Y -= Conversion.ToMeters(100); ShopkeeperAnimation.AttachTo(ShopAnimation); }
public bool ChangeActiveAnimation(SpriteAnimationType newAnimationType, bool transferState = false) { Debug.Assert(newAnimationType != SpriteAnimationType.Unknown); bool result = false; if (newAnimationType != ActiveAnimationType) { bool hasOldState = false; SpriteAnimationState oldState = default(SpriteAnimationState); if (ActiveAnimationType != SpriteAnimationType.Unknown) { hasOldState = true; oldState = ActiveAnimation.State; ActiveAnimation.Stop(); } ActiveAnimationType = newAnimationType; ActiveAnimation.Play(); if (hasOldState && transferState) { ActiveAnimation.State.CurrentFrameTime = oldState.CurrentFrameTime; ActiveAnimation.State.CurrentFrameIndex = oldState.CurrentFrameIndex; } Spatial.LocalAABB = Conversion.ToMeters(ActiveAnimation.CalcAABB()); result = true; } return(result); }
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(); }
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 :; } }
public void CreateScreen(int posX, int posY) { Screen screen = new Screen { WorldPosition = Conversion.ToMeters(posX * ScreenTileWidth, posY * ScreenTileHeight), GridPosition = new Point(posX, posY), }; _screens[posY, posX] = screen; }
public override void Initialize() { base.Initialize(); if (SpriteContentName != null) { Sprite.Texture = Global.Game.Content.Load <Texture2D>(SpriteContentName); Spatial.LocalAABB = Conversion.ToMeters(Sprite.CalcAABB()); } }
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; }; }
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); }); } } }
public Tankton() { BodyComponent = new BodyComponent(this) { InitMode = BodyComponentInitMode.Manual, }; RootComponent = BodyComponent; Animation = new SpriteAnimationComponent(this) { AnimationTypes = new List <SpriteAnimationType> { SpriteAnimationType.Tankton_Idle_Left, SpriteAnimationType.Tankton_Idle_Right, }, }; Animation.Spatial.Position.Y += Conversion.ToMeters(100); Animation.AttachTo(BodyComponent); Health = new HealthComponent(this) { MaxHealth = 20, }; Health.OnHit += OnHit; Health.OnDeath += OnDeath; HealthDisplay = new HealthDisplayComponent(this) { Health = Health, HealthIcon = SpriteAnimationFactory.CreateAnimationInstance(SpriteAnimationType.Cross), InitialDisplayOrigin = HealthDisplayComponent.DisplayOrigin.Bottom, NumIconsPerRow = 5, }; HealthDisplay.AttachTo(Animation); GameObjectFactory.CreateOnHitSquasher(this, Health, Animation).SetDefaultCurves( duration: HitDuration, extremeScale: new Vector2(0.9f, 1.1f)); GameObjectFactory.CreateOnHitBlinkingSequence(this, Health, Animation).SetDefaultCurves(HitDuration); }
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(); }
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(); }
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(); }
public Gate() { LeftEdgeOffset = new SpatialComponent(this); { SpriteAnimationData anim = SpriteAnimationFactory.GetAnimation(SpriteAnimationType.Gate_Closed); Vector2 hotspot = anim.Config.Hotspot * anim.Config.Scale; float offset = Conversion.ToMeters(hotspot.X - 128); LeftEdgeOffset.Spatial.Position.X -= offset; } LeftEdgeOffset.AttachTo(this); InnerBodyComponent = new BodyComponent(this) { InitMode = BodyComponentInitMode.Manual, }; InnerBodyComponent.AttachTo(LeftEdgeOffset); OuterBodyComponent = new BodyComponent(this) { InitMode = BodyComponentInitMode.Manual, }; OuterBodyComponent.AttachTo(LeftEdgeOffset); Trigger = new BodyComponent(this) { InitMode = BodyComponentInitMode.Manual, }; Trigger.AttachTo(this); Animation = new SpriteAnimationComponent(this) { AnimationTypes = new List <SpriteAnimationType> { SpriteAnimationType.Gate_Closed, SpriteAnimationType.Gate_Open, }, }; Animation.AttachTo(this); }
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(); }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { CurrentFrameIndex++; DebugDrawCommands.Clear(); float deltaSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds; Perf.BeginSample(PerformanceSlots.InputUpdate); Input.Update(deltaSeconds); Perf.EndSample(PerformanceSlots.InputUpdate); if (Input.PlatformInput.WantsExit) { Exit(); } if (Input.PlatformInput.ToggleFullscreen) { graphics.ToggleFullScreen(); } #if DEBUG deltaSeconds *= Input.DebugInput.SpeedMultiplier; { ActiveCamera.Movement.MovementVector = Input.DebugMovement; } if (Input.DebugInput.ToggleMainDrawing) { MainDrawingEnabled = !MainDrawingEnabled; } if (Input.DebugInput.ToggleDebugDrawing) { DebugDrawingEnabled = !DebugDrawingEnabled; } if (Input.DebugInput.TogglePhysicsDebugView) { PhysicsDebugView.Enabled = !PhysicsDebugView.Enabled; } if (Input.DebugInput.ToggleCameraVisibilityBounds) { if (ActiveCamera.CameraComponent.VisibilityBounds == null) { ActiveCamera.CameraComponent.VisibilityBounds = CurrentLevel.LevelBounds; } else { ActiveCamera.CameraComponent.VisibilityBounds = null; } if (ActiveCamera.SpringArm.Target == null) { ActiveCamera.SpringArm.Target = Owliver; } else { ActiveCamera.SpringArm.Target = null; } } if (Input.DebugInput.ResetCameraPosition) { ActiveCamera.Spatial.Position = Owliver.GetWorldSpatialData().Position; } #endif { Owliver.Movement.MovementVector = Input.CharacterMovement; Owliver.Input = Input.CharacterInput; } // TODO(manu): Make use of `Input.CompationInput`! // Add pending game objects. GameObjects.AddRange(GameObjectsPendingAdd); foreach (GameObject go in GameObjectsPendingAdd) { go.Initialize(); go.PostInitialize(); } GameObjectsPendingAdd.Clear(); // Execute pre-physics update. foreach (GameObject go in GameObjects) { go.PrePhysicsUpdate(deltaSeconds); } // Physics simulation float simTime = _excessSimTime + deltaSeconds; Perf.BeginSample(PerformanceSlots.WorldStep); while (simTime > _secondsPerSimStep) { World.Step(_secondsPerSimStep); simTime -= _secondsPerSimStep; } Perf.EndSample(PerformanceSlots.WorldStep); _excessSimTime = simTime; CurrentLevel.Update(deltaSeconds); // Post-physics update. foreach (GameObject go in GameObjects) { go.Update(deltaSeconds); AABB aabb = Global.CreateInvalidAABB(); foreach (SpatialComponent sc in go.GetComponents <SpatialComponent>()) { AABB other = sc.GetWorldSpatialData().AbsoluteAABB; aabb.Combine(ref other); } DebugDrawCommands.Add(view => view.DrawPoint(aabb.Center, Conversion.ToMeters(3), Color.MonoGameOrange)); DebugDrawCommands.Add(view => view.DrawAABB(ref aabb, Color.Lime)); } // Remove pending game objects. GameObjects.RemoveAll(go => GameObjectsPendingRemove.Contains(go)); foreach (GameObject go in GameObjectsPendingRemove) { go.Destroy(); } GameObjectsPendingRemove.Clear(); base.Update(gameTime); Perf.AdvanceFrame(); }
public void PerformChase(float deltaSeconds) { Body body = MyBody; if (Target != null) { Vector2 worldPosition = this.GetWorldSpatialData().Position; Vector2 targetPosition = Target.GetWorldSpatialData().Position; Vector2 targetDelta = targetPosition - worldPosition; targetDelta.GetDirectionAndLength(out Vector2 targetDir, out float targetDistance); if (targetDistance > TargetRange) { // Note(manu): Without this value the target would always be out of range until it has _completely_ stopped. const float compensationForSlowMovement = 0.01f; Vector2 newPosition = targetPosition - (targetDir * (TargetRange - compensationForSlowMovement)); if (body != null) { Debug.Assert(body.BodyType == BodyType.Static); body.Position = newPosition; } else { Spatial.SetWorldPosition(newPosition); } } else if (targetDistance > TargetInnerRange) { float relevantTargetDistance = targetDistance - TargetInnerRange; float weightedDistance = relevantTargetDistance * SpeedFactor; Vector2 velocity = targetDir * weightedDistance; if (body != null) { if (body.BodyType == BodyType.Static) { Vector2 deltaPosition = velocity * deltaSeconds; body.Position += deltaPosition; } else { // TODO(manu): Setting the linear velocity is kind of bad. Can we do this with an impulse instead? // Note(manu): This code path is untested (2017-06-15). body.LinearVelocity = velocity; } } else { Vector2 deltaPosition = velocity * deltaSeconds; Vector2 newPosition = worldPosition + deltaPosition; Spatial.SetWorldPosition(newPosition); } } } 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); }); } }
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); }); } }
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(); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { WorldRenderer.Initialize(GraphicsDevice); UIRenderer.Initialize(GraphicsDevice); PhysicsDebugView.LoadContent(GraphicsDevice, Content); CurrentLevel = new Level(Content) { ContentNameFormat_Ground = "level01/level1_ground_{0}{1}", ContentNameFormat_Collision = "level01/static_collision/static_collision_{0}{1}", ContentNameFormat_Layout = "level01/layout/layout_{0}{1}", }; for (int x = 0; x < 4; x++) { for (int y = 0; y < 7; y++) { CurrentLevel.CreateScreen(x, y); } } { Owliver = new Owliver(); Owliver.Spatial.Position += Conversion.ToMeters(450, 600); AddGameObject(Owliver); CurrentLevel.CullingCenter = Owliver; } CurrentLevel.LoadContent(); { ActiveCamera = new CameraObject(); ActiveCamera.CameraComponent.VisibilityBounds = CurrentLevel.LevelBounds; ActiveCamera.CameraComponent.OnGraphicsDeviceReset(GraphicsDevice); Window.ClientSizeChanged += (o, e) => { ActiveCamera.CameraComponent.OnGraphicsDeviceReset(GraphicsDevice); }; ActiveCamera.SpringArm.BeforeInitialize += () => { ActiveCamera.SpringArm.Target = Owliver; }; AddGameObject(ActiveCamera); } #if true { var testSlurp = GameObjectFactory.CreateKnown(KnownGameObject.Slurp); testSlurp.Spatial.Position += Conversion.ToMeters(300, 250); AddGameObject(testSlurp); } { var testTankton = new Tankton(); testTankton.Spatial.Position += Conversion.ToMeters(900, 350); AddGameObject(testTankton); } { Random rand = new Random(); Global.SpawnGameObjectsInRingFormation( center: Conversion.ToMeters(2400, 500), radius: 2.5f, numToSpawn: 15, rand: rand, types: new[] { KnownGameObject.Bonbon_Gold, KnownGameObject.Bonbon_Red }); Global.SpawnGameObjectsInRingFormation( center: Conversion.ToMeters(2400, 500), radius: 1.0f, numToSpawn: 5, rand: rand, types: new[] { KnownGameObject.Bonbon_Gold, KnownGameObject.Bonbon_Red }); } { var testKey = new KeyPickup() { KeyType = KeyType.Gold }; testKey.Spatial.Position += Conversion.ToMeters(700, 720); AddGameObject(testKey); } { var testGate = new Gate(); testGate.Spatial.Position += Conversion.ToMeters(2300, 1100); AddGameObject(testGate); } { var testShop = new Shop(); testShop.Spatial.Position += Conversion.ToMeters(1300, 500); AddGameObject(testShop); var testFruitBowl = new ShopItem() { ItemType = ShopItemType.FruitBowl }; testFruitBowl.Price = ShopItemPriceType._20; testFruitBowl.AttachTo(testShop); testFruitBowl.Spatial.Position += Conversion.ToMeters(-110.0f, -90.0f); AddGameObject(testFruitBowl); var testRod = new ShopItem() { ItemType = ShopItemType.FishingRod }; testRod.Price = ShopItemPriceType._100; testRod.AttachTo(testShop); testRod.Spatial.Position += Conversion.ToMeters(128.0f, -80.0f); AddGameObject(testRod); } { var testSinger = new Singer(); testSinger.Spatial.Position += Conversion.ToMeters(2600, 300); AddGameObject(testSinger); } { var testTrap = new SpikeTrap() { Orientation = SpikeTrapOrientation.Vertical, SensorReach = 4.0f, }; testTrap.Spatial.Position += Conversion.ToMeters(1600, 500); AddGameObject(testTrap); } #endif { var BackgroundMusic = Content.Load <Song>("snd/FiluAndDina_-_Video_Game_Background_-_Edit"); MediaPlayer.IsRepeating = true; #if false MediaPlayer.Play(BackgroundMusic); #endif } Hud.Initialize(); Hud.ResetLayout(GraphicsDevice.Viewport.Bounds); Window.ClientSizeChanged += (o, e) => { Hud.ResetLayout(GraphicsDevice.Viewport.Bounds); }; }