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 19, 2012

Revisiting SDL and C++, a Log Class

Hello again, while I feel like I'm making progress with Nick Gravelyn's Tile Engine series in C#, I also want to brush up on my SDL/C++ programming, as I feel like that would be the most applicable to professional game studios. Therefore, I have decided to focus on making a simple shmup (shoot 'em up) while also working on the Rpg in C#. This new project will be in C++ using SDL (if you are unfamiliar with SDL, please take the time to read up at lazyfoo.net). It will be in the classic 2D style that you would have seen in an old SNES game.

I am very excited about this new venture and I anticipate this will help me complete one of my goals for this new year, actually finishing a game. By the way, for those of you wondering, I do plan to return to Prospectus in the future. Let's begin our new project with a basic overview. I am going to do some basic game framework coding in the beginning that can be reused in other game projects as well. I am following stayscrisp's tutorials over at dreamincode.net. After getting through the first 4 tutorials, we find that we have a basic game up and running with basic game state management, which will benefit us later on when we don't have to write that code after the game is done. I have followed his tutorials pretty much to the letter until this point and will quickly venture off and write my own code soon.

The first feature that I'm going to add to this basic game engine is the ability to have a global logging system that can be used to give feedback from the game via a log.txt file. This gives us a great debugging tool from the start because we can use this to monitor our game's activity while it is running. To start, we need a Logger.h added to our project. Here is the code I wrote for this class:

#ifndef Logger_H
#define Logger_H

#include <fstream>

class Logger {
    public:
        static Logger* Instance();
        bool open(const char* file);
        void log(int level, const char* message);
        bool close();
        
    private:
        Logger() {};
        Logger(Logger const&) {};
        Logger& operator=(Logger const&) {};
        static Logger* m_Instance;
        std::ofstream logFile;
};

#endif

You can see that we are making this class a singleton by creating an Instance() method that is static and returns a pointer to the Logger class. This will make sure that there is only one instance of this class at any one time in our game. The open() and close() methods are straight forward; they open and close the log file. The log() method is also very basic; it takes an integer to define the warning level of the message, and a string (const char*) for the actual message of the particular log entry.

Next up we have the Logger.cpp file to add to our project:

#include <iostream>
#include "Logger.h"

// Global static pointer used to ensure a single instance of the class
Logger* Logger::m_Instance = NULL;
    
// This function is called to create an instance of the class.
// By calling the private constructor through this method, we
// ensure that there is only one instance of this class at any point.
Logger* Logger::Instance() {
    if (!m_Instance) 
        m_Instance = new Logger;
        
    return m_Instance;
}

bool Logger::open(const char* file) {
    logFile.open(file);
}

void Logger::log(int level, const char* message) {
    switch (level) {
        case 0:
            logFile << "Debug - " << __DATE__ << " " << __TIME__ << " | " << message << std::endl;
            break;
        case 1:
            logFile << "Warning - " << __DATE__ << " " << __TIME__ << " | "  << message << std::endl;
            break;
        case 2:
            logFile << "Critical - " << __DATE__ << " " << __TIME__ << " | "  << message << std::endl;
            break;
        case 3:
            logFile << "Fatal - " << __DATE__ << " " << __TIME__ << " | "  << message << std::endl;
            break;
        default:
            logFile << __DATE__ << " " << __TIME__ << " | " << message << std::endl;
            break;
        }            
}

bool Logger::close() {
    logFile.close();
}

You can see that we create an instance of the class in the Instance() method. We also open and close the file in the open() and close() methods. The log() method uses a switch statement to determine which message to output, based on the level that was passed to the method. The __DATE__ and __TIME__ macros are a great addition as well, because they show us what time stamp the message was created at. And that's it! The Logger class is complete. Now to use it anywhere in the game all we have to do is make sure we include the header file in the .cpp file we want to use the Logger class, then call the log() method like so:

Logger::Instance()->log(-1, "----------------Game Initialized-------------\n");

or...
Logger::Instance()->log(-1, "PlayState has been loaded");

or...
Logger::Instance()->log(3, "Game failed to start, Quitting game now.");

Thanks everyone for reading and make sure to check back often as I will be making progress updates and simple informative posts such as this one in the future.

Monday, January 9, 2012

2D Vector Art Made Simple

Hello all, I just wanted to take a minute to point out a great blog for 2D vector art. Here art is made simple and understandable, and the target audience is programmers like myself. The blog is 2D Game Art For Programmers and I highly recommend it for anyone looking to create simple vector art for their games. Please take a few minutes and visit the blog to see for yourself!