Asteroids style wrap around code problem

Blitz3D Forums/Blitz3D Programming/Asteroids style wrap around code problem

Rob(Posted 2003) [#1]
Hi all,

Please take the time to look at the following code.
As you can see, it is a simple asteroids style game where you use the mouse to rotate and thrust with the mouse button.
I have used X and Z in 3D to emulate 2D.

I just want the rock to wrap around the other side without popping. To see it happen, just follow the asteroid :)

I must be able to use proper coordinates for the rocks and players seperately from the render positions. This is because of multiplayer.

Please see the minimap and examine the pop-in to understand how I must have proper positions and a render position.

The tempx var will eventually reposition everything so there is no pop-in. At the moment I cannot work it out...

Any help appreciated as usual! :)

;--------------------------------------------------------------------------------------------
;NOTE: I have removed Z movement (we only use x and z anyway)
;Mouse button to thrust and mouse to rotate. Only X movment for now. See map.
;--------------------------------------------------------------------------------------------

Global rx#,rvx#,x#,vx#,tempx#,mxspd#
Global worldsize=300 ; the size of the square world

Graphics3D 640,480,16,2
HidePointer
camera=CreateCamera()
PositionEntity camera,0,100,0
light=CreateLight(2,camera)
LightRange light,20
TurnEntity camera,90,0,0

rock=CreateSphere()
ScaleEntity rock,8,8,8

ship=CreateCone()
RotateMesh ship,90,0,0
ScaleEntity ship,2,1,4
EntityColor ship,255,0,0


;rock is moving right
rvx = 0.5

;--------------------------------------------------------------------------------------------

While Not KeyHit(1)

	;-------------------------------
	;PLAYER
	;update player + camera (we don't move the meshes)
	;remember the camera and ship don't move, but we use
	;their variables to move everything else instead
	
	;thrust
	If MouseDown(1) Or MouseDown(2) vx=vx+Cos(EntityYaw(ship)+90) * 0.025

	;apply movement
	x=x+vx

	;apply friction
	vx=vx*0.99
	
	;out of bounds wrapping
	If x<-worldsize x=worldsize
	If x>worldsize x=-worldsize

	TurnEntity ship,0,-mxspd*0.1,0

	;-------------------------------



	;-------------------------------
	;ROCKS	
	;rocks are moved by an offset of the player position
	;the reason why is because we need to know their X and Z
	;positions internally for networking, so merely
	;subtracting player velocities will not work
	;suffixed by r
	
	;apply movement
	rx=rx+rvx 
	
	;out of bounds wrapping
	If rx<-worldsize rx=worldsize
	If rx>worldsize rx=-worldsize
	
	
	;THIS IS WHERE WE NEED TO CALCULATE ITS RENDER POSITION SO IT DOESNT POP
	;tempx will be our offset. how can we make it work?
	tempx = rx - x

	

	PositionEntity rock,tempx,0,0
	;-------------------------------




	;-------------------------------
	;input & render
	mxspd#=MouseXSpeed()
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	UpdateWorld
	RenderWorld
	;render a mini-map
	Color 255,255,255 : Plot (2+((rx/worldsize)*32))+32,32 ; rock
	Color 255,0,0 :	Plot (2+((x/worldsize)*32))+32,32 ; ship
	;map box
	Color 150,150,150
	Rect 2,2,64+2,64+2,0
	Text 3,0,"map"
	Flip
	;-------------------------------
	
	
	
Wend
End

;--------------------------------------------------------------------------------------------



Floyd(Posted 2003) [#2]
This looks essentially correct with one exception.

You are wrapping player and rock positions.
Before rendering you must also wrap tempx, i.e. position of rock relative to player.

This is simpler with a function for wrapping:
Function wrap#( u# )

	w2# = 2.0 * worldsize

	u = u Mod w2
	
	If u < -worldsize Then Return u + w2
	If u > +worldsize Then Return u - w2
	
	Return u
	
End Function 

Then the movement code is reduced to this:
	x  = wrap( x + vx )    ; move player
	rx = wrap( rx + rvx )  ; move rock
	vx = vx * 0.99         ; friction

	TurnEntity ship, 0, -mxspd * 0.1, 0

	PositionEntity rock, wrap( rx - x ), 0, 0



Rob(Posted 2003) [#3]
Thats really marvellous, thanks a million Floyd. I don't know how you managed to work it out. Perfect! :)