Tuesday, March 17, 2009

'Pascal Gamer' Concept Cover

Well after seeing that there had been very little exposure of Pascal-based projects since PGD had it's major upgrade, I decided to take up the magazine project that had been started under the name 'Delphi Gamer' a while back. I'm asking for content from those that can write something about game development, their own experiences or projects or tricks and tips for graphics, audio or library specific topics.

The cover you see to the right is only a concept and will most likely drastically change by the time the issue is out. Please tell me what you think. Any ideas about content or the magazine it's self are most welcome.



You can read the PGD forum thread about the new online magazine here: http://www.pascalgamedevelopment.com/forum/index.php?topic=5670.0

Sunday, March 15, 2009

I made Water!

I've been pondering making some actual 3D water effect for my latest project, Garland's Quest for quite some time now. Well I've finally gotten around to doing it. Actually this is my first actual 3D program so yay for me! :)



I have used 2 layers; 1st is an animation using Caustics lighting, the 2nd layer goes on top and uses a static texture that is instead drawn on a wavy sinusoidal shaped plane consisting of a 40 x 40 grid. (3200 triangles) I gave the 2nd layer a transparency of 40%. Looks much nicer in motion than as a still image, but the above image is the best I could do on short notice.


Caustics Generator:

Free Caustics Generator program


Water Demo:

Download (1 MB)

Wednesday, March 11, 2009

Canceled Projects: Cyber-Crisis

This was my first crack at doing a 2D platformer. I had a gritty back story and whole plot line planned out for it. Unfortunately it fell prey to a common mistake I made in all my earlier projects, it was a content nightmare!

Yes, what you see is great and amazing looking, but that just doesn't do it when you cannot pay for or do the amount of graphical work required that goes with this type of game.

The graphics that I'm showing off here are from that of Keirren Small, a very talented fellow who also worked with me on one of my current projects, Garland's Quest. Together we designed the main character's look based off some random artwork that I gathered to generate ideas and tell my story. He did an amazing job and this game would have been quite the eye candy if we had the time and money to complete it. Unfortunately only these concept images and the start of a platform engine remain.


Brief Synopsis

You are a prototype robot based on revolutionary new technology developed by a brilliant scientist who had intended to use it for good and honourable purposes.

However as fate would have it, the good doctor was hunted down, killed and his research stolen by a militant organization ran by a power-hungry madman. Fortunately for you, and for all that is decent still, the good doctor found out of those wanting his demise and put in place emergency measures to be carried out in case of such an even.

In the evacuation however, the escaping convoy carrying his prototype work was attacked and was assumed lost.

60 years later, you wake up to find a darker world that awaits you.


Concept Imagery





Game Engine Source

Download (1.4 MB)

Feel free to download and make use of my source. Please credit me if you do! It is written in Object Pascal. You'll need to get Lazarus and JEDI-SDL to compile it. Uses OpenGL for graphics and SDL for the rest. Enjoy!


More About the Project

I had posted quite a bit on my plans throughout the making of the project. Feel free to have a look to see how my creative process was working for me back then.

My old post on PGD

Monday, March 9, 2009

Artillery Game Tutorial: Part 2 - The Dirt

Introduction

Hey guys, now that the intro and all the dull stuff is over with, we can get right into the goods! Playing in the dirt. :D

In this first lesson I'm going to show you how to generate a nice random 2D battle ground for your tanks to kill each other in. You'll be able to then display it on top of your sky background that will either be a single color or the nice bitmap I've included or one of your own making.

OK enough with the explanations, lets get right into the code!


Some More Files

OK, I know that I've already given you some files to start with in the intro, but these ones will be the beef of our game code now. Here is what they are for;

GameConstantsUnit.pas -- All the default settings for our game.
GameObjectUnit.pas -- Houses all our game objects. As I mentioned before in the intro we'll be using OOP.




Game Constants

Lets get this one out of the way shall we? I'll be supplying this file at the end of this tutorial, but if you wish you make simply copy and paste the following code into the file named GameConstantsUnit.pas.

unit GameConstantsUnit;

interface

const
  LandSmoothing  = 50;
  LandVariation  = 60;
  LandHighest    = 500;
  LandLowest     = 1;

implementation

end.


I will explain these values later on as they are needed.


TBattlefield Object

This is our battlefield object which we will make generate our dirt.

type
  TBattlefield = class(TObject)
    Width, Height: Integer;
    LandHeight: Array[0 .. 1024] of Integer;
    LandColor, SkyColor: Cardinal;

    isBGImage: Boolean;
    Background: PSDL_Surface; // Background Graphic

    constructor Init(ScreenWidth, ScreenHeight: Integer; Land, Sky: Cardinal; useBGImage: Boolean; BGImageFile: String);
    procedure GenerateLand(Highest, Lowest, Variation: Integer);
    procedure SmoothenLand(SmoothSize: Integer); // Tries to smoothen rough generated land!
    procedure DrawSky(GameScreen: PSDL_Surface);
    procedure DrawLand(GameScreen: PSDL_Surface);
  end;


Init() will create the battlefield object!
GenerateLand() will do the initial generation of the shape of the land.
SmoothenLand() will help make the land more usable in the game.
DrawSky() will draw our sky background.
DrawLand() will draw the land we generate.


Initializing The Battlefield

I don't see a need to go into great depth here so here is the function straight out.

constructor TBattlefield.Init(ScreenWidth, ScreenHeight: Integer; Land, Sky: Cardinal; useBGImage: Boolean; BGImageFile: String);
begin
     Width := ScreenWidth;
     Height := ScreenHeight;

     LandColor  := Land;
     SkyColor   := Sky;
     isBGImage := useBGImage;

     // Load Background
     if (useBGImage) then
        Background := LoadImage('images\\' + BGImageFile, False);
end;


ScreenWidth & ScreenHeight are the dimensions of the game screen you'll be using.
Land & Sky are the colors of the land and sky.
useBGImage is the switch for using a bitmap instead of a solid single color for the sky background.
BGImageFile is the filename within the images directory of the bitmap to load into the Background surface.


Initial Generation

To generate our land we're going to go through it in a couple of passes. Once to get the general shape and then again afterward to make it a little more practical for the game's use. But for now lets look at how we'll get the basic 'shape' of the land we want.

GenerateLand() uses 2 values to keep the surface of the dirt with a high and a low range. There are Highest and Lowest.

Have a look at this example to see what effect this has...



Notice how the peeks will never go above the Highest value and the valleys will never go below the Lowest value?


Now we have to figure out the rate of which we the land will vary as we go along the surface. We could simply use a random value between Lowest and Highest but that wouldn't produce a very nice shape for our land.

Instead what we'll do is have a Variation value that will govern the change in the heights of each segment of land from left to right. Each segment will be 1 pixel wide for the most precise effect!

Here's our function...

procedure TBattlefield.GenerateLand(Highest, Lowest, Variation: Integer);
var i: Integer;
    rand: Real;
begin
end;


So lets go from left to right as this is most logical way. We should start with a totally random value between the Lowest and Highest as a starting height to work from.

     LandHeight[0] := Lowest + Round(Random * (Highest - Lowest));


Of course we will want the land to randomly go higher and lower so we'll allow the new height of each segment to either go up or down within the range of Variation.

     for i := 1 to Width - 1 do
     begin
          repeat
            rand := Random;
            LandHeight[i] := Round(LandHeight[i - 1] + (rand * Variation) - Variation / 2);
            if (LandHeight[i] < Lowest) then
               LandHeight[i] := Lowest;
          until (LandHeight[i] <= Highest);
     end;


Here you see we cycle through each segment along the x-axis and calculate a height for the land based on the previous calculated height.

If the land travels higher than the Highest range, it will recalculate another random height until it fits under the required range. Also when a height value is created lower than Lowest it will, instead of recalculating the height, level the height to the Lowest value.

Both high and low values are treated this way to simulate peeks and valleys in a more realistic way.

Our completed function should look like this...

procedure TBattlefield.GenerateLand(Highest, Lowest, Variation: Integer);
var i: Integer;
    rand: Real;
begin
     LandHeight[0] := Lowest + Round(Random * (Highest - Lowest));
     for i := 1 to Width - 1 do
     begin
          repeat
            rand := Random;
            LandHeight[i] := Round(LandHeight[i - 1] + (rand * Variation) - Variation / 2);
            if (LandHeight[i] < Lowest) then
               LandHeight[i] := Lowest;
          until (LandHeight[i] <= Highest);
     end;
end;



Smoothen Out The Land

So now we have our land, but it's very jagged, ugly and unusable. Worry not! This can be done quite easily with a 2nd pass on the land height values. :)

The technique that I will be using to create more usable land will involve passing through a set of the initial generated land. It'll take a number of segment values from the left and right sides of the current segment and calculate an average which it will be changed to. The value SmoothSize will determine the amount of samples on each side.

You will also notice that we must stay within the bounds of the screen so we will be checking that the code that gathers the average from other segments does not drift off the screen.

This will be our function to do this...

procedure TBattlefield.SmoothenLand(SmoothSize: Integer);
var i, j: Integer;
    Mass, NumOfMassSamples: Integer;
begin
     for i := 0 to Width - 1 do
     begin
          // Get average height of selected area...
          Mass := 0;
          NumOfMassSamples := 0;
          for j := i - SmoothSize to i + SmoothSize do
              if (j > 0) and (j < Width - 1) then // Samples must be in bounds!
              begin
                   inc(NumOfMassSamples);
                   Mass := Mass + LandHeight[j];
              end;

          // Resize LandHeight element
          LandHeight[i] := Round(Mass / NumOfMassSamples);
     end;
end;


Mass is the total added height of all of the segments within the SmoothSize area including it's own height.
NumOfMassSamples is the count of how many actual samples were taken regardless of the value feed into SmoothSize.

This should give you a relatively nicer result and land that you can actually use to place tanks on and have them accurately aim and fire at each other.


Drawing It

Ok so now that we've got our nice land generating functions, I'm sure that you'll want to actually see it in action. So here is our drawing code...

procedure TBattlefield.DrawLand(GameScreen: PSDL_Surface);
var
  i: Integer;
begin
     // Land
     for i := 0 to Width - 1 do
         SDL_DrawLine(GameScreen, i, Height - 1, i, Height - 1 - LandHeight[i], LandColor);
end;


NOTE: It makes use of the sdlutils unit so make sure that it's included in the uses path of GameObjectUnit.pas

Pretty simple huh? :)

The DrawSky function is rather simple too. It will either draw a solid sky color or a stored bitmap surface.

procedure TBattlefield.DrawSky(GameScreen: PSDL_Surface);
begin
     if (isBGImage) then
         DrawBackgound(GameScreen, Background)
     else
         SDL_FillRect(GameScreen, PSDLRect(0, 0, 800, 600), SkyColor);
end;



Putting It All Together

Now we'll create our battlefield object, run the land generator and draw everything to the screen.

In scorch2d.lpr add the following under var at the top of the code...

  // Level Data
  Level: TBattlefield;


While there, also remove the following line of code...

Background: PSDL_Surface; // Background Graphic


It will be replaced by TBattlefield.Background and is no longer needed for testing.

Find the ProgramCreate; procedure and remove the 2 following lines of code.

     // Load Background
     Background := LoadImage('images\\DesertEclipse.bmp', False);


Go down to the main code block and add the following code after ProgramCreate;...

     Level := TBattlefield.Init(GameScreen.w, GameScreen.h, $229900, $0000ee, True, 'DesertEclipse.bmp');
     Level.GenerateLand(LandHighest, LandLowest, LandVariation);
     Level.SmoothenLand(LandSmoothing);


Now the only thing left to do is add the code to draw the sky background and generated land. Find DrawScreen; and add this as the top 2 lines...

     Level.DrawSky(GameScreen);
     Level.DrawLand(GameScreen);


That should do it. Considering you pieced TBattlefield together properly you should be able to press F9 to compile and run the code. Remember that it's the Esc key to quit!


The Source

Here is the complete updated source that shows how it's all done together.

Download the source files here!


End of Part 2

So now we have our randomly generated dirt to place tanks on and plow shells into. In the next part I'll be showing you how to place our tanks randomly about the land we've generated and do so in a smart manner.

Until then, play with the code a little bit and see what else you can do with it. There is lots of room for innovation here.

Suggestions, helpful code snippets and kudos are welcome! :)

Artillery Game Tutorial: Part 1 - Introduction

Introduction

Welcome to the first in a series of tutorials that I hope will help new developers and fans of the genre. When I first started to learn about computers and even before I got serious about programming, one of the first PC games I ever owned was a shareware game called 'Scorched Earth'. It was a cleverly designed game where you were in a tank against up to 9 other tanks on a landscaped 2D screen, and the main idea was to try to destroy all of them and be the last one standing to win the round. Do this for a chosen number of rounds and whoever has the highest score at the end, wins the game.

In addition, you had many nice features where you could buy all kinds of different weapons and items to aid you in fighting. This money was earned as you played and destroyed other tanks for points. Different tank types, fuel to get around, levels of computer AI, randomly generated yet configurable land and many other things that made this an exciting, addictive and extremely fun game. The 'Artillery Game' genre was born, and I was hooked!

You may have also played a more recent game that is based on the same concept of game play called 'Worms'. It also falls under this genre. It has had several sequels that have been leading the way of this type of game adding new things in each edition of the series.


Throughout this tutorials series I will be teaching how to design an Artillery Game yourself. It will feature the basics of the game play and then move on to the many neat features and systems you see within these great games.



Scorched Earth 1.5



What do I need before we start?

I will be using Lazarus and JEDI-SDL to create the game. I however, will not cover how to use Lazarus or JEDI-SDL. This does not mean that if you have not used it before you will not be able to follow along. The concepts and game play design will be independent of this. You may substitute with any Object Pascal compiler/IDE or graphics library you like instead.

I will also be making use of objects using Object Pascal. I will assume that the reader knows at least the basics of 'Object Oriented Programming' or OOP for short. This will help to keep the code clean and manageable as we go though it's development.

Though you do not need to know a lot of math for this game, it would most certainly help in some cases. More specifically with the game physics portion where we get into a small bit of trigonometry. But it is not by any means an obstacle, so please read on!


Direction and Scope

Like all tutorials, I will start by covering the basics first. We will create the game as we go along separating each step so that it'll make for easy consumption and act as a reference for later.

We'll start off in the 2nd installment with how to generate the battlefield, draw and display it. Then in the 3rd, placing the tanks into the battlefield. After we'll move along to the tank controls, the game's physics for fired shots and collision detection. Then we'll later learn tank damage, wind and weapons explosions. These are the basic features of the game before you can go ahead and make it all fancy afterward.



Worms World Party



And now, our humble beginnings; Enter The Code!

We will start out with the main source that we will build upon and GraphicsUnit.pas to help speed along some of the graphics handling.

When run it should show the included background scene. You can then press Esc to close the program. If you are new to JEDI-SDL or even Pascal then you will be able to play with this further to get a better grasp of how to work with the two before you jump onto Part 2.


Download the source files here!


Setup

The project file included already has Delphi Compatibility mode enabled, which is required. But ensure that you have it on in case you are copying and pasting my code into a new project of your own making.

You will need to supply the path to the JEDI-SDL folder for the sdl header!

In Lazarus go to Projects -> Compiler Options... and click on the Paths tab. There in the Other Unit Files (-Fu) field change C:\Documents and Settings\WILL\My Documents\Pascal Projects\JEDI-SDLv1.0\SDL\Pas\ to match the path of your own copy of JEDI-SDL.

Lastly, since I have not supplied the sdl.dll file along with the source, you will be required to make a copy of the file to their the source directory or a location within your system's path.

Once complete you should be able to compile and run it without any problems!


End of Part 1

That's it for now. In the next tutorial, 'The Dirt' we'll start to get into the good stuff where we'll be creating the play-field on which we'll be causing our mayhem! ;)

Saturday, March 7, 2009

Welcome to My First Blog!

Hey everyone! After years of reading so many blogs of fellow developers and enthusiasts, I've finally decided to buckle down and start my own. I'm hoping that this format will be a fun way to show off some of my own personal projects that I have been working on over the years.

A few of my first few posts will obviously be to show off some of my past works with screenshots of course. And maybe even some source code for those new Object Pascal programmers just waiting to make their first masterpiece. :)

A Little About Me
For those that do not know of or have heard of me here is a bit of a bio; I create games and other software using Object Pascal. My tools of choice are Lazarus and Free Pascal.

I've been making all kinds of small games since high school. I mean games are what got me to learn everything about them. My biggest break for making games for Windows however was a really amazing little library for it's time called DelphiX. It was a visual component library, created by a guy in Japan named Hori, that allowed a developer to drag and drop objects onto your application's form and create your game with DirectX without having to play with headers at all. It all sort of took off from there I was making games and looking up site of other developers and a few community sites where I could learn to do more.

In 2002 I joined a small, but growing community of Pascal programmers on a forum site called DGDev. About that time, I also frequented a game development news site called DelphiGamer ran by Dominique Louis and Dean Ellis. In 2004, after the community had grown a bit more, Dominique Louis and myself created and co-founded Pascal Game Development (.com) which was the combination of both the community forums at DGDev and DelphiGamer's news site.

The site's launch in 2005 was introduced with an annual game programming competition which would come to be called the 'PGD Annual'. Two successive competitions were ran in 2006 and 2007 with growing success. We even sponsored two teams to compete in the IGF for 2006 and 2007.

I eventually 'retired' as webmaster and co-site runner in late 2007 so that I could focus on my new career working with electronics. The site has since had a complete make-over and is definitely worth a visit; www.PascalGameDevelopment.com Go check it out. :)

I've started many game projects, but unfortunately I've completed very few. I've taken almost a whole year off to focus on my studies, but I. To name some of my favorite projects I've worked on off the top of my head I'd have to name; Garland's Quest (a very active effort right now), Cyber-Crisis, Subject 33, SkyBlast Game Engine project (had a nifty storyline I was cooking up for a game with it) and Iron Strike: Stormfront. (story and design work for Dirk Nordhusen's 2006 IGF entry)

Definitely look for new progress on my latest game Garland's Quest, which is a neat little puzzle game that I'll talk about more in my next post.

Well that's all from me for now. Be sure to come back for more. Cheers!