Archive for the ‘programming’ Category

Making a heat map effect for Toxin

Posted on June 20th, 2013 in game development, iPhone, programming, Toxin | No Comments »

Toxin Heatmap

As you might already know my forthcoming iOS game, Toxin involves shooting rapidly dividing toxic cells which eventually fill the playfield or burst to spawn flying enemies.

Now, not long ago I read an article about generating heat maps to display web statistics, and I thought it would be cool to use this technique to colourise the ever changing clumps of cells in Toxin. After finding out how they work, I knocked up a prototype in Processing before adding the effect to the game.

Generating heatmaps is pretty simple. Take a 2d grid of values, perform a Gaussian blur on it, then use each resulting value as an index into a gradient of colours.

For Toxin, the first step was to create a simple array of numbers representing the current state of the cell grid. Toxin cells can be different sizes. To simplify things, I store each big cell as several small cells.

Each cell is given an initial value of 255. When we draw our cells, we use a range from black to white, where values of 0 are black, 255 is white and values in between are shades of gray.

heatmap-initial
The cells are represented as a grid of numbers. Each cell is given the initial value of 255

The next step is to apply a simple box blur to this grid of numbers. Normally heat maps use Gaussian blur, but since Toxin’s grid is such a low resolution we can get away with using a simpler algorithm which is much faster to calculate. To learn more about blurring techniques, I recommend Alex Evan’s article on Gamasutra.

Toxin heat map blur
The cell grid after being blurred. Notice how the values have changed

Now look what happens when we draw our original cell grid using the values from the blur operation. Cells in the middle of large clumps have higher values than solitary cells.

Toxin heat map grayscale
Drawing the original grid with the blurred values

The final step is to colourise these grayscale values so they look cool. We do this by mapping these values onto a gradient I made in Photoshop. Values of 0 map onto the left of this gradient, 255 to the right, and the others to the colours in between.

Toxin heat map gradient

When we draw the grid with the colours from the gradient we get our heatmap!

Toxin final heat map

Submit to reddit

The Next Photoshop

Posted on February 24th, 2013 in photoshop, programming | No Comments »

If you’ve read this blog for very long you’ll know that I am a big fan of Photoshop scripting and procedural graphics. Toxin, the iPhone game I’ve been working on, uses procedural art and animated image processing effects extensively. I don’t think the game would be possible without Photoshop scripting.

However, Photoshop’s scripting system is far from perfect. You cannot access pixel data from within scripts, nor can you draw lines or circles or anything like that. These limitations have become really frustrating to me.

For example, on the day I started work on Toxin, I needed to draw an ellipse with precise dimensions. The whole game takes place inside an ellipse, you see. I couldn’t do it in Photoshop by clicking and dragging, it was too inaccurate, so I wrote a C program using the Allegro game library to create the precise shapes I needed. These were then loaded into Photoshop and used as guides while I created the game artwork.

Later I discovered Processing, which is much quicker to develop in than C. I soon developed a workflow where I would go back and forth between Photoshop and Processing, generating procedural content then processing it or running it through scripts until I got the desired result.

Processing, however has some frustrating quirks of its own. As a simplified front end to Java, you often get Java errors that are incomprehensible without digging into the underlying platform. Also, it cannot effectively save semi-transparent PNGs which means that the anti-aliased sprites I was creating all had a solid background which had to be removed. I ended up redesigning my workflow and using the excellent Ghost and AntiGhost plugins from Flaming Pear to overcome these problems.

From graphics app to graphics platform

All these issues got me thinking about what I really want from a high end graphics program. What I want is something like a programmable, graphical Lisp Machine; a powerful graphics programming platform with the UI of an art application, not an art application with a bolted-on scripting system.

I want the ability to programmatically control every aspect of Photoshop from both external scripts and from a real-time REPL inside Photoshop that works like the command line used in some CAD programs.

I want to be able to type line(10,10,100,100) and have a line appear on my presently selected image. I want to be able to open the REPL and assign my current selection to a variable which I can later re-select with a simple command. I want to be able to access the pixel data in my images, and write my own filters in Javascript within the scripting system itself. I think anyone in high-end graphics or scientific imaging would love something like this.

A true graphics platform like I have described would likely have to be written from the ground up with programmability built in. Nevertheless I did spend some time finding out how far I could go with Photoshop’s native capabilities.

I had the idea of writing a Photoshop plugin that contained a number of drawing functions which could be called from scripts via a Javascript library that integrates with the Photoshop document model. So you could write PSDraw.line(10,10,100,100); in ExtendScript Toolkit, and my Javascript library would construct a call to the plugin which would draw the line.

Unfortunately, it’s not possible to get information from a plugin back to the Photoshop script thats running it, so it wouldn’t be possible to do a getPixel() or anything like that. At best, this plugin/script combo would give us a somewhat clunky way of drawing programmatically but little else that would justify the effort involved. (have you ever seen the Photoshop plugin API?)

As a secondary option I thought about actually embedding V8 inside a plugin which would contain an editor and debugger. Besides the ugliness of having 2 distinct Javascript engines running in the same app, the plugin architecture put paid to this idea. Photoshop plugins are one-shot operations. Load the plugin, set the parameters, perform the operation, then shutdown. My idea would only be effective if the plugin was a persistent part of the Photoshop environment.

So the only options then, would be for Adobe to integrate scripting more completely, or for someone else to start making what would be a true sucessor to Photoshop.

 

Submit to reddit

Programming Toxin – Part One

Posted on October 19th, 2012 in programming, Toxin | No Comments »

Over the next few posts I want to write a bit about how my first iPhone game, Toxin, is being developed. Although I’ve been programming for a long time, this is my first ever project in the Apple ecosystem; I hadn’t even used a Mac before starting this game.

Toxin is written in C++ inside a thin layer of Objective C. I did this for a number of reasons. Firstly I am much more familiar with C++. Secondly, as the most common game development language I knew I would have better luck finding additional libraries and answers to any development problems if I worked in it.

It also meant I could reuse some of my own code. Toxin actually contains code used in my first game, Starblaster (2003). Some of it goes back to DirectX stuff I did in the late 90′s. I always liked having a sense of continuity in my work, a feeling that all my games are connected.

The Objective C layer handles iOS specific stuff like getting the app started up, passing touch information to the game logic, and setting up threads for Toxin’s concurrent level loading. The sound library I use, CocosDenshion is also in Objective C. I wouldn’t rule out doing a whole project in Objective C. I’ve enjoyed learning it and I’ve used it to create several utilities already, including the Toxin Level Editor, which I will probably write about soon. I would, however, want to spend some time comparing the performance of the Objective C Container libraries with the STL beforehand.

Engine? What Engine?

Now, some of my friends believe that the main reason Toxin has taken me so long is because I didn’t use one of the popular 2d engines out there like Cocos2d and instead wrote all my own graphics code. They don’t believe me when I tell them that large engines are unnecessary for small games (though I would never stop anyone from using them) and that I could rewrite my entire graphics system in about 2 weeks.

What’s in Toxin

  • Batched sprite drawing
  • Resource management
  • Messaging system
  • 2d particle system
  • JSON file loading
  • Zip file loading
  • Chipmunk physics
  • Oriented bounding box collision
  • Keyframe interpolation system
  • Concurrent level loading

My “engine” if you could call it that, is a basic set of classes for things like sprite drawing, line drawing, loading textures, and drawing basic primitive shapes. All sprite and line drawing is batched using vertex buffers for maximum speed. The classes are loosely related; I just add something when I need it, not worrying about architecture or anything. The whole thing is about 7000 lines of code, and that includes some significant utility classes I wrote, such as my keyframe interpolation system. I use this all over the place to animate transitions, colour blends and movements of all kinds. I wrote interpolators for many different data types and I’m sure I could reduce the lines of code by making them into template classes.

I used this graphics system to build Toxin’s particle engine which I based on John van der Burg’s Gamasutra article, Building an advanced Particle System. The particles use some simple physics to bounce them off the inside of the elliptical playfield.

At one point, the game had elliptical gravity: When a particle hit the ellipse, gravity would activate for that particle and it would “fall” into the ellipse, over 360 degrees. It was a cool effect but it didn’t look like anything you would expect to happen, so I replaced it with simple bouncing which is much more satisfying to watch.

Some of the enemies in Toxin use the Chipmunk physics engine. One of the things I’m proud of in this game is how you can easily mix and match different types of objects. Some use Chipmunk, others use simple bounding box and oriented-bounding box collision.

Game structure is accounted for by a basic game state manager with simple transitions and there’s a resource managment system that lets me load and unload graphics whenever I need to.

After reading Mike McShaffry’s Game Coding Complete I wrote a messaging system which allows different parts of my game to easily communicate with each other with a minimal amount of dependency. I use this messaging system for spawning enemies, creating explosions, and playing sound effects.

Next time I’ll write something about how Toxin levels work, and I’ll describe my first native Mac program, the Toxin Level Editor. Please let me know if you have any questions or if you want more information about any of the things in this post.

Submit to reddit

Toxin – Coming Soon

Posted on June 10th, 2011 in game development, iPhone, programming | No Comments »

Toxin Title Screen

This is the titlescreen of Toxin, my first iPhone game. It was only supposed to be a warm-up; a short project to help me get back into the game after a few years developing web applications, but it has taken much longer than I anticipated.

I’m doing the whole thing myself, code, graphics and sound, largely because I don’t know anyone who could help me out, but also because I was a child in the 80′s, and despite all the developments in gaming that have happened since then, I still have the image of the lone game developer somewhere in the foundations of my mind. I grew up idolizing 8-bit legends like Tony Crowther and Andrew Braybrook, and learned to code in a world where games had authors associated with them. Things have changed, but I still carry all that with me; I just wouldn’t feel like a proper game developer if I didn’t do at least one game on my own.

Oh, and the title screen is animated. It uses a pretty cool effect that I will probably write about soon.

Submit to reddit

Getting the size of a PNG without loading it

Posted on October 9th, 2010 in game development, programming | 1 Comment »

My current iPhone game (more info coming soon, I promise!) has a resource system that allows me to load texture maps when I need them and unload them when I don’t. This helps makes the game very memory efficient, but it had one annoying flaw. At program startup I had to load and unload several textures to get size information I needed to set up other game structures. To avoid this wasteful operation I started looking at ways to extract information from a png without loading the whole thing.

This StackOverflow discussion was useful, along with this guide to the png format from the W3C, but unfortunately, Apple threw a spanner in the works.

If you’ve been programming the iPhone for a while you’ll know that by default, Xcode premultiplies the alpha channel of PNG files before adding them to the application bundle. It also adds its own undocumented data chunk to the beginning of the file, breaking PNG guidelines which state that the IHDR chunk should always be at the beginning.

This Objective C function will return the size of an image for both standard and Apple PNGs. It scans through the file looking for the IHDR chunk, making no assumptions about its position. It should be easy enough to convert to other members of the C family.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
 
//----------------------------------------------------------------------------
// GetPNGSize() - gets PNG Dimensions without loading any data
//----------------------------------------------------------------------------
BOOL GetPNGSize(const char *fileName,CGSize *pngSize)
{
    // PNG Signature
    unsigned char png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    // IHDR chunk identifier
    unsigned char ihdr_signature[4]={'I','H','D','R'};
 
    FILE *fp;
    if( (fp = fopen(fileName,"rb")) == NULL )
    {
        return NO;
    }
 
    // load png signature and check it
    unsigned char sigBuf[8];
    fread(sigBuf, 1, 8, fp);
 
    if(memcmp(&sigBuf[0], &png_signature[0], 8))
    {
        fclose(fp);
        return NO;
    }
 
    // examine chunks until we find IHDR
    BOOL done = NO;
    while(!done && !feof(fp))
    {
        // get chunk length and type
        unsigned char chunkInfo[8];
        fread(&chunkInfo, 1, 8, fp);
 
        long length = (chunkInfo[0] << 24) | (chunkInfo[1] << 16) | (chunkInfo[2] << 8) | chunkInfo[3];
 
        // is this the IHDR?
        if(!memcmp(&chunkInfo[4], &ihdr_signature[0], 4))
        {
            unsigned char sizeInfo[8];
            fread(sizeInfo,1,8,fp);
 
            pngSize->width = (sizeInfo[0] << 24) | (sizeInfo[1] << 16) | (sizeInfo[2] << 8) | sizeInfo[3]; 
            pngSize->height= (sizeInfo[4] << 24) | (sizeInfo[5] << 16) | (sizeInfo[6] << 8) | sizeInfo[7];
            done = YES;
        }
        else 
        {
            // skip over the data and checksum and go to next chunk
            fseek(fp, length+4 , SEEK_CUR);
        }
    }
    fclose(fp);
    return done;
}
Submit to reddit