/// <summary> /// Update projectile /// </summary> public bool Update(float elapsedTime, GameManager game) { if (game == null) { throw new ArgumentNullException("game"); } // add elapsed time for this frame this.elapsedTime += elapsedTime; // normalize time float normalizedTime = Math.Min(1.0f, this.elapsedTime / totalTime); // compute current projectile position Vector3 position = Vector3.Lerp(sourcePosition, destinationPosition, normalizedTime); // set postion into projectile transform matrix transform.Translation = position; // if projectile includes a particle system update its position if (system != null) { system.SetTransform(systemTransform * transform); } // check if projectile hit any player int playerHit = game.GetPlayerAtPosition(position); // if a player is hit or reached destination explode projectile if ((playerHit != player && playerHit != -1) || normalizedTime == 1.0f) { // compute explosion position moving hit point into hit normal direction Vector3 explosionPosition = position + 0.5f * animatedSpriteSize * transform.Backward; // set transform to explosion position transform.Translation = explosionPosition; // if an animated sprite explosion is available, create it if (animatedSpriteSize > 0) { game.AddAnimSprite(animatedSprite, explosionPosition, animatedSpriteSize, 10.0f, animatedSpriteFrameRate, animatedSpriteDrawMode, -1); } // if splash damage is available, apply splash damage to nearby players if (explosionDamageRadius > 0) { game.AddDamageSplash(player, explosionDamage, explosionPosition, explosionDamageRadius); } // if exploded on a player add contact damage if (playerHit != -1 && game.GetPlayer(playerHit).IsAlive) { game.AddDamage(player, playerHit, contactDamage, Vector3.Normalize(destinationPosition - sourcePosition)); } // if explosion sound is available, play it if (explosionSound != null) { game.PlaySound3D(explosionSound, explosionPosition); } // add explosion particle system if (projectileType == ProjectileType.Missile) { game.AddParticleSystem( ParticleSystemType.MissileExplode, transform); } else if (projectileType == ProjectileType.Blaster) { game.AddParticleSystem( ParticleSystemType.BlasterExplode, transform); } // kill trail particle system if (system != null) { system.SetTotalTime(-1e10f); } // return false to kill the projectile return(false); } // return true to keep projectile alive return(true); }
/// <summary> /// Updates the player ship for given elapsed time /// </summary> public void Update( float elapsedTime, // elapsed time on this frame CollisionMesh collision, // level collision mesh EntityList entities) // level spawn points { if (collision == null) { throw new ArgumentNullException("collision"); } if (entities == null) { throw new ArgumentNullException("entities"); } // updates damage screen time (zero for no damage indication) damageTime = Math.Max(0.0f, damageTime - elapsedTime); // if player dead if (IsAlive == false) { // disable engine particle system particleBoost.Enabled = false; // updates dead time (if zero, player is alive) deadTime = Math.Max(0.0f, deadTime - elapsedTime); // if player dead time expires, respawn if (IsAlive == true) { // reset player to a random spawn point Reset(entities.GetTransformRandom(random)); // add spawn animated sprite in front of player Vector3 Pos = movement.position + 10 * movement.rotation.Forward; gameManager.AddAnimSprite(AnimSpriteType.Spawn, Pos, 140, 80, 30, DrawMode.Additive, playerIndex); // play spawn sound gameManager.PlaySound("ship_spawn"); // reset energy, shield and boost energy = 1.0f; shield = 1.0f; boost = 1.0f; missileCount = 3; } return; } // hold position before movement Vector3 lastPostion = movement.position; // update movement movement.Update(elapsedTime); // test for collision with level Vector3 collisionPosition; if (collision.BoxMove(box, lastPostion, movement.position, 1.0f, 0.0f, 3, out collisionPosition)) { // update to valid position after collision movement.position = collisionPosition; // compute new velocity after collision Vector3 newVelocity = (collisionPosition - lastPostion) * (1.0f / elapsedTime); // if collision sound enabled if (collisionSound) { // test collision angle to play collision sound Vector3 WorldVel = movement.WorldVelocity; float dot = Vector3.Dot( Vector3.Normalize(WorldVel), Vector3.Normalize(newVelocity)); if (dot < 0.7071f) { // play collision sound gameManager.PlaySound("ship_collide"); // set rumble intensity dot = 1 - 0.5f * (dot + 1); gameManager.SetVibration(playerIndex, dot * 0.5f); // disable collision sounds until ship stops colliding collisionSound = false; } } // set new velocity after collision movement.WorldVelocity = newVelocity; } else { // clear of collisions, re-enable collision sounds collisionSound = true; } // update player transform transform = movement.rotation; transform.Translation = movement.position; // compute inverse transform transformInverse = Matrix.Invert(transform); // get normalized player velocity float velocityFactor = movement.VelocityFactor; // update bobbing bobbingTime += elapsedTime; float bobbingFactor = 1.0f - velocityFactor; float time = GameOptions.ShipBobbingSpeed * bobbingTime % (2 * MathHelper.TwoPi); float distance = bobbingFactor * GameOptions.ShipBobbingRange; bobbing.M41 = distance * (float)Math.Sin(time * 0.5f); bobbing.M42 = distance * (float)Math.Sin(time); bobbingInverse.M41 = -bobbing.M41; bobbingInverse.M42 = -bobbing.M42; // compute transform with bobbing Matrix bobbingTransform = bobbing * transform; // update particle system position particleBoost.Enabled = true; particleBoost.SetTransform(boostTransform * bobbingTransform); // if shield active if (shieldUse) { // update shield position animatedSpriteShield.Position = bobbingTransform.Translation + 10f * bobbingTransform.Forward; // update shiled charge shield -= elapsedTime / GameOptions.ShieldUse; // if shield charge depleted if (shield < 0) { // disable shield shieldUse = false; shield = 0; // kill shield animated sprite animatedSpriteShield.SetTotalTime(0); animatedSpriteShield = null; } } else { // change shield shield = Math.Min(1.0f, shield + elapsedTime / GameOptions.ShieldRecharge); } // if boost active if (boostUse) { // increase ship maximum velocity movement.maxVelocity = GameOptions.MovementVelocityBoost; // apply impulse force forward AddImpulseForce(transform.Forward * GameOptions.BoostForce); // set particle system velocity scale particleBoost.VelocityScale = Math.Min(1.0f, particleBoost.VelocityScale + 4.0f * elapsedTime); // update shield charge boost -= elapsedTime / GameOptions.BoostUse; // if boost depleated if (boost < 0) { // disable boost boostUse = false; boost = 0; } } else { // slowly returns ship maximum velocity to normal levels if (movement.maxVelocity > GameOptions.MovementVelocity) { movement.maxVelocity -= GameOptions.BoostSlowdown * elapsedTime; } // slowly returns particle system velocity scale to normal levels particleBoost.VelocityScale = Math.Max(0.1f, particleBoost.VelocityScale - 2.0f * elapsedTime); // charge boost boost = Math.Min(1.0f, boost + elapsedTime / GameOptions.BoostRecharge); } // charge blaster blaster = Math.Min(1.0f, blaster + elapsedTime / GameOptions.BlasterChargeTime); // charge missile missile = Math.Min(1.0f, missile + elapsedTime / GameOptions.MissileChargeTime); // update chase camera chaseCamera.ChasePosition = transform.Translation; chaseCamera.ChaseDirection = transform.Forward; chaseCamera.Up = transform.Up; chaseCamera.Update(elapsedTime, collision); }