How to control your HTML5 game using Arduino
Yesterday I made a mini HTML5 game based on the retro game Asteroids (here is a flashversion) without the asteroids, so I just made a ship with those controls. You can check it out on my personal site and the code is at my Github.
What about instead of using the keyboard for controls, using a potentiometer for the controls? Here is a video with me explaining it (the demo is at 8:30 into the video).
Here is the code to get it working:
The arduino code is straight from the node duino module. Read more about it in my article about duino.
Nodejs script
dependencies: node, duino, socket.io
var l = console.log;
var http = require('http');
var url = require('url');
var io = require('socket.io').listen(1337);
io.set('log level', 1);
var arduino = require('duino');
var board = new arduino.Board({
// debug: true
});
// defaults to a01
var pot = new arduino.Sensor({
board: board,
});
var init = function() {
broadcast();
}
board.on( 'ready', function() {
// still not ready somehow
setTimeout( init, 100 );
});
HTML file
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
?>
<!doctype html>
<!--#
Insert coin(s)
<Push any button to start>
-->
<html lang=en>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
<title>ardiono game</title>
<style>
body {
background-color:black;
}
#game {
position: absolute;
top: 0px;
left: 0px;
z-index: -1;
}
</style>
</head>
<body>
<canvas id=game></canvas>
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js">
<script src="game.js"></script>
</body>
</html>
<!--#
GAME OVER
front end javascript (game)
(function(d, c){
//helpers
var getHeight = function() {
var D = document;
return Math.max(
Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
Math.max(D.body.clientHeight, D.documentElement.clientHeight)
);
};
var getWidth = function() {
var D = document;
return Math.max(
Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),
Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),
Math.max(D.body.clientWidth, D.documentElement.clientWidth)
);
};
// polyfill: set the window.requestAnimationFrame to the browsers specific version.
(function() {
var lastTime = 0
, vendors = ['ms', 'moz', 'webkit', 'o']
, x
, length
, currTime
, timeToCall;
for(x = 0, length = vendors.length; x < length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
currTime = new Date().getTime();
timeToCall = Math.max(0, 16 - (currTime - lastTime));
lastTime = currTime + timeToCall;
return window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
var angle = 0;
// socket io hook
var socket = io.connect('http://localhost:1337');
socket.on('news', function (data) {
// console.log(data.v);
angle = data.v / 1024 * 8;
});
var canvas = document.getElementById("game");
canvas.height = getHeight();
canvas.width = getWidth();
// draw function is in a closure
var draw = (function() {
var PI = Math.PI
, twoPI = PI * 2
, speed = 5
, shipX = 100
, shipY = 100
, degrees
, cap = function( n, cap ) {
return n < 0 ? n + cap : n % cap;
}
return function() {
// clear the stage
ctx.clearRect( 0, 0, canvas.width, canvas.height );
ctx.save();
// calc new position
shipX += Math.sin( angle ) * speed;
shipY -= Math.cos( angle ) * speed;
shipX = cap( shipX, canvas.width );
shipY = cap( shipY, canvas.height );
// draw the changes
// position
ctx.translate( shipX, shipY );
// rotate
ctx.rotate( angle );
// draw
ctx.beginPath();
ctx.fillStyle = 'white';
ctx.strokeStyle = 'white';
// ship
ctx.lineTo(0, -15);
ctx.lineTo(10, 15);
ctx.lineTo(0, 13);
ctx.lineTo(-10, 15);
// finish
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
}
})();
if( canvas.getContext ) {
var ctx = canvas.getContext("2d");
// the loop
(function animloop(){
requestAnimationFrame( animloop );
draw();
})();
}