protected override void Update(GameTime gameTime) { _inputManager.Update(gameTime); for (int i = 0; i < _world.Count; i++) { var obj = _world[i]; obj.Update(); if (obj.IsDestroyed) { _world.RemoveAt(i--); } if (obj is Rocket) { _particles.Emit(_ppRocket, obj.Position - new Vector2(10f * Maf.Sin(obj.Rotation), -10f * Maf.Cos(obj.Rotation)), 1f * Chaos.GetFloat() * Chaos.GetVector2()); } if (obj is PlasmaBullet) { _particles.Emit(_ppPlasma, obj.Position, Vector2.Zero); } } _particles.Update(); Collisions.Detect(_world, _particles, _ppExplosion); _worldLoopParticles.Clusterize(_particles.ParticlesList); _worldLoop.Clusterize(_world); base.Update(gameTime); }
public static void Detect(List <GameObject> gameObjects, Particles particles, ParticleParameters particleParameters) { for (int j = 0; j < gameObjects.Count; j++) { for (int i = 0; i < gameObjects.Count; i++) { if (i == j || i < 0 || j < 0) { continue; } var go1 = gameObjects[i]; var go2 = gameObjects[j]; float dx = go2.Position.X - go1.Position.X; float dy = go2.Position.Y - go1.Position.Y; float rr = go2.Size / 2 + go1.Size / 2; float ol2 = rr * rr - dx * dx - dy * dy; if (ol2 > 0) { if ((go1 is Rocket || go1 is PlasmaBullet) && (go2 is Asteroid || go2 is Ship)) { for (int h = 0; h < 100; h++) { particles.Emit(particleParameters, (go1.Position + go2.Position) / 2f, 3f * Chaos.GetFloat() * Chaos.GetVector2()); } gameObjects.RemoveAt(i--); if (go2 is Asteroid) { go2.Size -= 20f; if (go2.Size < 40f) { gameObjects.RemoveAt(j--); } } continue; } if ((go1 is Ship) && go2 is SpeedBonus) { go1.Speed += new Vector2(10f * Maf.Sin(go1.Rotation), -10f * Maf.Cos(go1.Rotation)); gameObjects.RemoveAt(j--); continue; } // ось столкновения и нормаль к ней var nrm = new Vector2(dx, dy); var tan = new Vector2(dy, -dx); nrm.Normalize(); tan.Normalize(); // проекция скорости на ось столкновения (нормальная скорость) float go1nrm = Vector2.Dot(go1.Speed, nrm); float go2nrm = Vector2.Dot(go2.Speed, nrm); // перераспределяем импульс между нормальными скоростями в соответствии с массами float go1rsp = ((go1.Mass - go2.Mass) * go1nrm + 2f * go2.Mass * go2nrm) / (go1.Mass + go2.Mass); float go2rsp = ((go2.Mass - go1.Mass) * go2nrm + 2f * go1.Mass * go1nrm) / (go1.Mass + go2.Mass); // проекция скорости на нормаль к оси столкновения (тангенциальная скорость) float go1tan = Vector2.Dot(go1.Speed, tan); float go2tan = Vector2.Dot(go2.Speed, tan); go1.Speed = nrm * go1rsp + tan * go1tan; go2.Speed = nrm * go2rsp + tan * go2tan; float gp = Maf.Sqrt(ol2); go1.Position -= gp * go2.Mass / (go1.Mass + go2.Mass) * nrm; go2.Position += gp * go1.Mass / (go1.Mass + go2.Mass) * nrm; } } } }
private void InitializeInputManager() { _inputManager = new InputManager(this); this.Activated += new EventHandler <EventArgs>(Game_Activated); this.Deactivated += new EventHandler <EventArgs>(Game_Deactivated); _inputManager.ExitGame += Exit; _inputManager.DebugMode += () => GameOptions.IsDebugMode = !GameOptions.IsDebugMode; _inputManager.PlayStopMediaPlayer += () => { if (MediaPlayer.Queue.ActiveSong != null) { if (MediaPlayer.State == MediaState.Paused) { MediaPlayer.Resume(); } else { MediaPlayer.Pause(); } } else { MediaPlayer.Play(_song); } }; var strafeAcceleration = 0.5f; _inputManager.MoveRightLeft += e => _ship.Strafe(strafeAcceleration * e.Value); var moveAcceleration = 0.5f; _inputManager.MoveUpDown += e => { _ship.SpeedUp(moveAcceleration * e.Value); if (e.Value > 0) { _particles.Emit(_ppFire, _ship.Position - new Vector2(10f * Maf.Sin(_ship.Rotation), -10f * Maf.Cos(_ship.Rotation)), _ship.Speed - new Vector2(4f * Maf.Sin(_ship.Rotation), -4f * Maf.Cos(_ship.Rotation)) + Chaos.GetFloat() * Chaos.GetVector2()); } }; _inputManager.PrimaryWeapon += e => _ship.Shoot(e.State); _inputManager.SecondaryWeapon += e => _ship.ShootAlt(e.State); _inputManager.Rotate += e => _ship.Rotate(e.Value * 0.1f); }