C# / XNA - Map Tiling System

Good day, signed up hoping someone can maybe help me. I'm busy doing tech research for a Roguelike Survival game I want to make and while I have most of it functioning properly, I'm stuck with getting the tiling system to work seamlessly.

I've read countless resources pointing me to what I want, having this explain it properly (http://blog.rpgmakerweb.com/tutorials/anatomy-of-an-autotile/). The problem I'm facing is I'm struggling to interperet this into C# code using the XNA game libraries.

I have come so far as to being able to split up the tiles down to their quads. But can't seem to get the code together the stitch each part back together(which is mostly math as I would understand it). As another reference I have a LUA(Using LOVE Game library) tutorial which taught me basically just that I should break up the tiles (https://love2d.org/forums/viewtopic.php?t=7826), it does however show LUA script to do exactly as I want in C# / XNA, although I can't translate from LUA to C# either.

Example of my tileset split into pieces.
https://imgur.com/1lE3oFq

Comments

  • I'm not entirely sure which part you're struggling with. Is it the drawing of each tile, or is it the logic of picking which tile to draw?
    Below I've put some simple code which will draw a single sprite/tile over and over again to create a seamless floor.
    In your case you'll want more than one sprite. One way to store that would be to replace private List<Vector2> tiles; with a list of a class that has position and sprite. Then when looping through just draw each items own sprite.


    In Game.cs:

    Environment ourEnvironment;
    
            protected override void LoadContent()
            {
                ourEnvironment = new Environment(new Vector2(2000, 2000), Content.Load<Texture2D>("Sprites/ground"), graphics.GraphicsDevice.Viewport);
                spriteBatch = new SpriteBatch(GraphicsDevice);
            }
    
            protected override void Update(GameTime gameTime)
            {
                Vector2 velocity = Vector2.Zero;
                KeyboardState kbs = Keyboard.GetState();
                if (kbs.IsKeyDown(Keys.W)) 
                { velocity.Y = -2f; } 
                if (kbs.IsKeyDown(Keys.A)) 
                { velocity.X = -2f; }
                if (kbs.IsKeyDown(Keys.S))
                { velocity.Y = 2f; }
                if (kbs.IsKeyDown(Keys.D))
                { velocity.X = 2f; }
                ourEnvironment.UpdateMe(velocity);
                base.Update(gameTime);
            }
    
            protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
    
                spriteBatch.Begin();
                ourEnvironment.DrawMe(spriteBatch);
                spriteBatch.End();
    
                base.Draw(gameTime);
            }


    And then Environment.cs:
    public class Environment 
        {
            public Vector2 position;
            private Texture2D texture;
            private Vector2 size;
            private List<Vector2> tiles;
            private Viewport screen;
            private int minXPos, minYPos;
            public Environment(Vector2 size, Texture2D texture, Viewport screen)
            {
                this.size = size;
                this.texture = texture;
                this.screen = screen;
                this.position = new Vector2(0, 0);
                this.tiles = new List<Vector2>();
    
                minXPos = (int)-(size.X - screen.Width);
                minYPos = (int)-(size.Y - screen.Height);
    
                double xRepeats = Math.Ceiling(size.X / texture.Width);
                double YRepeats = Math.Ceiling(size.Y / texture.Height);
                for (int y = 0; y < YRepeats; y++)
                {
                    for (int x = 0; x < xRepeats; x++)
                    {
                        tiles.Add(new Vector2(x * texture.Width, y * texture.Height));
                    }
                }
                
            }
    
            public void UpdateMe(Vector2 movement)
            {
                position -= movement;
                position.X = MathHelper.Clamp(position.X, minXPos, 0);
                position.Y = MathHelper.Clamp(position.Y, minYPos, 0);
            }
    
            public void DrawMe(SpriteBatch sb)
            {
                foreach (Vector2 tile in tiles)
                {
                    sb.Draw(texture, position + tile, Color.White);
                }
            }
        }
    Thanked by 1PainKillerREX
  • edited
    Good day, thanks for the swift reply. It is the logic of picking the segments from the split tileset and stitching them back together as one tile again. At the moment, I am able to split the tiles into segments and dividing up like A1-4, B1-4, C1-4, etc.

    Thanks for the sample code on drawing the environment. It showed me an easier way to clamp the screen view to the map.

    Here is a pastebin of my code used to cut the tiles up: pastebin.com/1ETvi4FV


    See below images for sample data from my generation process.

    https://imgur.com/KFtisnl - (Enlarged from 64x64 to 1024x1024 to view easily) This represents the generated map from which I extract the pixel color as a value for setting the tile texture, First 3 shades going from black to the 2nd gray is Water (at different depth), then it's sand, then ground/grass then mountain(White) in the middle.

    http://imgur.com/87isVWB - This is when I draw the entire map.

    Edit: While I have not yet solved my auto tile issue. I did sort out a majour problem I had with memory usage in my engine. Went from 64x64 tile map using 2.3 gb up to a 4096x4096 tile map using less than half of the memory at 730mb. Framerate is up from 27 to 98-100(max).
Sign In or Register to comment.