3
\$\begingroup\$

I'm currently working on a side-scroller which lets the player alter their speed and I wondered how should I properly generate and control background tiles for such a kind o game. I'm using Flixel but I believe it's a strictly mathematical problem. Here's how I see and do it right now:

  • actually the player is static but he has a pseudo-velocity, that can be increased and decreased (but there is some minimal pseudo-velocity)
  • tiles are random so they are not kept in any tilemap - they are generated by an emitter instead
  • background tiles observe player's pseudo-velocity and alter their own velocity (base velocity is static for a given tile but different tiles can have different base velocities) based on it (so they use their velocity to move in the opposite direction to the player but they also increase/decrease this velocity according to the player to create the illusion of acceleration/deceleration)
  • the starting velocity of each background tile is maintained no matter what the pseudo-velocity of player is (so when the player accelerates, two given tiles with different velocities approach faster to the player but there is no change in the delta of their velocities, so you can say that one tile aproaches the player fast and the other even faster :-))
  • background tiles are generated based on same frequency which is also dependend on the player's pseudo-velocity (so when for example the velocity of all tiles is constant, the distance between consecutive tiles is also constant but when the player accelerates, the frequency of tile generation should increase to retain the same distance between generated tiles)
  • and the last one trick: when the player is moving at minimal speed their sprite is located exactly on the center of the screen but when they accelerate the sprite floats to the left edge of the screen (proportionally to the current speed but with some lag) so the player can see more and has more time to react

Ok, now it's finally time for the problems! :D

  • I cannot come up with the proper formula for the tile generation frequency according to the player's pseudo-velocity (when the player accelerates the frequency increases too slowly and the distance between tiles increases, and when the player decelerates the frequency decreases also too slowly and the distance between tiles gets much too small, they begin to clutter)
  • the problem is also intensified by the last point of the above list - when the pseudo-velocity increases the player's sprite is moved to the left so the tile generation frequency should be additionally increased (and respectively delayed during player's deceleration)

Phew! I think that's a whole description of the problem. Has any of you ever fiddled with such a game mechanic and if yes, have you encountered similar problems and what were your solutions?

If the description is not clear enough, please let my know and I'll provide working example showing above concerns.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I think a working example would be helpful to understand the problem. \$\endgroup\$
    – bummzack
    Nov 3, 2010 at 10:44
  • \$\begingroup\$ I agree on a working example; I can't figure out why already-emitted tiles don't speed up with the player. It seems like it would result in a strange, elastic feel to the environment since changes in speed would take time to propagate. \$\endgroup\$ Nov 3, 2010 at 12:39
  • \$\begingroup\$ are you just moving the background and keeping the player in the middle? ... \$\endgroup\$
    – Spooks
    Nov 3, 2010 at 14:15
  • \$\begingroup\$ @bummzack: I've prepared an example that can be seen here: bit.ly/9Kqomy @Gregory Weir, @Spooks: The full-blown version, as described above, had some elastic feel in it but to simplify things I've fixed player's position at the center of the screen just to show the main problem which is inproper tile generation frequency. Nonetheless I've decided to completely rebuild the generation mechanism which I believe was fundamentally flawed. I've described a proper way in an answer to this question. \$\endgroup\$
    – goshki
    Nov 4, 2010 at 21:15

3 Answers 3

2
\$\begingroup\$

I think you should make the algoritm work differently.

Place your "view" in an array (2D tilemap) and then look forward eg. 20 tiles. The "scroll" is the amount of pixels for 1 tile, so if your scroll becomes negative, just add the size of a tile, and increment offset for "view" with 1. Repeat until scroll pos is postive again.

Then repeat this pattern each frame.

Here is my suggested loop in pseudo programming language.

  1. ScrollPos -= speed;
  2. while (ScrollPos<0) { scrollPos += tilewidth; viewOffset +=1 ; if (viewOffset>has }
  3. "Reposition every active tile inside view" (called updating the frame)

The ScrollPos is the "fraction" of a tile. The viewOffset is the current screen/view position in the tilemap (left side of screen)

Array/tilemap is needed pr. "row" of background. You could do this in multiple levels too, to produce a "parallax" depth - and with 3D this might look even more cool.

var back[10] : array;
back[0] = ".....................X.........X........X...........X............XXXXX"
back[1] = "....................X.........X........X...........X............XXXXX."
back[2] = "...................X.........X........X...........X............XXXXX.."
back[3] = "..................X.........X........X...........X............XXXXX..."
back[4] = ".................X.........X........X...........X............XXXXX...."
back[5] = ".................X.........X........X...........X............XXXXX...."
back[6] = "..................X.........X........X...........X............XXXXX..."
back[7] = "...................X.........X........X...........X............XXXXX.."
back[8] = "....................X.........X........X...........X............XXXXX."
back[9] = ".....................X.........X........X...........X............XXXXX"

Now start with "offset=0" and perhaps look 15 tiles ahead (depending on screen and game size).

Everytime you scroll a tile, your viewOffset will give you an extra "cell" this means that the most left set tiles must be destroyed and a new set should be inserted.

I think I might do it vertically instead of horisontally while displaying the tiles, because the horisontal arrays makes it easy to build a level here, but the vertial array would make it easier to scroll in realtime I think. But you decide.

Look up how the old "snake game" is build too. There is the idea too, as the head and the end of the snake is a matter of positions in a growing array (same trick with the view here, just a "horisontal snake pr. row".

Does it make any sense?

\$\endgroup\$
0
\$\begingroup\$

Don't 'spawn and move' individual tiles. That way will only lead to pain.

Create a big 2-dimensional array of tile types (the 'tilemap') containing your whole level, and display the section that is currently on-screen.

Just keep track of a 'scroll position' - either the location of the top-left or centre of your screen measured in pixels within the entire tilemap. Then use this to determine which range of tiles to draw, and where they should be on the screen.

\$\endgroup\$
-2
\$\begingroup\$

It appears that the problem was the tile generation algorithm itself. I've completely rebuild the mechanism according to the solution given here: http://forums.tigsource.com/index.php?topic=15642.msg450370#msg450370

So instead of applying velocity adjustments to each and every tile and generating one tile at a time with adjusted frequency, it proved to be much easier and efficient to just generate tiles in groups that can be refilled with tiles and reused after they get out of the screen.

I hope this question (and answer) will be useful for someone.

\$\endgroup\$

You must log in to answer this question.

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