jueves, 26 de diciembre de 2013

HTML Game for the Weekend

Just for playing, I did a small game in pure HTML. But not using the usual <canvas> from HTML5. I used only pure old Javascrip and a couple of HTML tags.

All goes inside index.html
You first create a simple HTML file with the following:

<body onLoad="doWork()">
<div id="canvas"></div>
</body>

Make a reference to mousetrap.min.js to handle the keyboard events (Google the library, it's pretty cool)

<!-- http://craig.is/killing/mice -->
<script type="text/javascript" src="mousetrap.min.js"></script>

For the <style>, this is what I did (pretty basic)

<style>
.tile {
border : 1px dotted #ccc;
width: 10px;
height: 10px;
position: fixed;
}
.marked {
background-color: #ccc;
}
</style>

The fun part is the Javascript code.

<script>
//
// TILES
//
var totalCols = 100;
var totalRows = 50;
//
// TILES POSITION AND SIZE
//
var grid_x = 0;
var grid_y = 0;
var grid_w = 10;
var grid_h = 10;
//
// SPEED FOR MOVING ACTORS
//
var speed_w = grid_w * 1;
var speed_h = grid_h * 1;
//
// MARKED TILES ARE OBSTACLES FOR ACTORS
//
var totalMarkedTiles = 0;
var markedTilesLeft = new Object();
var markedTilesTop = new Object();
//
// FRAMES LEFT
//
var framesLeftKid = new Object();
framesLeftKid['0'] = 'i/kid/frame_000.gif';
framesLeftKid['w'] = grid_w * 6;
framesLeftKid['h'] = grid_h * 10;
//
// FRAMES RIGHT
//
var framesRightKid = new Object();
framesRightKid['0'] = 'i/kid-right/frame_000.gif';
framesRightKid['w'] = grid_w * 6;
framesRightKid['h'] = grid_h * 10;
//
// ACTORS
//
var actorKid1 = new Object();
actorKid1['name'] = 'kid1';
actorKid1['framesLeft'] = framesLeftKid;
actorKid1['framesRight'] = framesRightKid;
actorKid1['currentTop'] = 20;
actorKid1['currentLeft'] = 20;
actorKid1['currentFrame'] = 0;
//
// ACTORS ADDED TO THE MAIN ARRAY
//
var actors = new Object();
actors[0] = actorKid1;
function loadMap() {
var top = grid_y;
var left = grid_x;
var str = "";
for ( var row=0; row < totalRows; row++ ) {
for ( var col=0; col < totalCols; col++ ) {
// all the bottom is blocked
if ( col >= 0 && row == totalRows - 1 && col <= totalCols - 1 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
// first row is blocked
if ( col >= 0 && row == 0 && col <= totalCols - 1 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
// first col is blocked
if ( col == 0 && row >= 0 && row <= totalRows - 1 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
// last col is blocked
if ( col == totalCols - 1 && row >= 0 && row <= totalRows - 1 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
if ( col == 5 && row == 30 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
if ( col == 50 && row == 5 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
if ( col == 60 && row == 40 ) {
markedTilesLeft[totalMarkedTiles] = col;
markedTilesTop[totalMarkedTiles] = row;
totalMarkedTiles ++;
}
}
}
}
function drawGrid() {
var top = grid_y;
var left = grid_x;
var str = "";
for ( var row=0; row < totalRows; row++ ) {
for ( var col=0; col < totalCols; col++ ) {
var painted = false;
for ( var m=0; m < totalMarkedTiles; m++ ) {
if ( markedTilesLeft[m] == col && markedTilesTop[m] == row ) {
str += "<div id=" + row + "_" + col 
+ " style='border:1px dotted #ccc; " 
+ "position:fixed; " 
+ "width:" + grid_w + "px; " 
+ "height:" + grid_h + "px; " 
+ "left:" + left + "px; " 
+ "top:" + top + "px; " 
+ "background:#ccc; ' " 
+ "/>";
painted = true;
}
}
if ( painted == false ) {
str += "<div id=" + row + "_" + col 
+ " style='border:1px dotted #ccc; " 
+ "position:fixed; " 
+ "width:" + grid_w + "px; " 
+ "height:" + grid_h + "px; " 
+ "left:" + left + "px; " 
+ "top:" + top + "px;' " 
+ "/>";
}
left += grid_w;
}
top += grid_h;
left = grid_x;
}
document.getElementById('canvas').innerHTML = str;
}
function drawAllActors() {
var str = "";
for (var actor in actors) {
var a = actors[actor];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
str += "<div id='" + a['name'] + "' " 
+ "style='left:" + left 
+ "px; top:" + top + "px; position:fixed; " 
+ "width:" + w + "px; " 
+ "height:" + h + "px; " 
+ "border:1px solid #333;" 
+ "' " 
+ ">";
}
document.getElementById('canvas').innerHTML += str;
}
function moveActorDown(index, newTop, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var e = document.getElementById(a['name']);
for ( var m=0; m < totalMarkedTiles; m++ ) {
var markedLeft = (markedTilesLeft[m] * grid_w);
var markedTop = (markedTilesTop[m] * grid_h);
var markedW = grid_w;
var markedH = grid_h;
if ( markedLeft >= left && markedLeft + markedW  <= left + w 
&& markedTop >= newTop && markedTop + markedH <= newTop + h ) 
{
if ( callback != null ) callback(false);
return false;
}
}
e.style.top = newTop + "px";
a['currentTop'] = newTop;
actors[index] = a;
if ( callback != null ) callback(true);
return true;
}
function moveActorUp(index, newTop, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var e = document.getElementById(a['name']);
for ( var m=0; m < totalMarkedTiles; m++ ) {
var markedLeft = (markedTilesLeft[m] * grid_w);
var markedTop = (markedTilesTop[m] * grid_h);
var markedW = grid_w;
var markedH = grid_h;
if ( markedLeft >= left && markedLeft + markedW  <= left + w 
&& markedTop >= newTop && markedTop + markedH <= newTop + h ) 
{
if ( callback != null ) callback(false);
return false;
}
}
e.style.top = newTop + "px";
a['currentTop'] = newTop;
actors[index] = a;
if ( callback != null ) callback(true);
return true;
}
function moveActorLeft(index, newLeft, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var e = document.getElementById(a['name']);
for ( var m=0; m < totalMarkedTiles; m++ ) {
var markedLeft = (markedTilesLeft[m] * grid_w);
var markedTop = (markedTilesTop[m] * grid_h);
var markedW = grid_w;
var markedH = grid_h;
if ( markedLeft >= newLeft && markedLeft + markedW  <= newLeft + w 
&& markedTop >= top && markedTop + markedH <= top + h ) 
{
if ( callback != null ) callback(false);
return false;
}
}
e.style.left = newLeft + "px";
a['currentLeft'] = newLeft;
actors[index] = a;
if ( callback != null ) callback(true);
return true;
}
function moveActorRight(index, newLeft, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var e = document.getElementById(a['name']);
for ( var m=0; m < totalMarkedTiles; m++ ) {
var markedLeft = (markedTilesLeft[m] * grid_w);
var markedTop = (markedTilesTop[m] * grid_h);
var markedW = grid_w;
var markedH = grid_h;
if ( markedLeft >= newLeft && markedLeft + markedW  <= newLeft + w 
&& markedTop >= top && markedTop + markedH <= top + h ) 
{
if ( callback != null ) callback(false);
return false;
}
}
e.style.left = newLeft + "px";
a['currentLeft'] = newLeft;
actors[index] = a;
if ( callback != null ) callback(true);
return true;
}
function moveActorDownUntilCollide(index, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var newTop = top + speed_h;
moveActorDown(index, newTop, function(result) {
if (result) {
moveActorDownUntilCollide(index, callback);
}
else {
callback();
}
});
}
function moveActorUpUntilCollide(index, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var newTop = top - speed_h;
moveActorUp(index, newTop, function(result) {
if (result) {
moveActorUpUntilCollide(index, callback);
}
else {
callback();
}
});
}
function moveActorRightUntilCollide(index, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var newLeft = left + speed_w;
moveActorRight(index, newLeft, function(result) {
if (result) {
moveActorRightUntilCollide(index, callback);
}
else {
callback();
}
});
}
function moveActorLeftUntilCollide(index, callback) {
var a = actors[index];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
var newLeft = left - speed_w;
moveActorLeft(index, newLeft, function(result) {
if (result) {
moveActorLeftUntilCollide(index, callback);
}
else {
callback();
}
});
}
function onKeyPressed(keyCode) {
var a = actors[actorIndex];
var f = a['framesLeft'];
var top = a['currentTop']; 
var left = a['currentLeft']; 
var w = f['w'];
var h = f['h'];
if ( keyCode == 'left' ) {
moveActorLeft(actorIndex, left - speed_w, function() {
setTimeout( function() {
moveActorDownUntilCollide(actorIndex, function() {})
}, 500);
});
}
if ( keyCode == 'right' ) {
moveActorRight(actorIndex, left + speed_w, function() {
setTimeout( function() {
moveActorDownUntilCollide(actorIndex, function() {})
}, 500);
});
}
if ( keyCode == 'up' ) {
moveActorUp(actorIndex, top - speed_h, function() {
setTimeout( function() {
moveActorDownUntilCollide(actorIndex, function() {})
}, 500);
});
}
if ( keyCode == 'down' ) {
moveActorDown(actorIndex, top + speed_h, function() {
setTimeout( function() {
moveActorDownUntilCollide(actorIndex, function() {})
}, 500);
});
}
}
function initKeyboard() {
Mousetrap.bind('esc', function(e) {
e.preventDefault();
onKeyPressed('esc');
return false;
});
Mousetrap.bind('up', function(e) {
e.preventDefault();
onKeyPressed('up');
return false;
});
Mousetrap.bind('down', function(e) {
e.preventDefault();
onKeyPressed('down');
return false;
});
Mousetrap.bind('left', function(e) {
e.preventDefault();
onKeyPressed('left');
return false;
});
Mousetrap.bind('right', function(e) {
e.preventDefault();
onKeyPressed('right');
return false;
});
}
function doWork() {
initKeyboard();
loadMap();
drawGrid();
drawAllActors();
// the only actor can not be floating...
moveActorDownUntilCollide(actorIndex, function() {})
}
// this is the only actor index we use in this demo
var actorIndex = 0;
</script>

That's it. Put all that inside an index.html and use your arrow keys in your keyboard to move the actor.