1
\$\begingroup\$

Well I was creating a TRON style game, but had an issue with creating the actual light trails for the game. What I'm doing currently is I have an array the same size as my window in pixel size, implemented like this:

int* collision[800][600];

Then when the bike goes on a certain pixel, it is marked with a 1 for traveled on. However what is the most efficient way to create a working light trail display?

I tried to do something like this:

int i, j;
for(i=0; i<800; i++)
    for(j=0; j<600; j++)
        if(*collision[i][j] == 1)
            Image::applySurface(i, j, trailSurface, gameScreen);

But it isn't working properly? It just fills the whole screen with a sprite instead. Whats a better/faster/working way to do this?

\$\endgroup\$

5 Answers 5

1
\$\begingroup\$

You don't need to keep track of each and every pixel.

Just create a class like this

class MyTrail
{
    int x;
    int y;
    public MyTrail(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public void Draw()
    {
        //code to draw a pixel at (x, y)
    }
}

Then create its instance at each and every pixel your bike passes. Through this, you will have a OO way of doing this. This benefits in a way that you will also have control over the trail. Suppose you may want to have timer after which the trail should disappear; Or you may want its color to fade with time. You can include additional members like this

class MyTrail
{
    int x;
    int y;
    int life;
    Color color;
    public MyTrail(int x, int y)
    {
        this.x = x;
        this.y = y;
        this.life = 3000;   //3000ms = 3seconds
        this.color = Color.Blue;  //(R, G, B) = (0, 0, 255)
    }
    public void Draw()
    {
        if(life > 0)
        {
            //code to draw a pixel at (x, y)
        }
    }
    public void Update()
    {
        //Lets say Update is called after 16ms
        //decrement the time
        life -= 16;   //depends upon frequency of method call
        //update the color with respect to time
        color.B -= 16;    //depends on your implementation
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ how would I do collision detection? \$\endgroup\$
    – Rivasa
    Sep 14, 2012 at 20:11
  • \$\begingroup\$ For collision detection, one way is to traverse every point of trail at every movement of the bike. That would be too slow. Another way is to store 800x600 booleans for every pixel. But instead of storing one boolean value in 'int' (like you did), try to compress them and utilize all the 16 bits of the integer. That would be effective and won't considerably slow down the process. \$\endgroup\$
    – Shashwat
    Sep 17, 2012 at 5:14
2
\$\begingroup\$

The first thing that comes to my mind is to create a list of points. Add a point to the list at the start, then each time the bike makes a turn. Then simply draw a line between those points plus the bike position at the end. This way you'll have easy time doing collision aswell. Trying to do this pixel by pixel seems like just a massive waste of resources.

\$\endgroup\$
1
  • \$\begingroup\$ Also this scales extremely well without requiring additional resources- both in size of playarea and lightcycle speeds. Collision is simple as you only need to check the delta of the lightcycle (lastpos->newpos) in a line intersection routine. \$\endgroup\$
    – Felsir
    Oct 29, 2016 at 8:09
2
\$\begingroup\$

For trails, my objects usually have an X/Y structure (such as a Vector2 in XNA) stored in an array of 100 members or so. Element 0 is the current position, with each subsequent value being the previous step. This is a quick and dirty method, and isn't very efficient however, especially if you start to move the elements around.

You might be able to use a queue to easily push data, and pop it when the position structure expires. The answer by Shashwat seems the most robust, as it you can extend it in many ways, including giving them timers.

\$\endgroup\$
1
\$\begingroup\$

I'm not sure if it's applicable in your case, but back in the old days people used a very simple method. they just didn't clear the screen for each frame draw. or in the case they want to distinguish body and head, they used to draw head and only the first body part after head. again not clearing render surface at when render function begins.

\$\endgroup\$
1
\$\begingroup\$

If I read this correctly, you're drawing a sprite at every pixel that is marked as collided with. However, you might not even need to keep record of which pixels or blocks have been collided with. Can you use offscreen render targets? Because if so, you could just draw the sprite at the position of the object making the light trail and not clear the surface. That would produce a smearing effect which is, in this case, what you want.

Pseudocode:

render to canvas()
  draw sprite(vehicle.x, vehicle.y)
end()

draw canvas(0, 0)

Update: collision detection! (in Lua, untested)

 --collision on right side of box
for i = box1.y, box1.y + box1.height do
    if box1.x + box1.width > box2.x and box1.x + box1.width < box2.x + box2.width and i > box2.y and i < box2.y + box2.height then
        --there is a collision!
    end
end

And then you just do a similar block of code for each side of the block.

\$\endgroup\$
4
  • \$\begingroup\$ how do I do a collision detection? In order to check if a user has died? \$\endgroup\$
    – Rivasa
    Sep 14, 2012 at 10:12
  • \$\begingroup\$ Just do simple bounding box collision detection. For all points on each side of the first box, check if that point is within the second box. I would post the code but it's unreadable in comments. \$\endgroup\$
    – tesselode
    Sep 14, 2012 at 13:25
  • \$\begingroup\$ edit your answer? \$\endgroup\$
    – Rivasa
    Sep 14, 2012 at 20:16
  • \$\begingroup\$ Added some basic collision code (in Lua, just as an example). \$\endgroup\$
    – tesselode
    Sep 15, 2012 at 2:56

You must log in to answer this question.

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