Algorithms

**tcaudilllg**:

Glad to be of service. I was thinking that we really don't understand these algorithms that much, or it would be easier to create complex effects.

Scrolling Algorithm: Determine the Distance Scrolled by the Camera

In determining the distance, two rules are applicable:

if a potential position is lower on a dimensional axis than an immediate position, the distance is between those two points is expressed as a negative number.

if a potential position is higher on a dimensional axis than an immediate position, the distance is between those two points is expressed as a positive number.

meaning

if the potential x coordinate is left of the immediate position, the horizontal distance is negative.if the potential x coordinate is right of the current position, the horizontal distance is positive.if the potential y is north the current position, the vertical distance is negative.if the potential y is south the current position, the vertical distance is positive.

We use "left" and "right" instead of "east" and "west" because on a 2D plain left is always west and right is always east. East and West are objective assessments of direction; left and right are subjective. In general, it is more familiar to use left vs right if possible. We cannot use "above" or "below" in this sense because the coordinate axes imply values that are above or below each other on the number line, meaning there is risk for confusion between subjective assessments of direction and mathematical comparisons between numbers. Besides, "north" and "south" are more familiar than either above or below in the context of coordinates.

How to determine the distance traveled? The answer is that we already have it, but we need to set its sign for the purpose of guiding the choice of possibilities above.

We use two rules to set the sign of the distance.

if the camera's position on an axis' number line is decreasing with the movement, the distance is negative.if the camera's position on an axis' number line is increasing with the movement, the distance is positive.

Which expands to:

if the camera's position on the x axis is decreasing with the movement, the horizontal distance is negative.if the camera's position on the x axis is increasing with the movement, the horizontal distance is positive.if the camera's position on the y axis is decreasing with the movement, the vertical distance is negative.if the camera's position on the y axis is number line is increasing with the movement, the vertical distance is positive.

Now compute:

Code:

if (ghostCamX < cameraX)

{

xDistance = xDistance * -1;

}

if (ghostCamY < cameraY)

{

yDistance = yDistance * -1;

}

Because the distance is positive by default, we only need to change the sign if we need a negative value.

Next up, parallax scrolling and continuous movement.

**tcaudilllg**:

Parallax scrolling is accomplished by moving two or more cameras at once. Understanding how parallax works is difficult because the effect itself is complex. At first we are inclined to assume that the cameras are somehow "splitting" the map somehow. But this is impossible: how can the "map" be split? It cannot. Parallax scrolling always involves independent layers of the same map -- maps unto themselves, which are stacked on top of each other. Each of these layers has its own independent camera.

To create a parallax scrolling effect, we must first stack the layers.

Scrolling Algorithm: stack map layers on top of each other

Procedure:

draw each layer of tiles from the farthest to the closest to the fore.

In general, whenever the conditions for scrolling are met on the "leading" layer, the other layers scroll with it. (assuming they have not crossed the boundaries of the own maps). To achieve parallax, these layers must scroll at different rates. Because we associate stillness with distance, parallax can convey a sense of depth and realism which is impossible to obtain without it.

Scrolling Algorithm: Parallax Scrolling

Procedure:

Scroll the leading layer.Scroll the other layers in proportion to their distance from the leader and their proximity to the foreground.

Code:

moveCamera (layer)

{

// move camera

}

for (layerIndex = 0; layerIndex < layerLimit; layerIndex++)

{

moveCamera(layerIndex);

}

Basically, the non-leading layers follow after the leader at a rate which is a percentage of the leader's rate. How to calculate this percentage?

Compare the size of the camera to that the layer. When the leading layer camera box hits a bound, all of the other layers' camera boxes should also hit their bounds. Therefore when the leading camera is halfway across its layer, all of non-leading cameras should be also be halfway across their layers.

In general, each of the layer camera boxes should travel the same percentage of the dimensions of the layer as each of the others. If the leading layer's camera scrolls 16 pixels per unit of distance, then a layer that is 4 times that size should scroll 64 pixels per unit scroll of the leader. A layer that is half the leader's size, conversely, would scroll eight pixels per unit scroll. In general, the ratio of a non-leading layer's unit scroll to the leader's unit scroll is the same as the ratio of the non-leader's total width/height to the leader's.

Scrolling Algorithm: Compute the scroll rate of a non-leading layer from a layer's rate for a given dimension.

Code:

cameraUnitDistance = leaderCameraUnitDistance * (layerWidth / leaderLayerWidth);

(that was hard)

Next, smooth movement and smooth scrolling.

**tcaudilllg**:

Smooth scrolling is accomplished by moving the camera gradually over a unit of distance. It requires the institution of a delay between each translation of the camera from one point to another. This delay is always implemented with a timer function.

Scrolling Algorithm: Compute the delay period between point translations

Choose the duration for a unit scroll Divide the unit scroll duration by the distance unit to be scrolled.

Increasing the pause between point translations has the effect of decelerating the scroll. Decreasing the pause, conversely, accelerates the scroll.

The best way to control acceleration/deceleration is to make a copy of the translation interval for each camera. Make two copies, one which is left constant and another which is subject to change.

Code:

camera[index].scroll.intervalConstant = scrollInterval;

camera[index].scroll.interval = camera[index].scroll.intervalConstant;

Layers scrolling at different speeds (due to parallax) must decelerate proportionally to each other. Managing this can be complicated, but is simplified by giving each camera a "step" variable. The step variable acts as a counter, and relies on another variable as its limit. When the step variable passes its limit, it is reset to zero and the layer is scrolled by a single pixel. The limit is found by dividing the unit scroll of the leading layer by the unit scroll of the non-leader. The limit may not be even; however, integer arithmetic will still yield (usually) passable results.

**tcaudilllg**:

Hey Richard, could you put a program together demonstrating parallax? It would be best to post the code and a video clip of the program running.

**Richard Marks**:

Quote from: tcaudilllg on October 28, 2009, 02:21:14 PM

Hey Richard, could you put a program together demonstrating parallax? It would be best to post the code and a video clip of the program running.

Yeah after the contest I will. (You entering it by chance?)

Navigation

[0] Message Index

[#] Next page

[*] Previous page