/// <summary> /// Collision handling. /// </summary> /// <param name="e">The collision event thrown</param> public override void OnCollision(CollisionEvent e) { base.OnCollision(e); IGameObject collisionObject = e.OtherSolid.UserData as IGameObject; if (collisionObject == null) { return; } if (health <= 0) { return; } // Checkpoints! (Waypoints) add Time if (collisionObject.ContactGroup == Engine.Physics.ContactGroup.Waypoint) { if (((WaypointObject)collisionObject).SecondsToAdd > 0) { Intercom.SendMessage( String.Format("You past a Checkpoint! {0} seconds remaining!", remainingTime), true); remainingTime += ((WaypointObject)collisionObject).SecondsToAdd; ((WaypointObject)collisionObject).SecondsToAdd = 0; game.GameStates.Score.KilledEnemy += 5; game.GameStates.Score.AddPoints(500); } } if (!game.Physics.CanSolidsCollide(e.ThisSolid, e.OtherSolid)) { return; } switch (collisionObject.ContactGroup) { case Engine.Physics.ContactGroup.Canyon: if (!Helper.Lock("Collision.Player.With.Canyon", TimeSpan.FromSeconds(1))) { ReceiveDamage((int)speed / 2); } // mirror velocity to "bounce off" Vector3 normal = Vector3.Normalize(e.Normal); Vector3 dir = Vector3.Normalize(Velocity); Vector3 reflect = dir - 2 * Vector3.Dot(dir, normal) * normal; //Velocity = Velocity.Length() * reflect; //LocalRotation = Helper.RotateTo(Velocity, -Vector3.UnitZ); LocalPosition += 10 * normal; //angHorz = angHorzTemp = angVert = angVertTemp = 0; //angHorz = 360 - angHorz; //angVert = 360 - angVert; //angRoll = 360 - angRoll; //GraphicalConsole.GetSingleton(game).WriteLine("Horz:"+angHorz+" Vert:"+angVert+" Roll:"+angRoll,1); break; case Engine.Physics.ContactGroup.Sky: game.GameStates.Hud.DisplayScrollingText("Do not leave the canyon !", new GameTime()); Intercom.PlayerLeavingCanyon(); ReceiveDamage(1000); break; default: break; } AngularVelocity = Vector3.Zero; }
/// <summary> /// Allows the game component to update itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> public override void Update(GameTime gameTime) { base.Update(gameTime); //GraphicalConsole.GetSingleton(game).WriteLine("" + (device.IsConnected ? true : false), 1); if (hasSpaceMouse) { int eps = 20;//30; mouseY = 50 * (float)gameTime.ElapsedGameTime.TotalSeconds * ((float)device.Sensor.Rotation.X * eps); mouseX = 50 * (float)gameTime.ElapsedGameTime.TotalSeconds * ((float)device.Sensor.Rotation.Z * eps); } else { mouseX = 50 * (float)gameTime.ElapsedGameTime.TotalSeconds * game.Input.MouseMovement.X; mouseY = 50 * (float)gameTime.ElapsedGameTime.TotalSeconds * game.Input.MouseMovement.Y; } #region Finsh if time remaining is zero // Temp fix because we have no finish yet. if (remainingTime > 0) { if (Helper.WaitFor("RemainingTime", TimeSpan.FromSeconds(1))) { remainingTime--; Helper.ResetWait("RemainingTime"); } // Play the hurry up sound if (remainingTime <= 10) { if (!hurryUpEfx.Playing()) { if (Helper.Lock("Hurry Up Intercom", TimeSpan.FromSeconds(10))) { Intercom.HurryUp(); } hurryUpEfx.Loop = true; hurryUpEfx.Play(); } } } else { hurryUpEfx.Loop = false; hurryUpEfx.Stop(); hurryUpEfx.Dispose(); game.Sounds.MusicBox(MusicBoxStatus.Pause); if (gameOverEfx.Playing() == false) { gameOverEfx.Play(); } if (Helper.WaitFor("FlagDisplayTime", TimeSpan.FromSeconds(4))) { game.Sounds.MusicBox(MusicBoxStatus.Play); Helper.ResetWait("FlagDisplayTime"); Explode(); game.GameStates.Gameplayed = true; } Finish(); return; } #endregion Finsh if time remaining is zero #region Game over and respawn time = gameTime; if (gameOver) { if (Helper.WaitFor("PlayerGameOver", TimeSpan.FromSeconds(4))) { Helper.ResetWait("PlayerGameOver"); this.Enabled = false; game.GameStates.Gameplayed = true; } //Finish(); return; } if (respawn) { if (Helper.WaitFor("PlayerRespawn", TimeSpan.FromSeconds(4))) { //Reset Helpers respawn = false; // (REPAWN NOW!) //canyonPosition++; health = 100; shield = 50; Model.AfterBurnerLength = minBooster; SetPositionInCanyon(canyonPosition); game.GameStates.Hud.DisplayScrollingText(lifes + " Lifes remaining!", gameTime); Visible = true; Weapons.WeaponsVisible = true; } else { return; } } #endregion Game over and respawn #region Speed management if (game.Input.IsKeyDown("Player1.Up") && fuel > 0) // do we have enough fuel ? { // Booster temperature control if (Helper.WaitFor("BoosterHeat", TimeSpan.FromSeconds(0.5f))) { if (boosterHeat == maxBoosterHeat) { if (Helper.WaitFor("Overheat", TimeSpan.FromSeconds(3))) { Helper.ResetWait("Overheat"); Explode(); } } else { boosterHeat += boosterHeatGap; } Helper.ResetWait("BoosterHeat"); } decay = 0; if (speed < MaxSpeed) { speed += SpeedGap; } if (Model.AfterBurnerLength < maxBooster) { Model.AfterBurnerLength += boosterGap; } // Fuel Check fuel -= (int)((speed / (MaxSpeed / 100)) * 0.02f); } else { // Booster temperature control if (Helper.WaitFor("BoosterHeat", TimeSpan.FromSeconds(2))) { if (boosterHeat > minBoosterHeat) { boosterHeat -= boosterHeatGap; } Helper.ResetWait("BoosterHeat"); } if (game.Input.IsKeyDown("Player1.Down")) //if (device.Sensor.Rotation.Z > 0) { if (speed > MinSpeed) { speed -= SpeedGap; } if (Model.AfterBurnerLength > minBooster) { Model.AfterBurnerLength -= boosterGap; } } else { if (speed > MinSpeed) { if (decay < MaxDecay) { decay += 0.05f; } speed -= (int)decay; if (Model.AfterBurnerLength > minBooster) { Model.AfterBurnerLength -= boosterGap; } } } } // Check for a negative fuel value and correct it: if (fuel < 0) { fuel = 0; } // Calculate new velocity Velocity = Vector3.Transform(new Vector3(0, 0, -speed), LocalRotation); #endregion Speed management #region Set the flight distance if (Helper.WaitFor("Distance", TimeSpan.FromSeconds(0.001f))) { distance += (double)(speed * 0.0006f); Helper.ResetWait("Distance"); } #endregion Set the flight distance #region Compute banking and drift // Get direction for driftig Vector3 direction = Velocity; Vector3 translationDirection = Vector3.Cross(this.UP, direction); // Handle inputs and compute drift if (game.Input.IsKeyDown("Player1.Left")) { translationDirection *= translationGap; Velocity += translationDirection; angHorz += driftFactor; } if (game.Input.IsKeyDown("Player1.Right")) { translationDirection *= -translationGap; Velocity += translationDirection; angHorz -= DriftFactor; } // Compute banking angle angHorz += -(float)Math.Atan(mouseX) * BankingFactor; angHorz -= angHorz * AutoLevel; angVert += -(float)Math.Atan(mouseY) * BankingFactor; angVert -= angVert * AutoLevel; angRoll += angHorz; angRoll *= RollFactor; #endregion Compute banking and drift #region Update model and camera view if (firstTime == 0) { // Banking Quaternion banking = Quaternion.CreateFromYawPitchRoll(angHorz, angVert, angRoll); // Rotation Vector3 up = Vector3.Transform(UP, Quaternion.Conjugate(LocalRotation)); Quaternion horizontal = Quaternion.CreateFromAxisAngle(up, MouseIntensity * mouseX); Quaternion vertical = Quaternion.CreateFromAxisAngle(RIGHT, MouseIntensity * mouseY); Vector3 directionTemp = Vector3.Transform(direction, Matrix.CreateFromQuaternion(Quaternion.Concatenate(horizontal, banking))); if (IsFlightDirectionOK(directionTemp)) { this.Model.LocalRotation = banking; } else { horizontal = Quaternion.CreateFromAxisAngle(up, 0); vertical = Quaternion.CreateFromAxisAngle(RIGHT, 0); } Rotate(Quaternion.Concatenate(vertical, horizontal)); } else { // Banking this.Model.LocalRotation = Quaternion.CreateFromYawPitchRoll((angHorzTemp + angHorz) / 2, (angVertTemp + angVert) / 2, (angRollTemp + angRoll) / 2); firstTime--; LocalRotation = Quaternion.Identity; } #endregion Update model and camera view #region camera fov for boost // interpolate camera fov between 90° and 120° depending on current speed cam.Fov = 90 + 30 * (Math.Max(0, speed - minSpeed) / (maxSpeed - minSpeed)); #endregion // Update others UpdatePosition(); UpdateCameraZoom(); if (!isFinish) { if (hasSpaceMouse) { Weapons.UpdatePlayerWeapons3D(gameTime, device.Keyboard); } else { Weapons.UpdatePlayerWeapons(gameTime); } } UpdateAudio(); AngularVelocity = Vector3.Zero; #region Pre-Frame Buffer angHorzTemp = angHorz; angRollTemp = angRoll; angVertTemp = angVert; #endregion Pre-Frame Buffer }