Up tonight, I switch to a new Three.js / Physijs potential game for 3D Game Programming for Kids. This will be another 2D game, so I copy bits and pieces of last night's platform game.
In this game, the player will click, drag and rotate platforms to help the player reach a goal, normally near the top of the screen. The player itself can only move forward or backward, so ramps will be needed to move up.
The player is a simple Physijs object, shaped like a disc:
var player = new Physijs.ConvexMesh(
new THREE.CylinderGeometry(30, 30, 5, 16),
Physijs.createMaterial(
new THREE.MeshBasicMaterial({color:0xbb0000}), 0.2, 0.5
)
);
player.setAngularFactor(new THREE.Vector3( 0, 0, 0 )); // don't rotate
player.setLinearFactor(new THREE.Vector3( 1, 1, 0 )); // only move on X and Y axis
Since this is a 2D, not three dimensional game, I constrain movement to the X-Y plane. As with the platformer game, I use simple keyboard events to move the player: document.addEventListener("keydown", function(event) {
var code = event.keyCode;
if (code == 37) left(); // left arrow
if (code == 39) right(); // right arrow
});
The left and right functions set a maximum velocity in the appropriate direction.All of that is more or less a copy from the previous game. What is new is that I need four borders that constrain the player to the current screen. Since the player is restricted to the X-Y plane, all four borders are added with Z=0. What changes is the X-Y position of each and the size:
function makeBorder(x, y, w, h) {
var border = new Physijs.BoxMesh(
new THREE.CubeGeometry(w, h, 100),
Physijs.createMaterial(
new THREE.MeshBasicMaterial({color: 0x000000}), 0.2, 1.0
),
0
);
border.position.set(x, y, 0);
return border;
}
I think I might do this chapter after the introduction to JavaScript objects, in which case I might fiddle with default options. For now I require all four arguments.With that function, and the browser
width
and height
already calculated, I have my borders with: scene.add(makeBorder(width/-2, 0, 50, height));
scene.add(makeBorder(width/2, 0, 50, height));
scene.add(makeBorder(0, height/-2, width, 50));
scene.add(makeBorder(0, height/2, width, 50));
As for the ramps, I define a similar generator function. In this case, the shape will be fixed, but the rotation can change: function makeRamp(x, y, rotation) {
var ramp = new Physijs.ConvexMesh(
new THREE.CubeGeometry(50, 500, 10),
Physijs.createMaterial(
new THREE.MeshBasicMaterial({color:0x0000cc}), 0.2, 1.0
),
0
);
ramp.rotation.set(0, 0, rotation);
ramp.position.set(x, y, 0);
return ramp;
}
scene.add(makeRamp(0.4*width/2, -height/2 + 25, -Math.PI/4));
scene.add(makeRamp(-0.3*width/2, 0, Math.PI/3));
The last thing that I do tonight is to create a goal for the game. I add a hoop to the top-left corner of the window: var goal = new Physijs.ConvexMesh(
new THREE.TorusGeometry(90, 5, 5, 16),
Physijs.createMaterial(
new THREE.MeshBasicMaterial({color:0x00bb00}), 0.2, 0.5
),
0
);
goal.position.set(width/-2, height/2, 0);
goal.isGoal = true;
scene.add(goal);
The isGoal
property is an easy way for the collision detection to determine how (or if) to handle the event: player.addEventListener('collision', function(object) {
console.log('Collision!');
if (object.isGoal) gameOver();
});
With that, I have a fairly functional game:The code so far is available if anyone cares to try their luck. Up tomorrow, I will get started trying to figure out how best to expose the ability to move those ramps around the game area.
Day #644
No comments:
Post a Comment