Game Backgrounds in XNA 2D – Part 2

OK so we talked about layered background structure in 2D games in the first post and implemented 2 simple types; Fixed Background and Tiled Background. Although I keep saying them simple , those two are probably the most used types too. Especially Tiled Background is standard for top down or isometric view games.

In this post , we’ll talk about and implement two another types , Big Huge Background ( I honesty have no idea what to call it ) and Flowing Background ( I know I’m terrible at naming stuff ). ( Edit : I just decided to do Flowing Background in another post )

Big Huge Background

Let’s start with this one. Now you know sometimes they have a big environment in the background , like a city , and you slowly move on that background. That is exactly what we’ll going to do now. It’s pretty simple actually , only thing is ,  you have to be careful about X and Y Coordination of Camera. Have a look at this ;

bhb

As you can see , what are we supposed to do is , get a particular section of background image ( starting from Camera.X / Camera.Y and ending at Camera.X + 500 / Camera.Y +  500 ) and draw it on screen ( starting from 0 / 0 and ending at 500 / 500 )

 

Let’s have a look at the code ;

 publicclassBigHugeBackground : IBackground
{
     privateTexture2D _texture;
     privateRectangle _screenRectangle;
     privateRectangle _cameraRectangle;

    public BigHugeBackground(Texture2D texture)
    {
        _texture = texture;
    }

    publicvoid Update(Rectangle screenRectangle, Rectangle cameraPosition)
    {
        _screenRectangle = screenRectangle;
        _cameraRectangle = cameraPosition;
    }

    publicvoid Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(_texture, _screenRectangle, _cameraRectangle, Color.White);
    }
}

Again we have a texture for background ( Texture2D class also holds Width and Height data of that image ) , _screenRectangle which holds the data for camera Width and height and _cameraRectangle which hold the data for Camera.X and Camera.Y.

Actually if you’re going for something simple like one view full screen , then you can get _screenRectangle data from _cameraRectangle too. But if you ever want to resize your camera view , say use top half of the screen for the game and bottom half for hud , then you’ll need both of them.

Nothing fancy in constructor and Update methods really. And as I said earlier , draw method just takes a section of image ( _cameraRectangle ) and draws it on whole game screen ( _screenRectangle ).

So now it should look something like this ;

CodeMonekyGetUpGetCoffee (4)

Please don’t mind the terrible background , it just makes it easy to debug movement and position related stuff.

 

I was planning to write about Flowing Background too but I think it would be better to keep posts shorter from now on. So I’ll talk about Flowing Background in another post.

 

You can find a sample Visual Studio Solution below , it contains both BigHugeBackground and FlowingBackground ( and the other 2 from previous post ).

 

Hope you like it!

 

Visual Studio 2010 Solution

Game Backgrounds in XNA 2D ( Fixed & Tiled )

 

It was like 2-3 weeks ago when I got bored and decided to check out some gaming forums. Gaming forums are always fun after all. After a few hours of skimming / reading / talking ; I remembered about XNA, the gaming framework of Microsoft using C# , and decided to give it a shot.

So I’m playing with XNA for that last 2 weeks and it has been incredibly fun! It’s extremely easy if you’re somewhat decent at C# and you can create experimental stuff extremely quick. Also there are big huge professional games using XNA out there , like Terraria , Bloodline Champions and Bastion. I’m not really experienced in game programming and don’t know much about other game development frameworks either but XNA really looks like the perfect choice for indie game developers to me now.

I’ve been making small experimental stuff all those 2 weeks and I’ll slowly blog about them , stargin with background management and creation in 2D games.

But please note that , I’m not experienced in XNA or game development , not one bit. So my samples here might bad practices or wrong or something. Beware.

So , about background in 2D games. First thing I wanted to try was a simple platformer , actually I think I started it after checking out one of the Xna Platformer samples. And after recreating what is already in that sample , I decided to improve it a bit myself and the first thing came to my mind was the backgroun since background is the heart and soul of a platformer. It takes like %90 of the screen and you stare it almost all game long. Also it’s the most important part of creating the mood and showing off your art style etc etc.

In this post , we’ll create the two simplest background types , static and tiled background.

What I call static background is just putting an image into background and no matter where does the player character moves , it doesn’t change one bit. It just stays there , pretty much like “Fixed Background” in Cascading Style Sheets.

On the other hand , tiled background is craeted by repeating same tile texture until it fills the whole screen , like grass or water in good old 2D games. It’s a bit repetitive of course but with good symmetrical textures , it looks pretty good and much more usable then one huge background image.

OK here we go , first of all I’ll create some services to take care of background elements. This might not be the best practice in XNA but I just like to work with my custom services to do stuff. I guess “Components” is the XNA way of doing the same thing but I prefer my good old simple service classes for now. I’ll read & learn about component later.

PlayerService = new PlayerService(this);
EnvironmentService = new EnvironmentService(this);
CameraService = new CameraService(this, EnvironmentService, PlayerService);

These are the first 3 services I like to use in every project. Obviously Player service creates and takes care of player , EnvironmentService handles background stuff and the level , CameraService takes care of camera position , where camera looks ( for 3D ) and stuff like that.

Constructor of the EnvironmentService is also simple and not much there for now;

 

 

public EnvironmentService(TheGame game) : base(game)
{
    _background = new Background(game, MapWidth, MapHeight);
}

 

tangle.Height))
Now the real content is all in Background object.

public class Background
{
    public List<IBackground> BackgroundLayers { get; set; }

    public Background(TheGame game, int mapWidth, int mapHeight)
    {
        BackgroundLayers = new List<IBackground>();

        BackgroundLayers.Add(new FixedBackground(_game.Content.Load<Texture2D>("space")));
        BackgroundLayers.Add(new TiledBackground(_game.Content.Load<Texture2D>("astroid"), _game.GraphicsDevice.Viewport.Width, _game.GraphicsDevice.Viewport.Height));

    }

    public void Update(GameTime gameTime)
    {
        foreach (IBackground bg in BackgroundLayers)
        {
            bg.Update(_game.CameraService.CameraRectangle);
        }
    }

    public void Draw(SpriteBatch spriteBatch, Rectangle screenRectangle, Rectangle nextPosition)
    {
        foreach (IBackground bg in BackgroundLayers)
        {
            bg.Draw(spriteBatch);
        }
    }
}

OK , what do we got here. We have a background layers list , we add our 2 background layers to that list in constructor method , update them in generic Update Method and Draw them on screen in generic Draw Method , nothing fancy.

As you can guess , Game Update method calls , EnvironmentService Update method which calls Background Update method. And same thing for Draw method too.

Oh and I got an interface for Backgrounds so I can keep them all in one list ;

   

public interface IBackground
{
    void Update(Rectangle screenRectangle);
    void Draw(SpriteBatch spriteBatch);
}

Now , let’s have a look at Fixed Background ;

   

public class FixedBackground : IBackground
{
    private Texture2D _texture;
    private Rectangle _screenRectangle;

    public FixedBackground(Texture2D texture)
    {
        _texture = texture;
    }

    #region Implementation of IBackground

    public void Update(Rectangle screenRectangle)
    {
        _screenRectangle = screenRectangle;
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(_texture, new Rectangle(0,0,_screenRectangle.Width,_screenRectangle.Height), Color.White);
    }

#endregion
}

That’s all and hardly anything there really. We just set texture in constructor method , update screen data in Update method and draw a simple rectangle in Draw method. One thing you may ask tho , do we really need to update screen data , it’s not like screen will change in the middle of game after all. But then , what if we want to change our camera position and Viewport? You may remove it too of course but I prefer having it there , just feels like it’s working properly checking out where to draw stuff every time.

In the draw method , we’re using generic spriteBatch.Draw method to draw an image using the texture set in contructor , starting from the top left of the screen (0,0) and ending at bottom right corner. ( Color.White is the standart input for no tinting , not really important for now ) Easy Peasy.

Now it should look something like this ;

Yea I’m using that ship , from one of those Xna samples , as player and a random space image from internet.

Now even tho our “space” is 4000×960 , no matter where player goes , background will stay the same.

And now let’s have a look at Tiled Background and add an astroid field to our game. But before the code , let’s see what do we really need.

This is simply how tiled backgrounds work. We create screenWidth / tileWidth + 1 amount of tiles ( because one tile will be used to fill empty space created by scrolling ) and start drawing them one by one , starting from a point close to top left ( which always changes according to player movement ). And if we assume our tile width is 100px , starting point X must be somewhere between 0 and -100. If it’s below -100 then there is no need to draw that tile , player can’t see it anyway and if it’s above 0 , then we’ll have empty space at the left of that tile , right?

Now let’s have a look at code ;

public class TiledBackground : IBackground
{
    private readonly Texture2D _texture;
    readonly int _horizontalTileCount;
    readonly int _verticalTileCount;
    public Vector2 _startCoord;

    public TiledBackground(Texture2D texture, int environmentWidth, int environmentHeight)
    {
        _texture = texture;
        _horizontalTileCount = (int) (Math.Round((double)environmentWidth / _texture.Width) + 1);
        _verticalTileCount = (int) (Math.Round((double)environmentHeight / _texture.Height) + 1);

        _startCoord = new Vector2(0, 0);
    }

    public void Update(Rectangle _cameraRectangle)
    {
        _startCoord.X = ((_cameraRectangle.X / _texture.Width) * _texture.Width) - _cameraRectangle.X;
        _startCoord.Y = ((_cameraRectangle.Y / _texture.Height) * _texture.Height) - _cameraRectangle.Y;
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        for (int i = 0; i < _horizontalTileCount; i++)
        {
            for (int j = 0; j < _verticalTileCount; j++)
            {
                spriteBatch.Draw(_texture,
                new Rectangle(
                (int)_startCoord.X + (i * _texture.Width),
                (int)_startCoord.Y + (j * _texture.Height),
                _texture.Width, _texture.Height),
                Color.White);
            }
        }
    }
}

It’s pretty close to that simpler Fixed Background actually. We have a texture , a starting point and tile counts for each dimension. We set them all in constructor and then update starting coordination in the update method. I didn’t update tile count ( which depends on screen size ) here as an example. As I said in Fixed Background , it’s optional. Now if we change screen size during game , this background won’t be able to resize according to new screen.

Anyway , as I said, in update method we update starting coordination. Note that _cameraRectangle is the place where camera is looking at that given moment. We have a 4000×960 environment and our game screen is just 766×500 , so yes starting points of the camera rectangle changes as player moves.

(_cameraRectangle.X / _texture.Width) will give you the required tile count from absolute 0,0 to the top left of camera.

((_cameraRectangle.X / _texture.Width) * __texture.Width) will give you the X position of our first tile.

(((_cameraRectangle.X / _texture.Width) * __texture.Width) – _cameraRectangle.X) will give you the X position of our first tile relative to camera ( or relative to the (0,0) you have on your screen ) , or in other words it’s where we should draw the tile.

Draw method is pretty straight forward , it just draws a 2D matrix on screen.

And now it should look something like this;

Yes I know it looks horrible but it’s all because of the terrible textures I’m using , nothing related to the code. Hopefully I’ll have time and patience to find better textures for future blog posts. Who would want to try out such a bad looking sample right? It’s not really encouraging…

What’s next? Hmm I guess something like Flowing Background or I guess people call it Parallaxing Background eh? Anyway hope you like this one!

Visual Studio 2010 Solution

Oh and in case you’re curious about the solution name ; Code Monkey


Simple Map Generator Part 2

Wow , it has been 31 days since that last post? Damn I’m lazy. Ok so in this second part of the series , we’ll create our island and visualize it in 2D with some basic colors.

Remember we had our voronoi diagram and our polygons in previous post? Now we’ll need a logic to decide which polygons will be ocean/water and which part will be land. There are some generic algorithms like perlin noise for these stuff , but I decided to use a sine wave function which I saw in Amit’s example and actually it looks kinda better than perlin noise to me.

It’s a simple function which takes a point ( between 0 and 1 since we’ll use sine wave ) and returns a boolean to set IsLand property of the polygon.

It goes something like this ,

private bool IsLandShape(Point point)
{
    double ISLAND_FACTOR = 1.07;
    int bumps = islandRandom.Next(1, 6);
    double startAngle = islandRandom.NextDouble() * 2 * Math.PI;
    double dipAngle = islandRandom.NextDouble() * 2 * Math.PI;
    double dipWidth = islandRandom.Next(2, 7) / 10;

    double angle = Math.Atan2(point.Y, point.X);
    double length = 0.5 * (Math.Max(Math.Abs(point.X), Math.Abs(point.Y)) + GetPointLength(point));

    double r1 = 0.5 + 0.40 * Math.Sin(startAngle + bumps * angle + Math.Cos((bumps + 3) * angle));
    double r2 = 0.7 - 0.20 * Math.Sin(startAngle + bumps * angle - Math.Sin((bumps + 2) * angle));
    if (Math.Abs(angle - dipAngle) < dipWidth
    || Math.Abs(angle - dipAngle + 2 * Math.PI) < dipWidth
    || Math.Abs(angle - dipAngle - 2 * Math.PI) < dipWidth)
    {
        r1 = r2 = 0.2;
    }
    return (length < r1 || (length > r1 * ISLAND_FACTOR && length < r2));
}

I have to admit I just (shamelessly) converted Amit’s AS3 code to C# for this function and don’t totally understand what’s going on. I’m not really good at math and I didn’t want to waste time on this one. For all I know , it returns a “noisy” boolean series. Yes I’m a terrible person and coder , let’s move on.

Now we’ll just iterate through corners and set water/land values according to results of the function above. Not much to see here ;

foreach (var c in App.AppMap.Corners.Values)
{
     c.Water = !InLand(c.Point); // calculate land&water corners
}

Now that we have set corners’ land/water values , we’ll iterate through polygons ( centers ) and decide if a polygon is water or land according to states of it’s own corners. Also we’ll do some other stuff like fixing edges for polygons at the edge of the map and ordering corners as we’ll need them in order for creating visuals ( WPF Polygons ).

First ;

 

 

foreach (var ct in App.AppMap.Centers.Values)
{
    ct.FixBorders(); //Fix edges at map edge, set "border" and "ocean" values
    ct.OrderCorners(); //Order corners clockwise as we'll need it for polygons and 3d stuff

    //if it touches any water-corner , it's water
    ct.Water = (ct.Corners.Any(x => x.Water)) ? true : false;
}

 

As you can see I decided to set a polygon as water ( or sea , whatever ) if it has even one corner set as water. Of course you can use the exact opposite here ( land if it has one corner set as land ) or something more complex.

Then we’ll floodfill the oceans starting from map edges. Oh I set polygons at map edge as “Ocean” in FixBorders method but that method is pretty ugly and should be rewritten, so I’m not going to talk about it here. You can just go set a polygon as Ocean if it has a corner at map boundaries ( like X = 0 or Y = 0 etc )

 

var Oceans = new Queue<Center>();
    //start with oceans at the borders
foreach (Center c in App.AppMap.Centers.Values.Where(c => c.Ocean))
{
    Oceans.Enqueue(c);
}

//floodfill oceans
while (Oceans.Count > 0)
{
    Center c = Oceans.Dequeue();

    foreach (Center n in c.Neighbours.Where(x => !x.Ocean))
    {
        if (n.Corners.Any(x => x.Water))
        {
            n.Ocean = true;
            if (!Oceans.Contains(n))
            Oceans.Enqueue(n);
        }
        else
        {
            n.Coast = true;
        }
    }
}

I guess it’s pretty clear what’s going on here. We just ahve a queue for Oceans and we floodfill starting from the polygons at the edge of the map. Then we set every polygon , which has at least one corner set as water , as ocean. A nice little touch here, if a polygon we reached by this floodfill , doesn’t have any corners set as water ( all land ) this means that’s the coast! So we set it as coast and later we’ll visualize it as beach.

One last thing , we have to set polygon “biome”. We’ll use biome for template selection at the front end. You know ocean will be blue and land will be brown and stuff like that.

 

 

foreach (Center c in App.AppMap.Centers.Values)
{
    c.SetBiome();
}

Just wanted to clarify what it is.

Hmm we now have our island , created oceans and lands even beaches. Should be enough for this post but of course we need to visualize this all now right?

Since we already set biome for all polygons , we just need to set a visual style for that biome and use a template selector to choose polygon styles according to polygon biomes.

It’s kinda hard to write and explain Xaml stuff but I’ll try ; we’ll use this style for oceans

   

<DataTemplate x:Key="Ocean">
<Polygon Points="{Binding Converter={StaticResource MapPointToPointConverter}}"
Fill="#363661" />
</DataTemplate>

It creates a Polygon , do change corner points according to polygon center and fill the polygon with that probably blue-ish color. You can find all styles ( and even more, old test styles, which I forgot to delete ) in MapResource.xaml in the solution.

And since we’re using a Listbox as item container, we need to give our listbox a function to help him decide how to choose styles for each polygon.

It’s much longer but I’ll just paste a part of it as sample ;

 

public class MapDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item != null && item is Center)
        {
            var center = item as Center;
            var window = Application.Current.MainWindow;

            return window.FindResource(center.Biome) as DataTemplate; 
        }
    }
}

It’s pretty straight-forward I guess. If the item is a Center ( polygon ) we just get the MainWindow ( which holds all styles , actually I doubt we need to do that but anyway ) and find the style ( FindResource ) according to that Center’s Biome. Listbox will handle the rest , easy peasy.

Now this is how it should look;

In the next episode? Hmm probably some elevation work maybe even rivers!

Hope you enjoy it!

Visual Studio 2010 Solution

Simple Map Generator Part 1

Simple Map Generator – Introduction

OK so now that we have Amit’s blog post as a general guideline and a Voronoi diagram library , we can start coding. In this post , we’ll just create a nice Voronoi diagram and a 2D visualization of it.

First of all , we need a Voronoi diagram. We’ll throw bunch of points in an area and Bendi’s Voronoi library will calculate the edges between those points for us. And then we’ll create a better and more complicated structure so it’ll be easier to play with it in the future.

var rnd = new Random();
var points = new HashSet<BenTools.Mathematics.Vector>();

for (int i = 0; i < DotCount; i++)
{
    points.Add(new BenTools.Mathematics.Vector(rnd.NextDouble() * MapSize,
    rnd.NextDouble() * MapSize));
}

VoronoiGraph voronoiMap = Fortune.ComputeVoronoiGraph(loadMapParams.Points);

VoronoiGraph is a class from Bendi’s library. It inclused edges and vertices of the voronoi diagram.

Edges have all the data we need so we’ll use them but before that , if you have seen any Voronoi diagrams before , you may ahve noticed that area sizes varies a lot. And since extremely small or big areas looks pretty bad in later stages , I use Lloyd’s algorithm to generate a more “balanced” diagram.

I won’t go into details but in general , all you have to do is to

– generate a voronoi diagram ( using random number for first time )
– take the center points of the areas in that diagram
– regenerate the diagram with those points
– Repeat it as much as you want

After like 3-4 times , you’ll have a much better balanced diagram. If you run it too much , you’ll end up with a grid tho , so be careful. ( There is something wrong with my implementation tho , messing up after like 10 iterations. Oh well , I use 3 anyway. )

Now we a VoronoiDiagram object but it’s hardly usefull for anything. Sho now we’ll use that diagram object and create a structure pretty close to the one Amit used. We’ll create Centers ( the points we put in ) , Edges ( edges between those points ) and Corners ( where edges connect each other ) and then set some relations between them. For example , center object will have Neighbours ( centers ) , Borders ( edges ) and Corners.

As I said before , VoronoiEdges in VoronoiDiagram object has all the data we need , so we’Ll just iterate through them and get as much data as we can.

foreach (VoronoiEdge edge in voronoiMap.Edges)
{
    Corner c1 = fact.CornerFactory(edge.VVertexA[0], edge.VVertexA[1]);
    Corner c2 = fact.CornerFactory(edge.VVertexB[0], edge.VVertexB[1]);
    Center cntrLeft = fact.CenterFactory(edge.LeftData[0], edge.LeftData[1]);
    Center cntrRight = fact.CenterFactory(edge.RightData[0], edge.RightData[1]);

    c1.AddAdjacent(c2);
    c2.AddAdjacent(c1);

    cntrRight.AddCorner(c1);
    cntrRight.AddCorner(c2);

    cntrLeft.AddCorner(c1);
    cntrLeft.AddCorner(c2);

    Edge e = fact.EdgeFactory(c1, c2, cntrLeft, cntrRight);

    cntrLeft.AddBorder(e);
    cntrRight.AddBorder(e);

    cntrLeft.AddNeighbour(cntrRight);
    cntrRight.AddNeighbour(cntrLeft);

    c1.AddProtrudes(e);
    c2.AddProtrudes(e);
    c1.AddTouches(cntrLeft);
    c1.AddTouches(cntrRight);
    c2.AddTouches(cntrLeft);
    c2.AddTouches(cntrRight);
}

Pretty straight forward I guess? Create Corners , create centers , add a few relations then create the edge and then add that edges relations etc etc. Actually this is probably a lot more detailed than we need but still , it just makes everything easier in later stages.

Oh and by the way , as I mentioned before ; Bendi’s library doesn’t take map borders into account so you have to take care of it before this part. I won’t go into this here , but I added my fix function to the example solution below. It does a decent job but not perfect ( can mess up map corners etc ) so you may want to rewrite that part.

And also ; I’m skipping most of the small details in this post , like ordering area corners for visualization etc. You can find them all in the solution below.

So now we have our organized voronoi diagram but before moving any further , let’s have a look what we have done right? I’ll use an ObservableCollection to hold map items ( centers , edges , corners ) and then a ListBox ( using a Canvas as ItemConainer ) to view those items.

It seems FunnelWeblog doesn’t support XAML in posts. Whatever , now all we need is to create an ObservableCollection , fill it with our items and bind it to that ListBox.

You can find the sample solution below. It only includes the basics I described above and a 2D presentation.

Next , we’ll create the island and stuff.

Visual Studio 2010 Solution

Simple Map Generator

So I was thinking about some game concepts last week , stealing ideas from here and there etc. One thing I noticed tho , indie games with random maps really have an advantage over professional games with static content , especially when it comes to replay value of the game. Also random map generation is a must for sandbox games like Minecraft and Terraria right? Noone would like to play same sandbox game over and over again on same map ( unless it’s HUGE ie. Eve Online )

So I decided that I need a good random map generator more than everything else , if I have a good map generator , I can build any game on it right?!

After a little search , I found the awesome blog of Amit. I remember reading his A* algorithm articles a few years ago , but somehow I totally forgot about his blog after that. It seems he just posted a new little series about random map generation a few months ago ( September 2010 ) , based on Voronoi diagrams

After reading his article and a little more about voronoi diagrams , I knew I had to do it myself so yea I have been working on it for a few days now. It’s extremely fun playing with Voronoi diagrams , shaping the land , rivers , mountains etc and create my own little island!

I’ll slowly blog about my process here , and the first step is obviously ;

Voronoi Diagrams

So what is a Voronoi diagram?

Wikipedia says ;
   In mathematics, a Voronoi diagram is a special kind of decomposition of a metric space determined by distances to a specified discrete set    of objects in the space, e.g., by a discrete set of points.

Or we can simply say ; it divides an area based on a set of points. You take a field , then throw some points in it , then create zones around those points in a way that everywhere in that zone is closer to that point than any other. An image worths thousand words right?

Looks nice isn’t it? It’s a great diagram used for lots and lots of different stuff

Now what we will do , is just throw in a few thousand dots , divide the area , then work on it as if it’s a grid. We’ll use areas to decided land type , edges to create rivers and coastline etc etc.

But since I’m more interested in creating a random map more than a basic Voronoi diagram , I decided to use a 3rd party Voronoi Diagram library to take care of that. But it turns out there isn’t many Voronoi implementations for .Net. The best I was able to find , is an implementation by BenDi , posted on CodeProject.

It’s doing a pretty good job , fast and reliable. The only problem I had , is that it only works on points and generated edges between them , there is no way to actually set area boundaries. I had to work it out myself , not a big problem but my temporary fix isn’t good enough so borders of the maps looks a bit silly. ( I’ll redo it later , I’m hardly bothered about the map borders at the moment , our island will be at the center anyway )

As I said I’ll blog more about this in future , and probably even post the project when I’m done with it.

My current process ;