diff trunk/tests/ChipmunkDemos/samples/Tank.d @ 16:af2f61a96318

ported chipmunk demos
author Extrawurst
date Sat, 04 Dec 2010 02:02:29 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/tests/ChipmunkDemos/samples/Tank.d	Sat Dec 04 02:02:29 2010 +0100
@@ -0,0 +1,134 @@
+
+// written in the D programming language
+
+module samples.Tank;
+
+import chipmunkd.chipmunk;
+
+import samples.ChipmunkDemo;
+
+import gameApp;
+
+static cpSpace *space;
+
+static cpBody *tankBody;
+static cpBody *tankControlBody;
+
+static void
+update(int ticks)
+{
+	enum int steps = 1;
+	enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
+	
+	for(int i=0; i<steps; i++){
+		// turn the control _body based on the angle relative to the actual _body
+		cpVect mouseDelta = cpvsub(mousePos, tankBody.p);
+		cpFloat turn = cpvtoangle(cpvunrotate(tankBody.rot, mouseDelta));
+		cpBodySetAngle(tankControlBody, tankBody.a - turn);
+		
+		// drive the tank towards the mouse
+		if(cpvnear(mousePos, tankBody.p, 30.0)){
+			tankControlBody.v = cpvzero; // stop
+		} else {
+			cpFloat direction = (cpvdot(mouseDelta, tankBody.rot) > 0.0 ? 1.0 : -1.0);
+			tankControlBody.v = cpvrotate(tankBody.rot, cpv(30.0f*direction, 0.0f));
+		}
+		
+		cpSpaceStep(space, dt);
+	}
+}
+
+static cpBody *
+add_box(cpFloat size, cpFloat mass)
+{
+	cpVect verts[] = [
+		cpv(-size,-size),
+		cpv(-size, size),
+		cpv( size, size),
+		cpv( size,-size),
+	];
+	
+	cpFloat radius = cpvlength(cpv(size, size));
+
+	cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts.ptr, cpvzero)));
+	_body.p = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
+	
+	cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(_body, 4, verts.ptr, cpvzero));
+	shape.e = 0.0f; shape.u = 0.7f;
+	
+	return _body;
+}
+
+static cpSpace *
+init()
+{
+	cpResetShapeIdCounter();
+	
+	space = cpSpaceNew();
+	cpSpaceResizeActiveHash(space, 30.0f, 1000);
+	space.iterations = 10;
+	space.sleepTimeThreshold = 0.5f;
+	
+	cpBody *staticBody = &space.staticBody;
+	cpShape *shape;
+		
+	// 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;
+	
+	for(int i=0; i<50; i++){
+		cpBody *_body = add_box(10.0, 1.0);
+		
+		cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, _body, cpvzero, cpvzero));
+		pivot.biasCoef = 0.0f; // disable joint correction
+		pivot.maxForce = 1000.0f; // emulate linear friction
+		
+		cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(staticBody, _body, 0.0f, 1.0f));
+		gear.biasCoef = 0.0f; // disable joint correction
+		gear.maxForce = 5000.0f; // emulate angular friction
+	}
+	
+	// We joint the tank to the control _body and control the tank indirectly by modifying the control _body.
+	tankControlBody = cpBodyNew(INFINITY, INFINITY);
+	tankBody = add_box(15.0, 10.0);
+	
+	cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(tankControlBody, tankBody, cpvzero, cpvzero));
+	pivot.biasCoef = 0.0f; // disable joint correction
+	pivot.maxForce = 10000.0f; // emulate linear friction
+	
+	cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(tankControlBody, tankBody, 0.0f, 1.0f));
+	gear.biasCoef = 1.0f; // limit angular correction rate
+	gear.maxBias = 1.0f; // limit angular correction rate
+	gear.maxForce = 500000.0f; // emulate angular friction
+		
+	return space;
+}
+
+static void
+destroy()
+{
+	cpBodyFree(tankControlBody);
+	cpSpaceFreeChildren(space);
+	cpSpaceFree(space);
+}
+
+chipmunkDemo Tank = {
+	"Tank",
+	null,
+	&init,
+	&update,
+	&destroy,
+};