Fake car physics for one and all

Miscellaneous Forums/Blitz Showcase/Fake car physics for one and all

If you make use of it a bit of credit would be appreciated after all this doesn't just fall out of my computer and stuff.


I actually rewrote this from scratch and every time I rewrite stuff it's better and better! This is pretty cool actually even though I say so myself!

There's exaggerated drift on the back wheels so you get opposite lock going on which just looks cool. Exaggerated body roll, because it looks cool and Exaggerated steering lock because... well... it looks cool.

Who needs real physics when you can fake it eh!?

And yes... I know it looks like a brick on wheels.

Graphics3D 1024,768,32,2

camera = CreateCamera()
MoveEntity camera,0,30,-10
light = CreateLight():RotateEntity light,45,45,0


; Build Car
F_Axel = CreatePivot()
R_Axel = CreatePivot()
F_Bumper = CreatePivot()

RL_Wheel = CreateWheel(R_Axel)
RR_Wheel = CreateWheel(R_Axel)
FL_Wheel = CreateWheel(F_Bumper)
FR_Wheel = CreateWheel(F_Bumper)
Body = CreateCube(R_Axel)
EntityColor body,255,50,0
ScaleEntity body,2,1,4
PositionEntity body,0,2,2.5

MoveEntity RL_wheel,-2,0,0
MoveEntity RR_wheel,2,0,0
MoveEntity FL_wheel,-2,0,0
MoveEntity FR_wheel,2,0,0
MoveEntity r_axel,0,0,-5
EntityParent F_Bumper,R_Axel

speed# = 0
drift# = 0
steer# = 0


; Build Ground
Ground = CreatePlane()
i = CreateImage(64,64)
SetBuffer(ImageBuffer(i))
Color 0,0,255:Rect 0,0,32,32:Rect 32,32,32,32
Color 0,100,255:Rect 32,0,32,32:Rect 0,32,32,32
checker = CreateTexture(64,64)
CopyRect 0,0,64,64,0,0,ImageBuffer(i),TextureBuffer(checker )
FreeImage i
ScaleTexture checker ,50,50
EntityTexture ground,checker 
PositionEntity ground,0,-1,0

SetBuffer BackBuffer()

t=MilliSecs()

Repeat
	
	; Steering
	If KeyDown(205) Then steer = steer + 2
	If KeyDown(203) Then steer = steer - 2
	steer = steer * .6
	
	; turn the wheels
	RotateEntity f_axel,0,EntityYaw(r_axel)-steer,0
	RotateEntity FL_Wheel,0,EntityYaw(r_axel,True)-(steer*10),0,True
	RotateEntity FR_Wheel,0,EntityYaw(r_axel,True)-(steer*10),0,True
	
	; gas
	If KeyDown(200) Then speed = speed + .2
	speed = speed * .94
	
	; forwards
	MoveEntity f_axel,0,0,speed
	PointEntity r_axel,f_axel
	MoveEntity r_axel,0,0,EntityDistance(r_axel,f_axel)-5 ;5 is the car length
	
	; drift
	drift = drift + (steer * speed) * -.01
	drift = drift * .95
	
	MoveEntity f_axel,drift,0,0
	MoveEntity r_axel,drift*1.1,0,0
	PointEntity r_axel,f_axel
	MoveEntity r_axel,0,0,EntityDistance(r_axel,f_axel)-5 ;5 is the car length
	
	; roll body
	RotateEntity body,0,0,-drift*10
	
	; update cam
	PointEntity Camera, F_Bumper
	PositionEntity camera,EntityX(r_axel),30,EntityZ(r_axel)-50
	
	; blah blah
	RenderWorld
	
	Text 0,0,speed
	Text 0,20,steer
	
	; shite timing code
	t = MilliSecs()-t
	If t-20 < 0 Then Delay Abs(t-20)
	t= MilliSecs()
	
	Flip
	
Until KeyHit(1)

Function CreateWheel(Parent)
	Entity = CreateCylinder(12,0,Parent)
	RotateMesh Entity,90,90,0
	ScaleMesh Entity,.5,1,1
	EntityFX entity,16
	EntityColor entity,50,50,50
	Return Entity
End Function


Nice!

Rob, everything you do is so sweet! I can see making some type of racing game out of this fairly easy (but don't most blitz project look that way in the beginning?). Keep up the good work!

Yes, simple and nice thxs Rob.

Excellent stuff, again.

You lose points for not making the wheels Amiga balls though.

Just kidding.

Yeah, thats pretty cool stuff.

Quality-

thanks again! excellent

Perfect for doing donuts in...

Pretty neat. How hard would it be to get the car to power slide when at full speed, instead of doing donuts? That would be cool.

Stevie: Ta
Clown: It's all in the hips
M2Play: Ta
LineOf7s: ha! Ta
t3K|Mac: Ta
Danny: Ta
Pete: Ta
Matty: Indeed
big10p: It's got bias on the rear to slide the back out, simply even out the bias and it'll go sideways more that round and round.
MoveEntity f_axel,drift,0,0
MoveEntity r_axel,drift*1.3,0,0


Very impressive! I'm extremely jealous!

big10p: It's got bias on the rear to slide the back out, simply even out the bias and it'll go sideways more that round and round.
Ah, yes. Wicked. ;)

bad more B3D code! demo... ;-)

bad more B3D code! demo... ;-)
What the hell does that mean?

I think he means he wants an exe demo, coz he hasn't got B3D?

I think he just wants a cookie... :)

Not bad. This lot are easily pleased though.

A bit extreme though - in the way that it is like you are driving on a slippy surface.

A bit more traction is required.

A bit more traction is required.
Simply reduce the drift.
drift = drift + (steer * speed) * -.01


This lot are easily pleased though.


Yes we are, we don't non-functioning 10K£ game PCs for kicks ;P

Cool stuff, Rob!

puki just feels sad when someone just gives code away and he don't have to use his catch phrase?

"Hand over your code and media!"

this is the kind of thing that should be in tutorials once you have the basics. you could make a really fun little racer. just add collision a track and another car and your almost done.

This would be a great start to a community project.

I have some veeery old code which builds a track in code. The cars in this are very basic but the track building code could be easily ripped out.

Stevie

Graphics3D 640,480,16,1

Global camera
Global plane
Global light 
Global track
Global pivot = CreatePivot()
Global p1.CarType
Global p2.CarType
Global Points=0
Global PP=0

Type Vector
	Field x#, y#,z#
End Type

Dim Point.Vector( 2000 )
Dim TP.Vector( 6, 20000 )


Type CarType
	Field Model
	Field Vx#, Vy#, Vz#
	Field Acceleration#
	Field Brakes#
	Field Traction#
	Field Speed#
	Field TopSpeed#
	Field Wheel[3]
End Type


GAMEinit()
TRACKinit()
GAMEreset()
	
While Not KeyDown(1)

	GAMEupdate()

Wend

End

;=================================================
;=================================================
;=================================================

Function CARcreate.CarType( r,g,b)

	c.CarType = New CarType
	c\Model = CreateCube()
	PositionMesh c\Model,0,1,0
	ScaleMesh c\Model,.5,.5,1
	UpdateNormals c\Model
	EntityColor c\Model,r,g,b
			
	temp = CreateCylinder( 5 )
	RotateMesh temp,0,0,90
	ScaleMesh temp,.25,.5,.5
	EntityColor temp,50,50,50
	w=0
	For z# = .75 To -1 Step -1.75
		For x# = -1 To 1 Step 2
			c\Wheel[w] = CopyEntity( temp, c\Model )
			UpdateNormals c\Wheel[w]
			PositionEntity c\Wheel[w],x,.5,z
			w = w + 1
		Next
	Next
	FreeEntity temp
	
	shadow = CreateCube( c\Model )
	ScaleEntity shadow,1.25,.01,1.25
	EntityColor shadow,50,50,50
	EntityAlpha shadow,.5
	
	c\Acceleration = .01
	c\Brakes = .005
	c\Traction = .95
	c\Speed = 0.0
	c\TopSpeed = 1.25
	c\Vx = 0
	c\Vy = 0
	c\Vz = 0
			
	Return c

End Function

;=================================================
;=================================================
;=================================================

Function CARupdate( c.Cartype )

	jx = KeyDown(203)-KeyDown(205)
	jb = KeyDown(200)

	TurnEntity c\Model, 0, jx * 3.0,0
	For w = 0 To 1
		RotateEntity c\wheel[w],EntityPitch(c\wheel[w]),jx*45.0,0
	Next
		
	c\Speed = LIMIT ( c\Speed + ( jb * c\Acceleration ) - ( ( Not jb ) * c\Brakes ) , 0, c\TopSpeed )
	TFormVector 0,0,(1.0 - c\Traction ), c\Model, 0
	c\Vx = ( c\Vx * c\Traction ) + ( TFormedX() * c\Speed )
	c\Vz = ( c\Vz * c\Traction ) + ( TFormedZ() * c\Speed )
	c\Vy = ( c\Vy * c\Traction ) + ( TFormedY() * c\Speed ) - gravity

	TranslateEntity c\Model, c\Vx, c\vy , c\Vz
	
	For l = 0 To 3
		TurnEntity c\wheel[l],c\Speed * 90.0 / (Pi),0,0
	Next
	
	;collisions
	unused = LinePick ( EntityX(c\Model,1),EntityY(c\model,1)+5,EntityZ(c\model,1),0,-20,.2 )
	picked = PickedEntity()
	If picked = Track Or picked = plane
		;hug track
		TranslateEntity c\Model,0,PickedY()-EntityY(c\Model)+.1,0
		nx#=PickedNX():ny#=PickedNY():nz#=PickedNZ()
		AlignToVector c\Model,nx,ny,nz,2,.25
	EndIf 
	
End Function

;=================================================
;=================================================
;=================================================

Function GAMEinit()

	plane = CreatePlane()
	EntityColor plane,150,100,75
	EntityPickMode plane, 2
	EntityOrder plane,1
	EntityFX plane,1+16
	
	camera = CreateCamera()
	CameraClsColor camera,50,100,200
	PositionEntity Camera, 0,100,0
	
	light = CreateLight()
	RotateEntity light,30,-60,0 
		
	P1 = CARcreate( 200,200,50 )
	P2 = CARcreate( 50,200,200 )

End Function

;=================================================
;=================================================
;=================================================

Function GAMEupdate()

	CARupdate( p1 )
	CAMERAupdate()
	RenderWorld()
	Flip

End Function

;=================================================
;=================================================
;=================================================

Function GAMEreset()
	
	PositionEntity P1\Model,TP(3,0 )\x,TP(3,0)\y,TP(3,0)\z
	PositionEntity Pivot,TP(3,1)\x, TP(3,1)\y, TP(3,1)\z
	PointEntity P1\Model, Pivot

	PositionEntity P2\Model,TP(3,0 )\x,TP(3,0)\y,TP(3,0)\z
	PositionEntity Pivot,TP(3,1)\x, TP(3,1)\y, TP(3,1)\z
	PointEntity P2\Model, Pivot
	
End Function

;=================================================
;=================================================
;=================================================

Function CAMERAupdate()

	PointEntity Camera, p1\Model
	CameraZoom Camera, EntityDistance( Camera, p1\Model ) / 50
	
End Function

;=================================================
;=================================================
;=================================================

Function TRACKinit()

	;points
	Restore LEVELdata
	Read points
	For l = 0 To points-1
		point( l*2 ) = New Vector
		Read point(l*2)\x
		Read point(l*2)\y 
		Read point(l*2)\z
	Next
		
	;mid points
	For l= 0 To points-1 
		m = l*2+1
		v = ( l+1 ) Mod points
		point( m) = New Vector
		point( m)\x = ( point(l*2)\x + point(v*2)\x ) * .5
		point( m)\y = ( point(l*2)\y + point(v*2)\y ) * .5
		point( m)\z = ( point(l*2)\z + point(v*2)\z ) * .5
	Next
	points = points * 2 
		
	;smooth bezier curves
	For l= 0 To points-1 Step 2
		k = ( l+1) Mod points
		n = ( l + 2 ) Mod points
		m = ( l + 3 ) Mod points
		JOIN ( point( k )\x , point( k )\y, point( k )\z, point( n )\x, point ( n )\y, point(n)\z, point( m)\x, point(m)\y , point(m)\z )
	Next
	
	;tangents
	Color 255,255,255
	For l = 0 To pp-1
		m = ( l-1+pp ) Mod pp
		n = ( l + 1 ) Mod pp
		dx# = TP(3, l )\x - TP(3,m)\x
		dz# = TP(3, l )\z - TP(3,m)\z
		d#  = Sqr ( dx*dx + dz*dz) * 2.0
		ax# = dx/d
		az# = dz/d
		dx# = TP(3, n )\x - TP(3,l)\x
		dz# = TP(3, n )\z - TP(3,l)\z
		d#  = Sqr ( dx*dx + dz*dz) * 2.0
		ax# = ax# + dx/d
		az# = az# + dz/d
				
		For q = 0 To 6
			
			dr# = Sgn(q-3)
			
			Select Abs(q-3)
				Case 1 
					Width# = 5.0
					Height# = TP(3,l)\y
				Case 2 
					Width# = 6.0
					Height# = TP(3,l)\y+.5
				Case 3 
					width# = 10.0
					Height# = 0
					If TP(3,l)\y = 10.0 
						Height = TP(3,l)\y-2.5
						Width = 7.0
					EndIf 
			End Select
	
			If q<>3
				TP(q,l) = New Vector
				TP(q,l)\x = TP(3,l)\x - az * width *dr
				TP(q,l)\y = Height 
				TP(q,l)\z = TP(3,l)\z + ax * width * dr
			EndIf
			
		Next
		
	Next	
			
;	;show tangents
;	For l = 0 To pp-1
;		n = ( l + 1 ) Mod pp
;		For q = 0 To 6	
;			Select q
;				Case 3 Color 200,50,50
;				Default Color 50,50,50
;			End Select	
;			Line TP(q,l)\x+320, 240-TP(q,l)\z, TP(q,n)\x+320, 240 - TP(q,n)\z
;		Next
;		Color 50,50,200
;		Line TP(2,l)\x+320, 240-TP(4,l)\z, TP(2,l)\x+320, 240-TP(4,l)\z
;		Color 255,255,255
;		Text TP(3,l)\x + 320, 240-TP(3,l)\z,Str$(l),1,1
;	Next
;	Flip
;	MouseWait
	
	;make 3d mesh
	Track = TRACKcreate()
	
End Function

;=================================================
;=================================================
;=================================================

Function TRACKcreate()

	mesh = CreateMesh()
	s = CreateSurface( mesh )
	For l = 0 To pp-1
		n = ( l + 1 ) Mod pp
		d = ( l Mod 2 )

		;road
		v0 = AddVertex( s, TP(2,n)\x, TP(2,n)\y, TP(2,n)\z )
		v1 = AddVertex( s, TP(4,n)\x, TP(4,n)\y, TP(4,n)\z )
		v2 = AddVertex( s, TP(4,l)\x, TP(4,l)\y, TP(4,l)\z )
		v3 = AddVertex( s, TP(2,l)\x, TP(2,l)\y, TP(2,l)\z )
		For v = v0 To v3
			Select d
				Case 0 r=100:g=100:b=150
				Case 1 r=150:g=150:b=200
			End Select
			VertexColor s,v,r,g,b
		Next
		AddTriangle s,v2,v1,v0
		AddTriangle s,v0,v3,v2
		
		;kerb
		v4 = AddVertex( s, TP(0,n)\x, TP(0,n)\y, TP(0,n)\z )
		v5 = AddVertex( s, TP(1,n)\x, TP(1,n)\y, TP(1,n)\z )
		v6 = AddVertex( s, TP(1,l)\x, TP(1,l)\y, TP(1,l)\z )
		v7 = AddVertex( s, TP(0,l)\x, TP(0,l)\y, TP(0,l)\z )
		v8 = AddVertex( s, TP(5,n)\x, TP(5,n)\y, TP(5,n)\z )
		v9 = AddVertex( s, TP(6,n)\x, TP(6,n)\y, TP(6,n)\z )
		v10 = AddVertex( s, TP(6,l)\x, TP(6,l)\y, TP(6,l)\z )
		v11 = AddVertex( s, TP(5,l)\x, TP(5,l)\y, TP(5,l)\z )
		For v = v4 To v11
			Select d
				Case 0 r=50:g=150:b=50
				Case 1 r=75:g=200:b=75
			End Select
			VertexColor s,v,r,g,b
		Next
		AddTriangle s,v6,v5,v4
		AddTriangle s,v4,v7,v6
		AddTriangle s,v10,v9,v8
		AddTriangle s,v8,v11,v10
		
		;grass
		v12 = AddVertex( s, TP(1,n)\x, TP(1,n)\y, TP(1,n)\z )
		v13 = AddVertex( s, TP(2,n)\x, TP(2,n)\y, TP(2,n)\z )
		v14 = AddVertex( s, TP(2,l)\x, TP(2,l)\y, TP(2,l)\z )
		v15 = AddVertex( s, TP(1,l)\x, TP(1,l)\y, TP(1,l)\z )
		v16 = AddVertex( s, TP(4,n)\x, TP(4,n)\y, TP(4,n)\z )
		v17 = AddVertex( s, TP(5,n)\x, TP(5,n)\y, TP(5,n)\z )
		v18 = AddVertex( s, TP(5,l)\x, TP(5,l)\y, TP(5,l)\z )
		v19 = AddVertex( s, TP(4,l)\x, TP(4,l)\y, TP(4,l)\z )
		For v = v12 To v19
			Select d
				Case 0 r=200:g=50:b=50
				Case 1 r=200:g=200:b=200
			End Select
			VertexColor s,v,r,g,b
		Next
		AddTriangle s,v14,v13,v12
		AddTriangle s,v12,v15,v14
		AddTriangle s,v18,v17,v16
		AddTriangle s,v16,v19,v18
		
		;underside	
		If TP(3, n )\y =10 Or TP(3, l )\y=10
			v20 = AddVertex( s, TP(0,n)\x, TP(0,n)\y, TP(0,n)\z )
			v21 = AddVertex( s, TP(6,n)\x, TP(6,n)\y, TP(6,n)\z )
			v22 = AddVertex( s, TP(6,l)\x, TP(6,l)\y, TP(6,l)\z )
			v23 = AddVertex( s, TP(0,l)\x, TP(0,l)\y, TP(0,l)\z )
			For v = v20 To v23
				Select d
					Case 0 r=50:g=50:b=200
					Case 1 r=50:g=50:b=150
				End Select
				VertexColor s,v,r,g,b
			Next
			AddTriangle s, v20,v21,v22
			AddTriangle s,v22,v23,v20 
		EndIf
			
	Next
	
	EntityFX mesh,2
	EntityPickMode mesh,2
	UpdateNormals mesh
	Return mesh

End Function

;=================================================
;=================================================
;=================================================

Function WRAP#( q#, b#)

	If q>=b Then q=q-b
	If q<0 Then q=b+q
	Return q	

End Function

;=================================================
;=================================================
;=================================================

Function LIMIT#(n#,n1#,n2#)
	
	If n>n2 Then n=n2
	If n<n1 Then n=n1	
	Return n

End Function

;=================================================
;=================================================
;=================================================

Function JOIN (x1,y1,z1,vx,vy,vz,x2,y2,z2)

	For t#=.1 To 1 Step .1 
		TP( 3, pp ) = New Vector
		TP(3,pp)\x = x1*(1-t)^3 + 3*vx*(1-t)^2*t + 3*vx*(1-t)*t^2 + x2*t^3
		TP(3,pp)\y = limit( y1*(1-t)^3 + 3*vy*(1-t)^2*t + 3*vy*(1-t)*t^2 + y2*t^3 , 0, 10.0 )
		TP(3,pp)\z = z1*(1-t)^3 + 3*vz*(1-t)^2*t + 3*vz*(1-t)*t^2 + z2*t^3
		pp=pp+1
	Next

End Function

;=================================================
;=================================================
;=================================================
;=================================================
;=================================================
;=================================================

.LEVELdata

Data 25
Data 32,0,80
Data -32,0,80
Data -64,1,48
Data -96,3,-16
Data -128,0,-16
Data -160,3,48
Data -160,0,112
Data -160,5,176
Data -96,0,176
Data -32,0,208
Data 32,0,208
Data 96,5,176
Data 96,5,144
Data 32,0,144
Data -32,0,144
Data -128,11,144
Data -192,11,144
Data -224,0,112
Data -224,0,16
Data -256,8,-16
Data -256,8,-48
Data -192,3,-112
Data -128,0,-112
Data -64,5,-144
Data 32,7,-112
Data 96,0,16

Data 18
Data 0,0,112
Data -96,0,144
Data -160,0,144
Data -192,4,48
Data -192,4,-16
Data -128,5,-48
Data -128,0,-112
Data -192,0,-144
Data -192,0,-176
Data -160,0,-208
Data -128,11,-208
Data -32,11,-176
Data 32,11,-176
Data 64,0,-16
Data 160,0,-80
Data 224,0,16
Data 192,0,112
Data 96,0,144


funracer with physics with huge jumps and gaps and multiplayer - would be a nice community project.

The art of programming!. With a few lines of code you manage to make me spend half an hour playing with your car.
Good job.

Nice one Rob (and Stevie).

@ Rob Farley & Stevie G...

Cool work dudes... RESPECT ;).

Awesome. I tried to convert it to bmax with minib3d, here's to code:
Strict

Import sidesign.minib3d

Graphics3D(1024,768,32,2)
ClearTextureFilters()

Global camera:TCamera = CreateCamera()
MoveEntity(camera,0,30,-10)
Global light:TLight = CreateLight();RotateEntity(light,45,45,0)

' Build the car
Global F_Axel:TPivot = CreatePivot()
Global R_Axel:TPivot = CreatePivot()
Global F_Bumper:TPivot = CreatePivot()

Global RL_Wheel:TEntity = CreateWheel(R_Axel)
Global RR_Wheel:TEntity = CreateWheel(R_Axel)
Global FL_Wheel:TEntity = CreateWheel(F_Bumper)
Global FR_Wheel:TEntity = CreateWheel(F_Bumper)
Global Body:TEntity = CreateCube(R_Axel)
EntityColor(body,255,50,0)
ScaleEntity(body,2,1,4)
PositionEntity(body,0,2,2,5)

MoveEntity(RL_Wheel,-2,0,0)
MoveEntity(RR_Wheel,2,0,0)
MoveEntity(FL_Wheel,-2,0,0)
MoveEntity(FR_Wheel,2,0,0)
MoveEntity(R_Axel,0,0,-5)
EntityParent(F_Bumper,R_Axel)

Global speed:Float = 0
Global drift:Float = 0
Global steer:Float = 0

' Create the ground >> can't get texture creation done so I'll just add some random objects to see that we are driving
Global Ground:TEntity = CreateCube()
ScaleEntity(Ground,1000,0,1000)
PositionEntity(Ground,0,-1,0)
EntityColor(Ground,0,200,100)

' Add some random cubes so we can see we are driving
Global d:TEntity=CreateCube()
SeedRnd(MilliSecs())
For Local i=0 To 90
	Local p:TEntity=CopyEntity(d)
	PositionEntity( p, Rnd(0, 500), 0, Rnd(0, 500))
Next

' Main loop
Global t = MilliSecs()

While Not KeyHit(KEY_ESCAPE)
	' Steering
	If KeyDown(KEY_RIGHT) steer :+ 2
	If KeyDown(KEY_LEFT) steer :- 2
	steer :* .6
	
	' Turn wheels
	RotateEntity(F_Axel,0,EntityYaw(R_Axel)-steer,0)
	RotateEntity(FL_Wheel,0,EntityYaw(R_Axel,True)-(steer*10),0,True)
	RotateEntity(FR_Wheel,0,EntityYaw(R_Axel,True)-(steer*10),0,True)
	
	' Gas
	If KeyDown(KEY_UP) speed :+ .2
	speed :* .94
	
	' Forward
	MoveEntity(F_Axel,0,0,speed)
	PointEntity(R_Axel,F_Axel)
	MoveEntity(R_Axel,0,0,EntityDistance(R_Axel,F_Axel)-5) ' 5 is cars length
	
	' drift
	drift :+ (steer*speed)*-.01
	drift :* .95
	
	MoveEntity(F_Axel,drift,0,0)
	MoveEntity(R_Axel,drift*1.1,0,0)
	PointEntity(R_Axel,F_Axel)
	MoveEntity(R_Axel,0,0,EntityDistance(R_Axel,F_Axel)-5) ' 5 is cards length
	
	' roll body
	RotateEntity(body,0,0,-drift*10)
	
	' update camera
	PointEntity(camera,F_Bumper)
	PositionEntity(camera,EntityX(R_Axel),30,EntityZ(R_Axel)-50)
	
	' render etc
	RenderWorld()
	Text(0,0,speed)
	Text(0,20,steer)
	
	' timing
	t = MilliSecs()-t
	If t-20 < 0 Then Delay Abs(t-20)
	t = MilliSecs()
	
	Flip
Wend

Function CreateWheel:TEntity(Parent:TEntity)
	Local Entity:TMesh = CreateCylinder(12,0,Parent)
	RotateMesh(Entity,90,90,0)
	ScaleMesh(Entity,.5,1,1)
	EntityFX(Entity,16)
	EntityColor(Entity,50,50,50)
	Return Entity
End Function


Couldn't get the textures working so I just placed some random cubes so you can see that the car is actually moving.
Really liked it, thanks :)

Thanks, very useful.

i like it