Latest Blog

Multimedia Interaktif Tata Surya
Membuat Multimedia Pembelajaran Interaktif tentang tata surya
ALL BLOG
;
Sky Drifter - 3D Racing Games
The Game Play
Sky Drifter is very simple racing game, the idea is you drive a car on a track that floating on the sky. The main challenge of this game is you'll easily fall since there is no fences around the track. I've build this game for about a week because everything in this game is quite basic. Click this screenshot below to play the game



The Simple Racing Game Physic
Most developer will find that Flare3D's car physic performance is quite slow, so i can't use it for this game. The most difficult part on the 3D physic is the collision detection between two or more object with the 3D mesh/terrain - this is something that make the application's performance slower. Flare3D has some collision detection code that quite light and fast (Ray Collision and Sphere Collision), however we need to adjust some variable to get the best result when apply that code into a box shape (in this case is a car).
Sky Drifter is my first racing game - I made it just for learning how to make a racing game, so i make it on a flat track, thats why i don't need advance physic for it. The first code is a physic for car movement on the flat track, it is quite simple. I got some car's drifting code from FlashKit.com and combine it with simple racing script become like this :
private var TO_RAD:Number = Math.PI/180; //controls how slippery the car is (1 is no friction, 0 full friction) private var REAL_FRICTION:Number = 0.08; //how much the car must be skidding (moving perpendicularly to the direction its facing) in order to call it a skid private var SKID_START_THRESOLD:Number = 3; private var SKID_STOP_THRESOLD:Number = 2; private function move_car(ob:Object):void{ ob.xOld = ob.x; ob.yOld = ob.y; var xComp:Number = -Math.sin(-ob.rotation*TO_RAD); var yComp:Number = -Math.cos(-ob.rotation*TO_RAD); var perpForce:Number = -yComp * ob.xSpeed + xComp * ob.ySpeed; if(Math.abs(perpForce) > SKID_START_THRESOLD){ ob.isSkidding = true; } if(ob.isSkidding && Math.abs(perpForce) < SKID_STOP_THRESOLD){ ob.isSkidding = false; } var skidForceX:Number = -yComp * perpForce; var skidForceY:Number = xComp * perpForce; ob.xSpeed -= skidForceX * REAL_FRICTION; ob.ySpeed -= skidForceY * REAL_FRICTION; ob.xSpeed += ob._accel * xComp * REAL_FRICTION; ob.ySpeed += ob._accel * yComp * REAL_FRICTION; var speed:Number = Math.sqrt(Math.pow(ob.xSpeed, 2) + Math.pow(ob.ySpeed, 2)); ob.rotSpeed = ob._rotAccel * (speed / 10); ob.rotation += ob.rotSpeed; ob.x += ob.xSpeed; ob.y += ob.ySpeed; if(ob._accel > 0){ ob.xSpeed -= ob.xSpeed * 0.05 * REAL_FRICTION; ob.ySpeed -= ob.ySpeed * 0.05 * REAL_FRICTION; }else{ ob.xSpeed -= ob.xSpeed * 0.6 * REAL_FRICTION; ob.ySpeed -= ob.ySpeed * 0.6 * REAL_FRICTION; } ob.rotSpeed += 0.5 * (1 - REAL_FRICTION); if (!ob.fall){ if (Input3D.keyDown(Input3D.UP) && ob._accel<2){ ob._accel+=0.1; }else if (Input3D.keyDown(Input3D.DOWN) && ob._accel>-2){ ob._accel-=0.1; }else{ ob._accel*=.6; ob.xSpeed*=0.99; ob.ySpeed*=0.99; } if (Input3D.keyDown(Input3D.LEFT)){ if (ob._rotAccel>-8)ob._rotAccel-=0.2; }else if (Input3D.keyDown(Input3D.RIGHT)){ if (ob._rotAccel<8)ob._rotAccel+=0.2; }else{ ob._rotAccel = 0; } }else{ ob._accel*=.5; ob.xSpeed*=0.9; ob.ySpeed *= 0.9; } }
As you can see at the script above, i try to move an object, not a Pivot3D, so i can use simple 2D calculation using X Y - axis. After i got the best 2d movement, i can easily translate it into 3D world.
The second code is the simple collision between car's wheels against the track. I can use box Physic, but the performace will reduced - so i decide to use Ray Collision. Ray Collision is worderfull, because you can check the collision between 3D mesh with a single line - so its faster than any other Flare3D's collision. But I have a car not a line, so I have to check all the car's wheels - mean I have to check 4 times. Car in this game has 4 wheels, Front Right - Front Left - Rear Right -and Rear Left. The simple physic/logic to make this car fall from the track is whenever two wheels that aligned out of the track. So if FR - FL wheel out from track then car will fall forward, FR - RR car will fall to the right and so on. The simple code is :
wheel_col = new RayCollision(); wheel_col.addCollisionWith( track3d ); private function wheel_check():void { var from1:Vector3D = car3d.localToGlobal( new Vector3D( 10, 10, 10 ) ); if (wheel_col.test( from1, v_down )) { front_right = true; }else { front_right = false; fall_db.push(1); } var from2:Vector3D = car3d.localToGlobal( new Vector3D( -10, 10, 10 ) ); if (wheel_col.test( from2, v_down )) { front_left = true; }else { front_left = false; fall_db.push(2); } var from3:Vector3D = car3d.localToGlobal( new Vector3D( 10, 10, -10 ) ); if (wheel_col.test( from3, v_down )) { rear_right = true; }else { rear_right = false; fall_db.push(3); } var from4:Vector3D = car3d.localToGlobal( new Vector3D( -10, 10, -10 ) ); if (wheel_col.test( from4, v_down )) { rear_left = true; }else { rear_left = false; fall_db.push(4); } //fall var f_l:Number = fall_db.length; if (f_l >= 2) { if (fall_db[f_l - 1] == 1 && fall_db[f_l - 2] == 3) car.fall = true; if (fall_db[f_l - 1] == 3 && fall_db[f_l - 2] == 1) car.fall = true; if (fall_db[f_l - 1] == 1 && fall_db[f_l - 2] == 2) car.fall = true; if (fall_db[f_l - 1] == 2 && fall_db[f_l - 2] == 1) car.fall = true; if (fall_db[f_l - 1] == 2 && fall_db[f_l - 2] == 4) car.fall = true; if (fall_db[f_l - 1] == 4 && fall_db[f_l - 2] == 2) car.fall = true; if (fall_db[f_l - 1] == 3 && fall_db[f_l - 2] == 4) car.fall = true; if (fall_db[f_l - 1] == 4 && fall_db[f_l - 2] == 3) car.fall = true; } //reset fall db if (front_right && front_left && rear_right && rear_left) { fall_db = []; } }
Basically I use only one RayCollision and move it to each wheel every "enterframe", by doing this I'll know which wheel that still on the track, and which one that out of the track. I use the fall_db array to save the last record of the wheels that out of the track, so if the last two array value indicate that the two aligned wheels out from the track - then car will fall. And at the last line of that code the fall_db array is set to empty when all wheels on the track.
Thats it, i hope you can get the main idea how to move the car and how to detect the car against the 3D track without physic.
Share ( Ayo Berbagi )
Leave me a comment
untuk pertanyaan lebih baik di email langsung ke wandah [at] wandah [dot] com agar cepat direspon