/// <summary> /// Loads all the gameobject in the level /// </summary> /// <param name="path">the level file path</param> private void LoadLevelFromFile(string path) { //Stores the number of keys in th elevel numKeys = 0; numGems = 0; //removes all the gameobjects from last level gameObjects.Clear(); //stores all the lines in the file string[] lines = File.ReadAllLines(path); //loops over all the charachters for (int r = 0; r < NUM_CELLS_HEIGHT; ++r) { for (int c = 0; c < NUM_CELLS_WIDTH; ++c) { //adds the corresponding gameobject switch (lines[r][c]) { case '0': //save an addition refrence to the player before adding it player = new Player(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH); gameObjects.Add(player); break; case '1': gameObjects.Add(new Wall(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH)); break; case '2': //Saves a refrance to the crate so it could subscribe to events Crate crate = new Crate(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH); //Check that there are no gems or keys above whenever crate moves crate.CrateMove += cr => { IEnumerable <GameObject> objectsAbove = gameObjects.Where(g => Helper.IsPointInOrOnRectangle(g.TopLeftGridPoint.ToVector2(), new Rectangle(cr.Box.Location - new Point(0, cr.Box.Height), cr.Box.Size))); return(objectsAbove.Count() != 0 && (objectsAbove.First() is Gem || objectsAbove.First() is Key)); }; gameObjects.Add(crate); break; case '3': //save the position of the flag flagPos = new Point(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH); break; case '4': gameObjects.Add(new Door(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH)); break; case '5': gameObjects.Add(new Spike(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH)); break; case '6': gameObjects.Add(new Gem(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH)); ++numGems; break; case '7': gameObjects.Add(new Key(c * CELL_SIDE_LENGTH, r * CELL_SIDE_LENGTH)); ++numKeys; break; } } } //subscribe to the crate event for colliding with gems and keys (add them to the player count) gameObjects.OfType <Crate>().ToList().ForEach(c => c.CollideWithGem += () => player.AddGem()); gameObjects.OfType <Crate>().ToList().ForEach(c => c.CollideWithKey += () => player.AddKey()); //Notify Game of how many collectibles there are this level KeysAndGemsCounted.Invoke(numKeys, numGems); //add the 4 walls around the screem gameObjects.AddRange(new[] { new Wall(-SCREEN_WALL_WIDTH, 0, SCREEN_WALL_WIDTH, HEIGHT), new Wall(WIDTH, 0, SCREEN_WALL_WIDTH, HEIGHT), new Wall(0, -SCREEN_WALL_WIDTH, WIDTH, SCREEN_WALL_WIDTH), new Wall(0, HEIGHT, WIDTH, SCREEN_WALL_WIDTH) }); //subscribe to the move and delete events of all the gameobjects gameObjects.ForEach(g => g.MoveReady += gameObject => MoveGameObject(gameObject)); gameObjects.ForEach(g => g.DeleteReady += gameObject => gameObjects.Remove(gameObject)); //subscribe to the players hit spike event with a function that ends the level player.HitSpike += () => { //clears commands and pauses the game commands = new Queue <char>(); GamePaused = true; //Notify game that the player hit a spike RunCompleteFailed.Invoke("The player hit a spike : press ENTER to try again."); }; //subscribe to the players collect gem and key events (notify Game when happenes) player.KeyCollected += nk => playerKeyCollected.Invoke(nk); player.GemCollected += ng => playerGemCollected.Invoke(ng); }
/// <summary> /// Updates all the gameobjects in the level /// </summary> public void Update() { //If the game is paused dont update anything if (GamePaused) { return; } //If all the objects are standing still and there is more commands left, run them if (!commands.IsEmpty && gameObjects.All(g => g.IsStandingStill())) { //give player the next command and notify Game that the next command is being excecuted player.LoadNextCommand(commands.Dequeue()); ExecutingNextCommand.Invoke(); //If the command just loaded is the last command check if the player won if (commands.IsEmpty) { //pause the game GamePaused = true; //check if the player has reached the flag check if they collected all the gems if (player.Box.Location == flagPos) { //if they did not collect all the gems then inform Game they failed the level for that reason if (player.GemCount != numGems) { RunCompleteFailed.Invoke("You did not collect all the gems : press ENTER to try again."); } //the player won else { //stop the timer timer.Stop(); //Save the results for this level and update the final results finalResult.LevelResults[curLevel - 1] = new LevelResult(timer.Elapsed.Milliseconds + numCommands * 100, timer.Elapsed.Seconds); finalResult.TotalTime += finalResult.LevelResults[curLevel - 1].Time; finalResult.TotalScore += finalResult.LevelResults[curLevel - 1].Score; //check if that was the last level if (curLevel == NUM_LEVELS) { //inform Game all levels complete and send it final reslts AllLevelsComplete.Invoke(finalResult); } else { //inform Game that the level has been complete and send the correct level results RunCompleteSuccess.Invoke(finalResult.LevelResults[curLevel - 1]); //go to the next level and indicate that a new level is starting ++curLevel; startingNewLevel = true; } } } //the player did not reach the goal else { //Inform Game that the level did not reach the goal RunCompleteFailed.Invoke("A'w Shuc'ks Buddy ol Pal! Failed to reach goal : press ENTER to try again."); } } } //Update all the gameobjects gameObjects.ForEach(g => g.Update()); //Try to move all the gameobjects (while taking collision into account) MoveGameObjects(); }