Skip to content

Instantly share code, notes, and snippets.

@omaraboumrad
Created October 19, 2013 15:34
Show Gist options
  • Save omaraboumrad/7057376 to your computer and use it in GitHub Desktop.
Save omaraboumrad/7057376 to your computer and use it in GitHub Desktop.
space glider
<audio autoplay loop>
<source src="https://dl.dropboxusercontent.com/u/18982788/starwars.mp3" />
</audio>
window.onload = init;
function init() {
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var config = {
width: 400,
height: 400,
background: '#000000',
foreground: '#FFFFFF',
create_background: function(){
var _canvas = document.createElement('canvas');
var _ctx = _canvas.getContext('2d');
_canvas.width = this.width;
_canvas.height = this.height;
_ctx.fillStyle = this.background;
_ctx.fillRect(0,0,this.width, this.height);
_ctx.fillStyle = this.foreground;
var _stars = 100;
for(var i=0; i<_stars;i++){
star_x = Math.round(this.width*Math.random());
star_y = Math.round(this.height*Math.random());
_ctx.fillRect(star_x,star_y, 1,1);
}
return _canvas;
}
};
canvas.width = config.width;
canvas.height = config.height;
var ctx = canvas.getContext('2d');
var pressed = {};
var ship = {
score: 0,
icon: new Image(),
fire: new Image(),
asteroid: new Image(),
asteroids: [],
last_added: 0,
x: 20,
y: 20,
w: 10,
h: 10,
angle: 0,
cx: function(){ return this.x + this.icon.width/2; },
cy: function(){ return this.y + this.icon.width/2; },
color: '#FF0000',
moving: false,
bursting: false,
velocity: { current: 0, value: 0.08, max: 4 },
right: function() { this.handle_angle(-1); },
left: function() { this.handle_angle(1); },
handle_angle: function(sign){
this.angle += sign*2;
if(this.angle > 360) this.angle = 0;
else if(this.angle < 0) this.angle = 360;
},
accelerate: function() { this.handle_velocity(1); },
decelerate: function() { this.handle_velocity(-1); },
handle_velocity: function(sign){
this.moving = true;
if(this.velocity.current <= this.velocity.max)
this.velocity.current += sign * this.velocity.value;
if(this.velocity.current > this.velocity.max)
this.velocity.current = this.velocity.max
if(this.velocity.current < 0)
this.velocity.current = 0;
},
move: function(){
var _angle = this.angle * Math.PI / 180;
this.x += this.velocity.current * Math.cos(_angle);
this.y += this.velocity.current * Math.sin(_angle);
},
handle_edges: function(max_x, max_y){
if(this.x > max_x) this.x = 0;
if(this.x < 0) this.x = max_x;
if(this.y > max_y) this.y = 0;
if(this.y < 0) this.y = max_y;
},
render: function(){
ctx.fillStyle = '#000000';
ctx.save();
ctx.translate(this.cx(), this.cy());
ctx.rotate(this.angle * Math.PI/180);
ctx.drawImage(ship.icon, -this.icon.width/2,-this.icon.height/2);
if(this.bursting)
ctx.drawImage(ship.fire, -this.icon.width-10,-this.icon.height/3);
ctx.restore();
},
render_dashboard: function(data){
var percent = this.velocity.current/this.velocity.max * 100;
ctx.fillStyle = '#FFFF00';
ctx.fillRect(0, config.height-35, config.width, config.height);
ctx.fillStyle = '#000000';
ctx.font = 'italic 10pt verdana';
ctx.fillText('SPEED: ' + Math.round(percent), 10, config.height - 20);
ctx.fillText('ANGLE: ' + this.angle, 100, config.height - 20);
ctx.fillText('TIME: ' + data.elapsed_total, 200, config.height - 20);
},
handle_enemies: function(elapsed){
var seconds = Math.floor(elapsed);
if(seconds != 0
&& seconds % 5 == 0
&& seconds != this.last_added){
asteroid_x = Math.round(config.width*Math.random());
asteroid_y = Math.round((config.height-75)*Math.random());
this.asteroids.push([asteroid_x, asteroid_y]);
this.last_added = Math.floor(elapsed);
}
for(var i=0; i<this.asteroids.length; i++){
ctx.drawImage(this.asteroid, this.asteroids[i][0], this.asteroids[i][1]);
}
},
handle_collision: function(){
var self = this;
for(var i=0; i<this.asteroids.length; i++){
var asteroid = this.asteroids[i];
var r1 = {
left: asteroid[0],
top: asteroid[1],
bottom: asteroid[1] + self.asteroid.height,
right: asteroid[0] + self.asteroid.width
};
var error = 5;
var r2 = {
left: self.x - error ,
right: self.x + self.icon.width - error,
top: self.y - error,
bottom: self.y + self.icon.height -error
}
if(intersect(r1, r2)){
ctx.fillStyle = '#FF0000';
ctx.font = 'italic 40pt verdana';
ctx.fillText('NOOB!', 50, 50);
}
}
},
handle_events:function(){
if (pressed[38]){
ship.bursting = true;
ship.accelerate();
}
if (pressed[40]) ship.decelerate();
if (pressed[37]) ship.right();
if (pressed[39]) ship.left();
}
};
document.addEventListener('keydown', function(evt){
pressed[evt.keyCode] = true;
}, true);
document.addEventListener('keyup', function(evt){
pressed[evt.keyCode] = false;
ship.bursting = false;
}, true);
var intersect = function(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
};
var bg = config.create_background();
var bg1_y = -config.height;
var bg2_y = 0;
var elapsed_bg = 0;
var start = new Date();
var last = new Date();
var loop = function(){
var now = new Date();
var elapsed_frame = now - last;
var elapsed_total = (now - start) / 1000;
last = now;
elapsed_bg += elapsed_frame;
ctx.drawImage(bg, 0,bg1_y);
ctx.drawImage(bg, 0,bg2_y);
if(elapsed_bg > 100){
bg1_y +=1;
bg2_y +=1;
elapsed_bg = 0;
if(bg2_y > config.height) { bg2_y = -config.height; }
if(bg1_y > config.height) { bg1_y = 0; }
}
ship.render();
ship.render_dashboard({
elapsed_total: elapsed_total,
});
if(ship.moving)
ship.move();
ship.handle_enemies(elapsed_total);
ship.handle_collision();
ship.handle_edges(config.width, config.height);
ship.handle_events();
}
ship.icon.src = "https://dl.dropboxusercontent.com/u/18982788/ship.png",
ship.fire.src = "https://dl.dropboxusercontent.com/u/18982788/fire.png",
ship.asteroid.src = "https://dl.dropboxusercontent.com/u/18982788/asteroid.png",
setInterval(loop, 10);
}
@omaraboumrad
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment