This repository has been archived by the owner on May 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
6. Keyboard and mouse
Lubos Lenco edited this page Sep 11, 2016
·
3 revisions
Let's build a controllable camera so we can move around in our 3D world. We need mouse to look and arrow keys to move.
// Add mouse and keyboard listeners
Mouse.get().notify(onMouseDown, onMouseUp, onMouseMove, null);
Keyboard.get().notify(onKeyDown, onKeyUp);
// Used to calculate delta time
lastTime = Scheduler.time();
Mouse and keyboard event handlers. Nothing fancy to see here.
function onMouseDown(button:Int, x:Int, y:Int) {
isMouseDown = true;
}
function onMouseUp(button:Int, x:Int, y:Int) {
isMouseDown = false;
}
function onMouseMove(x:Int, y:Int, movementX:Int, movementY:Int) {
mouseDeltaX = x - mouseX;
mouseDeltaY = y - mouseY;
mouseX = x;
mouseY = y;
}
function onKeyDown(key:Key, char:String) {
if (key == Key.UP) moveForward = true;
else if (key == Key.DOWN) moveBackward = true;
else if (key == Key.LEFT) strafeLeft = true;
else if (key == Key.RIGHT) strafeRight = true;
}
function onKeyUp(key:Key, char:String) {
if (key == Key.UP) moveForward = false;
else if (key == Key.DOWN) moveBackward = false;
else if (key == Key.LEFT) strafeLeft = false;
else if (key == Key.RIGHT) strafeRight = false;
}
For the first time we will use update function to calculate our matrices based on input every frame. Let's add a listener in Main.init().
Scheduler.addTimeTask(game.update, 0, 1 / 60);
On to implementation.
public function update() {
// Compute time difference between current and last frame
var deltaTime = Scheduler.time() - lastTime;
lastTime = Scheduler.time();
// Compute new orientation
if (isMouseDown) {
horizontalAngle += mouseSpeed * mouseDeltaX * -1;
verticalAngle += mouseSpeed * mouseDeltaY * -1;
}
// Direction: Spherical coordinates to Cartesian coordinates conversion
var direction = new FastVector3(
Math.cos(verticalAngle) * Math.sin(horizontalAngle),
Math.sin(verticalAngle),
Math.cos(verticalAngle) * Math.cos(horizontalAngle)
);
// Right vector
var right = new FastVector3(
Math.sin(horizontalAngle - 3.14 / 2.0),
0,
Math.cos(horizontalAngle - 3.14 / 2.0)
);
// Up vector
var up = right.cross(direction);
// Movement
if (moveForward) {
var v = direction.mult(deltaTime * speed);
position = position.add(v);
}
if (moveBackward) {
var v = direction.mult(deltaTime * speed * -1);
position = position.add(v);
}
if (strafeRight) {
var v = right.mult(deltaTime * speed);
position = position.add(v);
}
if (strafeLeft) {
var v = right.mult(deltaTime * speed * -1);
position = position.add(v);
}
// Look vector
var look = position.add(direction);
// Camera matrix
view = FastMatrix4.lookAt(position, // Camera is here
look, // and looks here : at the same position, plus "direction"
up // Head is up (set to (0, -1, 0) to look upside-down)
);
// Update model-view-projection matrix
mvp = FastMatrix4.identity();
mvp = mvp.multmat(projection);
mvp = mvp.multmat(view);
mvp = mvp.multmat(model);
mouseDeltaX = 0;
mouseDeltaY = 0;
}
One more thing - to enable culling, we adjust pipeline state.
// Set culling
pipeline.cullMode = CullMode.Clockwise;
You can access complete sources here.
And here it is! Enjoy flying around our little cube.