User Tools

Site Tools


en:tutorials:orxscroll:scrollobject_along_a_curve

This is an old revision of the document!


Tutorial in progress.

Moving a ScrollObject along a curve segment

In this tutorial we'll go work through how to make an object travel along a curve segment.

Set up an orx/Scroll project

You can follow this tutorial to help you set up a new orx/Scroll project. Once set up, create a ScrollObject class for your scroll project. We will make use of the Update function in order to update the object's position every frame.

Assets

Here is a ship graphic that can be used:

The config for the ship which will fly along the curve is:

[Ship]
Graphic         = @
Texture         = fighter.png
Pivot           = center
Smoothing = true

The Curve

We'll need a curve for our project for the object to travel along. A bezier curve segment is made up of:

  • 2 Points, for the start and end, and;
  • 2 Control Points, for adjusting the size of the curve

Here is an illustration of a curve from the Orx Curve Editor:

This tutorial centers around the use of the orxVector_Bezier function. This function takes four vectors, 2 for the points, and 2 for the control points.

Before we discuss the function further, lets get some vectors for the curve segment first.

The curve segment we'll use in our config is the following:

[Curve]
Points = (-243.072, -82.3369, 0) # (-51.0597, 145.47, 0) # (175.771, -171.898, 0) # (241.819, 77.2513, 0)

This is the format that is outputted from the Orx Curve Editor, but you can use any collection of four vectors you like.

To get the four vectors from the config into variables, you can use:

	orxVECTOR vectors[4];
 
	if (orxConfig_PushSection("Curve")) {
		for (int i = 0; i < 4; i++) {
			orxConfig_GetListVector("Points", i, &vectors[i]);
		}
		orxConfig_PopSection();
	}

The last parameter of the orxVector_Bezier function takes the interpolation position. This is a value between 0.0 and 1.0. 0.0 is the very beginning of the curve segment. 1.0 is the very last point of the curve segment. A value between 0.0 and 1.0 is a position somewhere along the curve.

To illustrate, see the following:

In the image above, by setting 0.25 as the interpolation position, you will locate a vector position a quarter of the way along the curve segment.

The first parameter of the orxVector_Bezier function is the vector to store the result.

Now we have everything we need.

Making the object move

Now that we have the four vectors that define the curve segment, and an output vector to store the result, then we can loop over values between 0.0 and 1.0 and set our object position to whatever vector is returned from orxVector_Bezier.

We can do this is the Update function of our ScrollObject:

void Ship::OnCreate()
{
	if (orxConfig_PushSection("Curve")) {
		for (int i = 0; i < 4; i++) {
			orxConfig_GetListVector("Points", i, &vectors[i]); //define vectors[4] orxVECTOR array in the header
		}
		orxConfig_PopSection();
	}
}
 
void Ship::Update(const orxCLOCK_INFO &_rstInfo)
{
	orxVECTOR shipPosition = orxVECTOR_0;
 
	orxVector_Bezier(&shipPosition,
		&vectors[0],
		&vectors[1],
		&vectors[2],
		&vectors[3],
		curveIndex
		);
 
	SetPosition(shipPosition, orxTRUE);
	SetRotation(1.57, orxTRUE); //face right
 
	curveIndex += 0.001; //define curveIndex orxFLOAT in the header
	if (curveIndex > 1.0) {
		curveIndex = 0;
	}
}

This will have the ship fly smoothly over the curve. So… success!

Of course, the current effect would work well for a character who's rotation isn't intended to change. But for a ship, the rotation should follow the curve. There is a simple method to achieve this:

  1. Take the current vector position along the curve
  2. Take the next vector position along the curve
  3. Do an ATAN with the two vectors
  4. Set the result as the rotation.

Our updated Update function will look like this:

void Enemy::Update(const orxCLOCK_INFO &_rstInfo)
{
	const orxFLOAT unit = 0.001;
 
	orxVECTOR shipPosition = orxVECTOR_0;
 
	orxVector_Bezier(&shipPosition,
		&vectors[0],
		&vectors[1],
		&vectors[2],
		&vectors[3],
		curveIndex
		);
 
	SetPosition(shipPosition, orxTRUE);
 
	if (curveIndex + unit < 1.0) {
		orxVECTOR nextShipPosition = orxVECTOR_0;
		orxVector_Bezier(&nextShipPosition,
			&vectors[0],
			&vectors[1],
			&vectors[2],
			&vectors[3],
			curveIndex + unit
			);
 
		orxFLOAT rotation = orxMath_ATan((shipPosition.fX - nextShipPosition.fX), (shipPosition.fY - nextShipPosition.fY));
		SetRotation(-rotation, orxTRUE);
	}
 
	curveIndex += unit;
	if (curveIndex > 1.0) {
		curveIndex = 0;
	}
}

Now the ship should follow the curve both in position and orientation.

Complex curves contain more than one segment. If you wish to make your object travel along a more complicated curve, you'll need to code a routine that move the object through a list of points and control points, but the principle is the same.

Its worth noting that very soon, Orx will be able to take a direct list of points through a Position FX and do this job for you. This tutorial will be updated once tat facility is ready.

Enjoy working with objects on curves!

en/tutorials/orxscroll/scrollobject_along_a_curve.1516102578.txt.gz · Last modified: 2018/01/16 07:36 (6 years ago) (external edit)