http://chipmunk-physics.net/forum/downl ... view&id=81
I have modified the oneWay platform example of Chimpmunk Engine to implement a prototype jump. The video for the outcome is provided in http://www.youtube.com/watch?v=6CA9lTfXFjg.
Question 1 : My implementation is based on application of horizontal force ( cpBodySetForce call) to the object after giving an upward velocity. To obtain the projectile path I did trial & error to determine the force vector. I need a definitive way to determine the force vector to be applied given the distance between platforms ( say A and B). Any guidance will be appreciated.
Question 2 : While the body lands on platform after the jump, it falls with any one of the 4 edges. How do I make it land on a given edge?
Code: Select all
#include <cstdio>
#include "chipmunk.h"
#include "ChipmunkDemo.h"
typedef struct OneWayPlatform {
cpVect n; // direction objects may pass through
} OneWayPlatform;
FILE *fp;
static OneWayPlatform platformInstance;
static cpBody *body, *staticBody,*staticBody1,*staticBody2;
static cpShape *shape;
static cpBool
preSolve(cpArbiter *arb, cpSpace *space, void *ignore)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
OneWayPlatform *platform = (OneWayPlatform *)cpShapeGetUserData(a);
if(cpvdot(cpArbiterGetNormal(arb, 0), platform->n) < 0){
cpArbiterIgnore(arb);
return cpFalse;
}
return cpTrue;
}
static void
update(cpSpace *space)
{
static cpFloat startTime, diffTime;
cpVect end, jump={0,0};
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
/* execute only once while right click is pressed & initiate the jump */
if (ChipmunkDemoRightClick) {
end = ChipmunkDemoMouse;
cpVect start = cpBodyGetPos(body);
cpBodySetAngVel(body, 1.0f);
cpBodySetVel(body, cpv(-98, 145));
cpBodySetForce(body,cpv(40,0));
}
//if vertical velocity has reached + then make force= 0
jump = cpBodyGetVel(body);
if ( jump.y < 0.5 && jump.y > -0.5) {
cpBodySetForce(body,cpv(0,0));
}
}
static cpSpace *
init(void)
{
ChipmunkDemoMessageString = "Experiment for Jumping Distance on Mouse Click.";
fp=fopen("logfile.txt","w");
cpSpace *space = cpSpaceNew();
cpSpaceSetIterations(space, 10);
cpSpaceSetGravity(space, cpv(0, -75));
staticBody = cpSpaceGetStaticBody(space);
staticBody1 = cpSpaceGetStaticBody(space);
staticBody2 = cpSpaceGetStaticBody(space);
// Create segments around the edge of the screen.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
//-------------------------------------------------------------------------------------
// Add our 1st one way segment
// cpBodySetPos(staticBody1, cpvmult(cpvadd(cpv(260,-100),cpv(310,-100)), 0.5));
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody1, cpv(260,-100), cpv(310,-100), 5.0f));
cpShapeSetElasticity(shape, 1.0f);
cpShapeSetFriction(shape, 0.95f);
cpShapeSetCollisionType(shape, 1);
cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
// We'll use the data pointer for the OneWayPlatform struct
platformInstance.n = cpv(0, 1); // let objects pass upwards
cpShapeSetUserData(shape, &platformInstance);
// Add our 2nd one way segment
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody2, cpv(250,-200), cpv(310,-200), 5.0f));
cpShapeSetElasticity(shape, 1.0f);
cpShapeSetFriction(shape, 1.0f);
cpShapeSetCollisionType(shape, 1);
cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
// We'll use the data pointer for the OneWayPlatform struct
platformInstance.n = cpv(0, 1); // let objects pass upwards
cpShapeSetUserData(shape, &platformInstance);
// Add a ball to make things more interesting
// cpFloat radius = 8.0f;
// body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero)));
cpFloat mass = 0.5f;
cpFloat moment = cpMomentForBox( mass, 20,20);
body = cpBodyNew(mass, moment);
cpSpaceAddBody(space,body);
cpBodySetPos(body, cpv(260, -170));
shape = cpBoxShapeNew(body, 20,20);
cpShapeSetElasticity(shape, 0.0f);
cpShapeSetFriction(shape, 0.9f);
cpSpaceAddShape(space, shape);
cpShapeSetCollisionType(shape, 2);
cpSpaceAddCollisionHandler(space, 1, 2, NULL, preSolve, NULL, NULL, NULL);
return space;
}
static void
destroy(cpSpace *space)
{
ChipmunkDemoFreeSpaceChildren(space);
cpSpaceFree(space);
}
ChipmunkDemo OneWay = {
"One Way Platforms",
init,
update,
ChipmunkDemoDefaultDrawImpl,
destroy,
};