protected override void Update(GameTime gameTime) { foreach (var taxi in taxis) { taxi.Update(gameTime); float volume = Math.Max(0, Math.Min(1, taxi.DeltaVelocity.Length())); sound.SetEngineVolume(taxi, volume); #region Kollision mit der Wand Vector2 sizeHalf = taxi.Size / 2; if (taxi.Position.X - sizeHalf.X < 0) { taxi.Position = new Vector2(sizeHalf.X, taxi.Position.Y); taxi.Velocity *= new Vector2(0, 1); } if (taxi.Position.Y - sizeHalf.Y < 0) { taxi.Position = new Vector2(taxi.Position.X, sizeHalf.Y); taxi.Velocity *= new Vector2(1, 0); } if (taxi.Position.X + sizeHalf.X > level.Size.X) { taxi.Position = new Vector2(level.Size.X - sizeHalf.X, taxi.Position.Y); taxi.Velocity *= new Vector2(0, 1); } if (taxi.Position.Y + sizeHalf.Y > level.Size.Y) { taxi.Position = new Vector2(taxi.Position.X, level.Size.Y - sizeHalf.Y); taxi.Velocity *= new Vector2(1, 0); } #endregion #region Kollision mit Blöcken Vector2 deltaPosition = taxi.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; float taxiLeft = taxi.Position.X - sizeHalf.X; float taxiTop = taxi.Position.Y - sizeHalf.Y; float taxiRight = taxi.Position.X + sizeHalf.X; float taxiBottom = taxi.Position.Y + sizeHalf.Y; taxi.OnGround = null; float scratchVolume = 0f; float scratchPitch = 0f; foreach (var block in level.Blocks) { if (taxiLeft < block.Size.Right && taxiRight > block.Size.Left && taxiTop < block.Size.Bottom && taxiBottom > block.Size.Top) { float factorX = 0f; if (deltaPosition.X > 0) { float deltaLeft = taxiRight - block.Size.Left; factorX = deltaLeft / deltaPosition.X; } else { float deltaRight = block.Size.Right - taxiLeft; factorX = deltaRight / -deltaPosition.X; } float factorY = 0f; if (deltaPosition.Y > 0) { float deltaTop = taxiBottom - block.Size.Top; factorY = deltaTop / deltaPosition.Y; } else { float deltaBottom = block.Size.Bottom - taxiTop; factorY = deltaBottom / -deltaPosition.Y; } if (Math.Abs(factorX) > 1f) { factorX = 0f; } if (Math.Abs(factorY) > 1f) { factorY = 0f; } // TODO: Fix Friction if (factorX > factorY) { taxi.Position -= new Vector2(deltaPosition.X * (factorX + 0.05f), 0); if (Math.Abs(taxi.Velocity.X) > 20f) { sound.PlayCrash(Math.Max(0, Math.Min(1f, Math.Abs(taxi.Velocity.X) / 100))); } taxi.Velocity *= new Vector2(0, 1); } else { taxi.Position -= new Vector2(0, deltaPosition.Y * (factorY + 0.05f)); if (Math.Abs(taxi.Velocity.Y) > 20f) { sound.PlayCrash(Math.Max(0, Math.Min(1f, Math.Abs(taxi.Velocity.Y) / 100))); } taxi.Velocity *= new Vector2(1, 0); taxi.Velocity -= taxi.Velocity / block.Friction * (float)gameTime.ElapsedGameTime.TotalSeconds; if (taxi.Position.X - (taxi.Size.X / 2) >= block.Size.Left && taxi.Position.X + (taxi.Size.X / 2) <= block.Size.Right && taxi.Position.Y < block.Size.Top) { taxi.OnGround = block; if (taxi.Velocity.LengthSquared() < 100) { var guest = taxi.Guests.SingleOrDefault(g => g.Destination == block); if (guest != null) { taxi.Guests.Remove(guest); guest.Position = new Vector2(taxi.Position.X, guest.Destination.Size.Top); guest.CurrentBlock = guest.Destination; points++; } } } } scratchVolume = Math.Max(0, Math.Min(1, taxi.Velocity.Length() / 100)); scratchPitch = (scratchVolume - 0.5f) * 2; } } sound.SetScratchPitch(taxi, -scratchPitch); sound.SetScratchVolume(taxi, scratchVolume); #endregion } #region Respawn Guests if (level.Guests.Count < level.ParallelGuests) { var platforms = level.Blocks.Where(b => b.SpawnPlatform & !level.Guests.Any(g => g.Departure == b)).ToList(); var departurePlatform = platforms[rand.Next(platforms.Count)]; platforms.Remove(departurePlatform); var destinationPlatform = platforms[rand.Next(platforms.Count)]; Guest guest = new Guest() { Position = new Vector2( departurePlatform.Size.X + (departurePlatform.Size.Width / 2), departurePlatform.Size.Y), CurrentBlock = departurePlatform, Departure = departurePlatform, Destination = destinationPlatform, }; level.Guests.Add(guest); sound.PlayShout(); } #endregion foreach (var guest in level.Guests.ToArray()) { #region Einsteigen foreach (var taxi in taxis) { if (guest.Departure == taxi.OnGround && (guest.Position - taxi.Position).LengthSquared() < 10000 && taxi.Velocity.LengthSquared() < 10 && taxi.Guests.Count < taxi.GuestLimit && guest.CurrentBlock == guest.Departure) { float guestSpeed = (float)gameTime.ElapsedGameTime.TotalSeconds * 20; guest.Position += new Vector2(Math.Max(-guestSpeed, Math.Min(guestSpeed, taxi.Position.X - guest.Position.X)), 0); if (Math.Abs(taxi.Position.X - guest.Position.X) < 4) { guest.CurrentBlock = null; taxi.Guests.Add(guest); } } } #endregion #region Aussteigen if (guest.CurrentBlock == guest.Destination) { float guestSpeed = (float)gameTime.ElapsedGameTime.TotalSeconds * 20; guest.Position += new Vector2(Math.Max(-guestSpeed, Math.Min(guestSpeed, guest.Destination.Size.X + (guest.Destination.Size.Width / 2) - guest.Position.X)), 0); if (Math.Abs(guest.Destination.Size.X + (guest.Destination.Size.Width / 2) - guest.Position.X) < 4) { level.Guests.Remove(guest); } } #endregion } base.Update(gameTime); }