2. Keyboard & Mouse Control Functions with Includes
Now we are going to raise the camera up and point it down for a standard top-down view. As you start to plan the placement of objects in your 3D world it would help to use graph paper to keep track of your object locations (see right). Notice that since "Y" is up in 3D all 4 objects at the right have "0" for the 2nd Y-coordinate, meaning they are all at ground level.

In this lesson you will learn how to create reusable Functions that you can use to control movement of your player, or camera, or other game pieces. Code can be created in separate files and then inserted using an Include command to help keep things organized and uncluttered as well as kept in a convenient reusable form for your other future programs!

We will be keeping the code for these lessons split up into 3 separate files: A main lesson.bb, a functions.bb file and a loadworld.bb file. To keep things clean and simple, as you learn new code it will be added to these 3 files and we will just keep track of the new additions!

If you haven't already downloaded the tutorial files do so now, unzip to your desktop and OPEN up lesson2.bb, functions2.bb, and loadworld2.bb (below) and RUN / LAUNCH the lesson2.bb program by pressing the ROCKET ICON

and you should see this...
NEW CODE is BOLD.

Here's the CODE!
lesson2.bb

Include "functions2.bb" ; INSERTS this files contents here

Global escape_key = 1
Global screen_width = 640, screen_height = 480

Graphics3D screen_width, screen_height,16, 2
SetBuffer BackBuffer()

light1 = CreateLight(2)
cam1 = CreateCamera()
PositionEntity cam1, 0, 20, 0

; Point camera down for top down view!
RotateEntity cam1, 90, 0, 0

CameraViewport cam1, 0, 0, screen_width, screen_height

Include "loadworld2.bb" ; INSERTS this files contents here

; Start mouse cursor at center of screen!

MoveMouse screen_width/2, screen_height/2

While Not KeyHit( escape_key )

   ; key & mouse control functions!
    object_key_control( cube1 )
    object_key_control_2( cone1 )
; Player 2 !
    mouse_control( cam1 )

    UpdateWorld
    RenderWorld


    ; 2D here


    Flip
Wend

End


functions2.bb
This Include file will contain a growing library of POWERFUL functions that can be reused in other games!

Global up_key = 200, down_key = 208, left_key = 203, right_key = 205
Global W_key = 17, S_key = 31, A_key = 30, D_key = 32

; Our FIRST FUNCTIONS!

Function object_key_control( obj )
    If KeyDown( up_key ) = True Then MoveEntity obj, 0, 0, .2
    If KeyDown( down_key ) = True Then MoveEntity obj, 0, 0, -.2
    If KeyDown( left_key ) = True Then TurnEntity obj, 0, 2, 0
    If KeyDown( right_key ) = True Then TurnEntity obj, 0, -2, 0
End Function


; Same as before but different key set "WASD"
Function object_key_control_2( obj )
    If KeyDown( W_key ) = True Then MoveEntity obj, 0, 0, .2
    If KeyDown( S_key ) = True Then MoveEntity obj, 0, 0, -.2
    If KeyDown( A_key ) = True Then TurnEntity obj, 0, 2, 0
    If KeyDown( D_key ) = True Then TurnEntity obj, 0, -2, 0
End Function

Function mouse_control( obj )
    mx = MouseX() : my = MouseY()
    If mx < 50 Then MoveEntity obj, -.3, 0, 0
    If mx > screen_width-50 Then MoveEntity obj, .3, 0, 0
    If my < 50 Then MoveEntity obj, 0, .3, 0
    If my > screen_height-50 Then MoveEntity obj, 0, -.3, 0
End Function


loadworld2.bb
This code would normally appear before the MAIN GAME LOOP but can get quite large as we add more and more objects to our world. It's better to make a separate file and use Include "loadworld2.bb" to insert it keeping our MAIN file lesson2.bb uncluttered.

cube1=CreateCube()
PositionEntity cube1,0,-.5, 0
EntityColor cube1, 0,255,255

cone1=CreateCone()
PositionEntity cone1, 4, 0, 0
EntityColor cone1, 0, 255, 0


plane1 = CreatePlane()
texture1 = LoadTexture("water.jpg")
ScaleTexture texture1, 10, 10
EntityTexture plane1,texture1
EntityAlpha plane1, .6
PositionEntity plane1, 0, -1, 0


NEW COMMANDS
lesson2.bb
Include "functions2.bb" ; INSERTS this files contents here
. . .
; Point camera down for top down view!
RotateEntity cam1, 90, 0, 0
. . .
Include "loadworld2.bb" ; INSERTS this files contents here

; Start mouse cursor at center of screen!

MoveMouse screen_width/2, screen_height/2
. . .
   ; key & mouse control functions!
    object_key_control( cube1 )
    object_key_control_2( cone1 )
; Player 2 !
    mouse_control( cam1 )
. . .
Include "functions2.bb" is a powerful and simple command that allows you to insert big chunks of code from a separate file to keep things organized for easy management. The "function2.bb" contains our new keyboard and mouse control functions.
EXPERIMENT !
Rotate cube1, cone1, and cam1 into different functions

    object_key_control( cube1 )
    object_key_control_2( cone1 )

    mouse_control( cam1 )

Notice anything interesting?
Undo the changes you made...

function2.bb
; Character Control Key variable names for player 1 & 2
; Names make more sense than the "scancode" numbers

Global up_key = 200, down_key = 208, left_key = 203, right_key = 205
Global W_key = 17, S_key = 31, A_key = 30, D_key = 32

; Our FIRST FUNCTIONS!

; The "dummy" variable "obj" is used so that we can REUSE this function
; to control ANY object! (camera, player, etc)

Function object_key_control( obj )
    ; IF the up arrow key is pressed THEN the object is MOVED forward (+Z)
    If KeyDown( up_key ) = True Then MoveEntity obj, 0, 0, .2
    ; IF the down arrow key is pressed THEN the object is MOVED backward (-Z)
    If KeyDown( down_key ) = True Then MoveEntity obj, 0, 0, -.2
    ; IF the left arrow key is pressed THEN the object is TURNED left (+Yaw)
    If KeyDown( left_key ) = True Then TurnEntity obj, 0, 2, 0
    ; IF the left arrow key is pressed THEN the object is TURNED right (-Yaw)
    If KeyDown( right_key ) = True Then TurnEntity obj, 0, -2, 0
End Function


; Same as before but different key set "WASD"
Function object_key_control_2( obj )
    If KeyDown( W_key ) = True Then MoveEntity obj, 0, 0, .2
    If KeyDown( S_key ) = True Then MoveEntity obj, 0, 0, -.2
    If KeyDown( A_key ) = True Then TurnEntity obj, 0, 2, 0
    If KeyDown( D_key ) = True Then TurnEntity obj, 0, -2, 0
End Function

; Mouse screen scrolling function!
Function mouse_control( obj )
  
  ; Get Mouse X & Y position and store in variables mx & my
    mx = MouseX() : my = MouseY()
   
 ; IF Mouse gets within 50 pixels from the screen edge it will start scrolling!
    If mx < 50 Then MoveEntity obj, -.3, 0, 0
    If mx > screen_width-50 Then MoveEntity obj, .3, 0, 0
    If my < 50 Then MoveEntity obj, 0, .3, 0
    If my > screen_height-50 Then MoveEntity obj, 0, -.3, 0
End Function
These commands are in the separate Include file functions2.bb. These functions are "called" from the main lesson2.bb program with the object_key_control( obj ) code. Naming the function, i.e. object_key_control( obj ), is up to you and the wording should reflect what the function actually does. In this case, our function controls movement of an object with the keyboard. The object can be a camera, player, enemy, light, terrain, most anything!

Within our first function object_key_control( obj ) we combine a little logic IF...THEN with a check to see if a specific key is being pressed KeyDown( up_key ) = True and if true, then we move the object forward (+Z direction) with MoveEntity obj, 0, 0, .2. If KeyDown( left_key ) = True Then TurnEntity obj, 0, 2, 0 will turn (+YAW) the object LEFT when the left arrow key is being pressed.

Function mouse_control( obj ) uses the mouse to scroll the screen by checking to see if the mouse is within 50 pixels of the 4 screen edges and then moves the object (in this case, the camera) in the opposite direction. You've probably noticed this feature in other games before :)
EXPERIMENT !
Change the speed of moving and turning
in any of the 3 control functions!
Undo the changes you made...

loadworld2.bb

. . .
; Create an infinite plane, texture it, and make it 60% transparent
plane1 = CreatePlane()
texture1 = LoadTexture("water.jpg")
; Stretch out the texture a bit so it looks less "checkered"
ScaleTexture texture1, 10, 10
EntityTexture plane1,texture1
EntityAlpha plane1, .6
PositionEntity plane1, 0, -1, 0

As you can probably guess from what you've learned so far, this is an attempt to make a water like surface for our objects to "swim" in!
EXPERIMENT !
Try changing the color of the water plane
Try changing the scaling of the water texture
Undo the changes you made...

THE CHALLENGE!!!
Add "included" controls to your previous Lesson 1 Challenge

NEXT : Lesson 3 - Sound & Sky