Last active
December 23, 2016 05:23
-
-
Save omaraboumrad/7057538 to your computer and use it in GitHub Desktop.
sprite management w/ sample
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
window.onload = init; | |
function init(){ | |
// -- Sprite Management Api -- // | |
var rectangular_intersection = function(r1, r2){ | |
var t1 = [r1[0], r1[0] + r1[2], r1[1], r1[1] + r1[3]]; | |
var t2 = [r2[0], r2[0] + r2[2], r2[1], r2[1] + r2[3]]; | |
return !(t2[0] > t1[1] || | |
t2[1] < t1[0] || | |
t2[2] > t1[3] || | |
t2[3] < t1[2]); | |
}; | |
var ImageLoader = function(args, callback){ | |
// Usage: new ImageLoader({ | |
// 'img1':'/url/to/img1', | |
// 'img2':'/url/to/img2',}, cb); | |
// Returns: {'img1': [Image], 'img2': [Image]} | |
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]; | |
} | |
}; | |
var SpriteGroup = function(){ | |
var self = this; | |
this.children = []; | |
this.render = function(args){ | |
for(var i=0;i<this.children.length;i++){ | |
this.children[i].render(args); | |
} | |
}; | |
this.add = function(sprite){ | |
this.children.push(sprite); | |
}; | |
this.remove_index = function(index){ | |
this.children.splice(index, 1); | |
} | |
this.remove = function(sprite){ | |
for(var i=0;i<this.children.length;i++){ | |
if(this.children[i] == sprite){ | |
this.children.splice(i, 1); | |
break; | |
} | |
} | |
} | |
this.collides_with_sprite = function(sprite, callback){ | |
var collisions = []; | |
for(var i=0;i<this.children.length;i++){ | |
var target = this.children[i]; | |
if(target.collides_with(sprite)){ | |
collisions.push(target); | |
if(callback) callback(target); | |
} | |
} | |
return collisions; | |
} | |
this.collides_with_group = function(group, callback){ | |
var _source_collisions = []; | |
var _target_collisions = []; | |
for(var i=0;i<group.children.length;i++){ | |
var sprite = group.children[i]; | |
var _collisions = self.collides_with_sprite(sprite, callback); | |
if(_collisions.length){ | |
_source_collisions.push(sprite); | |
for(var j=0; j<_collisions.length;j++) | |
if(_target_collisions.indexOf(_collisions[j])==-1) | |
_target_collisions.push(_collisions[j]); | |
} | |
} | |
return [_target_collisions, _source_collisions]; | |
}; | |
}; | |
var Sprite = function(args){ | |
var self = this; | |
this.x = args.x || 0; | |
this.y = args.y || 0; | |
this.width = args.width || 0; | |
this.height = args.height || 0; | |
this.image = args.image; | |
this.render = args.render; | |
if(args.group) args.group.add(this); | |
this.rect = function() { | |
var target = self.image || args; | |
return [ | |
this.x, | |
this.y, | |
target.width, | |
target.height]; | |
}; | |
this.collides_with = function(sprite){ | |
return rectangular_intersection( | |
self.rect(), | |
sprite.rect()); | |
}; | |
}; | |
// -- Sample -- // | |
var canvas = document.createElement('canvas'); | |
canvas.width = 400; | |
canvas.height = 400; | |
document.body.appendChild(canvas); | |
var ctx = canvas.getContext('2d'); | |
var player1 = new Sprite({ | |
x: 10, | |
y: canvas.height/2, | |
width: 10, | |
height: 10, | |
render: function(args){ | |
ctx.fillStyle = '#FF0000'; | |
ctx.fillRect.apply(ctx, this.rect()); | |
} | |
}); | |
var player2 = new Sprite({ | |
x: canvas.width - 10, | |
y: canvas.height/2, | |
width: 10, | |
height: 10, | |
render: function(args){ | |
ctx.fillStyle = '#0000FF'; | |
ctx.fillRect.apply(ctx, this.rect()); | |
} | |
}); | |
var player3 = new Sprite({ | |
x: canvas.width/2 , | |
y: canvas.height -10, | |
width: 10, | |
height: 10, | |
render: function(args){ | |
ctx.fillStyle = '#00FF00'; | |
ctx.fillRect.apply(ctx, this.rect()); | |
} | |
}); | |
var player4 = new Sprite({ | |
x: canvas.width/2 , | |
y: 10, | |
width: 10, | |
height: 10, | |
render: function(args){ | |
ctx.fillStyle = '#FFFF00'; | |
ctx.fillRect.apply(ctx, this.rect()); | |
} | |
}); | |
function get_random_color() { | |
var letters = '0123456789ABCDEF'.split(''); | |
var color = '#'; | |
for (var i = 0; i < 6; i++ ) { | |
color += letters[Math.round(Math.random() * 15)]; | |
} | |
return color; | |
} | |
function generate_dot(color, group, x, y, from_angle, to_angle){ | |
var s = new Sprite({ | |
x: x, | |
y: y, | |
width: 5, | |
height: 5, | |
group:group, | |
render:function(args){ | |
var v = 2; | |
var _angle = this.angle * Math.PI / 180 - Math.PI/2; | |
this.x += v * Math.cos(_angle); | |
this.y += v * Math.sin(_angle); | |
if(this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height){ | |
group.remove(s); | |
survived += 1; | |
}else{ | |
ctx.fillStyle = color; | |
ctx.beginPath(); | |
ctx.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI, false); | |
ctx.fillStyle = color; | |
ctx.fill(); | |
} | |
} | |
}); | |
s.angle = from_angle + Math.random()*(to_angle-from_angle); | |
} | |
var p1_dots = new SpriteGroup(); | |
var p2_dots = new SpriteGroup(); | |
var p3_dots = new SpriteGroup(); | |
var p4_dots = new SpriteGroup(); | |
var survived = 0; | |
var generated = 0; | |
var start = new Date(); | |
var last = new Date(); | |
var elapsed = 0; | |
function loop() { | |
setTimeout(function(){ | |
window.requestAnimationFrame(loop); | |
var now = new Date(); | |
var dt = now - last; | |
var total = (now - start) / 1000; | |
last = now; | |
elapsed += dt; | |
ctx.fillStyle = '#FFFFFF'; | |
ctx.fillRect(0,0, canvas.width, canvas.height); | |
//if(elapsed > 10){ | |
// elapsed = 0; | |
generate_dot('#FF0000', p1_dots, player1.x, player1.y, 45 , 135); | |
generate_dot('#0000FF', p2_dots, player2.x, player2.y, 225, 315); | |
generate_dot('#00FF00', p3_dots, player3.x, player3.y, -45, 45); | |
generate_dot('#FFFF00', p4_dots, player4.x, player4.y, 135, 225); | |
generated += 4; | |
//} | |
var p1_p2_collisions = p1_dots.collides_with_group(p2_dots); | |
var p1_p3_collisions = p1_dots.collides_with_group(p3_dots); | |
var p1_p4_collisions = p1_dots.collides_with_group(p4_dots); | |
var p2_p3_collisions = p2_dots.collides_with_group(p3_dots); | |
var p2_p4_collisions = p2_dots.collides_with_group(p4_dots); | |
var p3_p4_collisions = p3_dots.collides_with_group(p4_dots); | |
for(var i=0;i<p1_p2_collisions[0].length;i++) p1_dots.remove(p1_p2_collisions[0][i]); | |
for(var i=0;i<p1_p2_collisions[1].length;i++) p2_dots.remove(p1_p2_collisions[1][i]); | |
for(var i=0;i<p2_p3_collisions[0].length;i++) p2_dots.remove(p2_p3_collisions[0][i]); | |
for(var i=0;i<p2_p3_collisions[1].length;i++) p3_dots.remove(p2_p3_collisions[1][i]); | |
for(var i=0;i<p1_p3_collisions[0].length;i++) p1_dots.remove(p1_p3_collisions[0][i]); | |
for(var i=0;i<p1_p3_collisions[1].length;i++) p3_dots.remove(p1_p3_collisions[1][i]); | |
for(var i=0;i<p1_p4_collisions[0].length;i++) p1_dots.remove(p1_p4_collisions[0][i]); | |
for(var i=0;i<p1_p4_collisions[1].length;i++) p4_dots.remove(p1_p4_collisions[1][i]); | |
for(var i=0;i<p2_p4_collisions[0].length;i++) p2_dots.remove(p2_p4_collisions[0][i]); | |
for(var i=0;i<p2_p4_collisions[1].length;i++) p4_dots.remove(p2_p4_collisions[1][i]); | |
for(var i=0;i<p3_p4_collisions[0].length;i++) p3_dots.remove(p3_p4_collisions[0][i]); | |
for(var i=0;i<p3_p4_collisions[1].length;i++) p4_dots.remove(p3_p4_collisions[1][i]); | |
player1.render(); | |
player2.render(); | |
player3.render(); | |
player4.render(); | |
p1_dots.render(); | |
p2_dots.render(); | |
p3_dots.render(); | |
p4_dots.render(); | |
ctx.fillStyle = 'black'; | |
ctx.fillText('Generated : ' + generated, 10,10); | |
ctx.fillText('Survived : ' + survived + ' ( ' + Math.floor(survived/generated * 100)+'% )', 10,30); | |
}, 1000/60); | |
} | |
loop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Click to run on jsfiddle