Movable Objects HowTo

This howto will show how you can make the character lift and drop objects.


Add the "objects" meshes to the game.

In the meshes directory there should be an "objects.c" file.
Add objects.c to the makefile...

For Windows:
Double click game Dev-C++ Project File and add the files "objects.c" and "objects.h" to the project.

For Linux:
Open "Makefile".
Add this near the bottom of the makefile:
meshes/objects.o: meshes/objects.c
//TAB// $(CC) -c meshes/objects.c -o meshes/objects.o $(CFLAGS)

Replace //TAB// with a tab.

Add this to "OBJ =" within the makefile:
meshes/objects.o

Add objects.c to the source code...

Add this near the top of main.c:
#include "meshes/objects.h"

Open "scene1.c".
Add this under "if (initializeDrawScene1) {":
// resize the objects
globalResize(objects_GLOBAL, objects_TRANS, objects_MESHCNT, 0, 0, 0, 20, 20, 20);

for (i = 0; i < 9; i++)
objects_STATICGLOBAL[i] = objects_GLOBAL[i];
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
objects_STATICTRANS[i] = objects_TRANS[i];
for (i = 0; i < sizeof(objects_POINT)/sizeof(float); i++)
objects_STATICPOINT[i] = objects_POINT[i];

Add this at the end of "scene1.c":
// draw objects
addRotLocSz(objects_TRANS, objects_POINT, objects_POINTDATSZ,
objects_STATICPOINT, objects_MESHCNT);
addScreenRotLocSz(xScreenRot, yScreenRot, zScreenRot,
xScreenSize, yScreenSize, zScreenSize,
xScreenLoc, yScreenLoc, zScreenLoc,
objects_POINT, objects_POINTDATSZ, objects_MESHCNT);
drawMesh(objects_POINT, objects_LINE, objects_COLOR,
objects_LINEDATSZ, objects_MESHCNT, bgColor, antialiasing, rI);

Compile and run...



To place the objects somewhere in the environment.

Add needed variables to the code.
Find this in "main.c":
if (sceneNumber == 0)
Add this above it:
static float movableObjTRANS[sizeof(objects_TRANS)];
static int objTimeToFall[sizeof(objects_TRANS)];
static float objFallSpeed[sizeof(objects_TRANS)];
static int liftedObjNum = -1;
static int droppedObj = 0;
float objCarriedxRot;
float objCarriedyRot;
float objCarriedzRot;

In "scene1.c" add this under "if (resetDrawScene) {":
// place objects
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
{
movableObjTRANS[i] = objects_STATICTRANS[i];
}

Find this in "scene1.c":
// return global and transformation data back to its original state
// this will keep rounding errors from deforming the meshes
Add this right after:
for (i = 0; i < 9; i++)
objects_GLOBAL[i] = objects_STATICGLOBAL[i];
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
objects_TRANS[i] = objects_STATICTRANS[i];

Add this right after "// apply the correct orientations":
// put the objects in the right position
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
objects_TRANS[i] = movableObjTRANS[i];
// keep the objects with the course
globalRot(objects_GLOBAL, objects_TRANS, objects_MESHCNT, 0, 0, 0, 0, 0, zCourseRotSave);
globalMove(objects_GLOBAL, objects_TRANS, objects_MESHCNT,
-xCharacterPosSave, -yCharacterPosSave, -zCharacterPosSave);
globalMove(objects_GLOBAL, objects_TRANS, objects_MESHCNT, 0, -(forward+backward), 0);
globalRot(objects_GLOBAL, objects_TRANS, objects_MESHCNT, 0, 0, 0, 0, 0, (turnLeft+turnRight));

Find:
// If the character falls or jumps this changes the z
// position of the course and if you have objects placed on
// the course this is the place to change the z positions
// of those objects to keep them with the course.
Add this right after:
// put the objects at there right heights
for (i = 0; i < objects_MESHCNT*9; i=i+9)
objects_TRANS[5+i] = course1_GLOBAL[5] + movableObjTRANS[5+i];

Compile and run...



Allow the objects to be lifted and moved.

Add a key press event for when you press "Z".
In "main.c".
Find:
// Input Events //
Add this right after:
static int liftDropObj = 0;
static int objLifted = 0;
// left or put down an object
if (keyDown[90])// z
{
if (liftDropObj == 0)
objLifted = !objLifted;
liftDropObj = 1;
}
if (keyUp[90])// z
liftDropObj = 0;

Allow objects to be lifted.
In "scene1.c".
Find where this was added:
// put the objects in there right positions
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
objects_TRANS[i] = movableObjTRANS[i];
Add this under it:
objCarriedxRot = objects_TRANS[0];
objCarriedyRot = objects_TRANS[1];
objCarriedzRot = objects_TRANS[2];
float xObjPos;
float yObjPos;
float zObjPos;

Find where this was added:
// place objects
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
{
movableObjTRANS[i] = objects_STATICTRANS[i];
}
Add this under it:
objLifted = 0;
liftedObjNum = -1;

Find where this was added:
// put the objects at there right heights
for (i = 0; i < objects_MESHCNT*9; i=i+9)
objects_TRANS[5+i] = course1_GLOBAL[5] + movableObjTRANS[5+i];
Add this right after:
// put the lifted object in its right position
if (liftedObjNum != -1)
{
objects_TRANS[0+liftedObjNum*9] = objCarriedxRot;
objects_TRANS[1+liftedObjNum*9] = objCarriedyRot;
objects_TRANS[2+liftedObjNum*9] = objCarriedzRot;

objects_TRANS[3+liftedObjNum*9] = character_TRANS[3];
objects_TRANS[4+liftedObjNum*9] = character_TRANS[4] + 25;
objects_TRANS[5+liftedObjNum*9] = character_TRANS[5] + 20;

localRot(objects_TRANS, liftedObjNum, 0, 0, 0, 0, 0, zCharacterRot);
objects_TRANS[2+liftedObjNum*9] = character_TRANS[2];

// rotate the movable object to 0
movableObjTRANS[0+liftedObjNum*9] = 0;
movableObjTRANS[1+liftedObjNum*9] = 0;
movableObjTRANS[2+liftedObjNum*9] = 0;
}

if (liftedObjNum == -1)
for (i=0; i < objects_MESHCNT*9; i=i+9)
{
// is the object at the right height for lifting
if (movableObjTRANS[5+i]-movableObjTRANS[8+i]/2 >= -course1_GLOBAL[5]-10 - 16)
if (movableObjTRANS[5+i]-movableObjTRANS[8+i]/2 <= -course1_GLOBAL[5]-10 + 16)
{
if (objLifted)
// is the charactor in the right position to lift the object
if (movableObjTRANS[4+i]-movableObjTRANS[7+i]-20 <= -course1_GLOBAL[4])
if (movableObjTRANS[4+i]+movableObjTRANS[7+i]+20 >= -course1_GLOBAL[4])
if (movableObjTRANS[3+i]-movableObjTRANS[6+i]-20 <= -course1_GLOBAL[3])
if (movableObjTRANS[3+i]+movableObjTRANS[6+i]+20 >= -course1_GLOBAL[3])
{
liftedObjNum = i / 9;
i = objects_MESHCNT*9;
}
}
}

Compile and run...



Allow objects to be dropped.

Find:
// place objects
for (i = 0; i < sizeof(objects_TRANS)/sizeof(float); i++)
{
Add this right under (within the for loop):
objTimeToFall[i] = 0;
objFallSpeed[i] = 0;



Find:
// keep the dome's z position with the course
Add this above it:

// move the objects far down out of view
// if they fall past a certain point
for (i = 0; i < objects_MESHCNT*9; i=i+9)
if (objects_TRANS[5+i] < -100000)
objects_TRANS[5+i] = -1000000;

// get the position of the dropped object
if (objLifted == 0)
{
if (liftedObjNum != -1)
{
droppedObj = 1;
movableObjTRANS[3+liftedObjNum*9] = -course1_GLOBAL[3];
movableObjTRANS[4+liftedObjNum*9] = -course1_GLOBAL[4] + 30;
movableObjTRANS[5+liftedObjNum*9] = -course1_GLOBAL[5] + 20;

localRot(movableObjTRANS, liftedObjNum,
-course1_GLOBAL[3], -course1_GLOBAL[4], 0, 0, 0, -zCourseRotSave+(turnLeft+turnRight));

localRot(movableObjTRANS, liftedObjNum,
-course1_GLOBAL[3], -course1_GLOBAL[4], 0, 0, 0, zCharacterRot);
}

liftedObjNum = -1;
}

// make "objLifted" variable false which was triggered by keydown event
// if no object was lifted
if (liftedObjNum == -1)
objLifted = 0;

for (i = 0; i < objects_MESHCNT; i++)
{
if (objTimeToFall[i])
{
objFallSpeed[i] = objFallSpeed[i] + 15;
localMove(objects_TRANS, i, 0, 0, -objFallSpeed[i]);
localMove(movableObjTRANS, i, 0, 0, -objFallSpeed[i]);
}

if (i != liftedObjNum)
objTimeToFall[i] = 1;
}

int j;
for (j = 0; j < objects_MESHCNT*9; j=j+9)
{
// Get the object's position relative to the position of the course.
xObjPos = course1_GLOBAL[3] + movableObjTRANS[3+j];
yObjPos = course1_GLOBAL[4] + movableObjTRANS[4+j];
zObjPos = course1_GLOBAL[5] + movableObjTRANS[5+j] - movableObjTRANS[8+j];

// keep the object from falling through platforms
for (i = 0; i < course1_MESHCNT*9; i=i+9)
{
xPlatform = course1_TRANS[3+i];
yPlatform = course1_TRANS[4+i];
zPlatform = course1_TRANS[5+i];
xEdge = course1_TRANS[6+i];
yEdge = course1_TRANS[7+i];

// if the object is within the platform's boundaries
if ((xObjPos <= xPlatform+xEdge) &&
(xObjPos >= xPlatform-xEdge) &&
(yObjPos <= yPlatform+yEdge) &&
(yObjPos >= yPlatform-yEdge))
{
if (zObjPos+2.0 >= zPlatform)
if (zObjPos-10.0 <= zPlatform+objFallSpeed[j/9])
{
floorToChrAmt = zPlatform - zObjPos;
// move the object up
localMove(objects_TRANS, j/9, 0, 0, floorToChrAmt);
localMove(movableObjTRANS, j/9, 0, 0, floorToChrAmt);

objTimeToFall[j/9] = 0;
objFallSpeed[j/9] = 0;
}
}
}
}

Compile and run...



Lift arms when carrying objects.

Find:
// turn the character toward the correct direction
// if it moves forwards, backwards, left or right
Add this above it:
// if carrying an object hold out arms
if (liftedObjNum != -1)
{
// left uper arm
character_TRANS[3*9+0] = run1_TRANS[3*9+0];
character_TRANS[3*9+1] = run1_TRANS[3*9+1];
character_TRANS[3*9+2] = run1_TRANS[3*9+2];
character_TRANS[3*9+3] = run1_TRANS[3*9+3];
character_TRANS[3*9+4] = run1_TRANS[3*9+4]-1.0;

// left lower arm
character_TRANS[9*9+0] = run1_TRANS[9*9+0];
character_TRANS[9*9+1] = run1_TRANS[9*9+1];
character_TRANS[9*9+2] = run1_TRANS[9*9+2];
character_TRANS[9*9+3] = run1_TRANS[9*9+3];
character_TRANS[9*9+4] = run1_TRANS[9*9+4]-1.0;
character_TRANS[9*9+5] = run1_TRANS[9*9+5]-1.4;

// right uper arm
character_TRANS[8*9+0] = run3_TRANS[8*9+0];
character_TRANS[8*9+1] = run3_TRANS[8*9+1];
character_TRANS[8*9+2] = run3_TRANS[8*9+2];
character_TRANS[8*9+3] = run3_TRANS[8*9+3];
character_TRANS[8*9+4] = run3_TRANS[8*9+4]-1.0;

// right lower arm
character_TRANS[4*9+0] = run3_TRANS[4*9+0];
character_TRANS[4*9+1] = run3_TRANS[4*9+1];
character_TRANS[4*9+2] = run3_TRANS[4*9+2];
character_TRANS[4*9+3] = run3_TRANS[4*9+3];
character_TRANS[4*9+4] = run3_TRANS[4*9+4]-1.0;
character_TRANS[4*9+5] = run3_TRANS[4*9+5]-1.4;
}

Compile and run...