I enjoyed a huge breakthrough last night. It's one of those breakthroughs that makes a developer's pain and struggles all seem worthwhile. Where you finally have a brilliant stroke of genius to solve a problem in a new or unexpected way. Or, you actually read the documentation. Anyhow...
With my Three.js Physijs rafting simulation in better shape, I am ready to add motion controls to the raft.
First I add a "rudder" to the raft to indicate the direction in which the raft is pointing. I do not have to mess with Physijs for this, since it is just an indicator. I do have to mess around with manual veritices in Three.js in order to create a line:
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
geometry.vertices.push(new THREE.Vector3(10, 0, 0));
var rudder = new THREE.Line(
geometry,
new THREE.LineBasicMaterial({color: 0xff0000})
);
rudder.position.z = 0;
rudder.position.x = 35;
raft.add(rudder);
raft.position.y = 20;
raft.rotation.x = Math.PI/2;
I suspect that it might be easier to create a cylinder, but I am glad for a way to create lines. With that, I have my direction indicated: To add motion controls, first I use the space bar to add a force in the current direction. A simple document listener ought to suffice:
document.addEventListener("keydown", function(event) { var code = event.which || event.keyCode; if (code == 0x20) { // space pushRaft(); } else { console.log(code); } }); function pushRaft() { var angle = raft.rotation.z , cos = Math.cos(angle) , sin = Math.sin(angle); raft.applyCentralForce(new THREE.Vector3(1e8 * cos, 0, 1e8 * sin)); }And indeed that does work. I am able to move forward in whatever direction I happen to be pointing.
I need a little more than that in my game, however. I need to be able to steer clear of trouble. For that, I add two more keys to listen for: J/K. When one of those is pressed, I rotate the raft accordingly:
document.addEventListener("keydown", function(event) { var code = event.which || event.keyCode; if (code == 0x20) { // space pushRaft(); } else if (code == 0x4a) { // J rotateRaft(-1); } else if (code == 0x4b) { // K rotateRaft(1); } else { console.log(code); } }); function rotateRaft(direction) { raft.__dirtyRotation = true; raft.rotation.z = raft.rotation.z + direction * Math.PI / 100; }And that actually works I am now able to rotate and move my raft. Two problems still remain.
First, when I collide with a river bank, the raft sometimes gets some angular velocity. I can likely solve that with some Physijs damping.
Second, when I apply enough force, I can move back upriver. The force that I applied last night from the river needs to be constant and greater than the force that my raft can exert. That seems a trickier proposition. Hopefully I will come up with something tomorrow.
Day #487
No comments:
Post a Comment