Nice relaxed evening of coding last night - got Brickbat up to a fully playable state with 6 working levels, score tracking and a Game Over screen when lives hit zero.
Still extremely rough around the edges, but all the basics are now in place so I’m calling this the start of alpha. Alpha will be mainly about adding features, then in beta I’ll concentrate on polishing it up and balancing.
Lots still to do but hoping to make good progress this weekend.
Another productive evening of work on Brickbat. Added in this session:
- New, much more elegant methods for updating and drawing the game, based on a global enum variable, GameState.
- Pause mode
- ‘Get Ready’ screen before each new level, showing level number and name
The bones of the game are now really taking shape, slowly but surely. The only real basics that need adding in now are an end-of-level screen with a rundown of the player’s score for that level, and a Game Over gamestate (lives are already sort-of implemented but happily tick over into negative figures), then I’ll consider it in Alpha and work on adding more features and improving the interface.
Had a major break
outthrough with Brickbat tonight - finally managed to get the ball bouncing off the bricks in a way I’m 95% happy with! This after 4 separate, failed, versions of the bouncing logic.
Going to bed happy! :D
Before I leap into making one of my more ambitious game ideas (of which I now have SEVERAL) I’m going to do another remake, just to firm up my skills and get to grips with my new programming environment (C# / XNA).
Last time it was a Pong clone, so a Breakout/Arkanoid clone seems a natural progression. Announcing… BRICKBAT!
Progress so far has been good. Over the last couple of weeks I’ve got most of the game engine up and running, along with a rough and ready level editor which has let me knock up 10 reasonably varied levels so I can test that the ball bounces how you’d expect it to (at the moment it doesn’t, so I need to refine my code).
Other stuff still to implement before it hits alpha inludes sound, power-ups and possibly enemies (though they might have to wait till beta).
Will post some screenies later, though be warned it isn’t very pretty at the moment - I’m treating all these graphics as placeholders and a more modern look to the game is on the list for later development.
While my Pong clone was always too rough and ready to inflict on the gaming public, the aim with Brickbat is for a release on Windows Phone 7 later this year.
So, yeah, I’ve not posted anything on here for a while.
Firstly: Onward My Zombie Horde is on an indefinite hiatus. Apologies to the one guy who got excited about it - it’s something I’ll come back to at some point, but I realise now that I was trying to take on too much, too soon.
On the plus side, hitting a roadblock with the AI for OMZH spurred me into a pretty major rethink of my options as a beginner indie dev, which has led to a few changed priorities.
So what have I been up to? Well:
1. For a number of reasons I’ve decided to ditch SFML in favour of something more beginner-friendly and with better options for distributing any finished games. After weighing up my options I went with Microsoft’s XNA Framework, which gives me the potential to create games for Windows, XBLIG and Windows Phone using the same code base. While I was impressed wtih SFML in some ways, it seemed a bit of a cul-de-sac where distribution is concerned.
2. Unfortunately, this choice required that I learned C#. Not an easy thing to commit to having just spent a couple of months getting to grips with C++, but with the help of online tutorials from csharp-station.com it was reasonably painless. For me, it makes more sense as a language than C++ and I like how it’s object-oriented from the ground up.
3. Then I needed to learn the basics of XNA. I’m now just at the stage where I’ve done enough with the tutorials to be able to start working on my own ideas, but rather than start a game straight away I’m trying to put together a few methods for things like sprite animation and 2D tiled maps that I can re-use between projects, making my life a bit easier.
So far I feel like I’ve made the right decision. I’m finding C#/XNA *much* easier to work with, and I’ve also had lots more game ideas that I want to try out.
I’m not sure if I will ever get back to updating this blog as often as I did in the early days, but do I plan to keep it going (perhaps with separate dev blogs for major projects as and when they warrant it).
Not managed to get as much coding time in recently as I’d have liked as real life, work and such things have been intruding too much. But yesterday I managed to get a good, meaty coding session in over the afternoon, working on the beginnings of the AI for OMZH.
Essentially there are zombies, and there are humans, and for starters I’m trying to get it so that each zombie pursues the nearest human while each human runs away from the zombies to the best of their ability.
This is, for the rookie, a pretty major AI undertaking (as compared to moving the AI bat in Pongoloid), 150-odd lines of code in all. And inevitably, it’s not quite working properly yet.
The zombies are doing roughly what they ought to - checking the co-ordinates of every human against their own, figuring out which is the nearest human and then heading towards them. If they touch, the human becomes a zombie (infection periods can wait until later).
The humans, though, are just standing stock still and waiting to be bitten. Once they become zombies they start to move, but until then they don’t want to know.
And just to top it all off, once everyone’s a zombie they head inexorably for the top left of the screen, which they shouldn’t be doing either.
I suspect the problem with the human AI is a new boolean variable, “panicked”, which I’ve added to the “person” class. Basically humans are meant to become “panicked” if they are less than a certain distance away from a zombie.
If panicked, they then tot up whether there are more zombies above or below them onscreen, and whether there are more zombies to their right or left onscreen, and decide which way to run accordingly.
If “panicked” is false, though, it triggers placeholder code that just makes the human stand still.
So chances are that people just aren’t passing the panic test.
Not a bad bit of progress tonight. After a few false starts with all the bugs (kind of inevitable given that I left it so long between finishing Pongoloid and starting OMZH), once I’d come up with something that would actually compile I managed to crack on a fair bit. I’m now at the stage of generating 20 human characters, turning one of them at random into a zombie, and drawing them on the screen (using placeholder graphics borrowed from Manning Krull, whose excellent pixel art walking animation tutorial I intend to follow later), and that’s where I’m going to leave it for tonight.
The next stage will be to come up with simple AI behaviour for humans (flee from zombies) and for zombies (shamble towards humans and attack). My plan is that I want to get a basic infection/epidemic model in place first (where being touched by a zombie instantly infects the person who gets touched - eventually this will be replaced by an infection with a short incubation period before zombification), then add in scenery and pathfinding.
My current concept for OMZH is reliant on ever-larger numbers of NPC zombies causing chaos in your wake and facing off against armed human resistance, so getting NPCs to behave roughly how I want them to is my top priority.
Only then will I think about adding in a playable character and starting to actually make it into a game.
So since coding has now finally begun on my new project I feel I can reveal some details of it. Can’t really keep too much secret if I’m going to blog it every step of the way, anyway.
1) This game has zombies in it! 2) Better yet, you play as a zombie! 3) Devour humans or infect them to strengthen your zombie horde - the choice is yours! 4) Old-school 2D gameplay blending action-RPG, arcade, RTS and puzzle elements within a narrative-driven story mode 5) Working title: Onward My Zombie Horde!
It’s going to be a while before this one starts properly taking shape but the groundwork has begun, setting up classes and trying to plan most of the variables needed from the outset.
MUCH more ambitious project than Pongoloid, so who knows when it’ll be finished :)
So, since finishing Pongoloid I’ve not really touched Codeblocks - somehow I couldn’t get worked up enough about the idea I was working on to make a start on it, never a good sign.
This morning, however, I’ve woken up with a real bee in my bonnet about a new game that I’m super-excited to make a start on.
Going to start planning it out properly tonight I think, now that my motivation is back.
1. Pixel art is difficult.
2. I need to learn to draw.
3. In the meantime, I need to do another game that doesn’t involve fancy graphics.
It’s a very minor update that just fixes the screen resolution problem mentioned in the edit of the last post. Game now uses whatever resolution the desktop is using.
New download link here (have also updated the link in the original post).
After an evening of polishing up the rough edges, it’s finally time to release this baby into the world! Possibly the best Windows-based Pong clone to be released in 2011 so far, Pongoloid boasts one-or-two-player action, a vaguely arty primary-colours-on-white design aesthetic and THREE (count ‘em!) sound effects!
It’s also completely FREE, so if you’re running Windows and have even the slightest interest in retro bat-and-ball games you have literally no excuse not to click this Ebucket download link to get the .ZIP file (5.8MB download). It’ll provide minutes of fun for up to two of the family!
I’d be particularly interested to hear whether or not it works on anyone else’s machine, as I’ve not had chance to test it on anything other than my laptop at the moment.
— Note: Currently you’ll need a display capable of a 1280x720 widescreen display mode as I was going to make the game autodetect and use the highest possible resolution on any given system but forgot!
— UPDATE: fixed this issue and updated the download link to point at new version (1.0.1)
So that was Christmas, and what have I done?
Not an awful lot on the coding front, it transpires. My pong clone remains in much the same state it was after that day of AI coding.
I’m trying to decide whether I ought to spend a little bit more time on it - just to practice on some of the other bits and bobs I’ll have to tackle eventually, like menus - or move directly onto something a bit more interesting. There’s only so much you can do with Pong, after all.
But then if I do that, what then? Something totally original, or another clone of another, more complex, game?
Not sure, to be honest…
After all the rigmarole and messing about I went through getting some text to draw itself on the screen, I was bracing myself for plenty of hassle checking off the next point on my Pong clone wishlist: a computer opponent. Until now both bats have been human-controlled via the keyboard.
But to my surprise it didn’t take much setting up.
First a new boolean variable within the player structure so that each player can be either human-controlled or computer-controlled.
Then a new function, moveAIbat, that does exactly what it says on the tin. It finds out where the ball is and what direction it’s moving in. Then if necessary (and if it won’t result in the bat moving off the screen) it moves the bat co-ordinates either up or down (towards the ball’s y position) by a fixed amount.
Fewer than 20 lines of code from start to finish, but it seems to do the job. It’s not quite what you’d call AI, but to my surprise it’s good enough to win a fair proportion of points. My first game vs CPU ended 10-7 (keeping tally of the score and making the first to 10 a winner was added soon after solving the zoomstring conundrum).
What a difference a good night’s sleep can make to a problem - in coding as in so much else.
Coming back to my troublesome ‘zoomstring’ function with a fresh set of eyes, I decided that, rather than go through all my code line by line looking for the problem, I ought to take a step back and think about it logically.
The function is definitely getting called - I know this because of the debugging line I added at the start using cout to leave evidence of this in the command line console.
There’s nothing actually “wrong” with the code - it compiles without giving an error, and it doesn’t crash or break the game when called during runtime. It’s just as if nothing is happening.
So, logically, that leaves a problem with the function’s main loop.
Everything takes place within a big nested “for” loop. I stare for minutes on end at the line that starts the loop off.
for (int n=1; n==9; n++)
Looks fine to me. But maybe I’d better just check - ACK!
Schoolboy error. I’d thought that for loops checked for their condition and continued until the condition was true. But a quick check of one of my earliest tutorial lessons tells me that in fact the for loop only continues while the condition is true. So, since n isn’t equal to 8 when the loop starts, everything else in the function gets completely ignored and the program goes back to where it was before!
A quick rewrite followed:
for (int n=1; n<=8; n++)
That’s more like it. As soon as I ran the game again, text zoomed onto the screen every time it was supposed to. Turns out everything else in the function worked perfectly. It’s just that I’d misunderstood one of the fundamentals of C++. No biggie.
Piece of cake, this debugging lark.
Aaaaaargh. This is doing my head in.
Perhaps unwisely, rather than implementing any more basic stuff just yet I decided to do something a bit more interesting: a function that will “drop” a word or phrase onto the screen one letter at a time, using SFML’s scaling function so that the letters appear to zoom in as if they were falling onto the surface of the screen from in front of it. (If that makes any sense.)
The function, which I’m calling zoomstring, will accept a nine-letter string as input so you can just call it as, e.g.
zoomstring (“GET READY”);
and the phrase “GET READY” will drop into the middle of the screen, letter by letter, and maybe wait a second or two before continuing with the main game loop.
So I worked out everything that zoomstring would have to do (transpose the contents of the string into an array of SFML’s sf::String objects, each holding one letter of the text. Calculate where each letter should be on the screen and how scaled up they need to be, and a loop to gradually scale them down and display them on screen at each iteration.)
Much to my surprise, compiling this produced no errors.
However, when I added a call to the function into my code (just before each new point is played for) a weird thing happened: nothing at all.
Again, my program didn’t give me any errors but the function call might as well not have been there. Everything proceeded exactly as before, with no sign of any text being dropped into the screen. Was it even really being called?
I added an extra line to the start of the function to spit a message out on the console every time zoomstring was called. Sure enough, next time I ran the game my console contained several lines of “calling zoomstring”. But that was the only clue that the function was there. No onscreen text, no errors.
Thoroughly bamboozled, I’m calling it a night.
For all the progress made on my Pong clone in my late night session, there’s been something niggling me about it ever since.
It just seems a bit… jerky.
Being completely new to this, my first instinct is that I must be doing something wrong. Something in my code, something in how I’ve set up the window, or how I’ve written my timing loop, must be making the animation less smooth than I’d like.
So I tried a few alternatives - enabling vsync, disabling vsync, changing the timing routine to run to framerate rather than to an absolute timer. None of which made the game any smoother, and some of which actually succeeded in making it even jerkier than ever.
A couple of hours later I was back to square one. Mooching around the SFML forums I stumbled on someone else who’d been having the same problem. He’d posted some source code, which looked very like mine. Forumites advised him that the code looked fine. He then compiled a binary and sent it to someone else to test on their machine. They reported back no jerkiness. The conclusion seemed to be that the SFML libraries just don’t work particularly well with his graphics chipset - which happens to be the same onboard Intel chipset that I have on the laptop I’ve been coding on.
This, it seems to me, is the trouble with developing for PCs. There are so many different devices out there that you can never assume any two of your end users will ever have exactly the same setup.
Some of these variables I’m already learning to adjust for - making my game work with various possible display sizes, for instance. Others, like this jerkiness issue, I’m less thrilled with and will have to keep an eye on.
For now I’m going to soldier on with what I have - it’s not that jerky, now I look at it more closely - but if it becomes more of a problem when I start on bigger, more ambitious projects I may have to bail out on SFML and try one of the alternatives.
Wow. Turns out that writing games is every bit as addictive as playing them. It’s gone 3am and I really should have been in bed hours ago, but I’ve been on a roll with my Pong clone and I didn’t want to stop while I was getting so much done.
Tonight I finished all the groundwork that I started yesterday. From there I implemented the basic graphics - flooding the screen with a background colour and drawing two bats and a ball on it. Once I’d done that, it seemed churlish to quit for the night before I’d made the bats move up and down when certain keys are pressed.
Then it would have been almost rude to stop without making the ball move, and once it was moving I needed to make it bounce off the top and bottom of the screen - and, of course, off the bats. And once I’d got that far it was a tiny extra step to make the ball position reset if it went out of play.
Also somewhere in the middle of all this I rewrote large chunks of my code so that, in theory, the graphics could adapt themselves to various different possible screen sizes.
And once all that was done, it was gone 3am and I really should be in bed.
But I retire to bed happy, with the main gameplay of my Pong clone implemented and feeling very pleased with my night’s efforts.
I may have had a great game idea the other day, but received Internet wisdom says the best way to earn one’s game programming chops in a new language is to create a clone of an existing game - the simpler the better.
So, never one to ignore the collective wisdom of the Internet, I’m going to become approximately the millionth person to code a version of Pong. Mr Bushnell, my apologies in advance.
This is where the stabilisers come off. I’ve stopped following tutorials and I’m writing code all of my own. And I’m making many, many mistakes. Mainly the basic stuff I mentioned in an earlier post - an extra bracket here, a missing semicolon there - it all adds up.
This is where Codeblocks has been coming to my rescue. Unlike the old-fashioned IDE I wrestled with 13 years ago, Codeblocks takes a lot of the pain out of debugging what you’ve written by flagging up in red any sections of the code that are causing an error when you try to compile them, and even telling you in reasonably specific terms what the problem is.
The other thing that strikes me setting out on my first full program is the amount of stuff you need to code just to build the infrastructure for the game, before you get to do anything fun like drawing things on the screen.
So tonight’s been about declaring variables, creating classes and working out the general flow of how the program will work. It compiles, but it doesn’t actually do anything yet except spit a few message back out to the console so I can tell it’s working properly.
It’s an odd feeling to break down something as simple as Pong into its component parts and realise how many things need to be made to work so it’ll run.
And it’s even weirder, after all those one-shot tutorial programs, to spend an evening coding and only get the bare bones of a program done, not being quite sure whether it will all come together and work.
My space invader now makes a PEW! noise when you press space.
This is the most awesome thing ever.
It also concludes my dabbling with the SFML tutorials. Next up, to tackle an actual honest-to-goodness game.
So, having swotted up on the nuts and bolts of C++ it’s time to make a start on my first game.
Before I get that far, though, there’s the small matter of making the leap from command-line based, text-only programs to all-singing, all-dancing (literally) games programming.
It’s a bigger leap than it might sound to the non-programmers out there. There are many things a game needs to do that aren’t covered in the standard C++ libraries or taught in the core tutorials, and that would be hugely complicated for a beginner to write from scratch.
Things like drawing things on the screen, moving sprites around, playing sounds and music, loading graphics and sound files from disk, checking for input from a joypad… that sort of thing.
Fortunately for the beginner, there are various free libraries out there that essentially provide extra commands to use in programs to do all that sort of thing for you.
Allegro, the library I used during my brief foray into C, is still doing the rounds and seems quite a popular choice for my fellow newbies. But although it works with C++, it isn’t built from the ground up for the language (it isn’t “object-oriented”, which I gather is quite important - although I’m not quite sure why).
Another popular choice is SDL, which has also been around for a fair old while and has many devotees. This, it seems, is the more “hardcore” option and has made its way into several commercial titles.
But I’m going with the new kid on the block. SFML (it stands for Simple Fast Multimedia Library) is in its relative infancy compared to the other two libraries mentioned but gets my vote due in no small part to the noob-friendly tutorial section on its website. It’s completely free, even if used to make commercial software. And, from the quick play about with it that I’ve had tonight, it’s pretty damn impressive.
After following the first couple of tutorials I’ve managed to plonk a big space invader on the screen and get it moving around according to keyboard presses. I can even rotate it, something I couldn’t have done in my wildest dreams back in the Amiga days. Life is good.
A second day in a row of cracking on through the cplusplus.com tutorial and I’m more or less done with it. Two and a bit days, 140 pages, 60 tutorial programs compiled.
I think I’m more or less on top of things, but so far I’ve just been typing in other people’s code and trying to understand what each line does. The acid test will be writing my own stuff.
I’m not going to be daft enough to leap straight into trying to realise my great game idea from yesterday, but it’s time to start trying to write a game of some sort. I’ll worry about that another day though - this weekend has been exhausting.
I woke up today with a great idea for a game. It just popped into my head fully formed. I know what the main characters look like, how the control scheme will work, how the levels will progress as you get further into it, what the sounds will sound like, even some of the music. This game, I thought, is going be brilliant.
Thus inspired, and this being a weekend, I promptly sat down in front of my laptop, loaded up Codeblocks and got cracking apace with the C++ tutorial I downloaded earlier in the week.
This brought me back down to earth with a thud.
It’s a bit like dreaming you’re winning the Monaco Grand Prix, then waking up and having to take your first driving lesson.
Don’t get me wrong, I’m gradually getting to grips with it. But my great game idea is going to have to stay on the back burner for a while. After a full day of following the tutorial and bashing out code, I’m still wrestling with the basic nuts and bolts of C++. The most interactive program I’ve written so far asks you to type in a series of numbers, then parrots them back on the screen.
It’s going to be a long slog before my game idea sees the light of day. But at least I now have something to aim towards.
One thing that’s changed since my youthful coding excursions: back in the days of BASIC and its variants, you used to just be able to type in your code and run it on the fly - the computer had time to interpret the lines of human-readable code into machine-readable instructions while it was actually running.
This is mainly because 8-bit BASIC programs ran very slowly indeed, although it was also possible to run a program like this in AMOS provided the person who wanted to run your program also owned the AMOS disk.
That’s a spectacularly inefficient way of working, though, so “proper” programming languages need to be translated into something a computer can run (e.g. an .exe file) before you try to run them.
To do this you need something called a compiler which, back when I briefly tried learning C, used to be an unfriendly, command-line only beast unless you had the cash to pay for a development environment that ran under Windows (in my case I was lucky enough to pick up a slightly outdated one free on a magazine coverdisc).
Fortunately these days it’s far easier to pick up a free and user-friendly development environment thanks to the internet and the growth of the open source movement. Me, I’m going to be using Code::Blocks, a completely free program that on first glance appears more than good enough for my needs.
I particularly like the way it colour-codes your code as you write and helps to keep track of the various brackets and braces so you can see at a glance if they all tally together.
It’s little things like that which make all the difference for a complete novice. As with learning any language, the most common stumbling blocks in a new computer language are grammar problems - my commonest errors in C++ so far have been forgetting to put a semicolon at the end of each instruction, and messing up with the brackets. Always the brackets.
But that said, I’ve now managed to compile and run my first program. In time-honoured fashion, it prints the phrase “Hello world” on the screen.
Baby steps and all that, but so far this doesn’t seem too complicated…
I did have one final foray into coding after the AMOS days when, as a student, I taught myself just enough C to program a frankly awful Operation Wolf style shooting gallery game that was basically an elaborate in-joke for a few mates. Hey, I had too much time on my hands.
That was 13 years ago, and I’ve not coded in anger since. I remember virtually nothing about C, except that I taught myself by downloading an in-depth tutorial in PDF format.
Well, if it worked for me once…
As luck would have it, a similar thing exists for C++, over at cplusplus.com, so that’s going to be my starting point.
And so, tutorial in hand, I press on.
Here, presented in its entirity, is the first computer program I ever wrote:
10 PRINT “HELLO”
20 GOTO 10
It may not have been the most elegant or useful of programs (the only way to stop it flooding the black screen with white text was to reset the computer).
It may not even have worked first time - I seem to remember missing the quotation marks out of the first line and thus getting my first taste of the BBC Micro’s dreaded, unhelpfully ambiguous SYNTAX ERROR message. (I was in primary school. Cut me some slack.)
But it was a start. I wrote dozens of little BASIC programs like that for the BBC Model B (none of them much use for any practical purpose). I never got as far as doing a game for the Beeb because maths was never my strong point and, in those days, anything involving graphics also involved maths advanced enough to comprehensively boggle my pre-teen mind.
Then came the 16-bit era, to my mind the golden age of homebrew games. We traded in our BBC Model B for an Amiga 500 - a technological leap akin to going straight from a transistor radio to a colour TV. I cobbled together a text adventure in AmigaBASIC and dabbled with Shoot Em Up Construction Kit (a “game making utility” rather than actually a programming language, with predictably rubbish results).
The breakthrough for bedroom coders of that era came with AMOS, a souped-up version of BASIC that made it easy for the hobbyist to display graphics, play sounds and get input from a joystick. Finally, the ability to make proper games! A friend and I spent much of our early teens producing neat little public domain games, excitably riffing off each other’s ideas and ending up with a steady stream of titles that were actually not that bad, considering that we were two rank amateurs.
Then the Amiga scene withered away, and with it my nascent programming career. Life got in the way. With no formal qualifications in computing and no improvement in my maths prowess, I abandoned programming languages for the richness of the English language and became a journalist.
Meanwhile the era of the bedroom coder seemed dead and gone. Videogames made the leap to 3D and required ever-swelling armies of coders, artists, designers and musicians to create. Games development was no longer the realm of the hobbyist.
Just recently, though, the tide seems to be turning. Take Minecraft and Super Meat Boy, two of the best games of 2010. Both compulsively, dazzlingly playable. Both labours of love for minuscule dev teams (two guys worked on SMB, while Minecraft had just the one developer until recently).
Now, I’m not vain enough to think that I’m going to be rivalling their creations any time soon. I’m not looking for a change in career. But just lately I’ve been feeling the old itch again. Right now is the best time in decades to be an indie game dev, and I want in.
Only problem is I haven’t done any coding in more than a decade and the only language I’m fluent in, AMOS, is dead and buried. Time to learn some real skills.
This blog will chart my progress as I blunder headlong into the uncharted territory of “proper” programming, in a proper grown-up language: C++.
Any comments, criticism (constructive or otherwise), hints and tips along the way are more than welcome.