I have a circular character that rolls down terrain like that shown in the picture below.

enter image description here

The terrain is created from an array holding 1000 points. The ground is drawn one screen width infront and one screen width behind. So as the character moves, edges are created infront and edges are removed behind.

My problem is, I want to create box2d bodies at certain locations along the path and need a way to store these creator methods or objects.

I need some way to store a position at which they are created and some pointer to a function to create them, once the character is in range. I guess this would be an array of some sort that is checked each time the ground is updated and then if in range, the function is executed and removed from the array. But I'm not sure if its even possible to store pointers to functions with parameters included... any help is much appreciated!


1 Answer 1


Since you are only moving from left to right, all you need to do is store a two dimensional array of x coordinates and object type/parameters.

If you have an objects x position, you just need to see if it's on screen using this, if it is, put it in and work out the y coordinate of the ground at that location. The X position can simply be an index to your terrain array.

You can use bit-masking to create unique ids for objects and parameters. Then create a Factory method which will accept this id, break it down to get the type, call the constructor for that type and pass the id to it. The constructor can then use the id to work out how the object should be constructed.

As a quick example;

#include <iostream>

enum Type
    Box = 0,
    Enemy = 1,
    House = 2,
    Plant = 3,
    Vehicle = 4,
    // We want to shift value to the right hand side
    // of the int. The biggest value is 4 which
    // requires 3 bits to specify, so we want to
    // shift the number up to 32 - 3 (29).
    TypeBitShift = 29

enum EnemyType
    Snake = 0,
    Rhino = 1,
    Shark = 2

void main()
    unsigned int * IDs = new int[3];
    IDs[0] = (Enemy << TypeBitShift) | Snake;
    IDs[1] = (Enemy << TypeBitShift) | Rhino;
    IDs[2] = (Enemy << TypeBitShift) | Shark;

    for(int i = 0; i < 3; ++i)
        // push the parameter bits off the end and convert to a type
        Type T = (Type)(IDs[i] >> TypeBitShift);
        if ( (int)T == Enemy )
            // trim the type section, you can use;
            // (IDs[i] - ((IDs[i] >> TypeBitShift) << TypeBitShift))
            // or IDs[i] - (int) T << TypeBitShift since we already have the type
            // You can also get rid of any type parameter with;
            // or (IDs[i] & 0xFFFFFFFF >> (sizeof(int) * 8 - TypeBitShift))
            // or (IDs[i] & 0xFFFFFFFF >> 3)
            EnemyType ET = (EnemyType)(IDs[i] & 0xFFFFFFFF >> (sizeof(int) * 8 - TypeBitShift);
            case Snake:
                std::cout << "I'm a snake.\n";
            case Rhino:
                std::cout << "I'm a rhino.\n";
            case Shark:
                std::cout << "I'm a shark.\n";
  • \$\begingroup\$ Quick note. I will try this out later and correct as needed. I don't have time right now. Unless someone else wants to correct any mistakes for me? I also know that the bit masking thing might be going a bit far, when two ints is also fine, but it's fun. \$\endgroup\$ Jun 11, 2012 at 13:23
  • \$\begingroup\$ Even with my edit it's not the most straight forward way of doing this (which is just to use an int array or an array of the types) but this should give you an easy way to generate small files to store things. And since it looks like your learning I figured you'd like an interesting solution. Also, the sample is in C as that was the tools I had available. \$\endgroup\$ Jun 11, 2012 at 19:38
  • 1
    \$\begingroup\$ Way overcomplicated. Bit shifting and masking are good skills to have but not something that solves every problem. This here seems utterly useless and only adds to the confusion. \$\endgroup\$
    – bummzack
    Aug 11, 2012 at 7:03
  • \$\begingroup\$ The only important part there is the first two paragraphs really. The rest was just to give an idea on how I would solve the same problem. It has a small impact on memory and I can randomly generate it for testing or for game-play. I also thought it suited the situation well as I didn't know how complicated the "objects" in the question would get. \$\endgroup\$ Aug 13, 2012 at 16:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .