/* load the level map from file - for now just load a dummy level with random tile types */ protected void Initialize(int[,] mapLayout, ArrayList tileTextures, int bgIndex, int levelNum) { tiles = new Tile[mapLayout.GetLength(0), mapLayout.GetLength(1)]; screenWidth = Game.GraphicsDevice.Viewport.Width; screenHeight = Game.GraphicsDevice.Viewport.Height; // hardcoded for now until we set up the file read background = (Texture2D)tileTextures[bgIndex]; bgPosition.X = 0; bgPosition.Y = 0; bgPosition.Width = screenWidth; bgPosition.Height = screenHeight; pixelOffset = 0; maxPixelOffset = (mapLayout.GetLength(1) * (screenWidth / colsPerScreen)) - screenWidth; minPixelOffset = 0; int spriteIndex = outsideIndex; if (levelNum >= 3) { spriteIndex = castleIndex; } for (int j = 0; j < mapLayout.GetLength(1); j++) { for (int i = 0; i < mapLayout.GetLength(0); i++) { tiles[i, j] = new Tile(Game, (Texture2D)tileTextures[spriteIndex], (CollisionType)mapLayout[i,j], j, i, screenWidth, screenHeight, rowsPerScreen, colsPerScreen); } } }
// join tiles that are side by side into larger rectangles to allow for smoother wall collisions // these tiles are not meant for foot collisions -> losing some of the collision types (only persisting platform vs. impassable) // where impassable will be a lump of all non-platform, non-hideable, non-passable tiles // // NOTE: this ONLY returns tiles that have merged up to larger tiles, anything that stayed as a single tile will still need to check collisions protected IList<ITile> joinTiles(IList<ITile> tiles) { IList<ITile> result = new List<ITile>(); if (tiles.Count > 0) { int singleWidth = 0; int singleHeight = 0; // the tile layout size will be more like 5 x 4 - using 10 so there is a buffer ITile[,] tileLayout = new Tile[10, 10]; // creating a dummy tile ITile dummyTile = new Tile(game); // initialize tileLayout to dummy values; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { tileLayout[i, j] = dummyTile; } } // the top-most y position of our tiles being sorted - -1 indicates no tiles yet int currY = -1; // start y index at -1 so the first y gets set properly int yIndex = -1; int xIndex = 0; // put the tiles into their appropriate row based on y value (smaller y is the top of the screen) foreach (ITile t in tiles) { // set the width of a single tile singleWidth = t.getPosition().Width; singleHeight = t.getPosition().Height; // new row, so insert the tile (deal with shifting the layout later) if (currY < 0 || currY < t.getPosition().Top) { xIndex = 0; yIndex += 1; tileLayout[yIndex, xIndex] = t; currY = t.getPosition().Top; } // otherwise that tile belongs to this row, so it is the next tile in the row else { xIndex += 1; tileLayout[yIndex, xIndex] = t; } } // adjust the tile layout to fix things being always pushed to the left i.e... // (0,0) (x,x) ----> (0,0)(x,x)(x,x) // (1,1) (1,2) ----> (x,x)(1,1)(1,2) for (int j = 0; j < 10; j++) { int xMin = -1; // get the min x in the current column for (int i = 0; i < 10; i++) { if (xMin == -1 || (tileLayout[i, j].getPosition().X != -1 && xMin > tileLayout[i, j].getPosition().X)) { xMin = tileLayout[i, j].getPosition().X; } } // we only care about shifts when there was a valid minimum if (xMin != -1) { // perform any shifts to the layout for (int i = 0; i < 10; i++) { // this row needs to shift to the right if (xMin < tileLayout[i, j].getPosition().X) { for (int k = 9; k > j; k--) { tileLayout[i, k] = tileLayout[i, k - 1]; } // set the start column of the row that just shifted to the dummy tile tileLayout[i, j] = dummyTile; } } } } ITile combined = new Tile(game); // do not merge platforms with any other tile-type -> these rectangles are not for foot collisions // combine tiles into taller tiles when they are touching each other for (int j = 0; j < 10; j++) { // for each row until the end of the rows is hit for (int i = 0; i < 10; i++) { // if the current tile is a valid tile if (tileLayout[i, j].getPosition().X != -1) { // start a new tile if (i == 0 || combined.getPosition().Bottom != tileLayout[i, j].getPosition().Top || !compatibleTypes(tileLayout[i, j].getCollisionBehaviour(), combined.getCollisionBehaviour())) { // add the merged tile to the result list if (combined.getPosition().X != -1 && combined.getPosition().Height > singleHeight) { result.Add(combined); } // build the next tile combined = new Tile(game); combined.setPosition(tileLayout[i, j].getPosition()); combined.changeType(tileLayout[i, j].getCollisionBehaviour()); } else { //extend the rectangle's height Rectangle r = combined.getPosition(); r.Height += tileLayout[i, j].getPosition().Height; combined.setPosition(r); } } } } // add the last combined tile to the result if there were any if (combined.getPosition().X != -1 && combined.getPosition().Height > singleHeight) { result.Add(combined); } // clear out the merged tile combined = new Tile(game); // combine columns into rectangles when they are beside each other for (int i = 0; i < 10; i++) { // for each row until the end of the rows is hit for (int j = 0; j < 10; j++) { // if the current tile is a valid tile if (tileLayout[i, j].getPosition().X != -1) { // start a new tile if (j == 0 || combined.getPosition().Right != tileLayout[i, j].getPosition().Left || !compatibleTypes(tileLayout[i, j].getCollisionBehaviour(), combined.getCollisionBehaviour())) { // add the merged tile to the result list if (combined.getPosition().X != -1 && combined.getPosition().Width > singleWidth) { result.Add(combined); } // build the next tile combined = new Tile(game); combined.setPosition(tileLayout[i, j].getPosition()); combined.changeType(tileLayout[i, j].getCollisionBehaviour()); } else { //extend the rectangle's height Rectangle r = combined.getPosition(); r.Width += tileLayout[i, j].getPosition().Width; combined.setPosition(r); } } } } // add the last merged tile to the result set if (combined.getPosition().X != -1 && combined.getPosition().Width > singleWidth) { result.Add(combined); } /* System.Console.WriteLine("------------merged-----------"); foreach (ITile t in result) { System.Console.WriteLine("(" + t.getPosition().X + ", " + t.getPosition().Y + ", " + t.getPosition().Width + ", " + t.getPosition().Height + ") -> " + t.getCollisionBehaviour().ToString()); } */ } return result; }
/* load the level map from file - for now just load a dummy level with random tile types */ protected void Initialize(string filename, ArrayList tileTextures) { background = new Tile[32, 100]; int screenWidth = Game.GraphicsDevice.Viewport.Width; int screenHeight = Game.GraphicsDevice.Viewport.Height; pixelOffset = 0; maxPixelOffset = (100 * (screenWidth / 64)) - screenWidth; minPixelOffset = 0; Random rand = new Random(); for (int i = 0; i < 32; i++) { for (int j = 0; j < 100; j++) { CollisionType colType = CollisionType.platform; /* switch (rand.Next(3)) { case 0: colType = CollisionType.passable; break; case 1: colType = CollisionType.impassable; break; case 2: colType = CollisionType.platform; break; } */ if (31 == i || (29 == i && 51 < j) || (30 == i && j > 50)) { colType = CollisionType.platform; } else if (99 == j || 0 == j) { colType = CollisionType.impassable; } else { colType = CollisionType.passable; } background[i, j] = new Tile((Texture2D)tileTextures[0], colType, j, i, screenWidth, screenHeight); } } }