/// <summary> /// Factory Method for level creation. Creates a new content manager for /// loading a particular theme and loads the level from the provided file. /// </summary> /// <param name="filepath"></param> /// <param name="theme"></param> /// <returns>The newly created level.</returns> public Level CreateLevel(String name, String filepath, String theme) { if (!File.Exists(filepath)) throw new FileNotFoundException("The level could not be loaded", filepath); random = new Random(354668); // Arbitrary, but constant seed //Setup the content manager for the level themedContent = new ContentManager(services); if (theme.Length == 0) themedContent.RootDirectory = "Content/Theme/default/"; else themedContent.RootDirectory = "Content/Theme/" + theme + "/"; Stream fileStream = TitleContainer.OpenStream(filepath); List<String> levelRows; List<String> levelBindings; using (StreamReader reader = new StreamReader(fileStream)) { //Phase 1 - Read the level rows levelRows = ParseLevel(reader); //Phase 2 - Read the level links levelBindings = ParseBindings(reader); } int width = 0; if (levelRows.Count > 0) width = levelRows[0].Split(',').Length; int height = levelRows.Count; Level level = new Level(name, width * 2, height, themedContent); BuildLevel(levelRows, level); BindLevel(levelBindings, level); //Clean-up themedContent = null; random = null; return level; }
public void NextLevel(String levelName) { if (existingLevels.ContainsKey(levelName)) { activeLevel = existingLevels[levelName]; player.EnterLevel(activeLevel); } }
/// <summary> /// Load a story and create all of the levels listed in the file by using the LevelFactory. /// </summary> /// <param name="storyPath">The filepath of the story file.</param> public void LoadStory(string storyPath) { if (!File.Exists(storyPath)) throw new FileNotFoundException("The story could not be found", storyPath); existingLevels.Clear(); Stream fileStream = TitleContainer.OpenStream(storyPath); using (StreamReader reader = new StreamReader(fileStream)) { //Just loads all the levels while(!reader.EndOfStream) { string newLine = reader.ReadLine(); string[] tuple = newLine.Split(','); //Should be level name, filepath, theme Level newLevel = levelFactory.CreateLevel(tuple[0].Trim(), "Content/" + tuple[1].Trim(), tuple[2].Trim()); existingLevels.Add(tuple[0].Trim(), newLevel); if (activeLevel == null) activeLevel = newLevel; } } //Vector2 SpawnPoint = activeLevel.ActiveSpawn.Position; player.EnterLevel(activeLevel); }
/// <summary> /// Assigns the level the water drain belongs to. /// </summary> /// <param name="level">Housing level.</param> public void bindToLevel(Level level) { this.level = level; }
/// <summary> /// Builds the level based on the tile layout. This method setups the /// basic tile grid, along with creating activators, activatables and moving tiles. /// </summary> /// <param name="levelRows"></param> /// <param name="level"></param> private void BuildLevel(List<String> levelRows, Level level) { // Load the tiles and components for (int y = 0; y < level.Height; ++y) { string line = levelRows[y]; string[] lineTiles = line.Split(','); for (int x = 0; x < level.Width; ++x) { if (x < lineTiles.Length) { string tileID = lineTiles[x].Trim(); char tileType = '.'; if (tileID.Length > 0) tileType = tileID[0]; //The type is always the first part of the string //Create level tiles; Tile newTile = CreateTile(tileType, x, y); level.addTile(x, y, newTile); if (newTile is WaterSource) { WaterSource waterSource = (WaterSource)newTile; waterSource.bindToLevel(level); level.addActivatable(tileID, waterSource); } if (newTile is WaterDrain) { WaterDrain waterDrain = (WaterDrain)newTile; waterDrain.bindToLevel(level); level.addActivatable(tileID, waterDrain); } int xDrawPostion = x * Tile.Width; int yDrawPostion = y * Tile.Height; //Create Activator Platformer.Tiles.Activator actor = CreateActivator(tileType, xDrawPostion, yDrawPostion); if (actor != null) { level.addActivator(tileID, actor); //Special case to link exits if (actor is Exit) { int uid = int.Parse(Regex.Match(tileID, @"\d+").Value, NumberFormatInfo.InvariantInfo); Exit exit = (Exit)actor; exit.LevelIndex = uid; } if (actor is Mirror) { level.addActivatable(tileID, (Mirror)actor); } } //Create Activatable IActivatable active = CreateActivatable(tileType, xDrawPostion, yDrawPostion); if (active != null) { level.addActivatable(tileID, active); //Special case to link spawn points into the levels, could do this inside level itself if (active is Spawner) { Spawner sp = (Spawner)active; sp.bindToLevel(level); } // Special case to create ladder tiles (which are both tiles and activatable) if (active is LadderTile) { level.addTile(x, y, (LadderTile) active); } } //Create Moving Platform MoveableTile mTile = CreateMoveable(tileType, xDrawPostion, yDrawPostion); if (mTile != null) { level.addMoveable(tileID, mTile); if (mTile is IActivatable) level.addActivatable(tileID, (IActivatable)mTile); } } else //Just add empty tiles to make up the length { level.addTile(x, y); } } } }
/// <summary> /// Adds bindings to the activators for their activatables. /// </summary> /// <param name="levelBinds"></param> /// <param name="level"></param> private void BindLevel(List<String> levelBinds, Level level) { //Link up stuff foreach (string link in levelBinds) { string[] linkGroup = link.Split(','); string actor = linkGroup[0].Trim(); int msDelay = int.Parse(linkGroup[1]); if (actor.Equals("ACTIVE")) //Special case { for (int i = 2; i < linkGroup.Length; i++) { string active = linkGroup[i].Trim(); level.activate(active); } } else { for (int i = 2; i < linkGroup.Length && linkGroup[i].Length > 0; i++) { string active = linkGroup[i].Trim(); level.addBind(actor, active); } } } }