Navigation Menu

Skip to content

Commit

Permalink
refactored play state
Browse files Browse the repository at this point in the history
refactored end zone detection to generic 3d hotspot in Physics
added debug output DOM element
  • Loading branch information
stevehb committed Mar 23, 2012
1 parent a259d69 commit 5c7e061
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 82 deletions.
20 changes: 18 additions & 2 deletions racecar.html
Expand Up @@ -3,9 +3,18 @@
<script src="jquery-1.7.1.js"></script>
<script src="Three.js"></script>
<script src="Stats.js"></script>
<script src="tween.js"></script>
<script src="Tween.js"></script>
<script src="THREEx.KeyboardState.js"></script>
<script src="racecar.js"></script>
<script src="rcPhysics.js"></script>
<script src="rcTitleState.js"></script>
<script src="rcPlayCountdownState.js"></script>
<script src="rcPlayRaceState.js"></script>
<script src="rcEndState.js"></script>
<script src="rcTrack.js"></script>
<script src="rcPlayer.js"></script>
<script src="rcRacer.js"></script>

<style type="text/css">
body {
margin: 0px;
Expand All @@ -25,7 +34,7 @@
position: absolute;
}
#game-timer {
color:#00ff00;
color: #ff0000;
display: none;
font-size: 48;
margin: 4px;
Expand All @@ -40,6 +49,12 @@
right: 0px;
top: 0px;
}
.debug {
position: relative;
display: inline;
font-family: Helvetica,sans-serif;
font-size: 12px;
}
</style>
</head>
<body onload="init()">
Expand All @@ -50,5 +65,6 @@
<img id="img-logo" src="img/logo.png" />
<img id="img-start" src="img/start.png" />
</div>
<div class="debug" id="debug"></div>
</body>
</html>
28 changes: 15 additions & 13 deletions racecar.js
Expand Up @@ -23,31 +23,24 @@ function init() {
RC.scene = new THREE.Scene();
RC.log("creating camera: fov=" + RC.FOV + ", aspect=" + (RC.WIDTH/RC.HEIGHT));
RC.camera = new THREE.PerspectiveCamera(RC.FOV, RC.WIDTH / RC.HEIGHT, 1, 10000);
RC.camera.position.set(0, 10, 0);
RC.camera.position.set(0, 1.5, 0);
RC.camera.rotation.y = Math.PI;
RC.scene.add(RC.camera);
RC.renderer = new THREE.WebGLRenderer({ antialias: true, maxLights: RC.NLIGHTS });
RC.renderer.setClearColorHex(0x223344, 1.0);
RC.renderer.setSize(RC.WIDTH, RC.HEIGHT);
$("#canvas-container")[0].appendChild(RC.renderer.domElement);

// get additional codes, no waiting
$.ajaxSetup({ async : false });
$.getScript("rcPhysics.js");
$.getScript("rcTitleState.js");
$.getScript("rcPlayCountdownState.js");
$.getScript("rcPlayRaceState.js");
//$.getScript("rcEndState.js");
$.getScript("rcTrack.js");
$.getScript("rcPlayer.js");
$.getScript("rcRacer.js");
$.ajaxSetup({ async : true });

// create the title state, and start the updates
RC.physics = new RC.Physics();
RC.stateStack = new Array();
RC.stateStack.push(new RC.TitleState());

// set up debug line
$(".debug").css({
"top": RC.HEIGHT + 10
});

RC.lastTime = new Date();
RC.update();
}
Expand All @@ -71,3 +64,12 @@ RC.update = function() {
RC.log = function(msg) {
console.log("RC: " + msg);
};

RC.debug = (function() {
var info = ["", "", "", ""];

return function(pos, msg) {
info[pos] = msg;
$("#debug").text(info[1] + " " + info[2] + " " + info[3])
};
}());
75 changes: 47 additions & 28 deletions rcPhysics.js
Expand Up @@ -2,18 +2,19 @@ var RC = RC || {};

RC.Physics = function() {
this.objList = new Array();
this.hotspots = new Array();
this.hotcubeCallbacks = new Array();

this.makePhysical = function(obj) {
obj.momentum = new THREE.Vector3(0, 0, 0);
obj.position = new THREE.Vector3(0, 0, 0);
obj.rotation = new THREE.Vector3(0, 0, 0);
obj.accumForce = new THREE.Vector3(0, 0, 0);
obj.friction = 0.0;
obj.friction = 0.0;
obj.moveable = true;
};

this.addObject = function(obj) {
RC.log("adding object to physics");
//RC.log("adding object to physics");
this.objList.push(obj);
};

Expand Down Expand Up @@ -52,38 +53,56 @@ RC.Physics = function() {
obj.momentum.z += -Math.cos(obj.rotation.y) * (magnitude * obj.friction);
};

this.addHotspot2d = function(rect, callback) {
this.hotspots.push({
"rect": rect,
"callback": callback
});
this.resetRotation = function(obj, rotation) {
// reset rotation
obj.rotation.y = rotation.y;

// reset momentum
var magnitude = obj.momentum.length();
obj.momentum.multiplyScalar(0.0);
obj.momentum.x = -Math.sin(obj.rotation.y) * magnitude;
obj.momentum.z = -Math.cos(obj.rotation.y) * magnitude;

// and accumForce
magnitude = obj.accumForce.length();
obj.accumForce.multiplyScalar(0.0);
obj.accumForce.x = -Math.sin(obj.rotation.y) * magnitude;
obj.accumForce.z = -Math.cos(obj.rotation.y) * magnitude;
};

this.addHotcubeCallback = function(cube, obj, func) {
RC.log("adding callback for cube " + cube.name);
this.hotcubeCallbacks.push({
"cube" : cube,
"obj" : obj,
"func" : func
});
}

this.update = function(elapsed) {
var objRectPos = new THREE.Rectangle();
$.each(this.objList, function(idx, obj) {
// turn accumulated forces into momentum,
// then turn momentum into movement
obj.momentum.x += obj.accumForce.x * elapsed;
obj.momentum.z += obj.accumForce.z * elapsed;
obj.position.x += obj.momentum.x * elapsed;
obj.position.z += obj.momentum.z * elapsed;
obj.accumForce.set(0, 0, 0);
if(obj.moveable) {
obj.momentum.x += obj.accumForce.x * elapsed;
obj.momentum.z += obj.accumForce.z * elapsed;
obj.position.x += obj.momentum.x * elapsed;
obj.position.z += obj.momentum.z * elapsed;
obj.accumForce.set(0, 0, 0);
}
});

// check hotcubes callbacks
$.each(this.hotcubeCallbacks, function(idx, callback) {
var cube = callback.cube;
var obj = callback.obj;
var pos = obj.position;

// trigger hotspots
$.each(RC.physics.hotspots, function(idx, spot) {
objRectPos.empty();
objRectPos.addPoint(obj.position.x, obj.position.z);
if(spot.rect.intersects(objRectPos)) {
RC.log("got a hit!");
spot.callback(spot.rect, obj);
} else {
//RC.log("no hit: spot=[" + spot.rect.getLeft() + "," + spot.rect.getTop() + "," +
// spot.rect.getRight() + "," + spot.rect.getBottom() + "] " +
// "obj=" + objRectPos.getLeft() + "," + objRectPos.getTop() + "," +
// objRectPos.getRight() + "," + objRectPos.getBottom() + "]");
}
});
if(pos.x > cube.min.x && pos.x < cube.max.x &&
pos.y > cube.min.y && pos.y < cube.max.y &&
pos.z > cube.min.z && pos.z < cube.max.z) {
callback.func(obj, cube);
}
});
};
};
28 changes: 22 additions & 6 deletions rcPlayCountdownState.js
Expand Up @@ -11,7 +11,11 @@ RC.PlayCountdownState = function() {
// set up timer, ready to countdown
var accumTime = 0;
var timer = $("#game-timer");
timer.text(this.COUNTDOWN_TIME.toFixed(2));
timer.text(this.COUNTDOWN_TIME.toFixed(0));
timer.css({
"left": (RC.WIDTH - timer.width()) / 2,
"top": (RC.HEIGHT - timer.height()) / 2
});

// create div to cover canvas, make it the background clear color,
// and fade it out to transparent
Expand All @@ -31,26 +35,38 @@ RC.PlayCountdownState = function() {
"background-color": rgbString
});
$("#tmp-cover").show();
$("#tmp-cover").fadeOut(3000, "linear", function() {
$("#tmp-cover").fadeOut(2000, function() {
RC.log("activating count down");
state = RC.PlayStateEnum.COUNTDOWN;
timer.show();
$("#canvas-container").remove("#tmp-cover");
});

// track & camera
// set up track and racers
RC.track = new RC.Track();
RC.camera.position.set(0, 10, 0);
RC.camera.rotation.y = Math.PI;
RC.player = new RC.Player();
RC.racers = new Array(RC.NRACERS);
RC.racers[0] = RC.player;
for(i = 1; i < RC.NRACERS; i++) {
RC.racers[i] = new RC.Racer(i);
}

// camera
RC.camera.position.copy(RC.player.position);
RC.camera.rotation.copy(RC.player.rotation);;

this.update = function(elapsed) {
if(state === RC.PlayStateEnum.COUNTDOWN) {
accumTime += elapsed;
var remaining = this.COUNTDOWN_TIME - accumTime;
if(remaining > 0.0) {
timer.text(remaining.toFixed(2));
timer.text(remaining.toFixed(0));
} else {
timer.text("0.00");
timer.animate({
"left": 0,
"top": 0
}, "fast");
RC.log("activating race");
RC.stateStack.pop();
RC.stateStack.push(new RC.PlayRaceState());
Expand Down
34 changes: 22 additions & 12 deletions rcPlayRaceState.js
Expand Up @@ -8,17 +8,18 @@ RC.PlayRaceState = function() {
timer.text("0.00");

RC.track = RC.track || new RC.Track();

RC.camera.position.set(0, 10, 0);
RC.camera.rotation.y = Math.PI;

RC.player = new RC.Player();
RC.racers = new Array(RC.NRACERS);
RC.racers[0] = RC.player;
for(i = 1; i < RC.NRACERS; i++) {
RC.racers[i] = new RC.Racer(i);
RC.player = RC.player || new RC.Player();
if(RC.racers.length !== RC.NRACERS) {
RC.racers.length = RC.NRACERS;
RC.racers[0] = RC.player;
for(i = 1; i < RC.NRACERS; i++) {
RC.racers[i] = new RC.Racer(i);
}
}

RC.camera.position.copy(RC.player.position);
RC.camera.rotation.copy(RC.player.rotation);

this.update = function(elapsed) {
accumTime += elapsed;
timer.text(accumTime.toFixed(2));
Expand All @@ -29,8 +30,17 @@ RC.PlayRaceState = function() {
}
RC.physics.update(elapsed);

RC.camera.position.x = RC.player.position.x;
RC.camera.position.z = RC.player.position.z;
RC.camera.rotation.y = RC.player.rotation.y;
RC.camera.position.copy(RC.player.position);
RC.camera.rotation.copy(RC.player.rotation);

RC.debug(1, " pos: [" + RC.player.position.x.toFixed(2) + "," +
RC.player.position.y.toFixed(2) + "," +
RC.player.position.z.toFixed(2) + "]");
RC.debug(2, " rotation=[" + RC.player.rotation.x.toFixed(2) + "," +
RC.player.rotation.y.toFixed(2) + ", " +
RC.player.rotation.z.toFixed(2) + "]");
RC.debug(3, " momentum=[" + RC.player.momentum.x.toFixed(2) + "," +
RC.player.momentum.y.toFixed(2) + ", " +
RC.player.momentum.z.toFixed(2) + "]");
}
};
31 changes: 24 additions & 7 deletions rcPlayer.js
Expand Up @@ -20,13 +20,35 @@ RC.Player = function() {
this.TURN_SPEED = Math.PI / 2;
this.accelState = RC.RacerAccelStateEnum.DRIFT;
this.turnState = RC.RacerTurnStateEnum.NOTURN;
RC.log("making physical with RC.physics=" + RC.physics);
RC.physics.makePhysical(this);
RC.physics.addObject(this);
this.rotation.y = Math.PI;
this.position.set(0.0, 5.0, RC.END_ZONE_LENGTH);
this.position.set(0.0, 1.5, RC.END_ZONE_LENGTH);
this.friction = 0.10;

this.lastEndZone = RC.TrackEndZoneEnum.NEAR;
this.lapCount = 0;

this.inEndZone = function(obj, cube) {
RC.log("player got end zone trigger (now lap " + obj.lapCount + ")");
RC.physics.resetRotation(obj, cube.resetVector);
if(cube.name === RC.TrackEndZoneEnum.NEAR.name) {
obj.position.z = RC.END_ZONE_LENGTH + 1;
} else if(cube.name === RC.TrackEndZoneEnum.FAR.name) {
obj.position.z = (RC.TRACK_LENGTH + RC.END_ZONE_LENGTH) - 1;
}
if(obj.lastEndZone !== cube) {
obj.lastEndZone = cube;
obj.lapCount++;
if(obj.lapCount >= RC.NLAPS) {
RC.log("player wins!");
// should probably push new EndState("win") here
}
}
};
RC.physics.addHotcubeCallback(RC.TrackEndZoneEnum.NEAR, this, this.inEndZone);
RC.physics.addHotcubeCallback(RC.TrackEndZoneEnum.FAR, this, this.inEndZone);

this.update = function(elapsed) {
// get acceleration and turning states from keyboard
if(RC.keyboard.pressed("up")) {
Expand Down Expand Up @@ -75,10 +97,5 @@ RC.Player = function() {
RC.physics.dampenMomentum(this, this.DRAG_MULTIPLIER);
break;
}

// check for end zone flip
//if(RC.track.inEndZone(this.position)) {
// this.rotation.y += Math.PI;
//}
};
};

0 comments on commit 5c7e061

Please sign in to comment.