private GameManager()
        {
            labyrinth = new Labyrinth();
            policeHouseTiles = new List<Vector2>();

            policeHouseTiles.Add(new Vector2(6, 0));
            policeHouseTiles.Add(new Vector2(7, 0));
            policeHouseTiles.Add(new Vector2(0, 4));
            policeHouseTiles.Add(new Vector2(0, 5));
            policeHouseTiles.Add(new Vector2(6, 9));
            policeHouseTiles.Add(new Vector2(7, 9));
            policeHouseTiles.Add(new Vector2(13, 4));
            policeHouseTiles.Add(new Vector2(13, 5));

            countDowns = new List<Countdown>();
            newCountDowns = new List<Countdown>();

            characters = new List<Character>();
            charactersToDelete = new List<Character>();
            charactersToCreate = new List<Character>();
            countDownsToDelete = new List<Countdown>();

            Countdown firstTrapCountDown = new Countdown(0, 0, 30 - level, Subject.NotifyReason.SPAWN_NEW_TRAP);
            firstTrapCountDown.AddObserver(this);
            countDowns.Add(firstTrapCountDown);
            Countdown firstPowerupCountDown = new Countdown(0, 0, 25 - level, Subject.NotifyReason.SPAWN_NEW_POWERUP);
            firstPowerupCountDown.AddObserver(this);
            countDowns.Add(firstPowerupCountDown);

            collectibles = new List<Collectible>();
            collectiblesToDelete = new List<Collectible>();
            collectiblesToCreate = new List<Collectible>();

            level = 1;

            gru = (PlayerCharacter)CharacterFactory.CreateCharacter(CharacterFactory.CharacterType.GRU, new Vector2(labyrinth.GetTile(DEPART_X, DEPART_Y).GetPosition().X, labyrinth.GetTile(DEPART_X, DEPART_Y).GetPosition().Y), labyrinth.GetTile(DEPART_X, DEPART_Y));
            characters.Add(gru);
            gru.AddObserver(this);

            StartGame();

            shouldStartGame = false;

            //Teleporter entrance
            warpEntreePos = new Vector2(labyrinth.GetTile(7, 4).GetPosition().X - Tile.LIGN_SIZE, labyrinth.GetTile(7, 4).GetPosition().Y + Tile.LIGN_SIZE);

            //Teleporter exits
            warpExitsPos[0] = new Vector2(labyrinth.GetTile(0, 0).GetPosition().X, labyrinth.GetTile(0, 0).GetPosition().Y);
            warpExitsPos[1] = new Vector2(labyrinth.GetTile(Labyrinth.WIDTH - 1, 0).GetPosition().X, labyrinth.GetTile(Labyrinth.WIDTH - 1, 0).GetPosition().Y);
            warpExitsPos[2] = new Vector2(labyrinth.GetTile(0, Labyrinth.HEIGHT - 1).GetPosition().X, labyrinth.GetTile(0, Labyrinth.HEIGHT - 1).GetPosition().Y);
            warpExitsPos[3] = new Vector2(labyrinth.GetTile(Labyrinth.WIDTH - 1, Labyrinth.HEIGHT - 1).GetPosition().X, labyrinth.GetTile(Labyrinth.WIDTH - 1, Labyrinth.HEIGHT - 1).GetPosition().Y);
        }
        public void Notify(Subject subject, Subject.NotifyReason reason)
        {
            switch (reason)
            {
                case Subject.NotifyReason.MONEY_DESTROYED:
                    RespawnGoalAfterPickup();
                    break;

                case Subject.NotifyReason.MONEY_GAINED:
                    //nothing
                    break;

                case Subject.NotifyReason.LIFE_LOST:
                    if (gru.Lives < 1)
                    {
                        level = 1;
                        shouldStartGame = true;
                    }
                    else
                    {
                        shouldStartLevel = true;
                    }
                    break;

                case Subject.NotifyReason.EXIT_REACHED:
                    level++;
                    gru.ResetMinionsAndMoney();
                    shouldStartLevel = true;
                    break;

                case Subject.NotifyReason.EXIT_DESTROYED:
                    RespawnGoalAfterPickup();
                    break;

                case Subject.NotifyReason.TRAP_ACTIVATED:
                    Countdown trapCountDown = new Countdown(0, 0, 3, Subject.NotifyReason.TRAP_EXPIRED);
                    trapCountDown.AddObserver(((Trap)subject).AffectedCharacter);
                    countDowns.Add(trapCountDown);
                    break;

                case Subject.NotifyReason.SPEEDBOOST_ACTIVATED:
                    Countdown powerupCountDown = new Countdown(0, 0, 2, Subject.NotifyReason.SPEEDBOOST_EXPIRED);
                    powerupCountDown.AddObserver((PlayerCharacter)subject);
                    countDowns.Add(powerupCountDown);
                    break;

                case Subject.NotifyReason.PLAYERTRAP_ACTIVATED:
                    SpawnPlayerTrap();
                    break;

                case Subject.NotifyReason.SPAWN_NEW_TRAP:
                    SpawnTrap();
                    Countdown newTrapCountDown = new Countdown(0, 0, 30 - level, Subject.NotifyReason.SPAWN_NEW_TRAP);
                    newTrapCountDown.AddObserver(this);
                    newCountDowns.Add(newTrapCountDown);
                    break;

                case Subject.NotifyReason.SPAWN_NEW_POWERUP:
                    SpawnPowerup();
                    Countdown newPowerupCountDown = new Countdown(0, 0, 25 - level, Subject.NotifyReason.SPAWN_NEW_POWERUP);
                    newPowerupCountDown.AddObserver(this);
                    newCountDowns.Add(newPowerupCountDown);
                    break;

                case Subject.NotifyReason.BANANA:
                    SpawnBanana(((Character)subject).CurrentTile);
                    break;

                case Subject.NotifyReason.STUNNED:
                    Countdown bananaCountDown = new Countdown(0, 0, 1, Subject.NotifyReason.WOKE_UP);
                    bananaCountDown.AddObserver(((Banana)subject).AffectedCharacter);
                    countDowns.Add(bananaCountDown);
                    break;

                case Subject.NotifyReason.MINION_SPAWN:
                    SpawnMinions();
                    Countdown minionCountDown = new Countdown(0, 0, 7, Subject.NotifyReason.MINION_KILL);
                    minionCountDown.AddObserver(this);
                    countDowns.Add(minionCountDown);
                    break;

                case Subject.NotifyReason.MINION_KILL:
                    KillMinions();
                    break;

                case Subject.NotifyReason.MINION_DROP_POWERUP:
                    MinionDropPowerup(((Character)subject).CurrentTile);
                    break;
            }
        }