BlendELF is a engine written by me, an IT student at the University of Jyväskylä. I am coding the engine as my portfolio project, as a proof of my skills in 3d graphics and game logics/systems coding. I release this engine under the assumption that it could be useful for other people in making quck prototypes and small games. I reserve the right to halt the development of this engine at will, at any given time.
Tutorial 3, Moving the camera
This tutorial builds on the first tutorial, so be sure to do that first! [Tutorial 1, BlendELF Basics]

In this tutorial you will learn how to make a simple fly through camera
Step 1, WSAD
First we will modify the init.lua script file main loop. Here is how the init.lua script should look now:
scn = elf.LoadScene("level1.pak") while elf.Run() == true do end
Hey! Whats that "scn" variable there before elf.LoadScene? I didn't see it in the first tutorial!

Yeah, we didn't need it in the first tutorial. In addition to loading the scene, elf.LoadScene also returns a handle to the loaded scene so that we can access the objects in the scene with it.

So the first thing we have to do is to gain access to the currently active camera. Lets write a line that does that for us.
scn = elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do end
We pass the scn variable we just got from elf.LoadScene to elf.GetSceneActiveCamera to get the active camera in that particular scene.

So now we have our camera stored in the cam variable, what then? Well, now we will check on each frame (inside our while loop) if the user is pressing a certain button, and if he/she is, we will move the camera accordingly. Lets check for the W (we go forward with W) button first.
scn = elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end end
The elf.GetKeyState function returns the current state of the key passed to it. In this case we pass elf.KEY_W, meaning the W key, to it. Here is a overview of the possible button states that elf.GetKeyState returns: So why do we have two states for a pressed button, elf.PRESSED and elf.DOWN? Basically when you press a button, its state changes to elf.PRESSED for the current frame. After that, if the button is still pressed, the state changes to elf.DOWN. The elf.PRESSED is useful if you want to, for example shoot a gun a single time. If you used elf.DOWN for that, you would be firing a bullet on every frame assuming that the button is still pressed. The elf.DOWN is useful for continuous movement. If you would use elf.PRESSED for that, your actor would move just for the instant the button is pressed and not when its down.

We use elf.MoveActorLocal to move our camera. The actor functions can be performed on any actor. That is cameras, entities, lights and particles. And what does Local stand for in elf.MoveActorLocal? That means that you are moving the actor according to its local orientation. For example, if you would use just elf.MoveActor, it would move according to the global x/y/z axises instead of moving according to the models local x/y/z axises. Yes, the three floating point values we pass to elf.MoveActorLocal represent the amount of movement in 3D space during one second. Since we are moving a camera, we want to move it locally every time we are moving it front, back, left or right. That being said, there are many situations where you will want to move an actor according to the global axises, and you will most likely know when to do that.

Hey! Why are we moving the camera -12.0 to the Z direction, is that really moving to the front?

Yes it is. Why is that? Well the camera coordinate system is different from the coordinate systems of other actors. For a camera, negative Z is front, positive Y is up and positive X is right. Just remember that and you are good to go ;). Also remember that this only applies when moving the camera locally. When you are moving the camera with elf.MoveActor or any other globally moving function, it works just like with other actors.

Try out the code so far, if it works right, it should make the camera go forward when you press W. If it doesn't work, please check the console or elf.log for errors.

Now, lets add the code for S, A and D.
elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end if elf.GetKeyState(elf.KEY_S) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, 12.0) end if elf.GetKeyState(elf.KEY_A) == elf.DOWN then elf.MoveActorLocal(cam, -12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_D) == elf.DOWN then elf.MoveActorLocal(cam, 12.0, 0.0, 0.0) end end
Again, go ahead and test your code. Be sure to test your code a lot and often. If it works, you should be able to move the camera forward, back, left and right. If the code doesn't work, check the console or elf.log for errors.
Step 2, Rotating the camera with the mouse
Now we are ready to code the rotation for the camera. We are going for a classic flythrough camera, so you will be able to rotate the camera with the mouse.

But wait, what is needed for that? First we need to make sure that the mouse is inside the window all the time so that we don't get weird jumps in rotation while the mouse enters the window and goes out. We can do this by passing true to function elf.HideMouse. Also since now we can't close the window by clicking the X symbol in the top right corner of the window like you usually do to windows, we need an alternate way to close the window. Lets do that with the ESC key. You can also shut down BlendELF with the F10 button on your keyboard, but it is nice to have some backup for it. Great! Lets add the code for this:
elf.HideMouse(true) scn = elf.LoadScene("level1.pak") cam = elf.GetSceneActiveCamera(scn) while elf.Run() == true do if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end if elf.GetKeyState(elf.KEY_S) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, 12.0) end if elf.GetKeyState(elf.KEY_A) == elf.DOWN then elf.MoveActorLocal(cam, -12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_D) == elf.DOWN then elf.MoveActorLocal(cam, 12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_ESC) == elf.PRESSED then elf.Quit() end end
For clarification, the new lines of code are marked in RED. Now try to run the code and see if the mouse disappears and if the ESC button works. If not, don't worry, you can still close the window with F10 or ALT + F4 so that you can come back to fix your code.

So now we can move to camera rotation. For this, we need to know how much the mouse has moved during the current and the last frame. You could store the previous frames mouse position and calculate the differece between it and the current frames mouse position, but BlendELF already does this. You can access the difference with elf.GetMouseForce. The rest is just using the values we get from that:
elf.HideMouse(true) elf.LoadScene("level1.pak") while elf.Run() == true do cam = elf.GetSceneActiveCamera(scn) if elf.GetKeyState(elf.KEY_W) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, -12.0) end if elf.GetKeyState(elf.KEY_S) == elf.DOWN then elf.MoveActorLocal(cam, 0.0, 0.0, 12.0) end if elf.GetKeyState(elf.KEY_A) == elf.DOWN then elf.MoveActorLocal(cam, -12.0, 0.0, 0.0) end if elf.GetKeyState(elf.KEY_D) == elf.DOWN then elf.MoveActorLocal(cam, 12.0, 0.0, 0.0) end mf = elf.GetMouseForce() elf.RotateActor(cam, 0.0, 0.0, -mf.x*10.0) elf.RotateActorLocal(cam, -mf.y*10.0, 0.0, 0.0) if elf.GetKeyState(elf.KEY_ESC) == elf.PRESSED then elf.Quit() end end
Because the mouse and 3d space coordinate systems are different, we use the negatives of the force as you can see. Also you can notice that we used just elf.RotateActor for the Z rotation instead of elf.RotateActorLocal. That is because unless you are writing a flight simulator, you don't want the camera to turn around Z according to its own orientation. That would make the user "stand tilted". You can try elf.RotateActorLocal on the Z rotation if you want to see the effect. Also keep in mind that the rotations we input are in degrees, not radians. Pretty much all rotation related functions in BlendELF use degrees.

If everything went right, you should be able to fly around the level now:
Tutorial 3 Flying around the level
Thats it! I hope you enjoyed the tutorial, and if you have any comments about it, please post to the forums.