//Generates a new name with a given word count, character total between 3 and 7 public static string GenerateName(int words = -1) { string result = ""; if (words == -1) { words = AlgorithmHelper.GetRandom(1, 3); //1 or 2 words } int maxTotalLen = 8; int remaining = maxTotalLen; for (int i = 0; i < words; ++i) { int len = AlgorithmHelper.GetRandom(3, Math.Max(3, Math.Min(remaining, 9))); string word = FirstLetterToUpper(GenerateWord(len)); result += word + " "; remaining -= len; } var name = result.TrimEnd(); if (!knownNames.Contains(name)) { knownNames.Add(name); return(name); } //Recursion, because we need to generate again if last name was already used return(GenerateName()); }
//Just aimlessly wander around private void AIIdle() //Idle { int randX = AlgorithmHelper.GetRandom(0, 11); int randY = AlgorithmHelper.GetRandom(0, 11); int changeDir = AlgorithmHelper.GetRandom(0, 51); if (changeDir == 50) //2% chance that direction will be changed { if (randX < 4) { horizontalDirection = -1; } else if (randX > 8) { horizontalDirection = 1; } else { horizontalDirection = 0; } if (randY < 3) { verticalDirection = -1; } else if (randY > 6) { verticalDirection = 1; } else { verticalDirection = 0; } } }
//Initialize items private void CreateItems(GraphicsDevice device) { items = new List <Item>(); //Find a spot where no block is present to create the item int count = AlgorithmHelper.GetRandom(1, 2 * TileCount); int nextX = AlgorithmHelper.GetRandom(0, Width / count); for (int i = 0; i < count; ++i) { var tile = GetTileForX(nextX); var tileX = (int)GlobalToTileCoordinates(new Vector2(nextX, 0), tile.Index).X; int blockIndexX = tileX / Block.Width; int tileBaseX = tile.Coords.Left; List <int> availableY = new List <int>(); for (int y = 0; y < tile.GroundLevel; ++y) { if (tile.Blocks[blockIndexX, y] == null) { availableY.Add(y); } } if (availableY.Count > 0) { int selectedY = availableY[AlgorithmHelper.GetRandom(0, availableY.Count)]; //Random item type Item.ItemType type = (Item.ItemType)AlgorithmHelper.GetRandom(0, Item.TypeCount); Item item = new Item(this, device, type, i, new Vector2(tileBaseX + blockIndexX * Block.Width, selectedY * Block.Height), tile.Index, 16, 16); items.Add(item); } //Move a little further and repeat nextX += AlgorithmHelper.GetRandom(16, Width / count); } }
//Generates the background texture public void CreateBackgroundTexture(GraphicsDevice device, SpriteBatch batch, int width, int height) { Texture = new RenderTarget2D(device, width, height); device.SetRenderTarget(Texture); device.Clear(palette[0]); batch.Begin(); Color StarWhite = palette[2]; Color StarBloom = ColorHelper.ChangeColorBrightness(palette[2], +0.4f); Color StarBig = ColorHelper.ChangeColorBrightness(palette[2], +0.6f); foreach (Point Star in Stars) { //big star if (AlgorithmHelper.GetRandom(0, 5) == 4) { RenderTarget2D BigStarSprite = new RenderTarget2D(device, 2, 2); GraphicsHelper.FillRectangle(BigStarSprite, StarBig); batch.Draw(BigStarSprite, new Rectangle(Star.X - 2, Star.Y, 2, 2), StarBloom); batch.Draw(BigStarSprite, new Rectangle(Star.X + 2, Star.Y, 2, 2), StarBloom); batch.Draw(BigStarSprite, new Rectangle(Star.X, Star.Y - 2, 2, 2), StarBloom); batch.Draw(BigStarSprite, new Rectangle(Star.X, Star.Y + 2, 2, 2), StarBloom); batch.Draw(BigStarSprite, new Rectangle(Star.X, Star.Y, 2, 2), StarWhite); continue; } RenderTarget2D StarSprite = new RenderTarget2D(device, 1, 1); GraphicsHelper.FillRectangle(StarSprite, StarBig); batch.Draw(StarSprite, new Rectangle(Star.X - 1, Star.Y, 1, 1), StarBloom); batch.Draw(StarSprite, new Rectangle(Star.X + 1, Star.Y, 1, 1), StarBloom); batch.Draw(StarSprite, new Rectangle(Star.X, Star.Y - 1, 1, 1), StarBloom); batch.Draw(StarSprite, new Rectangle(Star.X, Star.Y + 1, 1, 1), StarBloom); batch.Draw(StarSprite, new Rectangle(Star.X, Star.Y, 1, 1), StarWhite); } int line = 0; for (int i = 0; i < heightLines.GetLength(1); i++) { int sh = (int)(heightLines[0, i] * 0.75) + 50; int sh2 = (int)(heightLines[1, i]) + 50; int sh3 = (int)(heightLines[2, i] * 1.3) + 50; RenderTarget2D spike = new RenderTarget2D(device, 2, sh); GraphicsHelper.FillRectangle(spike, Color.White); batch.Draw(spike, new Rectangle(line, height - sh3, 2, sh3), palette[3]); batch.Draw(spike, new Rectangle(line, height - sh2, 2, sh2), palette[4]); batch.Draw(spike, new Rectangle(line, height - sh, 2, sh), palette[5]); line += 2; } batch.End(); device.SetRenderTarget(null); }
//Generates the background texture public void CreateBackgroundTexture(GraphicsDevice device, SpriteBatch batch, int width, int height) { Texture = new RenderTarget2D(device, width, height); List <House> buildings = new List <House>(); for (int zIndex = 0; zIndex < 3; zIndex++) { int fromLeft = 0; while (fromLeft < width) { //build house int stories = AlgorithmHelper.GetRandom(50, 140) * (4 - zIndex); House house = new House(fromLeft, height - stories, stories, zIndex); int step = (house.dimensions.Width / 12) + zIndex; //fill house with windows for (int X = (int)(step * 1.5); X < house.dimensions.Width - step; X += (int)(step * 1.5)) { for (int Y = step; Y < house.dimensions.Height; Y += step + step / 2) { house.windows.Add(new Window(new Rectangle(house.dimensions.X + X, house.dimensions.Y + Y, step, step), AlgorithmHelper.GetRandom(0, 4))); } } //add house to the city buildings.Add(house); //build street fromLeft += house.dimensions.Width + AlgorithmHelper.GetRandom(10, 50); } } device.SetRenderTarget(Texture); device.Clear(palette[0]); //or Color.Black batch.Begin(); foreach (House building in buildings) { //draw house RenderTarget2D house = new RenderTarget2D(device, building.dimensions.Width, building.dimensions.Height); GraphicsHelper.FillRectangle(house, palette[building.zIndex + 2]); batch.Draw(house, building.dimensions, Color.White); foreach (Window window in building.windows) { //draw windows on house RenderTarget2D house_window = new RenderTarget2D(device, window.dimensions.Width, window.dimensions.Height); GraphicsHelper.FillRectangle(house_window, ColorHelper.ChangeColorBrightness(Color.Multiply(window.color, (0.5f * building.zIndex) + 1f), darkenBy)); batch.Draw(house_window, window.dimensions, Color.White); } } batch.End(); device.SetRenderTarget(null); }
//Returns a new Zone placed randomly on the map protected Zone GetNewZone(GraphicsDevice device, Color zoneColor, Tile selectedTile = null) { Tile tile = (selectedTile == null) ? tiles[AlgorithmHelper.BiasedRandom(0, tiles.Count - 1, 1.3)] : selectedTile; int xblocks = tile.Coords.Width / Block.Width; int yblocks = tile.Coords.Height / Block.Height; List <int> valX = new List <int>(); List <int> valY = new List <int>(); for (int x = 1; x < xblocks; ++x) { for (int y = 1; y < tile.GroundLevel + 1; ++y) { int rand = AlgorithmHelper.GetRandom(0, (xblocks * yblocks) / 20); if (rand % 24 <= 3 && tile.Blocks[x, y] != null && x + 1 < tile.Blocks.GetLength(0) && y + 1 < tile.Blocks.GetLength(1)) { rand = AlgorithmHelper.GetRandom(0, 5); //Allways check whether adjacent tiles are empty -> whether the the Zone is to be created is not completely enclosed by blocks if (rand == 1 && tile.Blocks[x, y - 1] == null && tile.Blocks[x, y] != null && (tile.Blocks[x - 1, y - 1] == null || tile.Blocks [x + 1, y - 1] == null)) { valX.Add(x); valY.Add(y - 1); } else if (rand == 2 && tile.Blocks[x, y + 1] == null && tile.Blocks.GetLength(1) > y + 2 && tile.Blocks[x, y + 2] != null && (tile.Blocks[x - 1, y + 1] == null || tile.Blocks[x + 1, y + 1] == null)) { valX.Add(x); valY.Add(y + 1); } else if (rand == 3 && tile.Blocks[x - 1, y] == null && tile.Blocks[x - 1, y + 1] != null && tile.Blocks[x - 2, y] == null) { valX.Add(x - 1); valY.Add(y); } else if (rand == 4 && tile.Blocks[x + 1, y] == null && tile.Blocks[x + 1, y + 1] != null && tile.Blocks.GetLength(0) > x + 2 && tile.Blocks[x + 2, y] == null) { valX.Add(x + 1); valY.Add(y); } } } } if (valX.Count == 0) { return(GetNewZone(device, zoneColor)); } int rnd = AlgorithmHelper.GetRandom(0, valX.Count); return(new Zone(device, new Rectangle(tile.Coords.X + valX[rnd] * Block.Width, tile.Coords.Y + valY[rnd] * Block.Height, Block.Width, Block.Height), zoneColor)); }
//Default ctor public Tile(GraphicsDevice graphicsDevice, Map map, TileType type, Rectangle coords, int index) { this.map = map; Type = type; Coords = coords; Index = index; wblocks = coords.Width / Block.Width; hblocks = coords.Height / Block.Height; //Generate a color palette and randomize it's colors int gens = AlgorithmHelper.GetRandom(16, 33); int gskip = AlgorithmHelper.GetRandom(0, gens - 8); Palette = ColorHelper.Generate(gens).Skip(gskip).ToArray(); //Darken all palette colors by 50% for (int p = 0; p < Palette.Length; ++p) { Palette[p] = ColorHelper.ChangeColorBrightness(Palette[p], -0.5f); } //Initialize the background if (Type == TileType.LSystem) { Background = new LSystemBG(graphicsDevice, new SpriteBatch(graphicsDevice), Coords.Width, Coords.Height, Palette); } else if (Type == TileType.City) { Background = new CityBG(graphicsDevice, new SpriteBatch(graphicsDevice), Coords.Width, Coords.Height, Palette); } else if (Type == TileType.Mountains) { Background = new MountainsBG(graphicsDevice, new SpriteBatch(graphicsDevice), Coords.Width, Coords.Height, Palette); } else if (Type == TileType.Screen) { Background = new ScreenBG(graphicsDevice, new SpriteBatch(graphicsDevice), Coords.Width, Coords.Height, Palette); } CreateTileTexture(graphicsDevice); CreateBlockTexture(graphicsDevice); CreateBlocks(); //Don't generate NPCs automatically when a Screen is displayed if (Type != TileType.Screen) { CreateEntities(graphicsDevice); } }
//Teragen algorithm void Teragen(double[] heightmap, int start, int end, double rnd) { if (end - start <= 1) { return; } int width = heightmap.Length; heightmap[(start + end) / 2] = (heightmap[start] + heightmap[end]) / 2 + ((Math.PI) * rnd / 2); rnd = AlgorithmHelper.GetRandom(10, 100); Teragen(heightmap, (start + end) / 2, end, rnd); Teragen(heightmap, start, (start + end) / 2, rnd); }
//Default ctor public MountainsBG(GraphicsDevice device, SpriteBatch batch, int width, int height, Color[] palette) { this.palette = palette; heightLines = new double[3, width / 2]; Stars = new List <Point>(); int Starcount = AlgorithmHelper.GetRandom(200, 500); for (int i = 0; i < Starcount; i++) { Point Star = new Point(AlgorithmHelper.GetRandom(0, width), AlgorithmHelper.GetRandom(0, height)); Stars.Add(Star); } heightLines[0, 0] = AlgorithmHelper.GetRandom(height / 4, height / 2); heightLines[0, width / 2 - 1] = AlgorithmHelper.GetRandom(0, height / 5); heightLines[1, 0] = AlgorithmHelper.GetRandom(1, height / 5); heightLines[1, width / 2 - 1] = AlgorithmHelper.GetRandom(height / 4, height / 2); heightLines[2, 0] = AlgorithmHelper.GetRandom(height / 3, height / 2); heightLines[2, width / 2 - 1] = AlgorithmHelper.GetRandom(height / 6, height / 4); for (int i = 0; i < heightLines.GetLength(0); i++) { double[] heightLine = new double[width / 2]; heightLine[0] = heightLines[i, 0]; heightLine[width / 2 - 1] = heightLines[i, width / 2 - 1]; Teragen(heightLine, 0, width / 2 - 1, AlgorithmHelper.GetRandom(10, 100)); Smooth(heightLine, 5, 2); ArrCPYdim(heightLine, heightLines, i); } CreateBackgroundTexture(device, batch, width, height); CreateBlockTexture(device, batch, Block.Width, Block.Height); CreateTopmostBlockTexture(device, batch, Block.Width, Block.Height); }
//Creates a zone anywhere in the current tile private Zone GetScreenZone(GraphicsDevice device, Color zoneColor) { var tile = GetTileByIndex(0); int xblocks = tile.Coords.Width / Block.Width; int yblocks = tile.Coords.Height / Block.Height; int selX = -1; int selY = -1; while (selX == -1) { for (int x = 1; x < xblocks; ++x) { for (int y = tile.GroundLevel + 1; y < tile.GroundLevel + 2; ++y) { int rand = AlgorithmHelper.GetRandom(0, (xblocks * yblocks) / 10); if (rand % 12 == 0 && tile.Blocks[x, y] != null) { rand = AlgorithmHelper.GetRandom(0, 3); if (rand == 0 && tile.Blocks[x, y - 1] == null) { selX = x; selY = y - 1; } else if (rand == 1 && tile.Blocks[x, y - 2] == null) { selX = x; selY = y - 2; } else if (rand == 2 && tile.Blocks[x, y - 3] == null) { selX = x; selY = y - 3; } return(new Zone(device, new Rectangle(tile.Coords.X + selX * Block.Width, tile.Coords.Y + selY * Block.Height, Block.Width, Block.Height), zoneColor)); } } } } return(null); }
//Creates 1-10 NPCs on this tile private void CreateEntities(GraphicsDevice graphicsDevice) { //temporary testing code int npcCount = AlgorithmHelper.GetRandom(1, 11); for (int i = 0; i < npcCount; ++i) { int w = AlgorithmHelper.GetRandom(24, 57); //16-49 small, 24-57 medium int h = AlgorithmHelper.GetRandom(24, 57); //32-65 big Vector2 position = new Vector2(Coords.X + AlgorithmHelper.GetRandom(0, map.Width - w + 1), AlgorithmHelper.GetRandom(0, map.Height - h + 1)); int additionalBase = AlgorithmHelper.GetRandom(Index, 2 * Index); int addHP = AlgorithmHelper.GetRandom(additionalBase / 2, 2 * additionalBase); float addStr = AlgorithmHelper.GetRandom((float)additionalBase / 4, additionalBase); float addDef = AlgorithmHelper.GetRandom((float)additionalBase / 4, additionalBase); float addSpd = AlgorithmHelper.GetRandom(0, (float)additionalBase / 100); //balance additional speed NPC npc = new NPC(graphicsDevice, map, position, Index, this, w, h, addHP, addStr, addDef, addSpd); map.NPCs.Add(npc); } }
//Initializes all tiles we see ingame private void CreateTiles(GraphicsDevice graphicsDevice) { tiles = new List <Tile>(); int minWidth = Game.WIDTH; int maxWidth = 3 * Game.WIDTH; int totalWidth = 0; int tileIndex = 0; while (totalWidth < Width) { //Generate a random width for the next tile, but keep it divisible by Block.Width int newWidth = AlgorithmHelper.GetRandom(minWidth / Block.Width, maxWidth / Block.Width) * Block.Width; //If last tile wouldn't be able to fit, extend this one instead int testWidth = totalWidth + newWidth; if (Width - testWidth < minWidth) { //Don't make the last tile too big, otherwise MonoGame might crash if (Width - totalWidth <= 4096) { newWidth = Width - totalWidth; } else { newWidth = 4096; //This breaks the purprose of the whole algorithm, because the next tile might be too small. But it fixes the crashing. } } //Pick a random TileType var type = (Tile.TileType)AlgorithmHelper.GetRandom(0, Tile.TileTypeCount); //Create and add Tile tiles.Add(new Tile(graphicsDevice, this, type, new Rectangle(totalWidth, 0, newWidth, Height), tileIndex)); totalWidth += newWidth; ++tileIndex; } }
//Initializes the NPC private void InitNPC() { SightRange = new Vector2(640, 368); //todo: range can be adjusted IsBoss = AlgorithmHelper.GetRandom(0, 11) == 0; //currently 10% chance of being a boss //NPC defaults DefaultHP = 3; DefaultStrength = 1; DefaultDefense = 0; if (IsBoss) { Width += 5; Height += 5; //Boss defaults DefaultHP += 2; DefaultStrength += 1; DefaultDefense += 1; } Name = StringHelper.GenerateName(); }
//Generates the background texture public void CreateBackgroundTexture(GraphicsDevice device, SpriteBatch batch, int width, int height) { Texture = new RenderTarget2D(device, width, height); List <LSystem.Rule> rules = new List <LSystem.Rule>(); rules.Add(new LSystem.Rule("F", "1FF-[2-F+F-F]+[2+F-F+F]")); //basic tree defaultSystem = new LSystem("F", 10, 22, rules); turtle = new Turtle(device, batch, new Vector2(200, 640), -90, Color.White, palette); device.SetRenderTarget(Texture); device.Clear(palette[0]); batch.Begin(); RenderTarget2D target = new RenderTarget2D(device, width, height); //Pregenerate trees List <LSystem> trees = new List <LSystem>(); for (int i = 0; i < 6; ++i) { var currentSystem = new LSystem(defaultSystem); currentSystem.Iterate(i); trees.Add(currentSystem); } //create clouds int count = Math.Max(1, AlgorithmHelper.GetRandom(width / 512, width / 96)); int nextX = AlgorithmHelper.GetRandom(0, width / count); int nextY; for (int i = 1; i < count; ++i) { nextY = AlgorithmHelper.GetRandom(0, 100); int w = AlgorithmHelper.GetRandom(32, 512); int h = AlgorithmHelper.GetRandom(32, 128); Texture2D cloud = new Texture2D(device, w, h); GraphicsHelper.FillRectangle(cloud, palette[7]); GraphicsHelper.OutlineRectangle(cloud, ColorHelper.ChangeColorBrightness(palette[5], -0.2f), 8); batch.Draw(cloud, new Rectangle(nextX, nextY, w, h), Color.White); nextX += AlgorithmHelper.GetRandom(0, (int)(w * 1.5)); if (nextX > width) { nextX -= AlgorithmHelper.GetRandom(w, (int)(width / 1.5)); } } count = Math.Max(1, AlgorithmHelper.GetRandom(width / 256, width / 64)); nextX = AlgorithmHelper.GetRandom(0, width / count); for (int i = 0; i < count; ++i) { int size = AlgorithmHelper.GetRandom(1, trees.Count - 1); while (nextX + 100 * size > width) { --size; } if (size == trees.Count - 2 && AlgorithmHelper.GetRandom(0, 10) > 6) { size = size + 1; } if (size < 0) { break; } if (i == 0 && nextX < size * 20) { nextX = size * 20; } var currentSystem = trees[size]; turtle.SetDefaults(new Vector2(nextX, 640), -90); turtle.DrawSystem(currentSystem, target); nextX += 50 * size; } batch.Draw(target, new Rectangle(0, 0, width, height), Color.White); batch.End(); device.SetRenderTarget(null); }
//Generates a word of a given length with the use of some basic linguistic rules public static string GenerateWord(int len) { string result = ""; string[] syllables = new string[] { "e", "a", "o", "i", "u", "y", "r", "l" }; string[] consonants = new string[] { "t", "n", "s", "h", "r", "d", "l", "c", "m", "f", "g", "p", "b", "v", "w", "k", "j", "x", "z", "qu" }; string disabled = ""; bool lastType = AlgorithmHelper.GetRandom(0, 2) == 0; string next = "?"; for (int i = 0; i < len; ++i) { lastType = !lastType; string last = next; if (lastType) { do { next = syllables[AlgorithmHelper.BiasedRandom(0, syllables.Length - 1, 1.7)]; }while (disabled.Contains(next)); //prevent weird sounding combinations if (next == "r" || next == "l") { disabled = "gxzqusj"; } else { disabled = ""; } if ((last == "r" || last == "l") && (next == "r" || next == "l")) { disabled += "rl"; } if (next == "l") { disabled += "r"; } } else { do { next = consonants[AlgorithmHelper.BiasedRandom(0, consonants.Length - 1, 1.6)]; }while (disabled.Contains(next)); if (next == "r") { disabled = "rl"; } else if (next == "l") { disabled = "r"; } else if (next == "w") { disabled = "l"; } else { disabled = ""; } if (i == len - 2) //last letter { disabled += "w"; } } result += next; //keep the correct length even when adding multiple letters if (next.Length > 1) { i += next.Length - 1; } } return(result); }
//Picks a random behaviour type private NPCBehaviour CreateBehaviour() { return((NPCBehaviour)AlgorithmHelper.GetRandom(0, 3)); }
//Initializes quests private void CreateQuests(GraphicsDevice device) { Quests = new QuestManager(this); questZones = new List <Zone>(); //How many quests will this level have (1-3) int count = AlgorithmHelper.GetRandom(1, 4); List <Quest.QuestType> usedTypes = new List <Quest.QuestType>(); for (int i = 0; i < count; ++i) { //Only add one of each quest type Quest.QuestType type; do { type = (Quest.QuestType)AlgorithmHelper.GetRandom(0, Quest.QuestTypeCount); }while (usedTypes.Contains(type)); usedTypes.Add(type); string name = ""; List <Entity> targets = null; List <Item> itemFetchList = null; List <Zone> zones = null; //Kill quest - picks 1-4 NPCs and player's task is to kill them all if (type == Quest.QuestType.KillTargets) { name = "Kill "; targets = new List <Entity>(); var entities = NPCs; int enemyCount = AlgorithmHelper.GetRandom(1, Math.Min(5, entities.Count)); for (int j = 0; j < enemyCount; ++j) { Entity target; do { target = entities[AlgorithmHelper.GetRandom(0, entities.Count)]; }while (targets.Contains(target)); targets.Add(target); } } //Fetch quest - picks 1 or 2 items which player has to put down inside a specific area else if (type == Quest.QuestType.FetchIitems) { name = "Bring "; itemFetchList = new List <Item>(); zones = new List <Zone>(); int itemCount = AlgorithmHelper.GetRandom(1, Math.Min(3, items.Count)); //so that item names would fit into view -.- var newZone = GetNewZone(device, Color.Green); zones.Add(newZone); questZones.Add(newZone); for (int j = 0; j < itemCount; ++j) { Item item; do { item = items[AlgorithmHelper.GetRandom(0, items.Count)]; }while (itemFetchList.Contains(item)); itemFetchList.Add(item); } } //Reach quest - randomly select 1 - 4 empty blocks and task the player with reaching them else if (type == Quest.QuestType.ReachBlock) { name = "Reach orange areas located in these tiles: "; zones = new List <Zone>(); int pointCount = AlgorithmHelper.GetRandom(1, 5); for (int j = 0; j < pointCount; ++j) { var newZone = GetNewZone(device, Color.Orange); zones.Add(newZone); questZones.Add(newZone); } } Quests.AddQuest(new Quest(this, type, name, targets, itemFetchList, zones)); } CreateQuestBackground(device, usedTypes); }
//Randomly places blocks on the tile. No check iwhether private void CreateBlocks() { Blocks = new Block[wblocks, hblocks]; bool[,] blockGrid = new bool[wblocks, hblocks]; //Prepare grid (currently a random dumb layout, replace with a proper algorithm) for (int w = 0; w < wblocks; ++w) { for (int h = 0; h < hblocks; ++h) { blockGrid[w, h] = false; //Generate solid ground if (h > GroundLevel) { blockGrid[w, h] = true; continue; } //Only add blocks other than ground when not a Screen tile if (Type != TileType.Screen) { if (w < 4 || w > wblocks - 5) { blockGrid[w, hblocks - 3] = true; continue; } int tmp = AlgorithmHelper.GetRandom(0, 15); if (tmp > 3 && tmp < 7) { blockGrid[w, h] = true; } if (tmp == 1 && w < wblocks - 2) { blockGrid[w + 1, h] = true; } if (tmp == 5 && h < hblocks - 2) { blockGrid[w, h + 1] = true; } } } } //Generate textures according to the grid bool borderAbove; bool borderLeft; bool borderRight; bool borderBelow; for (int w = 0; w < wblocks; ++w) { for (int h = 0; h < hblocks; ++h) { if (blockGrid[w, h]) { //if there is a block above this one if (h > 0 && blockGrid[w, h - 1]) { borderAbove = false; } else { borderAbove = true; } //if there is a block below this one if (h < hblocks - 1 && blockGrid[w, h + 1]) { borderBelow = false; } else { borderBelow = true; } //if there is a block left of this one if (w > 0 && blockGrid[w - 1, h]) { borderLeft = false; } else { borderLeft = true; } //if there is a block right of this one if (w < wblocks - 1 && blockGrid[w + 1, h]) { borderRight = false; } else { borderRight = true; } //Assign texture accordingly //If block is topmost, use a different texture Texture2D texture = borderAbove ? GraphicsHelper.CopyTexture(BlockTexture) : GraphicsHelper.CopyTexture(BlockTopmostTexture); //need to COPY THE TEXTURE HERE if (Background.OutlineBlocks) { GraphicsHelper.OutlineRectangleSide(texture, Color.LightGray, 4, borderLeft, borderAbove, borderRight, borderBelow); } Blocks[w, h] = new Block(texture, borderAbove); } } } }