ON ERROR IF ERR = 17 CHAIN @lib$+"../examples/tools/touchide" ELSE REPORT : END REM Axle suspension simulation using the Box2D (v2.3.1) Physics Engine. REM v1.00 by Richard Russell, http://www.rtrussell.co.uk/, 22-Apr-2020. MODE 8 : OFF ORIGIN 0,300 Width% = 640 Height% = 512 INSTALL @lib$+"box2dlib" : PROC_b2Init INSTALL @lib$+"box2dgfx" INSTALL @lib$+"box2ddbg" IF INKEY$(-256) = "W" THEN INSTALL @lib$+"gdiplib" : PROC_gdipinit Brush%% = FN_gdipcreatebrush(&FF80F0FF) ELSE INSTALL @lib$+"aagfxlib" ENDIF *SYS 4 ON ERROR PROCcleanup : IF ERR = 17 CHAIN @lib$+"../examples/tools/touchide" ELSE REPORT : END ON CLOSE PROCcleanup : QUIT ON SYS Zoom += @wparam% / 200 : RETURN gravity_x = 0.0 gravity_y = -9.8 scale = 60 myWorld%% = FN_b2CreateWorld(gravity_x, gravity_y) PROC_gfxInit(gfx{}, Width%, Height%, scale) PROC_gfxLoad(nomad{}, @dir$+"nomad.png", scale*2) PROC_gfxLoad(wheel{}, @dir$+"wheel.png", scale*2) PROC_b2DebugInit(myWorld%%, %01011, scale) IF INKEY$(-256) = "W" THEN PROC_gfxMultiply(nomad{}) PROC_gfxMultiply(wheel{}) ENDIF ground%% = FN_b2StaticBox(myWorld%%, 0.0, -0.1, 0.0, 0.0, 0.1) Freq = 4.0 Zeta = 0.7 DIM x(499), y(499), gx(99), gy(99) x() = -3.0, 3.2, 3.2, 0.0, -2.3, -3.0 y() = -0.2, -0.2, 0.0, 1.2, 1.2, 0.4 axle1%% = FN_b2DynamicBody(myWorld%%, 2.8, 0.8, 0, 0, 0, 0, 0, 0.5) PROC_b2UserDataBody(axle1%%, wheel{}) tyre1%% = FN_b2CircleFixture(axle1%%, 0, 0, 0.75, 0.9, 0.0, 1.0) axle2%% = FN_b2DynamicBody(myWorld%%, 7.3, 0.8, 0, 0, 0, 0, 0, 0.1) PROC_b2UserDataBody(axle2%%, wheel{}) tyre2%% = FN_b2CircleFixture(axle2%%, 0, 0, 0.75, 0.9, 0.0, 1.0) buggy%% = FN_b2DynamicBody(myWorld%%, 5.0, 2.0, 0, 0, 0, 0, 0, 0) PROC_b2UserDataBody(buggy%%, nomad{}) chassis%% = FN_b2PolygonFixture(buggy%%, 6, x(), y(), 0.1, 0.0, 1.5) spring1%% = FN_b2WheelJoint(myWorld%%, buggy%%, axle1%%, 2.8, 0.8, 0.0, 1.2, Freq, Zeta) spring2%% = FN_b2WheelJoint(myWorld%%, buggy%%, axle2%%, 7.3, 0.8, 0.0, 1.2, Freq, Zeta) PROC_b2WheelMotorTorque(spring1%%, 20.0, 1) FOR i% = 1 TO 499 x(i%) = i% - 1 y(i%) = (RND(1)+RND(1)+RND(1)+RND(1)) / 6 NEXT y(0) = 1.0 : x(0) = x(1) y(499) = 1.0 : x(499) = x(498) sand%% = FN_b2ChainFixture(ground%%, 500, x(), y(), 0.9, 0.0, 1.0, FALSE) timeStep = 1.0/60.0 velIterations% = 8 posIterations% = 3 motor = 10.0 oldmotor = 0 scroll = 0 scale = 60 Zoom = 0 COLOR 11,255,240,128 COLOR 14,128,240,255 GCOL 14 : COLOR 128+11 *REFRESH OFF REPEAT CLS RECTANGLE FILL 0, scale, Width% * 2, Height% * 2 - scale - @vdu.o.y% IF motor <> oldmotor THEN oldmotor = motor PROC_b2WheelMotorSpeed(spring1%%, -motor, 1) ENDIF PROC_b2WorldStep(myWorld%%, timeStep, velIterations%, posIterations%) PROC_b2GetBody(buggy%%, x, y, a) scroll = scale * (x - Width%/scale/2) IF scroll < 0 scroll = 0 IF x > 450 AND motor > 0 motor = - motor IF x < 50 AND motor < 0 motor = - motor N% = Width% DIV scale + 5 : O% = INT(scroll / scale) IF O% > 499 - N% O% = 499 - N% FOR X% = 1 TO N%-1 gx(X%) = x(X%+O%) * scale * 2 - scroll * 2 gy(X%) = y(X%+O%) * scale * 2 - scale / 5 NEXT gx(0) = gx(1) : gy(0) = scale * 2 : gy(N%-1) = gy(0) PROC_b2DebugMatrix(-scroll, 0, scale) IF INKEY$(-256) = "W" THEN PROC_gdippolygon(Brush%%, N%, gx(), gy(), 0) ELSE PROC_aapolygon(N%, gx(), gy(), &FFFFF080) ENDIF PROC_gfxMatrix(gfx{}, -scroll, 0, scale) PROC_gfxRender(gfx{}, myWorld%%) IF INKEY(-1) PROC_b2DebugFlags(4, 0) ELSE PROC_b2DebugFlags(4, 4) IF INKEY-51 PROC_b2DebugDraw(myWorld%%) PROC_gfxDisplay CASE INKEY(0) OF WHEN 132,141: scale *= 1.02 WHEN 133,140: scale /= 1.02 ENDCASE scale += Zoom : Zoom = 0 IF scale < 20 scale = 20 ELSE IF scale > 200 scale = 200 UNTIL FALSE PROCcleanup END DEF PROCcleanup ON ERROR OFF myWorld%% += 0 : IF myWorld%% PROC_b2DestroyWorld(myWorld%%) : myWorld%% = 0 PROC_b2DebugExit IF INKEY$(-256) = "W" THEN PROC_gdipdeletebrush(Brush%%) PROC_gdipexit ENDIF PROC_gfxExit PROC_b2Exit ENDPROC