Asteroids style wrap around code problem
Blitz3D Forums/Blitz3D Programming/Asteroids style wrap around code problem
| ||
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 ;-------------------------------------------------------------------------------------------- |
| ||
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 |
| ||
Thats really marvellous, thanks a million Floyd. I don't know how you managed to work it out. Perfect! :) |