Archive for the Category Programming

 
 

Cocos2d-x + Box2d Breakout Updated

Cocos2d-x releases since version 3 have broken compatibility with old tutorials. This can especially be a problem when you want to do something slightly non-standard from the point-of-view of Cocos2d-x.

If you want to use physics in a Cocos2d-x game the current standard way to do this is to use the integrated physics classes, which are Chipmunk-based by default and can use Box2d too in some hybrid way the details of which are not at all clear. However,  in my case I want to use Box2d, period, Box2d in a non-integrated manner for transparency and in order to leverage the vast amount of code that you get to peruse and possibly use by writing to vanilla Box2d. When doing something like this it can be hard to know where to start given that any sample code you find will be broken.

For setting up a Box2d/Cocos2d-x project there was always this BreakOut implementation to Cocos2d-iphone by Ray Wenderlich, link, which is transliterated into Cocos2d-x here but to relatively ancient versions of both Box2D and Cocos2d-x. I’ve taken that code and updated it to Cocos2d-x version 3.2 and Box2d version 2.3.

Here is my updated version.

To use do the following:

  1. Setup a cocos2d-x v3.2 project via the python script. This will give you Box2d v2.3 set up in your project without you having to do anything else.
  2. Copy the source code in the above zip file into your project’s Classes directory.
  3. Copy the image files the Ball.jpg, Block.jpg, and Paddle.jpg from here into your project’s Resources directory.
  4. Build.

(You can copy over the music/sound files too. I have the relevant calls commented out in the code above)

Zzazzy 1.0.0

My iPad game Zzazzy has made it through the review process and is now on the App Store: see here.

So that took a little longer than I had intended …

I will be updating the page I have for it here this week with more detailed instructions than what the app itself provides (There is a tutorial mode but it really just covers the basics), but basically it is an action puzzle game in which you lay tiles on a board to form interlocking words, but you’re building words against the clock where

  • forming large grids of words puts time back on the clock
  • not using tiles eventually leads to tile death which takes time off the clock.

It’s a continuous play type of game, like Tetris or something, but with a completely new game mechanic.

Snurtle and My Greatest Contribution to Mathematics, Such That It Was

This summer coming up will be 20 years since the summer after I graduated from college. I’m currently in that golden period in between software jobs — starting a new one in March — and, given the free time, have just done something which I have been meaning to do since that summer.

I generated the following image in a non-ad hoc manner, with re-useable software that I developed myself.

That year after college I was kind of shiftless. I chose to just not participate in the whole interview circus that normally accompanies one’s senior year of MIT and let myself graduate without having plans of any kind for the future. I think that I was tired mostly and was kind of sick of the universe of engineering and all of its hurdles and dog and pony shows, and I think I kind of half-understood that this would be the last time in my life in which it would be possible for me to be totally free of that universe — until, I guess, retirement.

Anyway, I lived in the slums of Boston — that is, Roxbury — with a friend of mine from high school and some roommates we found, one of whom ended going to jail (but that is another story), worked temp jobs, and didn’t do much of anything … except for some reason I became obsessed with aperiodic tilings of the plane and substitution tilings generally and put a lot of effort into coming up with one of my own. I wanted to find, for reasons that aren’t clear to me now, an aperiodic analog of the normal regular hexagon tiling.

It’s kind of a blur — I don’t really remember where the above came from as a sequence of steps — but the above is a patch of the best tiling I discovered during this period. It is generated via the following substitutions. The lengths of the sides of triangles and trapezoids are multiples of ϕ, the golden ratio.

As far as I know, the above is original and has not been discussed in the literature but I never was able to come up with local matching rules on the hexagons to enforce aperiodicity.

At that time I did develop software for working on these sorts of structures but what I came up with in retrospect wasn’t The Right Thing. This wasn’t all together my fault. Those were different times: no GitHub, no free code. If I wanted to output into a vector format it would have to be my own vector format. If I wanted to render that format to the screen I would have to write code to render that vector format to the screen, and so on. Also GUI applications were all the rage and were still new and shiny, so I was biased in that direction. I never really liked what I came up with then, and it wasn’t portable anyway; it was a black-and-white Macintosh application in C.

Having the negative example of that project all those years ago made it easy to see what I actually needed: not a GUI application but a programming language. So last week, I wrote one: a little language for specifying recursive structures like the above and rendering them in SVG. I’m calling it Snurtle because it is basically a combination of Python (a snake) and the turtle-based graphics of Logo. I chose Python syntax because I wrote the Snurtle interpreter in Python and thus got tokenization for free using Python’s “tokenize” module.

So, for example, the following simple substitution

is represented by the following Snurtle script:

sub square(n):
    terminal:
        poly("bisque", "orangered", 1 ):
            forward(n)
            turn(PI/2)
            forward(n)
            turn(PI/2)
            forward(n)
    nonterminal:
        rectangle(n)
        branch:
            turn(PI)
            forward(n/2)
            turn(-PI/2)
            forward(n/2)
            square(n/2)
            square(n/2)

sub rectangle(n):
    terminal:
        poly("lightskyblue", "orangered", 1 ):
            forward(n/2)
            turn(PI/2)
            forward(n)
            turn(PI/2)
            forward(n/2)
    nonterminal:
        square(n/2)
        turn(PI)
        square(n/2)

yielding

which, I think, is self-explanatory except for the “branch” block. Branch blocks tell Snurtle to push the state of the turtle on to a stack and then pop it when exiting the branch i.e. branch works like parentheses operators in L-systems. Also the following Snurtle constructs are not illustrated in the above:

  • flip blocks: similar in syntax to branch above. Tell Snurtle to multiply the angle arguments passed to turn statements by -1. (i.e. flipping them)
  • stroke and fill blocks: similar to “poly” above.

Anyway, here is my snurtle source code. Usage to generate the above would be:

snurtle.py -w -s square -k 500 -m 8 -o squares.html -c “10,10” “snurtle_scripts\squares.snu

where

  • -w : wrap the generated SVG in HTML (so it can be viewed in browser)
  • -s : initital substitution used to kick off the recursion
  • -k : scale factor in SVG output
  • -m : max stack depth before substituting in terminal blocks rather than nonterminal and ending the recursion
  • -o : output filename
  • c : starting coordinate of the turtle.
  • -d : Comma delimited string as -c, that provides width and height attributes for the SVG. (not shown)

Snurtle is pretty rough at this point, but I plan to continue working on it, especially if there is interest. Check back here, The Curiously Recurring Gimlet Pattern, for updates — or on this Quora blog which I will try to keep in sync — if you are interested. In particular, I plan on adding the following features / dealing with the following issues:

  • Substitutions can’t currently have more than one argument. I just never got around to adding this functionality as I never had a use-case in all the sample scripts I have tried, but there is no reason to limit “sub” blocks in this way.
  • Color, stroke color, and stroke thickness parameters to poly, stroke and fill blocks should be optional with intelligent defaults but aren’t currently.
  • Maybe add a z-order parameter to poly, stroke, and fill.
  • Add variables.
  • Possibly add “mirror” blocks which would be syntactic sugar for executing the block’s body in a flipped branch and then executing it again normally. This would be handy in definitions of complicated structures like my golden hexagon substitution.
  • Add “reverse” blocks which would cause the statements in a block to be executed in last to first order, recursively running compound statements this way too.
  • Add some kind of loop control structure, “repeat” or something.
  • Built-in system variables for (like “PI” above) for current stack depth and max stack depth.
  • Add exponentiation to the set of operations that can be performed in expressions.

New Zzazzy screenshot

Here is what the game is looking like currently (click for fullscreen):
screenshot

The World’s Simplest 2D Curve Library

For the game I’m working on I need to have sprites that travel along curving paths.

I’m talking about the sprites traveling along somewhat arbitrary curves, meaning curves that look good, not curves that result from gravity or other physical forces. If you need those kinds of curves, e.g. the parabolic trajectories of cannonballs, you need to simulate the forces acting on the sprites and that is not what I’m talking about in this post.

Caveat aside, an arbitrary curving path is a pretty common thing to need but I think is unnecessarily headache-inducing because curves in graphics are just confusing. Maybe you’ve found yourself thinking

  • I don’t know what the difference between a spline, a bezier curve, a bezier curve of various degrees, a B-spline, a t-spline, etc. is.
  • I don’t know which of the things mentioned above I need.
  • Every time I try read the wikipedia article on these things the math gets heavy and my eyes glaze over

etc.?

So assuming it’s not just me, as a public service I’m going to try to clear this up.

Short version, if you need to have a sprite that travels along a curving path from point A to point B in x amount of time, you probably need a cubic bezier curve and generally, in 2d game programming, all you will ever need probably is n cubic bezier curves possibly concatenated together. You can concatenate them yourself if you need to do that, so what you need is a way to define a cubic bezier and a function get the point along the bezier at some time t. Despite what you would think from trying read the literature, this turns out to be trivial — I mean less than a dozen lines of code.

More thoroughly, explaining away my bulleted list above:

  • A spline is a more general term than a “bezier curve”: a bezier curve is a particular polynomial function (that I will implement below) that defines a curve that goes from point A to point B given some control points. A bezier spline is an aggregation of n of these. A general spline can be an aggregation of other kinds curves e.g. a B-spline is composed of a bunch of curves that are generalizations of bezier curves.
  • The only kinds of beziers you need to be concerned with are quadratic and cubic beziers. Quadratic beziers are just parabolas and are not interesting. Cubic beziers are curves that go from point A to point B and are tangent to a given line at A and tangent to given line at B. They are defined by A and B plus two other control points that define the tangent lines and the weight they have on the curve.
  • Cubic bezier curves are easy to implement. See below.

So here is my curve “library”:
Bezier.h

#include <utility>

class Bezier {
	private:
		float x1_, y1_, x2_, y2_, x3_, y3_, x4_, y4_;
	public:
		Bezier(float x1, float  y1, float x2, float y2, float x3, float y3, float x4, float y4);
		std::pair<float,float> getPoint(float t) const;
};

Bezier.cpp

#include "Bezier.h"

Bezier::Bezier(float x1, float  y1, float x2, float y2, float x3, float y3, float x4, float y4) :
		x1_(x1), y1_(y1),
		x2_(x2), y2_(y2),
		x3_(x3), y3_(y3),
		x4_(x4), y4_(y4) {
}

std::pair<float,float> Bezier::getPoint(float t) const {
	float x = (x1_+t*(-x1_*3+t*(3*x1_ - x1_*t))) + t*(3*x2_+t*(-6*x2_ + x2_*3*t)) + t*t*(x3_*3-x3_*3*t) + x4_*t*t*t;
	float y = (y1_+t*(-y1_*3+t*(3*y1_ - y1_*t))) + t*(3*y2_+t*(-6*y2_ + y2_*3*t)) + t*t*(y3_*3-y3_*3*t) + y4_*t*t*t;
	return std::pair<float,float>(x,y);
}

You define a cubic bezier by making a Bezier object giving the constructor four points. (x1,y1) and (x4,y4) will be the start and end of the curve. The curve will be tangent to line segment (x1,y1)-(x2,y2) at its start and tangent to (x3,y3)-(x4,y4) at the end. To get a point along the curve call getPoint(t) where t=0.0 gives you (x1,y1), t=1.0 gives you (x4,y4), and 0.0 < t < 1.0 gives you the point along the curve in which 100t percent of the curve has been traversed e.g. 0.5 is halfway.

So that’s it. Code is here. I also included a Win32 GDI project that draws cubic beziers, screenshot below. (The sample program is also a little example of how to write a very basic Win32 program, which these days younger programmers seem to appreciate as a sort of parlor trick…)

Syzygy Update

So, looking at the early entries of this blog, I must have started working on Syzygy around the beginning of the year 2012 because by March 2012 I had the Win32 prototype done. At that time, I didn’t own a Macintosh, didn’t own an iOS device, had never heard of cocos2d-x, and, professionally-wise, was still writing image processing code for Charles River Labs / SPC. Since then SPC was killed, and I moved from Seattle to Los Angeles … but anyway as of today, about a year later, I have the primary functionality of Syzygy running on my iPad, re-using the source code, mostly, from that prototype. I haven’t really been working on it the whole time — there was a lot of moving-to-California in there somewhere, but here’s a screenshot (click for full-size):

There’s a common question in the mobile games forum of gamedev.net, “How can I make a game for iOS only using Windows?”. The answer to this is either (1) you can’t or (2) write your game to Marmalade or cocos2d-x on Windows and then when you are done get a friend with a Mac to let you register as an Apple developer, build under Xcode, and submit to the App store. I always say (1) is the serious answer and if you are unserious, or want to develop a really simple game, then go with (2). Basically I say this because you need to run your game on a device frequently and early, and I’m seeing the truth to this now.

Now that I have Syzygy running on a device I’m seeing issues with input which are artifacts of running on an iPad. The prototype implemented mouse input as a stand-in for touch input. It turns out touch screens and mice aren’t the same thing. The game plays on the device, but when you drag tiles your finger is in the way of the tile visually. You can’t see the tile you are dragging — this seems like it wouldn’t be a big deal, but it kind of is. … This sort of thing is the reason, in my opinion, that if you are not testing on a device during primary development then you are not really serious…

So not sure what I’m going to do about this, I’m thinking of making the tile the user is dragging larger and offset to the upper-left while the user is dragging it. The problem with this is to make it look nice I’d have to have large versions of all the relevant art and some of it I don’t even really remember how I rendered in the first place…

Marble Madness Madness

gamedev.net recently linked to this video about the making of Marble Madness, which got me thinking about the raster-to-vector via contour extraction script I wrote in Python last year and the fact that, it being the future and all, I can probably find all of the art from Marble Madness unrolled into a single image file. So three clicks later and, oh yeah:

(Click the image for full size)

So I ran the above through my raster-to-vector converter. Here are the results (zipped, this is a huge file, over 20,000 SVG paths)  This file kills Adobe Illustrator. It took 15 minutes just to open it.

SVG for a single level is more manageable.  Here’s  the 2nd level as unzipped SVG … (curious to see if various browsers can handle this) Illustrator could handle this one pretty well so I experimented with applying various vector filters. Below is a bit of it with the corners rounded on the paths (click for a larger version):


Not sure what this all amounts to … just some stuff I did today. However I did learn

  • Python is slow. It took a really long time to generate the big file, seemed too long. I think C++ would’ve been like an order of magnitude faster — that’s my intuition anyway.
  • My contour extraction program really works which is kind of surprising — I thought for sure running it on something like this would crash it. (It does still have the problem that it can’t handle paletted raster image formats, but that’s the only bug I encountered)

Sprite Packing in Python…

I’ve been working on my puzzle game Syzygy again, after a long hiatus, and am now writing to iOS/cocos2d-x rather than just working on the prototype I had implemented to Win32.

The way that you get sprite data into cocos2d is by including as a resource a sprite sheet image and a .plist file which is XML that specifies which sprite is where. Plists are apparently an old Mac thing — I had never heard of this format. .plists describing a lot of sprites would be a chore to write by hand so there is a cottage industry of sprite packing applications.

I tried out one called TexturePacker and liked it a lot — except that it is crippleware; I need a few features that are only in the full version; plus I can’t stand crippleware; and I think $30 is too much for something that I can write myself over the weekend. So I decided to write my own sprite packer over the weekend.

The result is pypacker, a python script: source code here. Usage is like

pypacker -i [input] -o [output] -m [mode] -p

where

  • [input] = a path to a directory containing image files. (In any format supported by the python PIL module.)
  • [output] = a path + filename prefix for the two output files e.g. given C:\foo\bar the script will generate C:\foo\bar.png and c:\foo\bar.plist
  • [mode] = the packing mode. Can be either “grow” or fixed dimensions such as “256×256″. “grow” tells the algorithm to begin packing rectangles from a blank slate expanding the packing as necessary. “256×256″ et. al. tell the algorithm to start with the given image size and pack sprites into it by subdivision, throwing an error if they all won’t fit.
  • -p = optional flag indicating you want the output image file dimensions padded to the nearest power-of-two-sized square.

The algorithm I used is a recursive bin packing algorithm in which sprites are placed one-by-one into a binary tree. I based it directly on Jake Gordon’s work in Javascript for generating sprite sheets for use in CSS, described here, only my algorithm is sort of like version 2 of his i.e. I fixed an issue that bugged me about his algorithm.

The core of the algorithm is a function that looks like this:

def pack_images( named_images, grow_mode, max_dim):
    root=()
    while named_images:
        named_image = named_images.pop()
        if not root:
            if (grow_mode):
                root = rect_node((), rectangle(0, 0, named_image.img.size[0], named_image.img.size[1]))
            else:
                root = rect_node((), rectangle(0, 0, max_dim[0], max_dim[1]))
            root.split_node(named_image)
            continue
        leaf = find_empty_leaf(root, named_image.img)
        if (leaf):
            leaf.split_node(named_image)
        else:
            if (grow_mode):
                root.grow_node(named_image)
            else:
                raise Exception("Can't pack images into a %d by %d rectangle." % max_dim)
    return root

We iterate through the images we want to pack. For each image, try to find a rectangular node in the tree that can contain the image. If one exists, place the image in the node and subdivide the node such that the remaining space, not taken up by the image, is available in the tree (this is what ‘split_node’ does). If such a node cannot be found, throw an exception if we are not in ‘grow’ mode or expand the root rectangle node to accommodate the new image if we are in ‘grow’ mode.

This routine is very similar to the Javascript implementation I linked to above. The difference is in the details about the structure of the binary tree. Jake Gordon’s Javascript implementation uses a node type that stores an image in the upper left and has children that he calls ‘right’ and ‘down’  like this:

Since actual data is always burnt into the upper left, it means that the tree can never subdivide into this space; we can never recurse into the upper left. This results in the grow_node routine being awkward to write. When we grow the root we either want to extend to the right or extend down, if the upper left can be a node and not image data this is a simple matter of creating a new node and making the the existing root its upper or left child. Anyway, Jake Gordon’s implementation results in a packing tree that cannot both grow right and grow down simultaneously because it would have been complicated to implement this. This limitation is not a problem practically as long as you sort the images from largest to smallest before running the packing algorithm —  a standard heuristic from the bin packing literature.

I however wanted to see if the standard sorting heuristic is really accomplishing anything. I wanted to be able to pack rectangles in random order. I therefore simplified the trinary node structure of the Javascript implementation into true binary nodes either oriented horizontally or vertically like this:

Further now only leafs can contain images and if a node is not a leaf it always has two valid, that is non-null, children. Using this type of tree structure makes the full grow_node routine more or less trivial.

Beyond that, I’m using the following heuristics:

  • If the orientation (horizontally or vertically) of a split is not forced, split with the orientation that will result in the new empty node having the largest area
  • If the orientation of growing the root rect is not forced, grow in the direction that leads to the smallest increase in the maximum side length of the root rectangle. (This heuristic enforces squarishness and is extremely important. Without doing this the grow version of the algorithm is basically unusable, and in this sense this grow heuristic can be considered part of the algorithm rather than a heuristic that can be swapped out)

Sorting by size (max side length) turns out be about a 6% improvement with this algorithm. Here’s 500 rects packed with sorting (top) and without (bottom):

The Cocos2d-x Device Orientation Bug…

This took me all morning to figure out. I’m posting here so there is clear information on this subject in at least one place on the internet.

The situation is this: when targeting iOS6 using Cocos2d-x v2.0.2, there is a bug in the auto-generated “Hello, World” code that shows up in a fresh project such that the compiled game will not display in landscape orientation even after following the steps in this item from Cocos2d-x documentation (such that it exists).

The solution is to follow the steps enumerated in this note from Walzer Wang. This fix is probably already in v2.1 but 2.1 is still beta, as far as I know, so this issue is probably still in a lot of code out there…

Thoughts on porting Syzygy to iOS

I’ve started trying to figure out the way in which I’m going to port Syzygy to iOS. I don’t actually own a Mac — though I may get one this weekend — so this is all theoretical at this point.

What I have right now is an implementation written in C++ to the Win32 API. Part of this implementation is a very basic 2D game framework. This 2D framework has an abstract widget class that has render and update methods. I didn’t call this class “sprite” because it is more general (and basic) than a sprite class : it can be implemented as anything that knows how to update and draw itself. For example, I have text widgets, that call the Win32 DrawText function in the draw method. Widgets are contained in GamePhase objects; GamePhases have a vector of lists of widgets, where each widget list represents a layer, so the order of a GamePhases’s list vector is effectively enforcing a z-order. GamePhases have update and render functions that can do phase specific rendering (e.g. draw a background) and then call the render and update methods of the widgets contained in the layers. GamePhases also have a predicate “IsPhaseComplete” and an accessor “GetNextPhase” which are used along with update and render to implement the game loop.

That’s basically it as far as a game engine goes. This code clearly is not logically platform-dependent. In practice Windows leaked into the implementation in the Render method which takes an HDC as a formal parameter and elsewhere where I wasn’t being careful in avoiding Win32 types. So my initial plan on porting to iOS was to refactor the 2D game framework part of the codebase to be truly platform independent and then to find an open source 2D drawing library that someone else implemented on top of OpenGL ES and reimplement the rendering code in terms of that 2d library.

The trouble is the 2D OpenGl-based library surprisingly doesn’t seem to exist. There is a project that someone did called Gles2d which is what I want but it is orphaned and never adapted to iOS anyway. It was implemented for the GamePark32 hardware, I believe. So my options are

(1) Stick with the original plan and adapt the Gles2D codebase to iOS myself.
(2) Stick with the original plan and write my own 2D graphics in OpenGL ES layer.
(3) Throw out everything and reimplement the application to Cocos2d in ObjectiveC.
(4) Keep whatever I can of my code and re-factor to use the Marmalade framework in C++.
(5) Keep whatever I can of my code and re-factor to use Cocos2d-x in C++.
(6) Stick with the original plan and write the platform dependent drawing stuff to SDL 1.3.

Long story short, I think I’m going to do (5).

(1) and (2) are just not work I feel like doing at this time. (3) would be a good solution but I’d be locked into iOS and would have to gain more competence at ObjectiveC development than I feel like investing time-wise at this point — however, I may end up doing things this way if it becomes clear that it is the easiest approach. (4) is out because I don’t think I need a very powerful game engine, Marmalade costs money, and I wouldn’t be using most of it. I’m ruling out (6) because I don’t really trust SDL 1.3 on iOS; maybe I’m wrong about this but SDL doesn’t officially support iOS and it just seems like there would be problems.

So (5) … Cocos2d-x is a reimplementation of the Cocos2d API but to C++ rather than ObjectiveC. It is designed for cross-platform (i.e. across iOS and Android specifically) and the project looks alive and well. There is even a Win32 build of it that uses PowerVR’s GLES emulator for windows so I could in theory start work without actually owning a Macintosh. The only problem I see with Cocos2d-x is that documentation seems to be non-existent and it is being developed by guys who are clearly speaking English as a second language so I may have trouble finding answers to questions and so forth … we will see.

Anyway, … thoughts?