Need Acceleration Code for 3D Asteroid'sh Game

Blitz3D Forums/Blitz3D Programming/Need Acceleration Code for 3D Asteroid'sh Game

I'm seek help with acceleration for c e l l u l a r. The control I desire is exactly like the control found in the 2D asteroids in which you gradually accellerate to a cap'd speed limit. I tried the code archives but failed to get the results. Physics Math is not my strong suit. So any help is greatly appreciated.

Check out c e l l u l a r Source. The player (camera) control is in the cameraControl Function.

Use sin, or cos wave. just have a speed variable, and cap it at 90 or 80. Something like:


speed = speed + 1
if speed > 80 then speed = 80
moveentity mesh,0,0, sin(speed)



It might be Cos(), depending on whether you want your acc starting slowly, or starting fats, and getting less and less until full speed is reached. Remember and multiple sin(speed) by a number to get the sort of speed range your looking for.

Something like the following should do nicely :D ( use the right arrow key to speed up!

Graphics 640,480
SetBuffer BackBuffer()



Global speed# = 0
Global acc# = 0.5

Global speed_scale = 3
Global cut_off = 80 ; no more than 90, as it's a wave, it will decrease after 90

Global x# = 100
Global y# = 200

While Not KeyHit(1)

	Cls

	If KeyDown(205) Then
		speed = speed + acc
		If speed > cut_off Then
			speed = cut_off
		End If
	Else
		speed = speed - acc
		If speed < 0 Then speed = 0
	End If
	
	x = x + Sin(speed) * speed_scale
	If x > 640 Then x = 0
	
	Oval x,y,20,20
	
	Flip
	
Wend
End


Oh, by the way, since it's 3d, you should have any problems simply translating this over, since you can use moveentity in the direction your facing :o)

You can't use MoveEntity() like that. A fast-moving spaceship that turns around doesn't suddenly start travelling in the new direction it's facing. You need to model inertia for Asteroids-style physics.

Keep track of the velocity vector of your spaceship (vx, vy, and vz). When the ship accelerates, add a small amount to the velocity. To prevent the ship from going over a certain speed (Asteroids-style) normalize your velocity vector to your max speed if its magnitude is above the max speed. (This looks way simpler in code.)

I believe this example perfectly replicates the "physics" of the original Asteroids; specifically, how accellerating at a slight angle when already traveling at your max speed would affect your velocity. Controls: space accellerates, arrow keys turn on each axis of rotation.

Const TURN_SPEED# = 2
Const ACCEL# = .005
Const MAX_SPEED# = 1
Const GLOBAL_SPACE = 0
Const PLAYFIELD_SIZE# = 30

Graphics3D 800, 600

camera = CreateCamera()
PositionEntity(camera, 0, 0, -20)
light = CreateLight()

Type player
	Field entity
	Field x#, y#, z#
	Field vx#, vy#, vz#
End Type

Global p.player = New player
p\entity = CreateCone()

While Not(KeyHit(1))
	; input
	If KeyDown(200) Then TurnEntity(p\entity, TURN_SPEED, 0, 0)
	If KeyDown(208) Then TurnEntity(p\entity, -TURN_SPEED, 0, 0)
	If KeyDown(203) Then TurnEntity(p\entity, 0, 0, TURN_SPEED)
	If KeyDown(205) Then TurnEntity(p\entity, 0, 0, -TURN_SPEED)
	If KeyDown(57) Then
		; accellerate in the direction the player is facing (use Y axis because cones point in that direction)
		TFormVector 0, ACCEL, 0, p\entity, GLOBAL_SPACE
		p\vx = p\vx + TFormedX()
		p\vy = p\vy + TFormedY()
		p\vz = p\vz + TFormedZ()
		; measure current speed
		current_speed# = Sqr(p\vx*p\vx + p\vy*p\vy + p\vz*p\vz)
		If current_speed > MAX_SPEED Then
			; limit current speed to MAX_SPEED
			ratio_of_speed_to_keep# = MAX_SPEED / current_speed
			p\vx = p\vx * ratio_of_speed_to_keep
			p\vy = p\vy * ratio_of_speed_to_keep
			p\vz = p\vz * ratio_of_speed_to_keep
		EndIf
	EndIf
	
	; move the player
	p\x = p\x + p\vx
	p\y = p\y + p\vy
	p\z = p\z + p\vz
	
	; if the player goes off an edge of the playfield, move him to the other side
	While p\x < -PLAYFIELD_SIZE/2 : p\x = p\x + PLAYFIELD_SIZE : Wend
	While p\x >  PLAYFIELD_SIZE/2 : p\x = p\x - PLAYFIELD_SIZE : Wend
	While p\y < -PLAYFIELD_SIZE/2 : p\y = p\y + PLAYFIELD_SIZE : Wend
	While p\y >  PLAYFIELD_SIZE/2 : p\y = p\y - PLAYFIELD_SIZE : Wend
	While p\z < -PLAYFIELD_SIZE/2 : p\z = p\z + PLAYFIELD_SIZE : Wend
	While p\z >  PLAYFIELD_SIZE/2 : p\z = p\z - PLAYFIELD_SIZE : Wend
	
	; output
	PositionEntity(p\entity, p\x, p\y, p\z)
	RenderWorld
	Text 0, 0, "speed = " + current_speed
	Flip
Wend
End


That's the first time I've used the TForm* functions. Damn are they useful once you get the hang of them.

Agreed on the Tform functions - I tried creating asteroids style movement without using them (still being rather new to Blitz and not knowing how or what they were for) and actually managed it. It required way more code than necessary though!

One suggestion, even though it isn't strictly "realistic", you might want to gradually slow the player down when they're not accelerating. Originally, I designed my Asteroids 3D clone so the player would continue going in the same direction for ever, but that proved more of a hassle than a feature.

Drag can be accomplished by multiplying each component of the velocity vector by a number very close to 1.0 every update.

http://www.blitzbasic.com/codearcs/codearcs.php?code=1547


Andy

In these type of games you should never need to store a top speed , so in the above examples ...

Const Acceleration# = .03
Const Drag# = .99

.
.

Throttle# = mousedown(1)
.
tformvector 0,0,Acceleration * Throttle ,MyShip, 0
Velocity\x = Velocity\x * Drag + tformedx()
Velocity\y = Velocity\y * Drag + tformedy()
Velcoity\z = Velocity\z *Drag + tformedz()
translateentity MyShip, Velocity\x, Velocity\y, Velocity\z

So the max speed is effectively

Acceleration / ( 1.0 - Drag ) = 3.0

Stevie

Oh, sorry, I played celluar and didn't realise it was space faring type enviroment. Apologies.

Thanks everyone for the effort. Put the asteroid-like movement in and discovered doesnt work very well for control in first person perspective.