TGC Codebase Backup



Position object on the X/Z plane at position represented by mouse cursor with ability to move camera by Philip

10th 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

As both Red Eye and GuruSY asked for the ability to pitch the camera up and down I've revised my previous code to do achieve that. For good measure I've also included some code to spin the camera's lens and also you can now move the camera up and down on the Y axis. So basically it now does everything anybody could ever ask for in an isometric style game. I've also significantly expanded the rem statements - I hope that will be helpful.

I'll put the code into the codebase as well.

Two remaining issues:

1. the first time you use the pitch or roll keys the camera will "jump". This is a known DBPro bug I'm afraid - first reported by Spooky. Lee says he will fix it in U6

2. if the mouse cursor is "above" the plane of the matrix then the red cube will vanish into infinity. If you want to stop this just include some if statements around the position object 2 command in the function so that object 2 will not be positioned if the X and Z values are greater than the size of the matrix (-500 to +500)

Philip



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