예제 #1
0
        /// <summary>
        /// Обновляет состояние игрового поля.
        /// </summary>
        public void Update(GameTime gameTime)
        {
            // Пытаемся изменить состояние игры
            ChangeState();

            // Действие разрушителей
            List <Destroyer> destroyerListCopy = new List <Destroyer>(destroyerList);

            foreach (Destroyer destroyer in destroyerListCopy)
            {
                foreach (GameBoardObject gameBoardObject in objectList)
                {
                    Rectangle boundingBox      = gameBoardObject.GetScreenBoundingBox();
                    bool      boundingBoxHit   = boundingBox.Contains(GameBoardObject.WorldToScreen(destroyer.spriteWorldPos));
                    bool      alreadyImploding = implodingObjects.Contains(gameBoardObject);
                    if (boundingBoxHit && !alreadyImploding)
                    {
                        implodingObjects.Add(gameBoardObject);
                        ScaleAnimation implodeAnimation = new ScaleAnimation(
                            gameBoardObject,
                            beginScale: 1.0,
                            endScale: 0.0,
                            delay: 0.0,
                            blocking: true,
                            finishedCallback: _ => objectList.Remove(gameBoardObject)
                            );
                        activeAnimations.Add(implodeAnimation);
                        score++;
                        // Если это LineBonus
                        if (gameBoardObject.GetType() == typeof(LineBonus))
                        {
                            TriggerLineBonus((LineBonus)gameBoardObject);
                        }
                        // Если это BombBonus
                        if (gameBoardObject.GetType() == typeof(BombBonus))
                        {
                            TriggerBombBonus((BombBonus)gameBoardObject);
                        }
                    }
                }
            }

            // Обновляем состояние анимаций
            activeAnimations.ForEach(animation => animation.Update(gameTime));
            // Удаляем завершившиеся анимации
            List <Animation> animationsToDelete = activeAnimations.FindAll(animation => !animation.active);

            animationsToDelete.ForEach(animation => animation.OnDelete());
            activeAnimations = activeAnimations.Except(animationsToDelete).ToList();

            // Синхронизируем список implodingObjects с основным списком
            implodingObjects = implodingObjects.Intersect(objectList).ToList();

            // Уменьшаем остаток времени
            if (currentGamePhase != GamePhase.MainMenu && currentGamePhase != GamePhase.GameOver)
            {
                timeRemaining -= gameTime.ElapsedGameTime.TotalSeconds;
            }
        }
예제 #2
0
        /// <summary>
        /// Создать бонус Bomb.
        /// </summary>
        /// <param name="baseObject">Базовый объект.</param>
        public void CreateBombBonus(GameBoardObject baseObject)
        {
            // Создаем объект
            BombBonus newBombBonus = new BombBonus(baseObject, baseObject.worldPos, baseObject.worldPos);

            objectList.Add(newBombBonus);
            // Запускаем анимацию появления
            ScaleAnimation spawnAnimation = new ScaleAnimation(newBombBonus, 0.0, 1.0, blocking: true);

            activeAnimations.Add(spawnAnimation);
        }
예제 #3
0
        /// <summary>
        /// Активирует бонус Bomb.
        /// </summary>
        public void TriggerBombBonus(BombBonus bombBonus)
        {
            // Объекты вокруг бомбы
            for (int x = bombBonus.worldPos.x - 1; x <= bombBonus.worldPos.x + 1; x++)
            {
                for (int y = bombBonus.worldPos.y - 1; y <= bombBonus.worldPos.y + 1; y++)
                {
                    if (x == bombBonus.worldPos.x && y == bombBonus.worldPos.y)
                    {
                        continue;
                    }
                    GameBoardObject obj = GetObjectAtPosition(x, y);
                    if (obj is null)
                    {
                        continue;
                    }
                    implodingObjects.Add(obj);
                    ScaleAnimation implodeAnimation = new ScaleAnimation(
                        obj,
                        beginScale: 1.0,
                        endScale: 0.0,
                        delay: 0.25,
                        blocking: true,
                        finishedCallback: _ => objectList.Remove(obj)
                        );
                    activeAnimations.Add(implodeAnimation);
                    score++;
                    // Если это LineBonus
                    if (obj.GetType() == typeof(LineBonus))
                    {
                        TriggerLineBonus((LineBonus)obj);
                    }
                    // Если это BombBonus
                    if (obj.GetType() == typeof(BombBonus))
                    {
                        TriggerBombBonus((BombBonus)obj);
                    }
                }
            }
            // Сама бомба
            implodingObjects.Add(bombBonus);
            ScaleAnimation bombImplodeAnimation = new ScaleAnimation(
                bombBonus,
                beginScale: 1.0,
                endScale: 0.0,
                delay: 0.0,
                blocking: true,
                finishedCallback: _ => objectList.Remove(bombBonus)
                );

            activeAnimations.Add(bombImplodeAnimation);
            score++;
        }
예제 #4
0
        /// <summary>
        /// Удаление комбинаций.
        /// </summary>
        public void DeleteCombos(ComboList comboList)
        {
            // Список удаляемых объектов
            List <GameBoardObject> objectsToDelete = comboList.SelectMany(tempList => tempList).ToList();

            score += objectsToDelete.Count;

            // Срабатывание бонусов
            List <LineBonus> lineBonuses = objectsToDelete.FindAll(obj => obj.GetType() == typeof(LineBonus)).Cast <LineBonus>().ToList();

            foreach (LineBonus lineBonus in lineBonuses)
            {
                TriggerLineBonus(lineBonus);
                currentGamePhase = GamePhase.Bonus;
            }
            List <BombBonus> bombBonuses = objectsToDelete.FindAll(obj => obj.GetType() == typeof(BombBonus)).Cast <BombBonus>().ToList();

            foreach (BombBonus bombBonus in bombBonuses)
            {
                TriggerBombBonus(bombBonus);
                currentGamePhase = GamePhase.Bonus;
            }

            // Если бонусы активны, то новые создавать нельзя.
            if (currentGamePhase == GamePhase.Bonus)
            {
                return;
            }

            // Запуск анимации исчезновения
            implodingObjects.Clear();
            foreach (GameBoardObject obj in objectsToDelete)
            {
                implodingObjects.Add(obj);
                ScaleAnimation implodeAnimation = new ScaleAnimation(obj, 1.0, 0.0, blocking: true, finishedCallback: _ => objectList.Remove(obj));
                activeAnimations.Add(implodeAnimation);
            }

            // Бонус Bomb
            // Комбинации из 5 и более
            List <Vector2Int>      newBombPositions       = new List <Vector2Int>();
            ComboList              combinationsOf5AndMore = comboList.FindAll(combination => combination.Count >= 5);
            List <GameBoardObject> combination            = combinationsOf5AndMore.Find(combination => combination.Contains(objectSwap2));

            if (combination != null)
            {
                CreateBombBonus(objectSwap2);
                newBombPositions.Add(objectSwap2.worldPos);
            }
            // Перекрестные комбинации из 3 и более
            CrossList crosses = new CrossList();
            ComboList verticalCombinations   = comboList.FindAll(combination => combination[0].worldPos.x == combination[1].worldPos.x);
            ComboList horizontalCombinations = comboList.FindAll(combination => combination[0].worldPos.y == combination[1].worldPos.y);

            foreach (List <GameBoardObject> verticalCombination in verticalCombinations)
            {
                foreach (List <GameBoardObject> horizontalCombination in horizontalCombinations)
                {
                    List <GameBoardObject> intersection = verticalCombination.Intersect(horizontalCombination).ToList();
                    if (intersection.Count > 0)
                    {
                        GameBoardObject objectAtIntersection = intersection[0];
                        if (!newBombPositions.Contains(objectAtIntersection.worldPos))
                        {
                            CreateBombBonus(objectAtIntersection);
                            newBombPositions.Add(objectAtIntersection.worldPos);
                        }
                    }
                }
            }
            // Бонус Line
            ComboList combinationsOf4 = comboList.FindAll(combination => combination.Count == 4);

            combination = combinationsOf4.Find(combination => combination.Contains(objectSwap2));
            if (combination != null && !newBombPositions.Contains(objectSwap2.worldPos))
            {
                Debug.WriteLine($"Creating line bonus in {objectSwap2.worldPos}");
                bool vertical = combination[0].worldPos.x == combination[1].worldPos.x;
                // Создаем объект
                LineBonus newLineBonus = new LineBonus(objectSwap2, vertical, objectSwap2.worldPos, objectSwap2.worldPos);
                objectList.Add(newLineBonus);
                // Запускаем анимацию появления
                ScaleAnimation spawnAnimation = new ScaleAnimation(newLineBonus, 0.0, 1.0, blocking: true);
                activeAnimations.Add(spawnAnimation);
            }
        }