Created
April 11, 2009 17:23
-
-
Save FND/93642 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | |
<html lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<title>JavaScript-based game experiment</title> | |
<link rel="stylesheet" type="text/css" href="styles/main.css"> | |
</head> | |
<body> | |
<div id="screen"></div> | |
<div id="info"> | |
<h2>Controls</h2> | |
<dl> | |
<dt>space</dt> | |
<dd>toggle pause</dd> | |
<dt>cursor keys (↑, ↓, ←, →)</dt> | |
<dd>movement</dd> | |
</dl> | |
<h2>Description</h2> | |
<p>This is a simple experiment exploring how a game might be implemented using web standards.</p> | |
<p>The idea is for this to eventually become a (very basic) skydiving simulator.</p> | |
<h2>Caveats</h2> | |
<p>Currently only tested on Firefox.</p> | |
<p>Not using <code>canvas</code> yet.</p> | |
<p>Precision of motion calculations are imperfect (especially visible near the edges of the screen element).</p> | |
<p>Collision detection might turn out to be tricky to implement.</p> | |
</div> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script> | |
<script src="scripts/util.js" type="text/javascript"></script> | |
<script src="scripts/main.js" type="text/javascript"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* { | |
margin: 0; | |
padding: 0; | |
} | |
h2, | |
p, | |
dd { | |
margin: 0.2em 0; | |
} | |
dl { | |
overflow: auto; /* detach from floated neighbor */ | |
} | |
dt { | |
font-weight: bold; | |
} | |
dd { | |
margin-left: 1em; | |
} | |
#info { | |
margin-left: 830px; /* based on total size of screen element */ | |
} | |
#screen { | |
position: absolute; | |
top: 10px; | |
left: 10px; | |
width: 800px; | |
height: 600px; | |
overflow: hidden; | |
border: 5px solid #AAA; | |
background-color: #EEE; | |
} | |
.player { | |
position: relative; | |
top: 0; | |
left: 395px; | |
width: 10px; | |
height: 10px; | |
background-color: #F00; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
/* | |
* settings | |
*/ | |
var game = { | |
fps: 30, // frame rate | |
sensitivity: 0.5, // controls sensitivity | |
screen: "#screen" | |
}; | |
var keys = { | |
start: 32, // space -- XXX: rename? | |
up: 38, // up arrow | |
down: 40, // down arrow | |
left: 37, // left arrow | |
right: 39 // right arrow | |
}; | |
/* | |
* rendering and input processing | |
*/ | |
var busy = false; // indicates whether calculation in progress | |
var tick = function() { // redraw step | |
if(busy) { // skip to prevent sync disruption | |
log("throttled"); | |
return; | |
} | |
busy = true; | |
handleInput(); | |
busy = false; | |
}; | |
var handleInput = function() { // XXX: rename? | |
var cmds = game.commands; // alias | |
// player movement | |
var vert = 0; | |
var horiz = 0; | |
if(cmds.contains(keys.up)) { | |
vert += game.sensitivity * 0.1; | |
} | |
if(cmds.contains(keys.down)) { | |
vert -= game.sensitivity * 0.1; | |
} | |
if(cmds.contains(keys.left)) { | |
horiz -= game.sensitivity * 0.1; | |
} | |
if(cmds.contains(keys.right)) { | |
horiz += game.sensitivity * 0.1; | |
} | |
move(game.player, { | |
vert: vert, | |
horiz: horiz | |
}); | |
}; | |
/* | |
* keyboard handling | |
*/ | |
$(document).keypress(function(ev) { | |
if(ev.which == keys.start) { | |
togglePause(); | |
} | |
}); | |
// game controls -- XXX: prevent event propagation? | |
game.commands = []; // current command stack (processed on redraw) -- XXX: do not use key codes directly | |
$(document).keydown(function(ev) { | |
game.commands.push(ev.which); | |
}); | |
$(document).keyup(function(ev) { | |
game.commands.splice(game.commands.indexOf(ev.which), 1); | |
}); | |
/* | |
* utility functions | |
*/ | |
/* | |
* accelerate element along vector, using inertia from previous motions | |
* | |
* direction is determined by vector's "vert" and "horiz" members (negative | |
* values reverse direction) | |
* these members' values also determine acceleration rate (pixels per second) | |
* | |
* caches element position to avoid repeatedly querying the DOM | |
*/ | |
var move = function(el, vector) { // XXX: rename -- TODO: make jQuery method | |
var pos = el.pos || el.position(); | |
var impetus = el.impetus || { vert: 0, horiz: 0 }; // XXX: rename? | |
el.impetus = { | |
vert: impetus.vert + vector.vert * delay, | |
horiz: impetus.horiz + vector.horiz * delay | |
}; // XXX: ensure vector * speed >= 1 -- TODO: make vector members optional | |
el.pos = { | |
top: pos.top - impetus.vert, | |
left: pos.left + impetus.horiz | |
}; | |
el.css(el.pos); | |
}; | |
/* | |
* initialization | |
*/ | |
var delay = 1000 / game.fps; // milliseconds between redraws | |
var paused = true; | |
var togglePause = function() { | |
if(paused) { | |
log("launching"); | |
$(game.screen).fadeTo("normal", 1.0); | |
game.pid = setInterval(tick, delay); | |
paused = false; | |
} else { | |
clearInterval(game.pid); | |
paused = true; | |
$(game.screen).fadeTo("normal", 0.3); | |
log("paused"); | |
return; | |
} | |
}; | |
var init = function() { | |
$(game.screen). | |
click(function() { togglePause(); }); | |
game.player = $('<div class="player" />'). | |
appendTo(game.screen); | |
game.player.impetus = { vert: -10, horiz: 0 }; | |
togglePause(); // launch | |
togglePause(); // pause | |
}; | |
$(function() { | |
init(); | |
}); | |
})(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// log message for debugging | |
function log(message) { | |
if(window.console && console.log) { | |
console.log(new Date(), message); | |
} | |
} | |
// return a given item's position in the array | |
if(!Array.indexOf) { | |
Array.prototype.indexOf = function(item, from) { | |
if(!from) { | |
from = 0; | |
} | |
for(var i = from; i < this.length; i++) { | |
if(this[i] === item) { | |
return i; | |
} | |
} | |
return -1; | |
}; | |
} | |
// return whether an entry exists in the array | |
Array.prototype.contains = function(item) { | |
return this.indexOf(item) != -1; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment