/// <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) { GamePadState gpState = GamePad.GetState(PlayerIndex.One); // Allows the game to exit if (gpState.Buttons.Back == ButtonState.Pressed) this.Exit(); if (gpState.IsButtonDown(Buttons.LeftShoulder) && gpState.IsButtonDown(Buttons.A)) { if (!held) { Entities.Remove(building); building = new Building(this); Entities.Add(building); held = true; } } else held = false; Vector3 playerLook = Camera.Look; Vector3 playerRight = Camera.Right; // Fix Y coord if 'cool mode' is on. if (CoolModeActive && gpState.IsButtonUp(Buttons.LeftTrigger)) { playerLook.Y = 0; playerLook.Normalize(); playerRight.Y = 0; playerRight.Normalize(); } foreach (Entity e in Entities) e.Update(gameTime); Vector3 prevPos = Camera.Position; if (gpState.ThumbSticks.Left != Vector2.Zero) Camera.Position += gpState.ThumbSticks.Left.X * playerRight * (MoveSpeed / TimeSpan.TicksPerSecond) * gameTime.ElapsedGameTime.Ticks + gpState.ThumbSticks.Left.Y * playerLook * (MoveSpeed / TimeSpan.TicksPerSecond) * gameTime.ElapsedGameTime.Ticks; if (gpState.ThumbSticks.Right != Vector2.Zero) Camera.Angle += new Vector3(-(gpState.ThumbSticks.Right.Y * 0.1f), gpState.ThumbSticks.Right.X * 0.1f, 0f); if (gpState.IsButtonDown(Buttons.DPadUp)) MoveSpeed += 5.0f * gameTime.ElapsedGameTime.Ticks / (float) TimeSpan.TicksPerSecond; if (gpState.IsButtonDown(Buttons.DPadDown)) MoveSpeed -= 5.0f * gameTime.ElapsedGameTime.Ticks / (float) TimeSpan.TicksPerSecond; if (gpState.IsButtonDown(Buttons.Start) && !lastStartButtonState) CoolModeActive = !CoolModeActive; lastStartButtonState = gpState.IsButtonDown(Buttons.Start); if (CoolModeActive) { bool fail = false; if (gpState.IsButtonDown(Buttons.LeftTrigger)) CoolModeVelocityDown = 0f; else CoolModeVelocityDown += (((9.81f) / TimeSpan.TicksPerSecond) * (float) gameTime.ElapsedGameTime.Ticks); Camera.Position += Vector3.Down * CoolModeVelocityDown; BoundingBox playerBox = new BoundingBox(Camera.Position - new Vector3(1.6f, 6.0f, 1.6f), Camera.Position + new Vector3(1.6f, 1.0f, 1.6f)); //Ray downRay = new Ray(Camera.Position, Vector3.Down); // TODO: Move this code somewhere better. // TODO: Stop duplicating box collision code inside case EntityCollisionType.BuildingSpecial! foreach (Entity e in Entities) { switch (e.CollisionType) { case EntityCollisionType.BuildingSpecial: // TODO: Cleanup properly like. foreach (Entity emp in ((Building)e).Model.ModelParts) { Debug.Assert(emp.CollisionType == EntityCollisionType.BoundingBox, "BuildingModelPart does not have BoundingBox collision!"); // --- SLIDING COLLISION CODE --- if (emp.BoundingBox.Contains(playerBox) != ContainmentType.Disjoint) { foreach (Plane p in emp.GetPlanesFromBoundingBox()) { if (p.Intersects(playerBox) == PlaneIntersectionType.Intersecting) { Vector3 shove = (Camera.Position - prevPos) * p.Normal; if ((p.Normal.X != 0f && (p.Normal.X > 0f && shove.X < 0f)) || (p.Normal.Y != 0f && (p.Normal.Y > 0f && shove.Y < 0f)) || (p.Normal.Z != 0f && (p.Normal.Z > 0f && shove.Z < 0f))) shove = Vector3.Zero - shove; Camera.Position += shove; playerBox = new BoundingBox(Camera.Position - new Vector3(1.6f, 6.0f, 1.6f), Camera.Position + new Vector3(1.6f, 1.0f, 1.6f)); // making up for ground collision code if (p.Normal.Y == 1f) fail = true; } } } } break; case EntityCollisionType.BoundingBox: BoundingBox b = e.BoundingBox; // --- SLIDING COLLISION CODE --- if (b.Intersects(playerBox)) { foreach (Plane p in e.GetPlanesFromBoundingBox()) { if (p.Intersects(playerBox) == PlaneIntersectionType.Intersecting) { Vector3 shove = (Camera.Position - prevPos) * p.Normal; if ((p.Normal.X != 0f && (p.Normal.X > 0f && shove.X < 0f)) || (p.Normal.Y != 0f && (p.Normal.Y > 0f && shove.Y < 0f)) || (p.Normal.Z != 0f && (p.Normal.Z > 0f && shove.Z < 0f))) shove = Vector3.Zero - shove; Camera.Position += shove; playerBox = new BoundingBox(Camera.Position - new Vector3(1.6f, 6.0f, 1.6f), Camera.Position + new Vector3(1.6f, 1.0f, 1.6f)); // making up for ground collision code if (p.Normal.Y == 1f) fail = true; } } } // --- GROUND COLLISION CODE --- /*{ //BoundingBox tmphack = new BoundingBox(new Vector3(b.Min.X, b.Max.Y - 5f, b.Min.Z), b.Max); if (b.Intersects(playerBox)) { float? distFromFloor = downRay.Intersects(b); if (distFromFloor < 0) Debug.WriteLine(":)"); if (distFromFloor == null || distFromFloor == float.NaN || distFromFloor >= 6.0f || distFromFloor < 0) // cam is 6.0 units from ground continue; // Otherwise... fail = true; // we say in the boundingbox playerBox that the camera should be 60 units from the ground float distIntersectingFloor = ((float)distFromFloor) - 6.0f; distIntersectingFloor = MathHelper.Clamp(distIntersectingFloor, -6.0f, 0); Camera.Position.Y -= distIntersectingFloor; playerBox = new BoundingBox(Camera.Position - new Vector3(1.6f, 6.0f, 1.6f), Camera.Position + new Vector3(1.6f, 1.0f, 1.6f)); downRay = new Ray(Camera.Position, Vector3.Down); } }*/ break; case EntityCollisionType.None: break; default: throw new NotImplementedException(); } } if (fail) CoolModeVelocityDown = 0f; } base.Update(gameTime); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); cube = Content.Load<Model>("xsmoothmonkeyman"); lucidaConsoleBold = Content.Load<SpriteFont>("LucidaConsoleBold"); Entities = new List<Entity>(); Entities.Add(new TempGround(this)); building = new Building(this); Entities.Add(building); foreach (Entity e in Entities) e.Initialize(); }