Thursday, 26 January 2012

Episode 1 complete!

After a little more tinkering and the addition of some graphics and music, I'm proud to announce that Zommers! (Episode 1) is a fully playable game!

It started life as an experimental Artificial Intelligence pathfinding routine, and evolved into something playable. OK, it's not ground-breaking, but it's not bad for a months work. So without giving anything away (because I want you to play it and find out for yourself) here is a sneak peek at the title screen...

...fear my awesome Paintshop skills! Or something.

Anyway, the game comes in a zip file and doesn't need to be installed, just unzip the file and double-click the Zommers.exe to play.

It does require that Microsoft DirectX is installed, but if you don't already have that then, well, you should.

Have fun with it, but don't take it too seriously. It's only a hobby ;)

I already have an idea for my next project, I'll keep you updated.

Wednesday, 25 January 2012

A health bar.

So the game is pretty much playable now, it just needs a few mechanics added, a bit of a polishing, and I can call an end to "Zommers! - Episode 1". I've decided to do this episodically for two reasons. Firstly, I can try a different AI routine with each episode, and not bundle all my ideas up into a single, confusing game or application. Secondly, I can have a crack at different projects, and return to the Zommers franchise at any time, using routines from previous episodes in later projects if needed. This first episode is called "Direct Pathfinding" for obvious reasons.

Anyhow, this blog update is all about the "Health Bar" (and I don't mean a place to hang out with sporty types while drinking fruit smoothies...)

The idea of the health bar is to give an indication of how close the player is to getting killed. Morbid, but essential. So the health bar spans from left to right at the top of the screen, and gets shorter and shorter as the player takes damage from the Zommers, until it finally shrinks away to nothing, in which case the player dies and the game is over. Here's what the health bar looks like in-game...

(As usual, click to enlarge)'s up there at the top left corner of the screen, and as you can see, it spreads out from the left to right. In this case, the player has plenty of health remaining. But not for long ;)  So here's how it was made...

First, I designed the health bar graphic in a graphics application (Paintshop Pro 7 if you're interested), and saved it as a .png file (portable network graphics, lossless)..., within the Zommers source code,  I loaded it into memory, as image number 7, as follows... I define a global variable which will be used to hold the health of the player...

...and assign it an initial value of 100... you will notice I called that variable "playerdamage" where you would expect it to be called "playerhealth" or something. I did this because of the way I have decided to display and dynamically modify the health bar as the level of health decreases. Rather than decrease the amount of health the player has, I chose to increase the level of damage he has received. I've done it this way because it's created a platform for an idea I want to try out in the future, which I will no doubt explain in a future blog :)

So now to actually display the health bar. If you look at the design of the graphic, you will see that it is only one single vertical bar, whereas in-game the actual health bar is made up of lots of these vertical bars, arranged in a horizontal line. To facilitate the reduction (or later, addition) of player health, each one of these tiny bars needs to be controllable (not position-wise, although technically they are) in that I can turn them on or off as needed. So to that end, I wrote a routine to display 100 of these bars, each one as a sprite, with a gap between them. Here is the routine that does that...

...yes, I've counted backwards from 200 to 100 with the sprite definitions. This is because, as you will see in  the next code snippet, that as player damage goes up, it hides sprites starting at number 100 and going upwards to number 200. If I hadn't positioned them in reverse order, then the health bar would deplete from left to right, which is generally accepted (in my part of the world at least) as an indicated increase. This way, it depletes from right to left as you would expect. The temporary variable "barspacer" is just used to place a gap between each sprite do it doesn't look like a solid orange bar when it's rendered to the screen.

Finally, the code that actually changes the look of the health bar when the player is hit by a Zommer. It consists of two small routines, and they're both shown here...

...the "CheckFaceChew" function checks if the player object is hitting anything, and if it is, it goes on to check that the thing it's hitting is a Zommer, then if that's also true, it increases the value of the "playerdamage" variable. It also sets a flag called "playerdead" if the player damage exceeds the value 200. I think it's reasonably obvious what the "playerdead" flag represents...

The other function, "UpdateHealth", just hides a sprite in the healthbar which is directly related to the value held in the "playerdamage" variable, so the health bar looks like it's getting shorter, even though what's really happening is that some of the lined up sprites are being hidden. 

One final thing to note before I end this post. You might wonder why I've started the player health at a value of 100 and added damage up to a level of 200 (rather than starting at 0). Well if I'm totally honest, it was due to a lack of planning at the beginning (I'm sure you know the way I code by now!). I had already used a few sprites for other things (targeting reticle, score digits etc...) which were assigned low numbers, and I really couldn't be bothered recoding that lot, so I just started the first health sprite at number 100, and wrote the player damage routine around that value.

Trust me, I know what I'm doing....  

Sunday, 22 January 2012

What's the score?

I'm still undecided about whether to make the Zommers! "game" a score-based thing, or a "how long can you survive" type affair, so I thought I'd check out both scenarios.

This blog update is about the scoring system, or rather, how it works. Basically, you get 1 point for every Zommer killed, that much is obvious. What isn't obvious is how to display that score in game. Yes, I could just use the standard text output and reposition it somewhere on the screen, but that would be too easy, and look a bit pants, so I've gone for a sexy Orange font for the moment, and here's how it looks "in-game"... that might not look too fancy, but compared to normal text believe me it is. And because it's made of sprites, changing the look and feel of it is simply a case of changing the graphic from which it's built. And here is that graphic... if I wanted the score presented in a "space age" style font, I'd just edit that graphic and wouldn't have to change anything within the game code :)

So this block of code grabs that image, cuts it up into 10 equally sized pieces, and creates an animated sprite 10 frames in length, with 1 digit to each frame. It's repeated 4 times, once for each digit in the score readout...

...the "screen_w" variable you see there is just something I'm using to hold the value of the width of the screen. That's so this thing will work on PC's that are using a different screen resolution to the one I wrote this code on. As it happens, in this instance I'm using it to position the sprites which display the score.

So after doing that, it's just a case of looking at the current score variable, breaking it down into individual digits, then changing the displayed frame of the corresponding sprite to whatever is held by the score variable. I call this routine once every program cycle (which is 60 times per second), and as it's impossible to kill 60 Zommers in a single second, there is no chance of the displayed score lagging behind the actual score. 

At the moment the Zommers still don't cause damage to the player when they touch it, so once I have this scoring system exactly as I want it (or a timer system - I'm still undecided), creating a player damage routine is my next task.

Wednesday, 18 January 2012

Healthy zombies?

OK, the Zommers have health now. Well, they have a numerical value linked to their entity container that can be construed as "health". But the first sentence sounded better.

Each Zommer starts with a health value of 10, and this can be decreased until it reaches 0, in which case the Zommer is deleted. The colour of the model is also directly linked to its health status - if the health is good, the model appears bright Red, as the health decreases then the model gets darker and darker until it is eventually destroyed - of course the darker it gets, the harder it will be to see once I sort out some lighting routines...

You might ask how the Zommers even lose health in the first place? Well, I have implemented a crude system of bullets, meaning the player can "fire" at the Zommers. This was originally thrown together just for testing purposes, but (as with most things I seem to do on these projects) I think it will get developed into a usable routine. At the moment there is unlimited ammo and a constant rate of fire.

Here's a pic...

(as usual, click to enlarge)

So here you can see I'm aiming (badly) and firing at the Zommers who are trying to get to me by finding their way around the obstacles. You will notice that some Zommers are a darker shade of Red than others, and these are the ones that I've managed to hit a few times.

There are only 46 Zommers in that picture, I've killed 4. That's because I'm an awesome shot. *Ahem*.

So I'm not exactly sure what to do next. Something to do with limiting the amount of ammo, or controlling the rate of fire probably.

I'll keep you updated :)

Saturday, 14 January 2012

Realistic pathfinding

Well I've finally managed to get the Zommers to take a more realistic path when trying to get to the player. They look at where the player is, and if there is an object in the way, calculate the most efficient way around it. This is still pretty basic stuff, but it's way more advanced than my last attempt, and you can tell that just by looking at the entities in action.

At the moment, they all try to head directly for the player. I want to work on some routines where they wander around aimlessly (as Zombies tend to do) but then change behaviour if the player comes with a certain distance of them, or attracts them in some other way...

Here's a (short, low quality) video of the routine so far...

Since making that video, I have added the ability to delete a random Zommer (by pressing the 'x' key) and also spawn a new Zommer (by pressing the 'c' key). That might sound pretty straightforward, and the delete function is - it only has to check if a Zombie exists, then deletes it. But the spawn function is a bit more involved. It has to find the first available "entity slot" that isn't in use, and assign all the right variables according to its findings. There are only so many slots available - I have to draw the line somewhere!

For the demo above, the controlling variable is

#constant NUM_ZOMBIES 8

It's pretty obvious what that line does, but if I want to have 100 Zommers, I only need to change that number from 8 to 100 and the rest of the code adjusts accordingly. 

I'm not sure what to aim for next. I have a couple of things that need doing which won't make the project look any different, but involve some big(ish) changes "under the hood". I have a few days off coming up soon, so I might try and work on different Zommer behaviours. Or maybe health. I want each Zommer to have its own individual health level, and that means adding more attributes to the entity definition.

Onwards and upwards :)

Wednesday, 4 January 2012

Basic, but too basic...

I managed to get some preliminary AI code working . Here is a short video of a single "zombie" attempting to track the "player". I am controlling the Green player, the zombie is controlling itself ;)

Note that I haven't written any collision detection routines yet.

Based on this routine, I tweaked it a little and it handles up to 1000 zombies now! Unfortunately, that just looks like one huge red blob and you can't see the Green player at all. So here is the routine with a few more entities...

So the basics are there, or so I thought...

After messing around with the code, it's become apparent that I am approaching this from the wrong angle. The tracking code is so simplistic on these demo's that I shouldn't really have the nerve to call it AI. I've been doing some research, and I think I need to create the zombies as completely independent entities. That is, at the moment they are independent in a way, but their co-ordinates and paths are held in the same variable array, albeit multidimensional. I need to create them as completely standalone entities if they are to have any kind of semblance of a sentient character.

So I've got a scratchpad to work with, and that is basic but good enough for now. I'm going to completely strip out the existing zombie control routine and (try to) replace it with some sort of... well, I don't know what. But whatever it turns out to be, I want each zombie to react completely independently of each other. For example, if the player comes within a certain distance of a zombie I want that zombie to react, but zombies further away would just trundle on regardless.

I might not even be able to do this, but I will try. I think it might be a while until my next blog update, I have a feeling this next step will be my biggest challenge so far. (Including that Java thing...)

Monday, 2 January 2012

First day of coding

I had quite a busy day today which included (but was not limited to).. getting called into work on my day off, taking my dog for a walk up a mountain (I'm not kidding), colouring my wife's hair (again, not kidding), colouring my oldest daughter's hair (I shit you not), and generally getting caught up in all sorts of non-programming stuff.

But I did manage to get a few hours in this evening. And in those hours I have managed to get a bare bones scratchpad working. I loosely threw together some test code in order to check out object sizes, camera heights, a couple of automated calculations etc, and it looked like this...

...and then after food and a shower managed to get another hour or so on it, and it now looks like this...

...and I know it doesn't look like much, but...
  • The player character (Green square) can be controlled by the user in 8 directions
  • Travelling diagonally moves the same speed as vertically or horizontally (quite tricky to achieve)
  • The player cannot move outside of set boundaries (by mathematical checking, rather than collision detection)
  • The base is easily scalable - change two parameters and everything else adjusts automagically
So this will be the play area for the AI routine. I know it's basic but it's only a baby :)

Next, I intend to introduce a single NPC entity and see if I can get it chasing the Green square, er, I mean "Player". Alas, I'm back to work tomorrow so much like today, daytime coding is not happening. Just this minute I had an idea for something, so I'm off to make a note of it. Until next time, I bid you farewell.

Or something. 

Edit: Yes, I noticed the spelling mistake in the program. The question is, did you?  ;)

Sunday, 1 January 2012

New year, new project

Well I didn't seem to get much coding in over the Christmas holidays, there was simply too much going on around me. Family stuff, multiplayer gaming, a huge attic sort-out...

If you read this blog, you'll know I had a crack at Java which if I'm honest, is above me. I have no doubt that if I devoted enough time and energy to it, I could get a reasonable grip on it, but the whole idea of me getting back into coding was to create things, and I don't really want to put myself through learning a whole new language (again) to do that. Making a windows application in itself wasn't too hard - I did make an app where the user could click a button which would generate two random numbers, add them together, then display the result (all in a fancy window) - but when it comes to graphics and animation, it's a whole different ball game altogther.

So I'm back on familiar territory with my DBPro GUI. I want to look into AI (artificial intelligence) coding, but I'm not going to kid myself that I'm capable of making anything mind blowing. Just a simple 'target acquisition - tracking - movement' style thing will do me to start with. But I also want it to take the form of something I love, and that means a game of some sort. So I have an idea for my first test program.

It will involve a user-controlled character and a number of computer-controlled ones. The idea (at first) will be to avoid the NPC's (non-player characters) by moving away from them. Don't get me wrong, when I say "character" I mean "coloured square" or something. Start with the basics I say. I hope to get the NPC's to track and move towards the player, but at the same time, not move over each other. I think that's more than enough to be getting on with!

I also have some ideas that can be thrown into the mix later on, and for that reason, I am calling this project...

Zommers! (Cue theatrical soundbite)*

*If you're an internet geek like me, take this soundbite as being the music from Dramatic Hamster..