Position object on the X/Z plane at position represented by mouse cursor with ability to move camera by Philip10th Mar 2004 9:42
|
---|
Summary See the long description below. Description This is DBPro code. It has been tested by me and it works. It is basically a revision of the code previously posted at: http://darkbasicpro.thegamecreators.com/?m=forum_view&t=27469&b=6 and http://darkbasicpro.thegamecreators.com/?m=forum_view&t=27455&b=7 Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com REMSTART ************************************ Camera code for isometric style game By Philip As requested by GuruSY ************************************ REMEND Rem PJY - turn SYNC on (theres no point in a sync rate command without it) sync on sync Rate 60 Rem PJY - replace "grass" with exciting wireframe matrix (oooh!) Rem PJY - the matrix will sit on the X/Z plane. make matrix 1, 1000, 1000, 100, 100 position matrix 1, -500, 0, -500 Rem PJY - create a happy red cube to be the target (you know its happy Rem PJY - because its red) when you click the mouse make object cube 2, 5 color object 2, rgb(255, 0, 0) position object 2, 0, 0, 0 Rem PJY - position the camera above the matrix (on +Y axis) but point it Rem PJY - straight down the Y axis towards the matrix to begin with Rem PJY - and initialise global variables to hold the camera's X, Y and Z Rem PJY - positions global camera_x global camera_y camera_y = 100 global camera_z position camera 0, camera_x, camera_y, camera_z point camera 0, 0, 0, 0 Rem PJY - place happy red cube object above the matrix position object 2, 0, 2, 0 do Rem PJY - keep this legacy code here - this moves the red cube about if rightkey() = 1 then turn object right 2, 10 if leftkey() = 1 then turn object left 2, 10 if upkey() = 1 then Move object 2, -1 if downkey() = 1 then move object 2, 1 Rem PJY - control camera's basic movement with WASD keys if keystate(30) = 1 then camera_x = camera_x - 1 if keystate(17) = 1 then camera_z = camera_z + 1 if keystate(32) = 1 then camera_x = camera_x + 1 if keystate(31) = 1 then camera_z = camera_z - 1 Rem PJY - move camera up and down on the Y axis using Q and E keys if keystate(16) = 1 Rem PJY - but don't move the camera above +300 on the Y axis if camera_y =< 299 camera_y = camera_y + 1 endif endif if keystate(18) = 1 Rem PJY - also don't move the camera below +50 on the Y axis if camera_y => 51 camera_y = camera_y - 1 endif endif Rem PJY - roll camera left and right around the centre of the screen Rem PJY - using the C and V keys if keystate(46) = 1 roll camera left 0, 1 endif if keystate(47) = 1 roll camera right 0, 1 endif Rem PJY - pitch the camera up and down using the Z and X keys if keystate(44) = 1 then pitch camera up 0, 1 if keystate(45) = 1 then pitch camera down 0, 1 Rem PJY - reposition the camera every loop position camera 0, camera_x, camera_y, camera_z Rem PJY - if mouseclick then reposition the happy red cube at its new Rem PJY - recalculated position if mouseclick() = 1 movetoscreenloc(2) endif Rem PJY - print various useful information to the screen Rem PJY - first print the new position of the happy red cube text 50, 50, "Cube X position: " + str$(object position x(2)) text 50, 60, "Cube Y position: " + str$(object position y(2)) text 50, 70, "Cube Z position: " + str$(object position z(2)) Rem PJY - next print the camera's new position text 50, 130, "Camera X position: " + str$(camera_x) text 50, 140, "Camera Y position: " + str$(camera_y) text 50, 150, "Camera Z position: " + str$(camera_z) Rem PJY - and lets not forget its angles text 50, 170, "Camera angle X: " + str$(camera angle x(0)) text 50, 180, "Camera angle Y: " + str$(camera angle y(0)) text 50, 190, "Camera angle Z: " + str$(camera angle z(0)) Rem PJY - may as well display the keys as well (and why not?) text 500, 50, "Keys:" text 500, 80, "Arrow keys to move the red cube object" text 500, 90, "Mouseclick to reposition the red cube object" text 500, 100, "WASD to move the camera" text 500, 110, "Q and E to make the camera move up and down" text 500, 120, "Z and X to pitch the camera up and down" text 500, 130, "C and V to roll the camera left and right" Rem PJY - sync must be in the loop sync loop Rem PJY - function to position the happy red cube at the 3d world space coords Rem PJY - slightly above the matrix on the Y axis equivalent to the mouse cursor function movetoscreenloc(objectnum) Rem PJY - create some vectors - we LOVE them one = 1 two = 2 three = 3 four = 4 null = make vector3(one) null = make vector3(two) null = make vector3(three) null = make vector3(four) Rem PJY - create a 3d vector to represent the camera's "default" position Rem PJY - of pointing straight down the Y axis towards the matrix Rem PJY - (this neatly replaces the middle of the screen vector of the Rem PJY - previous version of the code) set vector3 one, 0, -1, 0 Rem PJY - create a 3d vector to represent the 3d world position of the Rem PJY - mouse cursor pick screen mousex(), mousey(), 1 px# = get pick vector x() py# = get pick vector y() pz# = get pick vector z() set vector3 two, px#, py#, pz# Rem PJY - get the acos dot product of vectors one and two to find the Rem PJY - angle between them angle# = acos(dot product vector3(two, one)) text 50, 90, "Acos angle: " + str$(angle#) Rem PJY - apply some basic trig to find out the length of the hypotenuse Rem PJY - in other words imagine a line that goes from the camera's 3d rem PJY - X, Y and Z world position through the mouse cursor's position Rem PJY - until it hits the matrix. This is the hypotenuse cos_angle# = cos(angle#) hypo_length# = camera_y / cos_angle# text 50, 100, "Length of Hypotenuse: " + str$(hypo_length#) Rem PJY - we need to scale the second vector to create a vector equivalent Rem PJY - to the hypotenuse imaginary line so before scaling it we need rem PJY - to normalize the third vector (i.e. make it 1 unit long) normalize vector3 two, two Rem PJY - as its normalized we can now scale it by the length of the Rem PJY - hypotenuse scale vector3 two, two, hypo_length# Rem PJY - now if we add the second vector to the camera's position the Rem PJY - mathematical result will be the X, Y and Z position of where Rem PJY - the cube should be positioned. Lets economise on vectors and Rem PJY - reuse vector one to add in the position of the camera set vector3 one, camera_x, camera_y, camera_z Rem PJY - then add vector one (camera position) to vector two (hypotenuse) rem PJY - to work out the new position for the happy red cube add vector3 four, one, two Rem PJY - now position the happy red cube at the new coordinates, slightly Rem PJY - above the matrix position object objectnum, x vector3(four), 2, z vector3(four) Rem PJY - and relax endfunction |