Standard 3rd person controls?

Blitz3D Forums/Blitz3D Beginners Area/Standard 3rd person controls?

Cubed Inc.(Posted 2010) [#1]
I'm trying to work on my first small game, and I need to know how to make standard 3rd person controls, similair to the ones in Super Mario 64. The type of controls that I'm talking about has been used in countless 3d platformers. Can someone with some experience help me out? please reply.thanks.


Doggie(Posted 2010) [#2]
Not sure just what, but a good start might be Blitz3d/Samples/Mak/Castle/castle.bb


Cubed Inc.(Posted 2010) [#3]
Doggie
well, I tried it, but it wasn't what I had in mind. I'm trying to achieve the controls thats similiar to the ones in Super Mario 64.


Kryzon(Posted 2010) [#4]
Not a lot of people know how to do this in these forums (unless I'm mistaking that for a lack of effort to try so).

Most will use globally aligned controls, meaning you will turn regarding the world's origin's axis. It's a simple TurnEntity(player,[...]).

What Super Mario 64 along with other N64 and Dual Shock PSOne games do is use the camera as reference to know in what direction the player should turn.
This method works better with analog controllers like gamepads. However, even with keyboards it's still great, since the player will have control of his character with the current view direction as reference, not some static axes.
By itself, this method does not allow strafing (walking sideways while aiming elsewhere, FPS style) - it can be added without a problem, though.

The method works like so:
;Before anything takes place in your game:

VectorPivot = CreatePivot()
EntityParent(VectorPivot, Camera, False) ;False makes the pivot snap to the camera's orientation and position automatically.
Then, in your game loop or whatever:
;You need a previously declared constant such as "pSpeed#" or something like that. It's the Player's movement speed.

;This snippet needs to run AFTER you pointed your camera to the player.

RotateEntity(VectorPivot, 0, EntityYaw(VectorPivot,True) , 0, True)

TFormVector(KeyRight-KeyLeft , 0, KeyUp-KeyDown, VectorPivot, 0)

;The KeyRight, KeyLeft and the other variables are simple key states: KeyRight = KeyDown(203). 
;Makes it easier to handle.

AlignToVector(Player, TFormedX(), 0, TFormedZ(), 3) 
MoveEntity(Player, 0, 0, pSpeed)

Coded this blindly (i.e: didn't test it).

EDIT: Tested. Seems to work.


GIB3D(Posted 2010) [#5]



Cubed Inc.(Posted 2010) [#6]
Kryzon
I tried to implement your code into mine, but all I got were some pretty ugly results.
heres the code.
;test;

Graphics3D 1280,600,32,2

Const GRAVITY#=-1.8
Const pSpeed#=2

Const TYPE_PLAYER=1,TYPE_TARGET=3,TYPE_WATER=3
Const TYPE_SCENERY=10,TYPE_TERRAIN=11

Collisions TYPE_PLAYER,TYPE_TERRAIN,2,3
Collisions TYPE_PLAYER,TYPE_SCENERY,2,3
Collisions TYPE_TARGET,TYPE_TERRAIN,2,2
Collisions TYPE_TARGET,TYPE_SCENERY,2,2
Collisions 1,2,2,2

seq=1

;player;
player=LoadAnimMesh ("media/Mechanibal.b3d")
playertex=LoadTexture ("media/(_Tg)mars70@...")
PositionEntity player,0,400,40
ScaleEntity player,.2,.2,.2
EntityShininess player,0
ExtractAnimSeq player,100,125
Animate player,2,1,seq,10
EntityRadius player,3,3
EntityType player,TYPE_PLAYER

;Lego Island;
island=LoadMesh("land3.b3d")
islandtex=LoadTexture("media/Untitled2.png",256+4)
islandtex2=LoadTexture("wood.png",256)
EntityShininess island,0
PositionEntity island,0,-160,60
ScaleEntity island,10,10,10
EntityFX island,0
EntityType island,TYPE_TERRAIN

;tree;
island2=LoadMesh("tree.b3d")
islandtex2=LoadTexture("media/Untitled2.png",256)
islandtex3=LoadTexture("wood.png",256)
EntityShininess island2,1
PositionEntity island2,30,-100,-120
ScaleEntity island2,1,1,1
EntityFX island2,0
EntityType island2,TYPE_TERRAIN

;water;
water = CreatePlane ()
h20=LoadTexture("patch (2).png")
EntityTexture water,h20
ScaleTexture h20, 50, 50
PositionEntity water,0,-140,60
EntityShininess water,0
EntityFX island,0
EntityType water,TYPE_TERRAIN

;camera (AKA the player);
camera=CreateCamera(target)
PositionEntity camera,0,200,-60
MoveEntity camera,0,3,-50
PointEntity camera,player

VectorPivot = CreatePivot()
EntityParent(VectorPivot, camera, False) ;False makes the pivot snap to the camera's orientation and position automatically.

;light;
LightPivot = CreatePivot()
TurnEntity LightPivot, 0, 1800, 0

Light=CreateLight(1, LightPivot)
TurnEntity Light, 60, 0, 0
LightColor Light,225,100,0

;target;
target=CreatePivot( player )
MoveEntity Target,0,80,-350
RotateEntity Target,0,80,0

;sky/fog/range;
sky=CreateSphere(100)
skytex=LoadTexture("media/sky_RT.jpg")
EntityTexture sky,skytex
ScaleEntity sky,9000,9000,9000
CameraFogMode camera,10
CameraFogColor camera,200, 220, 255
CameraRange camera, 1,50000
CameraFogRange camera,1,2500-10
CameraClsColor camera,200,220,255
FlipMesh sky

smooth=True
;move camera;
While Not KeyDown(1)
RotateEntity(VectorPivot, 0, EntityYaw(VectorPivot,True) , 0, True)
TFormVector(KeyRight-KeyLeft , 0, KeyUp-KeyDown, VectorPivot, 0)
KeyRight = KeyDown(203)
KeyLeft = KeyDown(208)
TurnEntity sky,0,.1,0
TranslateEntity player,0,GRAVITY,0

AlignToVector(player, TFormedX(), 0, TFormedZ(), 3)
MoveEntity(player, 0, 0, pSpeed)

If Not KeyDown(1)
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.3,dy*.1,dz*.3
EndIf
PointEntity camera,player

UpdateWorld
RenderWorld
Flip
Wend
End
I think maybe the problem could be in the camera, but i'm not sure. can you help?
please reply


Doggie(Posted 2010) [#7]
You might want to make a zip file that includes your b3d model. Believe it or not sometimes it's the model itself that throws things off. Also makes it easier for others to test your code. If you're worried about someone using it or something just say "please don't use the included model for commercial purposes" ;)


Cubed Inc.(Posted 2010) [#8]
Doggie
I think making and uploading a zip file would be over complicating it. I'll modify my code and chane the models with basic shapes. Just give me some time to modify the code:)


Kryzon(Posted 2010) [#9]
Hello TaGames.

I didn't give a tough look on your code so I can't say anything about it. Just make sure to adapt the example into your code, and not simply copy it. If you can't understand exactly what each line is doing, then nobody here can help you (no offense!).

That AlignToVector is the quick and dirty way to do the method, but it's certainly not the best. If you keep oscilating away and into the camera, the model turns in the X axis and screws everything up. Might work for a primitive, but not a player mesh.

The best is to do something like GIB3D did. We need to use another pivot so the player can turn to it with DeltaYaw, and don't use the Pitch axis.

Create another pivot, maybe called "PlayerOrientation", and use it like so:
;Replace the AlignToVector line from the snippet I showed previously with this:

TFormPoint(TFormedX(),0,TFormedZ(),Player,0)
PositionEntity(PlayerOrientation,TFormedX(),TFormedY(),TFormedZ(),True)
TurnEntity(Player,0,DeltaYaw(Player,PlayerOrientation),0,True)

All those 3 lines should replace the AlignToVector line. Also, make sure to create the PlayerOrientation pivot (no need to pre-place it anywhere, those 3 lines take care of that).


Cubed Inc.(Posted 2010) [#10]
Kryzon
I am having trouble understanding this code, and your right about how no one can help me if I don't understand it. I don't understand this code, so in result I just keep on copy and pasting yours into mine, and I keep getting horrific results. I need alot of help understanding your code and method.
;test;

Graphics3D 1280,600,32,2

Const GRAVITY#=-1.8
Const pSpeed#=2

Const TYPE_PLAYER=1,TYPE_TARGET=3,TYPE_WATER=3
Const TYPE_SCENERY=10,TYPE_TERRAIN=11

Collisions TYPE_PLAYER,TYPE_TERRAIN,2,3
Collisions TYPE_PLAYER,TYPE_SCENERY,2,3
Collisions TYPE_TARGET,TYPE_TERRAIN,2,2
Collisions TYPE_TARGET,TYPE_SCENERY,2,2
Collisions 1,2,2,2

seq=1

;player;
player=LoadAnimMesh ("media/Mechanibal.b3d")
playertex=LoadTexture ("media/(_Tg)mars70@...")
PositionEntity player,0,400,40
ScaleEntity player,.2,.2,.2
EntityShininess player,0
ExtractAnimSeq player,100,125
Animate player,2,1,seq,10
EntityRadius player,3,3
EntityType player,TYPE_PLAYER

;Lego Island;
island=LoadMesh("land3.b3d")
islandtex=LoadTexture("media/Untitled2.png",256+4)
islandtex2=LoadTexture("wood.png",256)
EntityShininess island,0
PositionEntity island,0,-160,60
ScaleEntity island,10,10,10
EntityFX island,0
EntityType island,TYPE_TERRAIN

;tree;
island2=LoadMesh("tree.b3d")
islandtex2=LoadTexture("media/Untitled2.png",256)
islandtex3=LoadTexture("wood.png",256)
EntityShininess island2,1
PositionEntity island2,30,-100,-120
ScaleEntity island2,1,1,1
EntityFX island2,0
EntityType island2,TYPE_TERRAIN

;water;
water = CreatePlane ()
h20=LoadTexture("patch (2).png")
EntityTexture water,h20
ScaleTexture h20, 50, 50
PositionEntity water,0,-140,60
EntityShininess water,0
EntityFX island,0
EntityType water,TYPE_TERRAIN

;camera (AKA the player);
camera=CreateCamera(target)
PositionEntity camera,0,200,-60
MoveEntity camera,0,3,-50
PointEntity camera,player

PlayerOrientation = CreatePivot()
EntityParent(PlayerOrientation , camera, False) ;False makes the pivot snap to the camera's orientation and position automatically.

;light;
LightPivot = CreatePivot()
TurnEntity LightPivot, 0, 1800, 0

Light=CreateLight(1, LightPivot)
TurnEntity Light, 60, 0, 0
LightColor Light,225,100,0

;target;
target=CreatePivot( player )
MoveEntity Target,0,80,-350
RotateEntity Target,0,80,0

;sky/fog/range;
sky=CreateSphere(100)
skytex=LoadTexture("media/sky_RT.jpg")
EntityTexture sky,skytex
ScaleEntity sky,9000,9000,9000
CameraFogMode camera,10
CameraFogColor camera,200, 220, 255
CameraRange camera, 1,50000
CameraFogRange camera,1,2500-10
CameraClsColor camera,200,220,255
FlipMesh sky

smooth=True
;move camera;
While Not KeyDown(1)
If KeyDown(200)
KeyRight = KeyDown(200)
EndIf
TurnEntity sky,0,.1,0
TranslateEntity player,0,GRAVITY,0
TFormPoint(TFormedX(),0,TFormedZ(),player,0)
PositionEntity(PlayerOrientation,TFormedX(),TFormedY(),TFormedZ(),True)
TurnEntity(player,0,DeltaYaw(player,PlayerOrientation),0,True)

If Not KeyDown(1)
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.3,dy*.1,dz*.3
EndIf
PointEntity camera,player
RotateEntity(PlayerOrientation, 0, EntityYaw(PlayerOrientation,True) , 0, True)
TFormVector(KeyRight-KeyLeft , 0, KeyUp-KeyDown, PlayerOrientation, 0)


UpdateWorld
RenderWorld
Flip
Wend
End

can you please explain?


_PJ_(Posted 2010) [#11]
Hey there, TAGames.

A few basic, general tips just to start off with:

1) Put your posted code into 'code' tags so it's easier to see and neater on the boards
[ codebox ] ;Code Here [ / codebox ]
(Without the spaces!)

2) If you are having real trouble with a large chucnk of code, and honestly can't seem to understand a lot of it, then try to break it down into smaller pieces and concentrate on the smaller pieces one at a time.

As for the code posted above, since I dont have the various media files associated with it, can you explain a little more on "WHAT" problem you are having with it now?


Cubed Inc.(Posted 2010) [#12]
Malice
The part in the code thats troubling me is this part.
This part is what I don't understand. When I put it in, the characters movements didn't work, the camera just started freaking out nonstop! I hope that now it's clearer




_PJ_(Posted 2010) [#13]
Well for starters, this bit is probably going to cause problems if it doesn't already:

If KeyDown(200)
KeyRight = KeyDown(200)
EndIf


If you took your finger off the key, there's nothing to tell KeyRight to go back to 0, so it will remain as "True".
You can remove the 'Ifs' and just have the following, so KeyRight is updated automatically.
KeyRight = KeyDown(200)


Next, onto the actual camera problem:

Every loop, the camera is moving closer to the target with this code:

dx#=EntityX( target,True )-EntityX( camera )
		dy#=EntityY( target,True )-EntityY( camera )
		dz#=EntityZ( target,True )-EntityZ( camera )
	    TranslateEntity camera,dx*.3,dy*.1,dz*.3


Try adding in some distance checks and see if that makes a difference.
I cannot tell what kind of distances are suitable, so you'd have to experiment a little, but here's the basic idea:

If ((EntityDistance(camera,target)<2) or (EntityDistance(camera,target)>5))
dx#=EntityX( target,True )-EntityX( camera )
		dy#=EntityY( target,True )-EntityY( camera )
		dz#=EntityZ( target,True )-EntityZ( camera )
	    TranslateEntity camera,dx*.3,dy*.1,dz*.3
End If



Cubed Inc.(Posted 2010) [#14]
malice
I tried your idea out, and I even did some tweaking here and there, but I think that the problem lies in this bit of the code.


I think that the lines that are making the camera jerk and twitch could be this one

and this one


I'm sorry about being so difficult, it's just that the controls that i'm trying to achieve are very important for the sake of this game.


Kryzon(Posted 2010) [#15]
What happened to VectorPivot? why did you take it away?

You were told to "create another pivot", not replace the one already in use. Check post #9.


Cubed Inc.(Posted 2010) [#16]
Kryzon
Sorry, I did that by accident
I added VectorPivot and PlayerOrientation and I even brushed up the code. Now the camera doesn't twitch and jerk, but the player doesn't turn to any directions when he moves(if I press the right key, he doesn't turn right etc..)
I tried pointing the player to the vectorpivot but that just made it go all wonky.
What part of the code is supposed to make the player point in the correct directions?



Kryzon(Posted 2010) [#17]
Check post #9 for that too. It answers that precise question (if you want, I can quote the line that says that).

What part of the code is supposed to make the player point in the correct directions?

I don't mean this in a demotivational way, but you REALLY shouldn't try to write code you don't understand.
If you can't visualize what your code is doing, you won't be able to solve it's bugs on your own (whether you're a beginner or advanced user).

I highly suggest you take the time to learn what each line is doing, even if that is the most boring thing of all. If you don't take the time to do that, it's impossible to get any better at this.


Cubed Inc.(Posted 2010) [#18]
Kryzon
I understand what you mean. I'll try to understand the functions of the code better. Who knows, maybe i'll make my own version of the code that will work just aswell. That's what happened to me while I was trying to learn how to make a player align to the terrian. I ended up making my own code that worked. Thanks for trying to help.


_PJ_(Posted 2010) [#19]

I understand what you mean. I'll try to understand the functions of the code better. Who knows, maybe i'll make my own version of the code that will work just aswell. That's what happened to me while I was trying to learn how to make a player align to the terrian. I ended up making my own code that worked. Thanks for trying to help.


That's how the learning process works with blitz :)

As I stated before, if you don't fully understand the entiretyy of a chunk of code, concentrate on smaller parts until you are confident that each smaller part works as intended.
for example, a 3rd-persson camera code might be made up of the following smaller parts:


1) create player
2) create pivot with player as parent
3) create camera with the pivot as parent
4) place the camera at a reasonable distance from the pivot
5) ensure distance and facing of pivot is correct wrt player
6) ensure distance and facing of camera is correct with wrt pivot


Cubed Inc.(Posted 2010) [#20]
Guys, I have looked and understood each of the functions of the code, I have checked many times and I have no doubt in myself that the code is executed correctly. After seeing how the code hasn't been working, I then studied it again and again, both by code and in game, and I realized the problem was all in my camera. The camera in my game was programmed so that it would STAY BEHIND the player AT ALL TIMES. The characters movements are correct, it's the camera that was messing it up.

Does anyone know any camera code that would work for this situation?
please reply


grindalf(Posted 2010) [#21]
Super ugly code taken from something i made years ago.
but you might be able to take the ideas and clean it up or something(because im to lazy lol)
double tap a direction to run

;----------code-----------
Graphics3D 800,600,32,2
SeedRnd MilliSecs()



player=CreateCube()
cam=CreateCamera()
cam_piv=CreatePivot()




Type cubes
Field mesh
End Type
;---create random cubes to walk around---
For tmp=1 To 50
cube.cubes=New cubes
cube\mesh=CreateCube()
PositionEntity cube\mesh,Rand(-100,100),0,Rand(-100,100)
Next







While KeyDown(1)=False

kh_200=False:If KeyHit(200)=True kh_200=True
kh_208=False:If KeyHit(208)=True kh_208=True
kh_203=False:If KeyHit(203)=True kh_203=True
kh_205=False:If KeyHit(205)=True kh_205=True
kh_28=False:If KeyHit(28)=True kh_28=True


;--camera physics--
PositionEntity cam_piv,EntityX(player),EntityY(player),EntityZ(player)
PositionEntity cam,EntityX(cam_piv),EntityY(cam_piv),EntityZ(cam_piv)
RotateEntity cam,0,EntityYaw(cam_piv),0
MoveEntity cam,0,5,-20

tmp_yaw=EntityYaw(cam_piv)
tmp_yaw2=EntityYaw(player)
If tmp_yaw<0 Then tmp_yaw=tmp_yaw+360
If tmp_yaw2<0 Then tmp_yaw2=tmp_yaw2+360

If cam_active=True Then
If tmp_yaw2<tmp_yaw-180 Then
TurnEntity cam_piv,0,1,0
ElseIf tmp_yaw2>tmp_yaw+180 Then
TurnEntity cam_piv,0,-1,0
ElseIf tmp_yaw2>tmp_yaw Then
TurnEntity cam_piv,0,1,0
ElseIf tmp_yaw2<tmp_yaw Then
TurnEntity cam_piv,0,-1,0
End If
End If

;--controlls--
If key_200_timer>0 key_200_timer=key_200_timer-1:If kh_200=True running=True
If kh_200=True And key_200_timer=0 key_200_timer=15
If key_208_timer>0 key_208_timer=key_208_timer-1:If kh_208=True running=True
If kh_208=True And key_208_timer=0 key_208_timer=15
If key_203_timer>0 key_203_timer=key_203_timer-1:If kh_203=True running=True
If kh_203=True And key_203_timer=0 key_203_timer=15
If key_205_timer>0 key_205_timer=key_205_timer-1:If kh_205=True running=True
If kh_205=True And key_205_timer=0 key_205_timer=15
If KeyDown(200)=False And KeyDown(208)=False And KeyDown(203)=False And KeyDown(205)=False Then running=False
idle=True:cam_active=False
If KeyDown(203) And KeyDown(200) Then
RotateEntity player,0,EntityYaw(cam_piv)+45,0:idle=False:cam_active=True
ElseIf KeyDown(205) And KeyDown(200) Then
RotateEntity player,0,EntityYaw(cam_piv)-45,0:idle=False:cam_active=True
ElseIf KeyDown(205) And KeyDown(208) Then
RotateEntity player,0,EntityYaw(cam_piv)-135,0:idle=False:cam_active=True
ElseIf KeyDown(203) And KeyDown(208) Then
RotateEntity player,0,EntityYaw(cam_piv)+135,0:idle=False:cam_active=True
ElseIf KeyDown(203) Then
RotateEntity player,0,EntityYaw(cam_piv)+90,0:idle=False:cam_active=True
ElseIf KeyDown(205) Then
RotateEntity player,0,EntityYaw(cam_piv)-90,0:idle=False:cam_active=True
ElseIf KeyDown(200) Then
RotateEntity player,0,EntityYaw(cam_piv),0:idle=False:cam_active=True
ElseIf KeyDown(208) Then
RotateEntity player,0,EntityYaw(cam_piv)-180,0:idle=False:cam_active=False
End If
If idle=False And running=False Then MoveEntity player,0,0,.15
If idle=False And running=True Then MoveEntity player,0,0,.3

UpdateWorld
RenderWorld
Delay 1
Flip
Wend
End


Rob the Great(Posted 2010) [#22]
Hello TAGames,

I used to have the same problem with 3rd person controls, and after a long time of playing around with some different functions, I finally came up with some code that helped me a lot. I am a Zelda fan, and have created my own little game based off of the series. I believe that the code is very easy to understand, but I am happy to answer any questions that you may have. Rather than give you the actual code, which is cluttered with everything else tied into my game, I will give you some Pseudo code, and explain it as I go along. The basic idea is to create a pivot that changes it's location relative to the character model based on user input (keyboard, mouse, joystick, ect.), and then to "point" the character at the pivot.

First, set up your graphics and a camera. For this example, I have called the camera simply "camera".

Next, create four global variables. Two will be for pivots (just declare the variables for now and we will create the pivots later), and let's call them piv1 and piv2 for this example. The other two are just variables to carry the x and z position of the 2nd pivot (piv2). Let's call those variables pivx and pivz for this example.

Global piv1
Global piv2
Global pivx
Global pivz

Now you will want to use a custom function to load your character model. The function should look like what is contained in the brackets (note that it is always good practice to declare your character variable name as global prior to this function):
{
Function CreateCharacter()

piv1 = CreatePivot()
piv2 = CreatePivot()

EntityParent piv2,piv1 ;The 1st pivot is now a parent to the 2nd pivot.
;This is needed to obtain relative position
;of your character, and without this line,
;the function will either fail or produce
;very random results.

;Load the character model here, and let's call him "player" in this example

;At this point, you will want to set up your character as much as possible,
;meaning that you can rotate, position, get animation, ect., before the game
;loop starts. The reason being is so that in the future, you can call the function ;"CreatePlayer" when making a new level, and Blitz now has a wonderful guide to do all ;of the grunt work for you.

End Function
}

Next, set up the rest of your game (load the rooms, lights, music, ect.)





And start the main loop (While Not Keydown(1), the loop is inside the brackets):
{
Update3rdPersonCamera ;Somewhere at the beginning of the loop, call this
;function to update your 3rd person camera, which
;is posted below.

Perform all game functions and updates as you normally would

Render the world, flip it, text drawing, ect., goes here
}
Wend





Now here is the function "Update3rdPersonCamera", which was called in the loop:



Function Update3rdPersonCamera()

PointEntity camera,player ;Point the camera at the character

If Keydown(75) ;If we push the number pad left key
MoveEntity camera,-5,0,0 ;Effectively orbits the camera left around the character
EndIf

If KeyDown(77) ;If we push the number pad right key
MoveEntity camera,5,0,0 ;Effectively orbits the camera right around the character
EndIf

;So far, this is pretty straight forward. Now, let's develop some code
;to help us determine how the character should rotate itself based
;upon which button we are pushing as well as how the camera is
;rotated. Because a keyboard has four basic directions (up arrow,
;down arrow, left arrow, and right arrow), let's focus on positioning
;our pivots in four basic directions (north, south, west, and east)
;based upon the camera's perspective. In other words, the up arrow
;will always correspond to north for the camera, which is straight
;forward into the screen. The down arrow will correspond to south
;for the camera, which is backward away from the screen. The
;left arrow will correspond to west for the camera, which is to
;the left in the 3D world, and the right arrow will correspond to east
;for the camera, which is to the right in the 3D world.

If KeyDown(200) ;If we push the up arrow
pivz = 50 ;Set our global variable of pivz to 50
EndIf

If KeyDown(208) ;If we push the down arrow
pivz = -50 ;Set our global variable of pivz to -50
EndIf

If KeyDown(203) ;If we push the left arrow
pivx = -50 ;Set our global variable of pivx to -50
EndIf

If KeyDown(205) ;If we push the right arrow
pivx = 50 ;Set our global variable of pivx to 50
EndIf

If Not KeyDown(200) ;If the up arrow is release
If Not KeyDown(208) ;and if the down arrow is released
pivz = 0 ;Reset the local "z" position of the 2nd pivot
EndIf
EndIf

If Not KeyDown(203) ;If the left arrow is release
If Not KeyDown(205) ;and if the right arrow is released
pivx = 0 ;Reset the local "x" position of the 2nd pivot
EndIf
EndIf

;This sets up a clean way to make a "box" of directions
;to surround our character. From here, the next step is
;to position the pivots accordingly, and to "point" the
;character at the 2nd pivot, thus rotating the character
;to point in the direction that we tell it to

RotateEntity piv1,0,EntityYaw(camera),0
;Rotate the 1st pivot to match
;the camera's current rotation

PositionEntity piv1,EntityX(player),EntityY(player),EntityZ(player)
;Position the 1st pivot exactly
;where your character is

PositionEntity piv2,pivx,EntityY(player),pivz,False
;This is the most important
;part. We want to position
;the 2nd pivot in a way that
;is offset from the 1st pivot.
;Remember that we had earlier
;set the 1st pivot to be a parent
;to the 2nd pivot, so when we
;first created the pivots, they
;were initially create at the point
;0,0,0. When we tell piv1 to go
;to the x,y,z location of the
;character, piv2 did the exact
;same thing. Now when we
;tell the piv2 to go to the
;point at pivx,EntityY(player),pivz,False,
;we are saying that pivot 2
;should be positioned at pivx
;(which is either 50 or -50),
;EntityY(player) (the y value of the
;character so we have consistent
;results), and pivz (which is either
;50 or -50). Now, the important
;concept to understand is the last
;constant of False, which tells
;Blitz that we want it to be based
;off of where the pivot 2 already
;was. For example, if the character
;was located at 10,15,30, the pivot
;will position itself at the same location, and
;then move itself in a relative
;direction from the point, and the
;new coordinates would be
;something like 10,15,80 (30+50
;is 80, which is where the pivot
;would go if we pushed the up key).

If EntityDistance(piv2,player) >= 10 ;Don't rotate the character unless
;unless the distance between the
;character and piv2 is greater than
;or equal to 10. Otherwise the
;character spazzes out when no
;button is pressed.

pitch = EntityPitch(player) ;Get the pitch rotation of the model

roll = EntityRoll(player) ;Get the roll rotation of the model

PointEntity player,piv2 ;Point the character in the correct direction

RotateEntity player,pitch,EntityYaw(player),roll
;This line simply corrects any
;unintended rotation other than
;on the y-axis. x-axis and z-axis
;can tilt the character is strange
;ways.

;The code below in brackets is completely optional, and allows for
;the character to walk in the direction that he is facing, and the
;camera moves with him at the same speed.
{
MoveEntity player,0,0,1 ;make the character walk or move in the
;direction that he is facing
pitch = EntityPitch(camera) ;get the temporary rotation of the camera

yaw = EntityYaw(camera) ;get the temporary rotation of the camera

roll = EntityRoll(camera) ;get the temporary rotation of the camera

RotateEntity camera,EntityPitch(player),EntityYaw(player),EntityRoll(player)
;The above line rotates the camera to match the rotation of the player

MoveEntity camera,0,0,1
;Move the camera at the same pace and direction as the player moved

RotateEntity camera,pitch,yaw,roll ;Return the camera back to it's original
;rotation. This allows for cool camera
;tricks such as pushing right while still
;pointing at the player (a.k.a. sweeping)
}

EndIf

;Finally, add camera code to correct any distance issues, such as the
;camera is too close or the camera is too far away. (Note that the values
;will need tweaking, because I just pulled this off of the top of my
;head for this example)

If EntityDistance(player,camera) > 100
PointEntity camera,player
MoveEntity camera,0,0,5
EndIf

If EntityDistance(player,camera) < 10
PointEntity camera,player
MoveEntity camera,0,0,-5
EndIf

End Function



If you have everything set up correctly, you should see a result in which when you push the up arrow, the character will point in that direction and move in that direction. The same applies with all of the other three arrow buttons, as well as camera orbiting with the number pad left and number pad right buttons.

After reviewing my way old code, I've noticed that there are certainly faster ways of performing this routine without creating as many variables and pivots. I won't go into detail, because this tutorial has already gone way longer than I intended. Put simply, you could omit the 1st pivot as it's only purpose is to gather the x,y,z location of the player. But Blitz can do this already with the functions EntityX(), EntityY(), and EntityZ().

You can also change the code to accept mouse and joystick input as well. Play around with it, and see what you can come up with.

I am always glad to answer any questions you may have, and I do have source code available. However, it is very lengthy, and it would not be practical to post the entire 20 pages or so of my game on the forums. If you would like, however, I can send you the file and you can see for yourself.

This is only one way to perform this routine, but if you find another process that works better, by all means, use it. Also, I highly recommend obtaining a thorough understanding of my code before you try to implement it into your game. Good luck, and I hope that you can someday market your game.

-Rob Merrick


Cubed Inc.(Posted 2010) [#23]
Rob the Great
sorry that I haven't replied in such a long time. I have tried to dot down the code, and I have just got one little problem. For some reason, the Update3rdPersonCamera doesn't seem to recongnize the the camera, when I clearly created it at the beggining of the code. Should I create another function for creating the function, or is it the way that I set up your code?
I put down the code so you can see how I set it up. I didn't use any 3d models becuase I just wanted to test first:)

please reply. Nothings worst than being abandoned from a post, especially a post like this:(


GIB3D(Posted 2010) [#24]
It might help if you make the camera and player global ;)


Cubed Inc.(Posted 2010) [#25]
GIB3D
I tried. It still did not recongnize it:(


Rob the Great(Posted 2010) [#26]
I haven't had a chance to try out the sample code that I provided. Keep in mind that I only extracted the parts related to 3rd person camera control from my game, which is in a very very messy state right now. So, I'm going to try the code you've provided and see if I can figure out the problem. If not, I bet I still have the earlier test version, which is a small program written similar to this one and uses a cube as a player. Give me a little bit and I will write back to you.
-Rob Merrick


Rob the Great(Posted 2010) [#27]
Ok, so I've checked out the code, and there were a lot of problems with it. Remember to always declare variables as global if you want to use them everywhere else in the program. Also, I have updated the function "CreatePlayer" in order to perform the actions you wanted. Make sure that you return your model loaded from this function with the "Return" command, otherwise you will have blitz thinking that "player = 0" or "player = ".

I've updated the code to provide a little more depth. I think that the function was working, but you couldn't see the different angles because a cube looks the same from any four of the directions you view it at. So, I've posted some tested and working code now below. Let me know what you think.

-Rob Merrick


Rob the Great(Posted 2010) [#28]
Graphics3D 800,600,1,2 ;Set up graphics

;Create global pivot variables, two are for the pivots and two are for the positions
Global piv1
Global piv2
Global pivx
Global pivz

Global camera=CreateCamera() ;Create a camera and make sure it is global

light = CreateLight() ;Create a light to give a sense of depth, looks better
PositionEntity light,10,10,10

PositionEntity camera,0,10,-5 ;Move the camera up and back a little, just to help with depth perception

Function CreateCharacter() ;Call this function to set up your 3rd person camera and create a player

piv1 = CreatePivot() ;create two pivots for 3rd person camera
piv2 = CreatePivot()

EntityParent piv2,piv1 ;assign 2nd pivot to have a parent of the 1st one, needs this line for relative positioning

character = CreateCube() ;create or load your character here
ball = CreateSphere() ;I've created a ball to represent the front of the character
MoveEntity ball,0,0,1 ;Position the ball to the front of the cube
EntityParent ball,character ;just tells the ball to follow wherever the cube goes
Return character ;IMPORTANT! Without this line, you've created a character, but the character is not saved as "player"

End Function

Global player=CreateCharacter() ;creates the player from above and saved it as "player"

PointEntity light,player ;just point the light at the player

While Not KeyDown(1) ;main loop
Update3rdPersonCamera() ;update the camera
PositionEntity camera,EntityX(camera),10,EntityZ(camera) ;this just ensures that the height of the camera doesn't change
RenderWorld ;update everything
Text 0,0,"player yaw: " + EntityYaw(player) ;get information to the screen
Text 0,20,"player x: " + EntityX(player)
Text 0,40,"player y: " + EntityY(player)
Text 0,60,"player z: " + EntityZ(player)
Text 0,100,"camera yaw: " + EntityYaw(camera)
Text 0,120,"camera x: " + EntityX(camera)
Text 0,140,"camera y: " + EntityY(camera)
Text 0,160,"camera z: " + EntityZ(camera)
Flip
Wend

Function Update3rdPersonCamera()

PointEntity camera,player ;Point the camera at the character

If KeyDown(75) ;If we push the number pad left key
MoveEntity camera,-.5,0,.05 ;Effectively orbits the camera left around the character
EndIf

If KeyDown(77) ;If we push the number pad right key
MoveEntity camera,.5,0,.05 ;Effectively orbits the camera right around the character
EndIf

If KeyDown(200) ;If we push the up arrow
pivz = 50 ;Set our global variable of pivz to 50
EndIf

If KeyDown(208) ;If we push the down arrow
pivz = -50 ;Set our global variable of pivz to -50
EndIf

If KeyDown(203) ;If we push the left arrow
pivx = -50 ;Set our global variable of pivx to -50
EndIf

If KeyDown(205) ;If we push the right arrow
pivx = 50 ;Set our global variable of pivx to 50
EndIf

If Not KeyDown(200) ;If the up arrow is release
If Not KeyDown(208) ;and if the down arrow is released
pivz = 0 ;Reset the local "z" position of the 2nd pivot
EndIf
EndIf

If Not KeyDown(203) ;If the left arrow is release
If Not KeyDown(205) ;and if the right arrow is released
pivx = 0 ;Reset the local "x" position of the 2nd pivot
EndIf
EndIf

RotateEntity piv1,0,EntityYaw(camera),0
;Rotate the 1st pivot to match
;the camera's current rotation

PositionEntity piv1,EntityX(player),EntityY(player),EntityZ(player)
;Position the 1st pivot exactly
;where your character is

PositionEntity piv2,pivx,EntityY(player),pivz,False

If EntityDistance(piv2,player) >= 10 ;Don't rotate the character unless
;unless the distance between the
;character and piv2 is greater than
;or equal to 10. Otherwise the
;character spazzes out when no
;button is pressed.

pitch = EntityPitch(player) ;Get the pitch rotation of the model

roll = EntityRoll(player) ;Get the roll rotation of the model

PointEntity player,piv2 ;Point the character in the correct direction

RotateEntity player,pitch,EntityYaw(player),roll
;This line simply corrects any
;unintended rotation other than
;on the y-axis. x-axis and z-axis
;can tilt the character is strange
;ways.
MoveEntity player,0,0,1 ;make the character walk or move in the
;direction that he is facing
pitch = EntityPitch(camera) ;get the temporary rotation of the camera

yaw = EntityYaw(camera) ;get the temporary rotation of the camera

roll = EntityRoll(camera) ;get the temporary rotation of the camera

RotateEntity camera,EntityPitch(player),EntityYaw(player),EntityRoll(player)
;The above line rotates the camera to match the rotation of the player

MoveEntity camera,0,0,1
;Move the camera at the same pace and direction as the player moved

RotateEntity camera,pitch,yaw,roll ;Return the camera back to it's original
;rotation. This allows for cool camera
;tricks such as pushing right while still
;pointing at the player (a.k.a. sweeping)


EndIf

If EntityDistance(player,camera) > 100
PointEntity camera,player
MoveEntity camera,0,0,5
EndIf

If EntityDistance(player,camera) < 10
PointEntity camera,player
MoveEntity camera,0,0,-5
EndIf

End Function


Rob the Great(Posted 2010) [#29]
On a side note, I've never posted a topic before. How do you embed the code so it looks nice like you did above? Thanks for the help!

-Rob Merrick


Doggie(Posted 2010) [#30]
 use brackets around the word "code" and then "/code" 



Rob the Great(Posted 2010) [#31]
Cool. Let me post the code again to help clean it up. As a programmer, I like using tabs and spaces to help seperate functions and whatnot.

Graphics3D 800,600,1,2  ;Set up graphics

;Create global pivot variables, two are for the pivots and two are for the positions
Global piv1
Global piv2
Global pivx
Global pivz

Global camera=CreateCamera()  ;Create a camera and make sure it is global

light = CreateLight()  ;Create a light to give a sense of depth, looks better
PositionEntity light,10,10,10

PositionEntity camera,0,10,-5  ;Move the camera up and back a little, just to help with depth perception

Function CreateCharacter()  ;Call this function to set up your 3rd person camera and create a player

	piv1 = CreatePivot() ;create two pivots for 3rd person camera
	piv2 = CreatePivot()

	EntityParent piv2,piv1  ;assign 2nd pivot to have a parent of the 1st one, needs this line for relative positioning
	
	character = CreateCube() ;create or load your character here
	ball = CreateSphere()  ;I've created a ball to represent the front of the character
	MoveEntity ball,0,0,1  ;Position the ball to the front of the cube
	EntityParent ball,character  ;just tells the ball to follow wherever the cube goes
	Return character  ;IMPORTANT! Without this line, you've created a character, but the character is not saved as "player"

End Function

Global player=CreateCharacter()  ;creates the player from above and saved it as "player"

PointEntity light,player  ;just point the light at the player

While Not KeyDown(1)  ;main loop
	Update3rdPersonCamera()  ;update the camera
	PositionEntity camera,EntityX(camera),10,EntityZ(camera)  ;this just ensures that the height of the camera doesn't change
	RenderWorld  ;update everything
	Text 0,0,"player yaw: " + EntityYaw(player) ;get information to the screen
	Text 0,20,"player x: " + EntityX(player)
	Text 0,40,"player y: " + EntityY(player)
	Text 0,60,"player z: " + EntityZ(player)
	Text 0,100,"camera yaw: " + EntityYaw(camera)
	Text 0,120,"camera x: " + EntityX(camera)
	Text 0,140,"camera y: " + EntityY(camera)
	Text 0,160,"camera z: " + EntityZ(camera)
	Flip
Wend

Function Update3rdPersonCamera()

	PointEntity camera,player ;Point the camera at the character
	
	If KeyDown(75) ;If we push the number pad left key
		MoveEntity camera,-.5,0,.05 ;Effectively orbits the camera left around the character
	EndIf
	
	If KeyDown(77) ;If we push the number pad right key
		MoveEntity camera,.5,0,.05 ;Effectively orbits the camera right around the character
	EndIf
	
	If KeyDown(200) ;If we push the up arrow
		pivz = 50 ;Set our global variable of pivz to 50
	EndIf
	
	If KeyDown(208) ;If we push the down arrow
		pivz = -50 ;Set our global variable of pivz to -50
	EndIf
	
	If KeyDown(203) ;If we push the left arrow
		pivx = -50 ;Set our global variable of pivx to -50
	EndIf
	
	If KeyDown(205) ;If we push the right arrow
		pivx = 50 ;Set our global variable of pivx to 50
	EndIf
	
	If Not KeyDown(200) ;If the up arrow is release
		If Not KeyDown(208) ;and if the down arrow is released
			pivz = 0 ;Reset the local "z" position of the 2nd pivot
		EndIf
	EndIf
	
	If Not KeyDown(203) ;If the left arrow is release
		If Not KeyDown(205) ;and if the right arrow is released
			pivx = 0 ;Reset the local "x" position of the 2nd pivot
		EndIf
	EndIf
	
	RotateEntity piv1,0,EntityYaw(camera),0
	;Rotate the 1st pivot to match
	;the camera's current rotation
	
	PositionEntity piv1,EntityX(player),EntityY(player),EntityZ(player) 
	;Position the 1st pivot exactly
	;where your character is
	
	PositionEntity piv2,pivx,EntityY(player),pivz,False
	
	If EntityDistance(piv2,player) >= 10 ;Don't rotate the character unless
	;unless the distance between the
	;character and piv2 is greater than
	;or equal to 10. Otherwise the 
	;character spazzes out when no
	;button is pressed.
	
	pitch = EntityPitch(player) ;Get the pitch rotation of the model
	
	roll = EntityRoll(player) ;Get the roll rotation of the model
	
	PointEntity player,piv2 ;Point the character in the correct direction
	
	RotateEntity player,pitch,EntityYaw(player),roll
	;This line simply corrects any
	;unintended rotation other than
	;on the y-axis. x-axis and z-axis
	;can tilt the character is strange
	;ways.
	MoveEntity player,0,0,1 ;make the character walk or move in the
	;direction that he is facing
	pitch = EntityPitch(camera) ;get the temporary rotation of the camera
	
	yaw = EntityYaw(camera) ;get the temporary rotation of the camera
	
	roll = EntityRoll(camera) ;get the temporary rotation of the camera
	
	RotateEntity camera,EntityPitch(player),EntityYaw(player),EntityRoll(player)
	;The above line rotates the camera to match the rotation of the player
	
	MoveEntity camera,0,0,1
	;Move the camera at the same pace and direction as the player moved
	
	RotateEntity camera,pitch,yaw,roll ;Return the camera back to it's original
	;rotation. This allows for cool camera
	;tricks such as pushing right while still
	;pointing at the player (a.k.a. sweeping)
	
		
	EndIf
	
	If EntityDistance(player,camera) > 100
		PointEntity camera,player
		MoveEntity camera,0,0,5
	EndIf

	If EntityDistance(player,camera) < 10
		PointEntity camera,player
		MoveEntity camera,0,0,-5
	EndIf

End Function



Rob the Great(Posted 2010) [#32]
Sorry to be annoying with the replies, but here is another demo adapted from the code above. This version shows more in depth what is really happening in the 3D world.

;Rob Merrick's 3rd Person Camera Test and Demo.

;This program sets up a character figure, a terrain, and trees, and 
;demonstrates the use of a 3rd person camera. I use this similar routine
;in a zelda game that I have designed. Note that the zelda game was only
;made for "shits and giggles", and I do not make any profit from the
;copyrighted material.

;Virtually every line is commented to ensure that whoever reads it can clearly understand
;what's happening.

;This routine is still a fairly inefficient one. I have taken code that is years old and
;written it in a way to give example of how a 3rd person camera works.
;It is based on the commands of relative positioning from the blitz3d engine.

;This code can be re-written to support joystick commands and other forms of input, and it
;was originally design to do so. For more information, contact me and I will provide
;other variations of this code.

;I consider this code to be open-source, and I do not require any credit that this code may
;appear in. I'm sure I'm not the first person to come up with this idea, but if you do
;desire to add in my credit, I will go by the name of Rob Merrick.

;For a complete version of my game demo, visit www.merrickproductions.com/videogame.htm.

;Thank you for your interest, and enjoy!


;Program Setup
;--------------------------------------------------------------------------------------------------------------------------

Graphics3D 800,600,1,2           ;Set up graphics

SetBuffer BackBuffer()           ;Set up double buffer. Makes smoother graphics.

Global piv1                      ;Create global pivot variables, two are for
Global piv2                      ;the pivots and two are for the positions.
Global pivx
Global pivz

Global camera=CreateCamera()     ;Create a camera and make sure it is global

Global plane = CreatePlane()     ;Let's Create a little ground for our player.
EntityColor plane,125,100,50     ;Give the ground a brown color
PositionEntity plane,0,-1,0      ;Move the ground down a little bit

CreateRandomTerrain()            ;Call a function to generate some "trees"

light = CreateLight()            ;Create a light to give a sense of depth, looks better
PositionEntity light,10,10,10    ;Move the light to give some shading effects

PositionEntity camera,0,10,-5    ;Move the camera up and back a little, just to help with depth perception

Global player=CreateCharacter()  ;Call a funtion to create the main character and save it as "player"

PointEntity light,player         ;just point the light at the player

;--------------------------------------------------------------------------------------------------------------------------
;End the Program Setup


;Start the Main Loop
;--------------------------------------------------------------------------------------------------------------------------


While Not KeyDown(1)                                          ;main loop

	Update3rdPersonCamera()                                   ;update the camera-This should be towards the top of the loop to avoid problems
	PositionEntity camera,EntityX(camera),10,EntityZ(camera)  ;this just ensures that the height of the camera doesn't change
	RenderWorld                                               ;update everything, get new positions and prepare to draw to the screen
	Text 0,0,"player yaw: " + EntityYaw(player)               ;get information to the screen
	Text 0,20,"player x: " + EntityX(player)
	Text 0,40,"player y: " + EntityY(player)
	Text 0,60,"player z: " + EntityZ(player)
	Text 0,100,"camera yaw: " + EntityYaw(camera)
	Text 0,120,"camera x: " + EntityX(camera)
	Text 0,140,"camera y: " + EntityY(camera)
	Text 0,160,"camera z: " + EntityZ(camera)
	Text 300,0,"3rd Person Camera Control:"                   ;Give controls information to the screen
	Text 300,20,"Push the arrow keys to point"
	Text 300,40,"the character in that direction."
	Text 300,60,"Push the pad left and right arrows"
	Text 300,80,"to orbit that camera in that direction."
	Flip                                                      ;The actual drawing process for blitz. Flipping the double buffer
	
Wend

End                                                           ;When you leave the main loop, always call this command.

;--------------------------------------------------------------------------------------------------------------------------
;End the Main Loop


;Start the Functions List
;--------------------------------------------------------------------------------------------------------------------------

Function CreateCharacter()               ;Call this function to set up your 3rd person camera and create a player

	piv1 = CreatePivot()                 ;create two pivots for 3rd person camera
	piv2 = CreatePivot()

	EntityParent piv2,piv1               ;assign 2nd pivot to have a parent of the 1st one, needs this line for
										 ;relative positioning
	
	character = CreateCube()             ;create or load your character here
	ball = CreateSphere()                ;I've created a ball to represent the front of the character
	MoveEntity ball,0,0,1                ;Position the ball to the front of the cube
	EntityParent ball,character          ;just tells the ball to follow wherever the cube goes
	Return character                     ;IMPORTANT! Without this line, you've created a character, but the character
										 ;is not saved as "player"

End Function

Function Update3rdPersonCamera()         ;Call this function to update your 3rd person camera

	PointEntity camera,player            ;Point the camera at the character
	
	If KeyDown(75)                       ;If we push the number pad left key
		MoveEntity camera,-.5,0,.05      ;Effectively orbits the camera left around the character
	EndIf
	
	If KeyDown(77)                       ;If we push the number pad right key
		MoveEntity camera,.5,0,.05       ;Effectively orbits the camera right around the character
	EndIf
	
	If KeyDown(200)                      ;If we push the up arrow
		pivz = 50                        ;Set our global variable of pivz to 50
	EndIf
	
	If KeyDown(208)                      ;If we push the down arrow
		pivz = -50                       ;Set our global variable of pivz to -50
	EndIf
	
	If KeyDown(203)                      ;If we push the left arrow
		pivx = -50                       ;Set our global variable of pivx to -50
	EndIf
	
	If KeyDown(205)                      ;If we push the right arrow
		pivx = 50                        ;Set our global variable of pivx to 50
	EndIf
	
	If Not KeyDown(200)                  ;If the up arrow is release...
		If Not KeyDown(208)              ;and if the down arrow is released
			pivz = 0                     ;Reset the local "z" position of the 2nd pivot
		EndIf
	EndIf
	
	If Not KeyDown(203)                  ;If the left arrow is release...
		If Not KeyDown(205)              ;and if the right arrow is released
			pivx = 0                     ;Reset the local "x" position of the 2nd pivot
		EndIf
	EndIf
	
	RotateEntity piv1,0,EntityYaw(camera),0
	                                     ;Rotate the 1st pivot to match
	                                     ;the camera's current rotation
	
	PositionEntity piv1,EntityX(player),EntityY(player),EntityZ(player) 
	                                     ;Position the 1st pivot exactly
	                                     ;where your character is
	
	PositionEntity piv2,pivx,EntityY(player),pivz,False
	                                     ;Position the 2nd pivot in a 
	                                     ;relative spot to your character
	                                     ;with the vector of the variables
	                                     ;pivx and pivz added to the x and
	                                     ;z values. Note that the "False"
	                                     ;command is what makes this whole
	                                     ;function work correctly.
	
	If EntityDistance(piv2,player) >= 10 ;Don't rotate the character unless
		                                 ;the distance between the
		                                 ;character and piv2 is greater than
		                                 ;or equal to 10. Otherwise the 
		                                 ;character spazzes out when no
		                                 ;button is pressed.
		
		pitch = EntityPitch(player)      ;Get the pitch rotation of the model
		
		roll = EntityRoll(player)        ;Get the roll rotation of the model
		
		PointEntity player,piv2          ;Point the character in the correct direction
		
		RotateEntity player,pitch,EntityYaw(player),roll
		                                 ;This line simply corrects any
		                                 ;unintended rotation other than
		                                 ;on the y-axis. x-axis and z-axis
		                                 ;can tilt the character is strange
		                                 ;ways.
		
		MoveEntity player,0,0,1          ;make the character walk or move in the
		                                 ;direction that he is facing
		
		pitch = EntityPitch(camera)      ;get the temporary rotation of the camera
		
		yaw = EntityYaw(camera)          ;get the temporary rotation of the camera
		
		roll = EntityRoll(camera)        ;get the temporary rotation of the camera
		
		RotateEntity camera,EntityPitch(player),EntityYaw(player),EntityRoll(player)
		                                 ;The above line rotates the camera to match
									     ;The rotation of the player
		
		MoveEntity camera,0,0,1
		                                 ;Move the camera at the same pace and direction
										 ;as the player moved
		
		RotateEntity camera,pitch,yaw,roll 
		                                 ;Return the camera back to it's original
		                                 ;rotation. This allows for cool camera
		                                 ;tricks such as pushing right while still
		                                 ;pointing at the player (a.k.a. sweeping)
		
		
	EndIf
	
	;Now let's do some camera distance checking and correct any problems
	
	If EntityDistance(player,camera) > 100 ;If the camera is too far away...
		PointEntity camera,player          ;Point the camera at the player
		MoveEntity camera,0,0,5            ;Move the camera 5 units closer to the player
	EndIf

	If EntityDistance(player,camera) < 10  ;If the camera is too close...
		PointEntity camera,player          ;Point the camera at the player
		MoveEntity camera,0,0,-5           ;Move the camera 5 units further from the player
	EndIf

End Function                               ;End the Function



Function CreateRandomTerrain()                               ;Call this function to generate trees.

	For x = 0 To 1000                                        ;Do this block 1000 times
		cone = CreateCone()                                  ;Create a cone
		EntityColor cone,0,125,0                             ;Color it mid tone green
		PositionEntity cone,Rand(-500,500),0,Rand(-500,500)  ;Position it on a random x and z location
	Next                                                     ;Tell blitz that this is the end of the block.

End Function                                                 ;End the Function

;------------------------------------------------------------------------------------------------------------
;End the Functions List



Cubed Inc.(Posted 2010) [#33]
Rob the Great
The code is very nice and it achieved the movements correctly, but the character doesn't "turn" towards the directions, instead it just points.
I should have said this in the first place, but i'm also trying to make the character rotate or turn in the correct direction as well with everything else. Your code is almost perfect for my problem, it's just that it doesn't "turn". Regardless, it's still a great code. Thanks for trying to help:)


Rob the Great(Posted 2010) [#34]
If you wanted to spend the time, try setting up a system where you can rotate the character over time based on the new point where the character should be pointed. I'm not sure how to go about that, but somebody else may have some tips or pointers. Also, I originally designed this program to work with a joystick, so there is less of a snap between one point and another due to the fact that the joystick has a wider range of directions than just the four basic directions. Anyways, good luck with everything!

-Rob Merrick


Rob the Great(Posted 2010) [#35]
One last note, there is a function in blitz called "AlignToVector", which may be useful. It's supposed to gradually turn an entity to a new rotation, but I haven't played around with it enough to know much about it.


Guy Fawkes(Posted 2013) [#36]
I know this is an old topic, but is there a way to control the speed movement of the player?