Skip to content

Instantly share code, notes, and snippets.

@omaraboumrad omaraboumrad/fiddle.css
Last active Dec 25, 2015

Embed
What would you like to do?
space shooter
p{
font-family: verdana;
font-size: 12px;
}
<p>[A/D] Move [Left/Right] Rotate [Space] Shoot [Ctrl] Super Weapon</p>
window.onload = init;
function init() {
var world = {
sound: false,
scene: {
width: 400,
height: 600,
url: 'https://dl.dropboxusercontent.com/u/18982788/projectile/bg.jpg',
background: '#FFFFFF',
foreground: '#000000',
stroke: { color:'#000000', thickness: 4 } // Border
},
info: { // Info bar
height: 50,
background: '#000000',
foreground: '#FFFF00',
},
game:{
turret: {
url: 'https://dl.dropboxusercontent.com/u/18982788/projectile/turret.png',
nuclear_url: 'https://dl.dropboxusercontent.com/u/18982788/projectile/nuclear.png',
color: '#FF0000',
length: 40,
thickness:8,
frequency: 300, // of fire
step: 2, // turn steps
angle: 0, // starting angle
bullet: {
url: 'https://dl.dropboxusercontent.com/u/18982788/projectile/shot.png',
super_url:'https://dl.dropboxusercontent.com/u/18982788/projectile/super.png',
color: '#000000',
width: 4,
speed: 10, // travel speed
}
},
enemies: {
url: 'https://dl.dropboxusercontent.com/u/18982788/projectile/enemy.jpg',
explosion: 'https://dl.dropboxusercontent.com/u/18982788/projectile/explosion.png',
color: '#0000FF',
frequency: 500, // of spawn
basespeed: 0.5,
levelmodifier: 0.4,
count: 10, // per level
},
elapsed: {
shot: 0,
spawn: 0,
},
score: {
level: 1,
lives: 3,
super: 2,
current: 0,
best: 0,
}
}
};
var intersect = function(r1, r2) {
return !(r2[0] > r1[1] ||
r2[1] < r1[0] ||
r2[2] > r1[3] ||
r2[3] < r1[2]);
};
var sprite = {
x: world.scene.width/2,
y: world.scene.height-10,
projectiles: [],
enemies: [],
spawned: 0,
pressed: {},
loaded : 0,
bg: { elapsed: 0, angle:0 },
images: {},
nuke: {
playing:false,
alpha: 0,
elapsed:0,
total:0
},
sounds:{
shoot: new Audio('https://dl.dropboxusercontent.com/u/18982788/projectile/shoot.wav')
},
reset: function(){
world.game.score.current = 0;
world.game.score.level = 1;
world.game.score.lives = 3;
world.game.score.super = 2;
world.game.elapsed.shot = 0;
world.game.elapsed.spawn = 0;
this.enemies = [];
this.spawned = 0 ;
},
right: function() { this.handle_angle(-1); },
left: function() { this.handle_angle(1); },
handle_angle: function(sign){
world.game.turret.angle += world.game.turret.step*sign;
if(world.game.turret.angle > 90) world.game.turret.angle = 90;
else if(world.game.turret.angle < -90) world.game.turret.angle = -90;
},
move_right: function() { this.handle_move(1); },
move_left: function() { this.handle_move(-1); },
handle_move: function(sign){
this.x += 5*sign;
if(this.x - world.game.turret.length < 0) this.x = world.game.turret.length;
else if(this.x + world.game.turret.length > world.scene.width) this.x = world.scene.width - world.game.turret.length;
},
render_projectiles: function(){
for(var i=0;i<this.projectiles.length;i++){
var projectile = this.projectiles[i];
var _angle = projectile[2] * Math.PI / 180 - Math.PI/2;
projectile[0] += world.game.turret.bullet.speed * Math.cos(_angle);
projectile[1] += world.game.turret.bullet.speed * Math.sin(_angle);
if(projectile[0] < 0
|| projectile[0] > world.scene.width
|| projectile[1] < 0){
this.projectiles.splice(i,1);
i--;
}else{
ctx.drawImage(
this.images.bullet,
projectile[0] - this.images.bullet.width/2,
projectile[1] - this.images.bullet.height/2
);
}
}
},
render_enemies: function(){
for(var i=0;i<this.enemies.length;i++){
var enemy = this.enemies[i];
enemy[1] += enemy[2];
if(enemy[1] > world.scene.height - world.scene.width/20){
this.enemies.splice(i,1);
i--;
if(world.game.score.current > world.game.score.best)
world.game.score.best = world.game.score.current;
world.game.score.lives -= 1;
if(world.game.score.lives === 0) this.reset();
}else{
ctx.drawImage(
this.images.enemies,
enemy[0]-this.images.enemies.width/2,
enemy[1]-this.images.enemies.height/2);
}
}
},
render: function(){
// Turret
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(world.game.turret.angle * Math.PI/180);
ctx.drawImage(
this.images.turret,
-this.images.turret.width/2,
-this.images.turret.height
);
ctx.restore();
},
shoot: function(){
if(world.game.elapsed.shot > world.game.turret.frequency){
var _angle = world.game.turret.angle * Math.PI / 180 - Math.PI/2;
this.projectiles.push([
this.x + this.images.turret.height * Math.cos(_angle),
this.y + this.images.turret.height* Math.sin(_angle),
world.game.turret.angle
]);
world.game.elapsed.shot = 0;
if(world.sound){
this.sounds.shoot.currentTime = 0;
this.sounds.shoot.play();
}
}
},
fire_super: function(){
if(world.game.score.super > 0){
this.enemies = [];
world.game.score.super -= 1;
this.pressed[17] = false;
this.nuke.playing = true;
}
},
spawn: function(){
if(this.enemies.length < world.game.enemies.count && this.spawned != world.game.enemies.count){
x = Math.floor((world.scene.width - this.images.enemies.width) * Math.random()) + 5 + this.images.enemies.width/2;
v = world.game.enemies.basespeed + world.game.score.level * world.game.enemies.levelmodifier ;
this.enemies.push([x, 10, v]);
this.spawned += 1;
}
if(this.spawned == world.game.enemies.count && this.enemies.length == 0){
world.game.score.level += 1;
this.spawned = 0;
}
},
handle_collision: function(){
for(var i=0;i<this.enemies.length;i++){
var e = this.enemies[i];
var r1 = [
e[0]-this.images.enemies.width/2,
e[0]+this.images.enemies.width/2,
e[1]-this.images.enemies.height/2,
e[1]+this.images.enemies.height/2];
for(var j=0;j<this.projectiles.length;j++){
var p = this.projectiles[j];
var r2 = [p[0], p[0]+world.game.turret.bullet.width, p[1], p[1]+world.game.turret.bullet.width];
if(intersect(r1, r2)){
explosions.push(new Explosion(e[0], e[1], this.images.explosion, partitions, false));
world.game.score.current += world.game.score.level;
this.projectiles.splice(j, 1);
this.enemies.splice(i, 1);
i--;
break;
}
}
}
},
handle_events: function(){
if(this.pressed[37]) this.right();
if(this.pressed[39]) this.left();
if(this.pressed[32]) this.shoot();
if(this.pressed[65]) this.move_left();
if(this.pressed[68]) this.move_right();
if(this.pressed[17]) this.fire_super();
},
handle_elapsed: function(dt){
world.game.elapsed.spawn += dt;
world.game.elapsed.shot += dt;
if(world.game.elapsed.spawn > world.game.enemies.frequency){
this.spawn();
world.game.elapsed.spawn = 0;
}
if(this.nuke.playing){
this.nuke.elapsed += dt;
this.nuke.total += dt;
var sign = 1;
if(this.nuke.total > 500) sign = -1;
if(this.nuke.elapsed > 100){
this.nuke.alpha += 0.2*sign;
this.nuke.elapsed = 0;
}
ctx.globalAlpha = this.nuke.alpha;
ctx.drawImage(
this.images.nuclear,
world.scene.width/2 - this.images.nuclear.width/2,
world.scene.height/2 - this.images.nuclear.height/2
);
ctx.globalAlpha = 1;
if(this.nuke.total > 1000){
this.nuke.playing = false;
this.nuke.elapsed = 0;
this.nuke.total = 0;
this.nuke.alpha = 0;
}
}
},
render_explosions: function(dt){
for(var i=0; i<explosions.length; i++){
if(explosions[i].render(dt)){
explosions.splice(i, 1);
i--;
}
}
}
};
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = world.scene.width;
canvas.height = world.scene.height + world.info.height;
var ctx = canvas.getContext('2d');
var draw_parallax = function(data){
sprite.bg.elapsed += data.dt;
var _angle = sprite.bg.angle * Math.PI / 180 - Math.PI/2;
x = Math.cos(_angle)*world.scene.width/2 - sprite.images.background.width/2 + world.scene.width/2;
y = Math.sin(_angle)*world.scene.height/2 - sprite.images.background.height/2 + world.scene.height/2;
ctx.drawImage(sprite.images.background, x, y);
if(sprite.bg.elapsed>10){
sprite.bg.angle+=0.1;
if(sprite.bg.angle > 360) sprite.bg.angle = 0;
sprite.bg.elapsed = 0;
}
};
var draw_world = function(data){
ctx.fillStyle = world.scene.background;
ctx.fillRect(0,0, world.scene.width, world.scene.height);
ctx.strokeStyle = world.scene.stroke.color;
ctx.lineWidth = world.scene.stroke.thickness;
// Parallax
draw_parallax(data);
// End Parallax
ctx.strokeRect(2, 2, world.scene.width-4, world.scene.height-4);
ctx.fillStyle = world.info.background;
ctx.fillRect(0, world.scene.height, world.scene.width, world.info.height);
ctx.fillStyle = world.info.foreground;
ctx.font = '12pt verdana bold';
ctx.fillText('[S] ' + world.game.score.current, 60, world.scene.height + 20);
ctx.fillText('[T] ' + world.game.score.best, 60, world.scene.height + 40);
ctx.fillText('[L] ' + world.game.score.level, 10, world.scene.height + 20);
ctx.fillText('[H] ', 150, world.scene.height + 20);
ctx.fillText("Sound: " + (world.sound?"On":"Off") , 150, world.scene.height + 40)
ctx.fillStyle = world.game.turret.color;
for(var i=0;i<world.game.score.lives;i++){
ctx.fillRect( 185 + i*22, world.scene.height + 8 , 15, 15);
}
ctx.fillStyle = world.game.enemies.color;
for(var i=0;i<world.game.score.super;i++){
ctx.drawImage(sprite.images.super, 285 + i*30, world.scene.height + 8);
}
};
document.addEventListener('keydown', function(evt){
sprite.pressed[evt.keyCode] = true;
}, true);
document.addEventListener('keyup', function(evt){
sprite.pressed[evt.keyCode] = false;
}, true);
window.requestAnimFrame = function(){
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback){
window.setTimeout(callback, 1000 / 60);
}
);
}();
var Explosion = function(x, y, sheet, partitions, repeat){
this.x = x;
this.y = y;
this.at = 0;
this.elapsed = 0;
this.render = function(dt){
this.elapsed += dt;
if(this.elapsed > 50){
this.elapsed = 0;
this.at += 1;
if(this.at == partitions.length){
if(repeat){
this.at = 0;
}else{
return true;
}
}
}
var offset_x = partitions[this.at][0];
var offset_y = partitions[this.at][1];
var dw = partitions[this.at][2];
var dh = partitions[this.at][3];
ctx.drawImage(
sheet,
offset_x, offset_y,
dw, dh,
this.x - dw/2 , this.y - dh/2,
dw, dh
);
return false;
};
};
var start = new Date();
var last = new Date();
var explosions = [];
var partitions = [
[0, 9, 8, 8],
[15, 6, 14, 14],
[33, 0, 25, 25],
[61, 2, 23, 22],
[86, 3, 21, 20],
[110, 5, 17, 17],
[130, 7, 14, 14],
[147, 9, 11, 10],
[161, 10, 8, 8],
[173, 11, 7, 7]
];
function loop() {
setTimeout(function(){
window.requestAnimFrame(loop);
var now = new Date();
var dt = now - last;
var total = (now - start) / 1000;
last = now;
draw_world({ total: total, dt: dt });
sprite.render();
sprite.render_projectiles();
sprite.render_enemies();
sprite.render_explosions(dt);
sprite.handle_elapsed(dt);
sprite.handle_collision();
sprite.handle_events();
}, 1000/60);
}
var ImageLoader = function(args, callback){
var self = this;
this.loaded = 0;
this.images = {};
for(var entry in args){
var _img = new Image();
this.images[entry] = _img;
_img.onload = function() {
self.loaded +=1;
if(self.loaded == Object.keys(args).length)
callback(self.images);
}
_img.src = args[entry];
}
};
image_map = {
'turret': world.game.turret.url,
'bullet': world.game.turret.bullet.url,
'scene': world.scene.url,
'enemies': world.game.enemies.url,
'explosion': world.game.enemies.explosion,
'nuclear_icon': world.game.turret.bullet.super_url,
'nuclear': world.game.turret.nuclear_url
};
var loader = new ImageLoader(image_map, function(images){
sprite.images.background = images.scene;
sprite.images.turret = images.turret;
sprite.images.bullet = images.bullet;
sprite.images.enemies = images.enemies;
sprite.images.super = images.nuclear_icon;
sprite.images.nuclear = images.nuclear;
sprite.images.explosion = images.explosion;
loop();
});
}
@omaraboumrad

This comment has been minimized.

Copy link
Owner Author

omaraboumrad commented Oct 19, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.