Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, September 30, 2012

Back from the Brink

Hello to everyone! I am excited to say that I am coming back to this blog and to game programming as a whole. I have many things to update everyone on since my last visit here. Since my last post I have started a new job, moved to a new city, and bought a new car! Many things have changed for me now and I am happy to say that I am finally getting some time back on my hands to program again (as well as blog about it).

I hope everyone will forgive my absence over the last few months. Real life has been more crazy than normal, and I must say that I am ready for things to slow down for awhile. While I have enjoyed my time away from programming games, I am anxious to begin again, and with the upcoming release of Windows Phone 8, I am happy to say that (*spoiler alert*) I will be delving into the world of making games for the Windows Phone using my trusted friend, XNA Game Studio.

I am looking forward to beginning development on my next fun project, a simple 2D game (more details to come) for Windows Phone. Stay tuned for my next blog posts to read about the exciting work I will be doing in the world of the Windows Phone.

Sunday, February 5, 2012

Xna Platformer Update

Hey guys here is a quick update on my platformer game. I've been able to add in some decent player physics, modeled after the Platformer Starter Kit on the Xna website. I've also spent most of my time on the editor lately, getting it up to speed with my engine and designing it in such a way that I will be able to create platformer games much quicker than just hard-coding in the levels for this one game.

 

Thanks for taking the time to check up on my game. I'm really looking forward to developing the engine and editor even more. One of the things I'm in the process of adding is a dedicated object layer for the maps. Right now, the only thing on that object layer (which is loaded in from a file by the way) is the player. Most likely, the next thing I will add to the layer is an exit tile, which will load up the next level (tile map in my case). This, I feel, will make the game start to feel more like an actual game than just a level demo.

Stay tuned for more updates!

Thursday, February 2, 2012

Loading Objects from a File

Hey guys, so I just finished getting object loading to work in my platformer game and I thought I would share some code with you and explain my technique. I realize there are probably a hundred ways to do this and do it better, but this is just my first iteration for this method. As the game progresses I fully expect to go back and make this loading code more efficient.

This method is based off of Nick Gravelyn's Tile Engine series where he loads in basic Tile Layers for his map. I take his method and expand upon it to include a dedicated layer of the map for objects (i.e. players, npcs, items, chests, portals, etc). I'll show you the code first and then explain it.

private static ObjectLayer ProcessFile(ContentManager content, string fileName)
{
    ObjectLayer objectLayer;
    List<List<int>> tempLayout = new List<List<int>>();
    string playerTexture = null;

    using (StreamReader reader = new StreamReader(fileName))
    {
        bool readingLayout = false;
        bool readingPlayer = false;

        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine().Trim();

            if (string.IsNullOrEmpty(line))
                continue;

            if (line.Contains("[Player]"))
            {
                readingPlayer = true;
                readingLayout = false;
            }
            if (line.Contains("[Layout]"))
            {
                readingLayout = true;
                readingPlayer = false;
            }
            else if (readingPlayer)
            {
                playerTexture = reader.ReadLine();
            }
            else if (readingLayout)
            {
                List<int> row = new List<int>();

                string[] cells = line.Split(' ');

                foreach (string c in cells)
                {
                    if (!string.IsNullOrEmpty(c))
                        row.Add(int.Parse(c));
                }

                tempLayout.Add(row);
            }
        }
    }

    int width = tempLayout[0].Count;
    int height = tempLayout.Count;

    objectLayer = new ObjectLayer(width, height);
            
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            objectLayer.SetCellIndex(x, y, tempLayout[y][x]);
            switch (objectLayer.GetCellIndex(x, y))
            {
                case 1:
                    objectLayer.player = new Player(content.Load<Texture2D>(playerTexture));
                    objectLayer.player.Position = new Vector2(x * Engine.TileWidth,
                                                                y * Engine.TileHeight);
                    objectLayer.player.OriginOffset = new Vector2(32, 64); // NEED TO NOT HARDCODE THESE VALUES
                    break;
                case 0:
                    break;
            }
        }
    }

    return objectLayer;
}

The first thing we do here is declare our List<List<int>> for our tempLayout of the map layer. This will allow us to read in each cell of the map from our file. I also declare a string for the player's Texture because the constructor for the player requires a Texture2D and I can't access objectLayer.player until after objectLayer has been instantiated. After the playerTexture, we declare that we're using the StreamReader class and begin reading in our file.

First off inside the while loop we read the first line of the file with string line = reader.ReadLine().Trim();. This reads in the first line of the ObjectLayer file. Here is that file for reference:

[Player]
Sprites/playerSheet

[Layout]
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


As you can see, the first line is "[Player]". This sets the "readingPlayer" variable to true and moves to the "if (readingPlayer)" section of the loop. We then simply read in the path to the player's texture file. Next we move onto reading in the Layout of the map.

This section is very similar to Nick's method, except that after we read in the map to the tempLayout list of list<int>, we loop through the map to do two things. The first is to set each cell index, and the second to run a switch statement on each cell, which at this point only recognizes and looks for a '1' (the player starting cell). Once we have found the player starting cell, we instantiate the objectLayer's player variable and set it's position to that of the cell where it was located in the objectLayer's map.

We use this method in our game1.cs file where we call:

tileMap.ObjectLayer = ObjectLayer.FromFile(Content, "Content/Layers/Objects.olayer");

This line of code is identical to the method used in Nick's Tile Engine, except it is a type ObjectLayer instead of TileLayer. I hope this has been fairly easy to understand, but I understand if it is a lot of code to take in. If you are confused, please read over the code a few times and really ask yourself what each piece is doing. As always, I am willing to answer basic questions about this code and will try to help you out as best I can. Please leave me a comment if you have a question you simply cannot find the answer to.

Until next time!

Wednesday, February 1, 2012

Prospectus Xna Relaunch

Hello everyone, I have exciting news to bring you today! I finally have discovered a way to make Prospectus available to everyone and utilize the ClickOnce feature which will allow for Prospectus to automatically update itself whenever a newer version is available.

My solution actually came about because I recently have been poking around on the dreamincode.net site and have become involved in a project that is hosted on CodePlex.com. Ironically enough, I was digging through their web site today and discovered that ClickOnce applications actually work on that site (my guess is because it is owned by Microsoft, but that may be incorrect).

Anyway, setting up the project was easy and I have uploaded the Alpha 1.0 version here. If you are a fan of the game, please stop by and download a copy (for free) of Prospectus, and it will update itself whenever I provide updates (pretty cool, huh?). Again, thanks for everyone who has followed along with this project and I do apologize for going so long without an update...and yes, for those of you wondering, this does mean that I'm back to using Xna for the development of Prospectus (let's face it, I love programming in C#)

Until next time!

Saturday, January 28, 2012

The Progress of My Platformer

Hey guys, it's been a few days and I thought I would update you on my current project, a classic platformer modeled after that oh so famous plumber we've all heard about before. Again, I'm back to using Xna for this project. For me, it's the simplest and quickest way to make a game the way I want to...through programming. I thought I would show you some video of the game so far. I'm also making an editor for the engine. Both of these started with Nick Gravelyn's Tile Engine series and have since branched off, as he made his engine for an rpg and mine is for a platformer.

On to the good stuff!
Here's a quick demo of the "game" so far (this is more of a tech demo than anything ;) )

I've done quite a few things with this game so far and I plan on going over some specifics with you soon, but for now I leave you with the flashy eye-candy that you've just seen. If you would like for me to cover something specifically that I'm doing in this game, please let me know in the comments. I like writing about game making and I like helping you guys out when I can.

That's all for now!

Thursday, January 5, 2012

Revisiting Nick's Tile Engine Series

Hello and welcome back to this revamped look at game development. The very first thing that I believe every old school rpg needs is a virtual world in which to exist. This world needs to be self-contained, but not flawless.  The first iteration of this world need not have any bells or whistles and only needs to display (in my case) a map of tiles that make it look like an actual world.

This is where Nick Gravelyn's old Tile Engine Series comes into play. I'm going to be going through his tutorial series, modifying where needed to suite my own designs, at least in the first parts of my rpg. I'll try to comment where needed.

The first thing that we need in order to display our tiles is a list of textures for those tiles. We do this by loading in a list of textures:

texture = Content.Load<Texture2D>("Tiles/grass1");
textureList.Add(texture);

texture = Content.Load<Texture2D>("Tiles/dirt1");
textureList.Add(texture);

These lines load individual texture images into a list of Texture2D textures. So far, we are following along with Nick's tutorial exactly.

After we have our list of textures we are free to create a map:

 int [,] tileMap = new int[,]{  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},  
   };  

Using this map we only have to iterate through the 2D array of 1's and 0's to draw our map:

 int tileMapWidth = tileMap[1].GetLength();  
 int tileMapHeight = tileMap[0].GetLength();  
     for (int x = 0; x < tileMapWidth; x++) {  
       for (int y = 0; y < tileMapHeight; y++) {  
         int textureIndex = tileMap[y, x];  
         Texture2D texture = textureList[textureIndex];  
         spriteBatch.Draw(
             texture,
             new Rectangle(
                  x * tileWidth,   
                  y * tileHeight,   
                  tileWidth,   
                  tileHeight),
             Color.White);  
       }  
     }  

The code here sets the width of the tile map to the second dimension of the array, while the height is the first dimension. We then grab the number at each spot in the array and draw the corresponding image indexed to the value of the spot on the 'map' (array). For my map, tileWidth and tileHeight are set to 64.

This is a very basic way of drawing a map in Xna. There is much room for improvement/development and we will be taking our time getting the features of this game fleshed out in order to ensure that this game is fun to play and fun to develop. I appreciate you reading this and welcome any comments, suggestions, and questions gladly.


Wednesday, December 28, 2011

A Fresh Start

Hello everyone! My sincerest apologies for being away for so long. I must admit that I had become burnt out at  making games and wasn't spending enough time actually playing games. But now I am back and ready to get started on what I'm sure every aspiring game developer has thought of making at some point in their programming career, a classic RPG. My favorite types of rpgs are the 2D ones from the days of the Super Nintendo and the old 486 computers that some of you may not even remember. I am therefore going to shift gears with my blog to work on a classic 2D rpg in the style of FF2. I'm going to be taking you along for the ride and showing you and explaining to you what I'll be doing at each iteration of the game, much like I did with Prospectus. I'll be making this game using C#, Xna Game Studio, and Microsoft Visual Studio. I feel that Xna is a great way to take out many of the annoyances that come with trying to design the perfect game loop, or construct the best structure of a game, or ensure that the game updates and draws everything it is supposed to. This will allow me to focus more on the meat and potatoes of the game and leave the rest up to Xna.

I appreciate everyone who follows along with this blog and I again apologize for being away for so long. Here's to a successful venture into the world of rpgs!

Monday, July 18, 2011

Thoughts on the Future of Prospectus

Hey guys it's been a few days now since I released the first Alpha of Prospectus and I must say 'Thank You'. I've seen a great response from you, the community, toward my game and I'm very excited about the future of this game. I've been working hard on adding in new features to the game to make it feel more like a game than just a blank sandbox world and I will be posting on here my updates as I make them.

I am also working very hard to come up with an effective way to make the newer versions of Prospectus automatically download and update your installed version, without requiring you to manually install them each time. I really appreciate everyone who has visited the Prospectus website and I would love to hear any feedback you may have at prospectus.game@gmail.com.

Until next time...

Friday, July 15, 2011

Prospectus Alpha 1.0 Is Here

Hello everyone, I am pleased to announce that I have chosen to name my game Prospectus, as it was the most popular in the poll. I appreciate everyone who voted in the poll and am excited about uploading Prospectus for you to download and play!

I have been hard at work creating a basic website for Prospectus for you to get your free copy of the Alpha 1.0 version. It's been a long time coming that I would distribute a game online and I am very excited to get feedback from the community about Prospectus. I have set up an email address as well that I would like you to direct any comments, feedback, bugs, issues, etc. of any kind to so that I can better organize my Prospectus-related traffic.

Again, I really appreciate everyone who reads this blog and look forward to hearing what you think about Prospectus. Please understand that right now, there is only basic mining and inventory in the game and it is very similar to early versions of Terraria and Minecraft, but rest assured I will be adding unique gameplay features very soon.

There will be detailed instructions on how to install Prospectus on the web site, along with a Read Me text file to assist with installation, basic gameplay, and controls.

You can find Prospectus here and feel free to contact me with any comments and feedback here. Thanks again everyone and have fun!

Sunday, July 10, 2011

Boring Work Before First Build

Hey guys, I know it's been a couple of days since my last post and I wanted to say that I'm still here and still working on the game, though I'm now in the boring part of cleaning up the code that I have before I make this first version ready for download.

I would like to apologize because I do not like to go this long between posts. I'm making minor tweaks to the code that will hopefully make it less buggy when it's ready for download. I'm getting very excited to see what everyone thinks about it up to this point. I would like to say to everyone who intends on downloading it to keep in mind that at this point it is basically a straight clone of Terraria. My plan is to make this game more of a Zelda-style game than a Terraria/Minecraft-style game before I'm done with it.

What do I mean by Zelda-style? I mean more intricate dungeons with bosses in the dungeons, different levels (as opposed to biomes), more NPC interaction with special items awarded (similar to Zelda games), and many more features to come! I hope that everyone appreciates this game and I would ask that anyone who decides to download it and has any type of comment (positive or negative) about it to let me know in a comment or in an email (I'll have an email address set up just for this game by Friday).

Thank you to everyone who follows this blog and game!

Tuesday, July 5, 2011

Alpha 1.0 Preview

Hey guys I'm just giving you a quick update about the latest addition to the game...updated, custom sprites for the player! I am very excited about this latest addition, mostly because I am not really an artist, just ask my wife :)

I'm getting even more excited about launch day, which I am glad to announce will be this next Friday, July 15. I will be uploading the first build of the game, mostly bug-free probably after I get back from the midnight showing of Harry Potter.

I will leave you now with a preview of my player:

And don't forget to vote for what the name of the game should be.

Monday, July 4, 2011

Player Animation Is Here

Hey guys it's been a few days since my last post, but I've been busy adding in one of the last things before my very first release of my game, player animation! I've been busy getting the game ready for it's first release and am pleased to announce that I now have a player in the game instead of just a rectangle.

I will say here that the sprite that I currently have in the game is just a dummy sprite I made for an rpg I was making and will definitely not be the final version of what the player will look like. I'm also including a poll on the blog for some names for the game to see what the popular choice will be for a name.

As for what I did to include player animation, I used a modified version of Nick Gravelyn's AnimatedSprite class and FrameAnimation class in his Tile Engine series for my game. I will likely have to modify those classes even further as the game progresses, but for now it works and that's good enough for me.

The features that you have to look forward to in the first build are,

  1. Basic mining and placing of blocks
  2. Basic inventory that shows the blocks the player has mined (scrollable)
  3. Random map and terrain generation with basic caves
  4. Player sprite with walking animations
  5. Dirt and Rock blocks



I would like to say 'Thank You' to everyone who reads this blog and I hope that you find my game entertaining. I am very excited about where this game can go in the future and look forward to hearing what you guys think of it as well.

Thanks again,
Jeff

Friday, July 1, 2011

Revamping the Terrain and Caves

Hey guys I've been busy reworking the terrain and cave generation code to give smoother and less rigid results. I've also cleaned up the HUD to show less things and not clutter up the screen as much. Enjoy!

Monday, June 27, 2011

Game Demos on YouTube

Hey guys I figured it was about time I upgraded my presentation quality with this game and starting recording some actual "gameplay" for you to see. So without further ado, here is the first in-game video for my Adventure Resource game:



I apologize for the low framerate, I'm still getting use to this new video capture program. I assure you the game runs plenty fast.

Friday, June 24, 2011

Updated Mining Technique

Hey guys it's been awhile since my last post but rest assured I've been working on my game and I do have a cool update to share with you. I now have a much better mining technique implemented where I'm actually using an item with statistics that affect the mining efficiency.

As of now, my first item in the game is a basic wooden pick that can mine blocks at a slow speed with poor mining strength. This makes it take longer to mine certain blocks compared to other blocks. I'm very excited about this new addition because it brings me one step closer to having a working inventory system in my game.

Please check back and thanks for reading about my adventures in making this game.

As always I won't leave you without an in-game screen shot.

Saturday, June 18, 2011

How to add a Basic Inventory

Hey guys it's been a great week here, I have a couple of new things added to my game and I thought I would share them with you. I admit that I have been spending a lot of time this week playing Terraria but I was still able to get some good progress made on my game. The two things I have added this update are

  1. A basic way to add different blocks into the game (still has a long way to go before I'll call it good)
  2. Very basic player inventory showing the block last mined (which I'm going to explain with code in this post)
Now I'm sure a lot of you have read, or been told, or know just from personal experience that when implementing something new into a game, or any software really, it's usually a great idea to create the most basic form of whatever it is you are trying to create. This way there is something to build on and improve on, as opposed to it remaining just an idea inside of your head.

The player inventory is a perfect example of this (in my mind). Instead of trying to create an elaborate inventory system from the start (since I have never made one before), I decided to simplify it and make my inventory (for now) consist of one block (the last block that the player 'mined'). This way I don't have to worry (yet) about managing a list of different items (which I don't even have in the game yet). The way that I do this is simply to add a:
 public Block Inventory;  
In my Player class. This allows me to add other lines whenever I click the left mouse button or right mouse button that (for example) look like this:
 Inventory = TileLayer.blocksDictionary[TileLayer.GetBlock(mouseCell.X, mouseCell.Y).Name + "SingleTop"];  
For the case of left mouse click (which adds the block the player clicked on to the inventory). When the player clicks the right mouse button, I simply have pass the block in the player's inventory to the method that I use to place a block:
 TileLayer.PlaceBlock(mouseCell.X,  
                  mouseCell.Y,  
                  Inventory);  
This very simplistic version of a player inventory is my starting place to expand upon later and add more functionality to it.

And that's the basics of adding in a player inventory. The only trick left to do is display it on the screen (which I do in the Game1.cs file). Basically, I added an itemBackground Texture2D variable with a rounded transparent rectangle as the item background texture. After that I simply told the spriteBatch to draw the item Background and the player's inventory's texture at the top right corner of the screen, thereby displaying a pretty cool new feature in the game. Here's some of the drawing code for a reference:
 spriteBatch.Draw(  
         itemBkgd,  
         hudLocation + new Vector2(titleSafeArea.Width - 42, 10.0f),  
         new Color(48, 48, 48, 100));  
 if (tileLayer.Player.Inventory != null) {  
    spriteBatch.Draw(  
           tileLayer.Player.Inventory.Texture,  
           hudLocation + new Vector2(titleSafeArea.Width - 42 + 16, 26.0f),  
           tileLayer.Player.Inventory.SourceRectangle,  
           Color.White,  
           0.0f,  
           new Vector2(8, 8),  
           1.0f,  
           SpriteEffects.None,  
           0.0f);  
 }  
I hope this has helped you understand that you don't have to have the biggest and best anything when you are first developing it. For most things, it's better to start off with the very basics and add to it as you go along. This helps keep you motivated as well as encouraged to put more things into your game.

And just in case you thought I wasn't going to show the "finished" product:


Check back soon for more updates to my game. On a side note, if you have an idea for a name for this game, leave me a comment because I think it's about time I started calling it something other than 'my game'. Thanks everyone!

Wednesday, June 15, 2011

Terrain Generation Explained

Hey guys I have been putting off writing this kind of a post for awhile (mostly because I didn't feel that my code was 'good enough' to show off), but I've had a request and so I will try and explain my method for terrain generation using a mixture of different techniques.

Let me start by saying that my way is definitely not the only way, or even the best way to create terrain; it just happens to work for me (for now). At first, what I tried to use was the Midpoint Displacement Algorithm for creating a rough sketch of ground-level blocks. This method was ok for the time, but I needed something else that gave me a more 'natural' look. This led me to the Perlin Noise algorithm, which turned out to be fairly easy for me to understand from reading a few good explanations of it. Before I put the code into my game, I also looked at techniques for cave generation, which was even easier for me to understand than the Perlin Noise.

For this reason, I decided to integrate the cave generation first as it was the easier of the two. My method for cave generation involves the classic 4-5 rule which states that a block is a wall if the 3x3 region centered on it contains at least 5 walls. Repeating this process n times gives decent looking caves in the map. The entire process is modified slightly in the last two iterations to further refine the shape of the caves and make them appear more 'natural'. Here is some code for example:

 private void CreateCaves(int i) { // i == Number of iterations  
      if (i == 1) {          
         for (int y = Height / 10; y < Height; y++) {            
           for (int x = 0; x < Width; x++) {  
             // Percentage needs to be 60% to make 40% filled  
             // NOTES 06/10: Perlin Noise method functional and not bad,  
             // "Poking holes" cave creation method pretty good.  
             // NOTES 06/14: Making the percentage 55% / 45% is pretty good  
             // with the addition of possibly skipping over the block if the   
             // depth is too little  
             if (rand.Next(100) <= 55) {  
               // PUTTING HOLES IN COMPLETELY FILLED MAP  
               // AS OPPOSED TO PUTTING BLOCKS IN EMPTY MAP  
               blocks[x, y] = LoadBlock('.', x, y);  
             }  
             else if (y < Height / 7)  
               continue;  
           }  
         }  
       }  
       else {  
         int neighboringWalls = 0;  
         string blockName = "";  
         for (int y = Height / 10; y < Height - 1; y++) {  
           for (int x = 1; x < Width - 1; x++) {  
             if (blocks[x - 1, y - 1].Texture != null) {  
               blockName = blocks[x - 1, y - 1].Name;  
               neighboringWalls++;  
             }  
             /////// Some block tests removed to shorten code \\\\\\\\\  
             if (blocks[x - 1, y].Texture != null) {  
               blockName = blocks[x - 1, y].Name;  
               neighboringWalls++;  
             }  
             if (i >= 4) {  
               if (neighboringWalls >= 6)  
                 blocks[x, y] = blocksDictionary[blockName + "SingleTop"];  
             }  
             else {  
               if (neighboringWalls >= 5)  
                 blocks[x, y] = blocksDictionary[blockName + "SingleTop"];  
               else if (neighboringWalls <= 2)  
                 blocks[x, y] = LoadBlock('.', x, y);  
             }  
             neighboringWalls = 0;  
           }  
         }  
       }  
     }  

The main difference between my code and the algorithm in the link I provided is that instead of filling in an empty map, I'm poking holes in a completely filled in map. This in my opinion gives different and better results for me.

After I added the cave generation to the game, I felt confident enough to tackle the Perlin Noise algorithm. Using the method provided in the link I gave above, I produced this code to create my surface terrain:

 private int[] CreatePerlinNoise() {  
       float[] values = new float[Width];  
       int[] realValues = new int[Width];  
       for (int i = 0; i < values.Length; i++) {  
         values[i] = PerlinNoise(i);  
         values[i] *= 10;  
         realValues[i] = (int)Math.Ceiling(values[i]);  
       }  
       return realValues;  
     }  
 private float Noise(int i, int x) {  
     if (i == 0) {  
       x = (x << 13) ^ x;  
       return (float)(1.0 - ((x * (x * x * 557 + 1049) + 2411) & 0x7fffffff) / 1073741824.0);  
     }  
     else if (i == 1) {  
       x = (x << 13) ^ x;  
       return (float)(1.0 - ((x * (x * x * 1303 + 2473) + 3229) & 0x7fffffff) / 1073741824.0);  
     }  
     else if (i == 2) {  
       x = (x << 13) ^ x;  
       return (float)(1.0 - ((x * (x * x * 4441 + 6277) + 7549) & 0x7fffffff) / 1073741824.0);  
     }  
     else {  
       x = (x << 13) ^ x;  
       return (float)(1.0 - ((x * (x * x * 4663 + 6007) + 6961) & 0x7fffffff) / 1073741824.0);  
     }  
 }  
 private float SmoothedNoise(int i, float x) {  
     return Noise(i, (int)x) / 2 + Noise(i, (int)x - 1) / 4 + Noise(i, (int)x + 1) / 4;  
 }  
 private float InterpolatedNoise(int i, float x) {  
     int y = (int)x;  
     float fractionalX = x - y;  
     float v1 = SmoothedNoise(i, y);  
     float v2 = SmoothedNoise(i, y + 1);  
     return MathHelper.Lerp(v1, v2, fractionalX);  
 }  
 private float PerlinNoise(float x) {  
     float total = 0;  
     float p = 0.5f; // persistance  
     int n = 4; // four octaves  
     for (int i = 0; i <= n; i++) {  
       float frequency = 2 ^ i;  
       float amplitude = (float)Math.Pow(p, i);  
       total += InterpolatedNoise(i, x * frequency) * amplitude;  
     }  
     return total;  
 }  

A high-level explanation of what happens in a Perlin Noise algorithm (as I understand it) is that the final product is an array of y values (for height) that is the size of all the x values in the map. To get these values, we basically generate random numbers for every x value in the array and linearly interpolate between them to 'smooth out' the shape of the terrain. The link I provided above was, for me, the best explanation I could find about how to make a Perlin Noise algorithm.

I am by no means the expert on Perlin Noise but if you have any questions please feel free to leave a comment below. This is a very basic overview of my technique for creating terrain and it is by no means the only way or the best way. Also, I intend to modify this technique before my game is complete, so feel free to use my code in your own projects, although it may not work with your specific game.

As always, thanks for reading and I will give a game update as soon as I have one.

Sunday, June 12, 2011

New Block Type

Hello everyone, I have a game update to share with you. As of tonight, I have a rudimentary way of random inserting a new block type into the game world. Right now, I'm only using dirt and coal (new) blocks. I'm pretty excited about this newest addition to the game, as it will allow me to begin work on other things such as the player's inventory.

My method for putting coal blocks in the game is pretty simple at this point. First, I loop through all the blocks in the map, looking for the first non-null blocks (meaning that this block is theoretically the ground level for this particular column). I then loop through the current column and have a set of 'if-then-else' conditions that check if the column block in question is at a certain depth. Based on the depth there is a chance that the block will be a coal type, otherwise it is a dirt type.

I'm sure there are many other more sophisticated ways to randomly put different block types into the map, but for now this method will do just fine for me. I appreciate everyone who is following this game's progress and I will continue to provide updates as I make changes and improvements to the game.

Saturday, June 11, 2011

Caves caves caves!

Hello everyone I am very tired but I thought I should write an update of my game. I have been working feverishly on cave generation using a form of Cellular Automata and so far I have had decent results. I am still tweaking the algorithm to give more natural "cave-like" structures that connect to each other better, but for now I am pleased with my cave making skills.

I am also still working on using Perlin Noise to generate the shape of the terrain at the surface level, though this cave generation turned out to be easier (which is why I worked on it first). I am really excited with how this game is coming together and I believe a name needs to be created for this game (hopefully name chosen soon!).

I really appreciate everyone who reads this development blog and I try to provide updates as frequently as I can. Thanks for reading and check back soon for more news!

Thursday, June 9, 2011

Dynamic Block Texturing Is Up

Great success! After too many days of struggling with the code to get the blocks updating their textures based on what blocks are neighboring around them, I finally have a working build that looks really good. The main trouble I was originally having was that I was trying to test for too many cases, which overcomplicated the entire thing.

What I first tried to do was test a block's eight neighbors to determine which texture should be used for that block. This was over-complicating the process; not only did I have to have the six textures for the simple left, right, top, bottom scenarios, but I also had to have textures for all of the possible corner cases. This left me very frustrated and in need of something else to do.

The solution to my problem was very easy in fact. What I did was shrink the block size from 32 x 32 to 16 x 16 and dropped the corner cases / corner textures. Please note that when I say corner textures I'm referring to a piece that has a corner cutout of it. I also created new textures for the blocks with edges that seemingly run together. This makes the cases in which there is an L-shape still look good in the corner spot because the top and right textures almost run together.

Other things that I did include changing the resolution to classic 800 x 600, changing the player sprite from a square to a thinner, taller rectangle (to more closely resemble the final sprite's size), and am running an UpdateBlock() method every time the player removes and adds a block (which updates the surrounding blocks' textures based on which action the player made).

The game is coming along nicely in my opinion. Next things on the list include better terrain generation, more types of blocks, player inventory, and many more things that I don't want to list for fear of getting overwhelmed by it all.

For now, please enjoy a screenshot of my small (but big to me) victory.