/// <summary>Обновление состояния объектов сцены</summary> public static void Update() { foreach (var visual_object in __GameObjects) { visual_object?.Update(); } var bullets_to_remove = new List <Bullet>(); foreach (var bullet in __Bullets) { bullet.Update(); if (bullet.Position.X > Width) { bullets_to_remove.Add(bullet); } } for (var i = 0; i < __GameObjects.Length; i++) { var obj = __GameObjects[i]; if (obj is ICollision collision_object) // Применить "сопоставление с образцом"! { collision_object = (ICollision)obj; __Ship.CheckCollision(collision_object); if (__Ship.CheckCollision(collision_object) && collision_object is HealthPack healthPack) { __GameObjects[i] = new HealthPack( new Point(Width, new Random().Next(0, Height)), new Point(-5), new Size(20, 20)); } foreach (var bullet in __Bullets.ToArray()) { if (bullet.CheckCollision(collision_object)) { bullets_to_remove.Add(bullet); for (var j = 0; j < __Asteroids.Count; j++) { if (__Asteroids[j].Equals(__GameObjects[i])) { __GameObjects[i] = null; __Asteroids.RemoveAt(j); break; } } _Score += 10; } } } } foreach (var bullet in bullets_to_remove) { __Bullets.Remove(bullet); } if (__Asteroids.Count == 0) { AllAsteroidsDestroyed?.Invoke(__Ship, EventArgs.Empty); } }
//============================================================ // Event Handlers: //============================================================ private void Asteroid_AsteroidDestroyed(Asteroid asteroid, Vector2 asteroidDeathPosition) { // stop tracking the asteroid as it no-longer exists trackedAsteroids.Remove(asteroid); // if the last asteroid was destroyed, send an alert so the next wave can begin if (trackedAsteroids.Count == 0 && asteroid.AsteroidSize == AsteroidSizes.Small) { if (AllAsteroidsDestroyed != null) { AllAsteroidsDestroyed.Invoke(); } return; } // if the asteroid was small, we don't need to do anything atm if (asteroid.AsteroidSize == AsteroidSizes.Small) { return; } // get the new asteroid size based on the size of the one which died AsteroidSizes newAsteroidSize = asteroid.AsteroidSize + 1; // spawn the number of asteroids that the asteroid splits into on death for (int i = 0; i < asteroidSplitAmount; i++) { // here, we are slightly adjusting the angle of velocity so the asteroids direction changes // this is randomised so the new asteroids head in their own directions Quaternion velocityAdjustment = Quaternion.AngleAxis(Random.Range(-MAXIMUM_VELOCITY_ADJUSTMENT, MAXIMUM_VELOCITY_ADJUSTMENT), asteroid.transform.forward); Vector3 adjustedVelocity = velocityAdjustment * asteroid.AsteroidVelocity; SpawnNewAsteroid(newAsteroidSize, asteroidDeathPosition, adjustedVelocity * ASTEROID_VELOCITY_MODIFIER); } }