Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

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, 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!

Tuesday, August 16, 2011

How to Setup JDeveloper with Slick2D

I know we have all struggled with something like this at one point in our coding and usually the first thing I will do is head to Google to find out if anyone else has had the same problem and figured out how to fix it. This post is an explanation on how to setup a game project in JDeveloper 11G to work with the Slick2D library for your games. I have spent many hours working on this in order to make sure how it works and so that I'll be able to explain it better. Please feel free to comment or email me with questions if this is confusing and you need further help setting up your game.

In this post I will assume that you are starting off from the beginning and don't even have the JDK downloaded. 

Firstly, head over to the downloads section on the JDeveloper website and download the version of the Java Development Kit (JDK) that you wish to use. Note that JDeveloper and Slick2D work better with 32 bit versions of the JDK. I downloaded the 32 bit version of JDK 1.6.0_26 even though I have a 64 bit computer (below)



Secondly, after the JDK has downloaded, click on the .exe file (the one you downloaded) and allow it to install the JDK onto your computer. The default settings are what you want for this install, so feel free to click Next until it installs.

After the JDK finishes installing (Default location is C:\Program Files (x86)\Java), return to the JDeveloper site and download JDeveloper. The "Generic Release Java Edition" is all that is necessary unless you plan on developing enterprise websites with elaborate databases on the side (below). Note that Oracle will require you to create a FREE account in order to download JDeveloper.

After you have downloaded the .zip file from Oracle, extract it to a place on your computer (C:\oracle, for example). It is recommended you place all of the files in a location that does not contain any spaces in the path (for example "C:\oracle", not "C:\my oracle"). The next thing I recommend doing is opening the folder where you just extracted all of the contents from the .zip file to and right click on the "jdeveloper.exe" file to create either a desktop shortcut or a taskbar shortcut, as this will be a much faster way to open JDeveloper than navigating to the directory and clicking the .exe every time. 

Next, open up JDeveloper by either clicking on the jdeveloper.exe file or by clicking on the shortcut you just created. Note that JDeveloper will open a window asking you to enter the path to the JDK folder you downloaded earlier. If you installed the JDK to the default location you need to enter (or browse to) C:\Program Files (x86)\Java\jdk1.6.0_26\bin\java.exe and click OK. After this, JDeveloper may pop open a window that asks you if you want to migrate settings from a previous version of JDeveloper to this one, in which case you should click NO (because there is no other version of JDeveloper on your computer). After this, JDeveloper should open up to the start page not present any other message windows (aside from the "Tip of the day" window).

Now, let's create our first application and project. Click File > New > General > Application and enter the name of the application (SlickTest will work just fine) and click Next, then fill in the project name (project1 will do) and then click Finish. 


Next, right click on your project in the Application Navigator and click New

This will open the same window that opened when you created your application. This time, however, we are going to choose Java Class

Click OK and you will be prompted to fill in some basic info for the class (Name, package, etc.)

I recommend matching it to what I have shown above. Click OK and your new class will open in the main window of JDeveloper.

Now let's take a break from JDeveloper and head over to the Slick2D website to download the library. On the right hand side of the main page, click on the link that says "Download Full Distribution" to get a zip file that will have everything we need in order to run our Slick games. Next, I recommend navigating to your project's folder and creating a \bin, and a \lib folder for our Slick2D library items. Optionally, you can create a \content folder for all of your game's assets (images, music, fonts, etc.).

These folders will be referenced from inside JDeveloper (our project's properties, specifically) later on. Next, extract the files from the Slick2D download to a temporary place (Desktop works just fine). Once that is done, create a folder inside of the lib folder in your project and call it Slick2D (\lib\Slick2D). Place everything except for the .dll files from the download into this new folder. Now take the .dll files (four of them, to be precise) and place them inside the bin folder in your project. This is a fairly standard way of packaging your game with the library files it will need in order to be distributed to other people (and work properly).

Now, go into JDeveloper and right click your project's name and select Project Properties. This is where we will setup the Slick library in our project. Click on the Libraries and Classpath node and on the right sight of the window click on Add Library. We will then select New because JDeveloper has no idea about our Slick Library (we haven't created it yet). Now fill out the information as I have it below

It is important that you include all of the .jar files except for slick.jar from the \lib folder. Now click OK and you will return to the libraries screen where you will select Slick2D and click OK. Now you should be back at the Project Properties window and your new Slick2D library will be included in your project. Now click Add Jar/Directory and navigate back to the \lib folder and add slick.jar.

Now you are nearly done with setting up the Project Properties. From the Project Properties window, click on the + sign next to Project Source Paths and click on the Resources node. Click Add and add the \content folder you created earlier. This will allow you to begin your resources' filenames from the content folder (instead of the project folder).

Next click on the Run/Debug/Profile node and click Edit. Under the Java Options text box, add this:

-Djava.library.path=bin

This will tell JDeveloper to look in the bin folder of your project for the .dll files we put there earlier.

Now click OK until you have closed the Project Properties. Now to test your setup and create a basic Hello World game you will need to modify the Game.java file. To keep it simple, modify your Game.java class so that it looks just like this:
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

public class Game extends BasicGame {

    Image background;

    public Game(String title) {
        super(title);
    }

    public void init(GameContainer container) throws SlickException {
        background = new Image("helloWorld.png");
    }

    public void update(GameContainer container, int delta) 
        throws SlickException {
    }

    public void render(GameContainer container, Graphics g) 
        throws SlickException {
        background.draw();
    }

    public static void main(String[] args) throws SlickException {
        AppGameContainer app = new AppGameContainer(new Game("Game Test"));
        app.setDisplayMode(640, 480, false);
        app.setTargetFrameRate(60);
        app.start();
    }
}

One last thing to do is create a Hello World image like this one:

and place it in the \content folder in your project.

Now click the Run button (Big Green Arrow) and with any luck, your game will start up in no time! I really hope you have learned something from this post and are able to use Slick2D in JDeveloper. Please feel free to comment or email me with any questions you may have.

Friday, August 5, 2011

Java 2D TileMap Code Optimization

Hey guys, just thought I would give you guys a quick tip on 2D tile map optimization that's been helping me in this transition from Xna to Java. Normally what I do in this kind of a game is have a 2D array of tiles (Tile class) which make up the contents of the map. I then set each tile to be the appropriate kind of tile (i.e. dirt, grass, rock, etc).

With this new Java version of Prospectus though, I thought I could do a little better than that, so I set off to find a different way to get the same result. I came up with the idea of using a 2D array of characters instead of tiles. I then use that character map to decide what tile I need to draw in my draw method, as I need it. I then use a few different methods that allow me to retrieve the correct type of tile to draw/do calculations with for a specific x and y coordinate on the map, solely based on what character is that the x and y coordinate.

This, I believe, saves me time and speeds up the execution of my code. Instead of having to keep each tile on the entire map in memory, now I only care about the tiles that are on the screen (plus a couple rows and columns for cleanliness). This also helps with start-up time because I'm setting character literals instead of user-defined class instances.

I hope this has given some of you ideas on how to improve your own games in Java or C#/Xna (this method will work for either language). As I near completion of the port to Java, I'm getting more and more excited about where Prospectus can and will go in the future. Thanks for reading and be sure to check back soon for more updates.

-Cheers

Thursday, July 28, 2011

Extreme Makeover: Prospectus Edition

Hey guys I am very excited to bring you more news about Prospectus. I'm sorry it's been so long since my last post, but I have been busy making some changes that I hope will benefit more people down the road. Over the past few weeks I have been struggling with developing Prospectus only for .Net capable machines. I feel like I would be able to reach more people with Prospectus if I was not tied down to .Net machines. I have therefore decided to migrate the existing version of Prospectus (as well as continue on from here) to the Java language using Netbeans and the Slick2D Library.

It is my intention that more people will be able to play this game because I'm making it more platform-independent than before. I hope this does not upset too many people who were using this as an Xna-specific learning tool. I will do my best to make any code-related posts as generic as possible in order to continue to be useful and informative for the Xna community.

As always I want to thank everyone who reads this blog as it is a huge motivational tool for me to keep working on Prospectus. I will be bringing you new posts as soon as I finish porting the existing version of the game to Java, but in the meantime I hope you take the time to try out Prospectus for yourself and don't lose faith in me...I'm going to keep building this game into something great.

Until next time!

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...

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!