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
(function() { | |
function $extend(superClass, fields) { | |
function base() { } | |
base.prototype = superClass; | |
var proto = new base(); | |
for (var name in fields) proto[name] = fields[name]; | |
if (fields.toString !== Object.prototype.toString) proto.toString = fields.toString; | |
return proto; | |
} | |
//{ | |
function reset() { | |
entities = [new ClosedChest(320., 180.)]; | |
} | |
function render() { | |
context.clearRect(0, 0, 640, 360); | |
var i = 0; | |
var n = entities.length; | |
var e; | |
while (i < n) { | |
e = entities[i]; | |
if (e.remove > 0 && --e.remove <= 0) { | |
entities.splice(i, 1); | |
n--; | |
} else { | |
e.update(); | |
i++; | |
} | |
} | |
entities.sort(Entity_compareY); | |
context.save(); | |
context.globalAlpha = 0.7; | |
context.fillStyle = "black"; | |
for (i = 0; i < n; i++) { | |
e = entities[i]; | |
var r = e.getShadowSize(); | |
var x = e.x - r; | |
var y = e.y - r / 2; | |
var w = r * 2; | |
var h = r; | |
var x1 = x + w / 2; | |
var y1 = y + h / 2; | |
var x2 = x + w; | |
var y2 = y + h; | |
var xm = w * 0.275892; | |
var ym = h * 0.275892; | |
context.beginPath(); | |
context.moveTo(x1, y); | |
context.bezierCurveTo(x1 + xm, y, x2, y1 - ym, x2, y1); | |
context.bezierCurveTo(x2, y1 + ym, x1 + xm, y2, x1, y2); | |
context.bezierCurveTo(x1 - xm, y2, x, y1 + ym, x, y1); | |
context.bezierCurveTo(x, y1 - ym, x1 - xm, y, x1, y); | |
context.closePath(); | |
context.fill(); | |
} | |
context.restore(); | |
for (i = 0; i < n; i++) { | |
e = entities[i]; | |
if (e.visible) context.drawImage(texture[e.frame], e.x - 32 | 0, e.y - e.z - 42 | 0); | |
} | |
} | |
function main() { | |
var atlas = window.document.createElement("img"); | |
atlas.onload = function() { | |
canvas.width = 640; | |
canvas.height = 360; | |
window.document.body.appendChild(canvas); | |
for (var i = 0; i < 10; i++) { | |
var tex = window.document.createElement("canvas"); | |
tex.width = tex.height = 64; | |
tex.getContext("2d", null).drawImage(atlas, -i * 64, 0); | |
texture.push(tex); | |
} | |
reset(); | |
canvas.addEventListener("mousedown", function(event) { | |
var x = event.offsetX; | |
if (x == null) x = 320.; | |
var y = event.offsetY; | |
if (y == null) y = 180.; | |
var n = entities.length; | |
for (var i1 = 0; i1 < n; i1 += 1) { | |
var e = entities[i1]; | |
var action = e.action; | |
if (action != 0) { | |
var ex = e.x; | |
var ey = e.y; | |
var ez = e.z; | |
var dx = ex - x; | |
var dy = ey - ez - y; | |
if (dx * dx + dy * dy < 1024) { | |
if (action == 1) { | |
entities.splice(i1, 1); | |
var oc = new OpenChest(ex, ey, ez); | |
oc.zspeed = e.zspeed; | |
entities.push(oc); | |
var num = 0 | (10 + Math.random() * 5); | |
while (--num >= 0) { | |
entities.push(new Coin(ex, ey, ez)); | |
} | |
} | |
break; | |
} | |
} | |
} | |
if (i1 >= n) entities.push(new ClosedChest(x, y)); | |
}); | |
window.setInterval(function() { | |
render(); | |
}, 50); | |
} | |
atlas.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAABACAMAAAC9ZDaMAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAFAwccWk/hUww0n0syqwA3r0A374A3bwa374a9ds4/+kA/+oA//862tRe3u7WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjA1oYgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNvyMY98AAAYpSURBVHhe7ZvtYtpIDEU3IU3abhPe/2mzvroSGht/SON0DUHnB8bDXJnRnNSFtP98fmOeFT1NouEBHSjCPCl6ukIJuIiGB3SgCKP+3b+AakCHAkj9VnoqeLovD5B7PH0h3vn8MnA6bUtYAi5QAvZyQwJyA/ZsnhowKKDDIdqkgTF9OcBcXl8Kguv9K+Su3IIk0NO7AMqdTufzxwcU3JawBJylBOzlSwXU9Xe3T/dONj9XZY8A11ny+hqtMV8h8w5MPiPfQ9TQC6flN1AD6On/xNPTywuk+xh4ecHNeE3CEnCGEnAPXybgvgY8P7+/a3zgdSCzgRoTkAWxvGVfX98VpuPvYaqfryP6DuSCAuT78yevILrX9i+XJvsF7gMCngZMQrAsYQl4RQm4j78g4I8f2SWwgUT3IixgK4BGlUgFpqf6GdsVrvUDeBbLo4JcSulR0Lrn149nnaMEdAVdwuUPJCXghBJwP18iYKvQ1wiYEQhoaMR2BeTH+v38KVEhlufV8ahlBuJ5m8mjKxjvYds9I542vEo+uw8XELQS4uuZsYIl4IQScD9fLmD2o/xUP+R51AkruAAtvp3rNXDlpdsv2crb1fGoZQR7R1trsJXKZCWrIFbR9hBEs45XyGShi6ODaVxBHlELEsrQcKbTBkrAESWgeHdBB9PcjIC6A7ohkSrIUoExtqXrNdp3zflTtvK4NgXUMgLHtvOowFkyWYF8+LGIdhGraFcColnHK0Sz0ISKGBjRF1OYgLjtSqEB1OYXMq2CJeCIElBcufBwAlpSQiOiAtoN+Ncvzp+ylRf/BtlYhXCMCm6tYU5AwEqxPqILbf9BLNniFWJZ3CQhDBFnhD4JoZuW0lo42lkJuEAJaIgzwuECop2Z5XMTLUtim+dXldCIqIBLeWMrL6b9brcf5/xQsp1HBc7Co6OlOgTEdUks6/gaYsmxgEC8EXISYjbydgSogg8hJeBGXva6BBSgCoFKOi2AiWdHgCrdAuYWb5vIDSNUYrsKryqRCbaxOnERVJDALJE8fnhwNVl8IwDWE+nDtYKsBGJ95BqY8C7Gsk5OQNOP/5i+BcJAHuikk1fALFRCBmmcS5mBEjCULwHHQJiDBYw2jrD13DADVTLNnwIteNRpi9jGuwDZX8Vx1bie6cfV4BhZQ6seYD0QywPvvncjmjV6BKSEYw0h39xXyNdQPpsLWMElpIIY0UgJOKUEBDchoLUuL6Btl8EqsRouoG9kXD/gCk5ViL8DYmvgeuJ/EWmvq6UGcBavoKEBKTMQzRpt/3RoBSgCeagJHgk/OjhLCkKy84BOO+G5J01CCtjWKAGvKAFvRkCjT0DbPlMq3vxWIZMPxCpMtXPi7wAbr4u4EO9Bu/WmEs90wiZHCMjbLiSkgHZuCpElBds85yHD/6DJGpRwmi8BZygB8exwAbXvsv2ZxU+TPRWQmJLZvusKGNOXA/gajEzaVqAGDchbSPYAKc/m0sDXEEny4wPl4dGeu3xgWUCJX/JI2bnpiDNIqBGhBJylBKQueLw7AT0rfRPyzdOgktMHIKHhjjTztg480+Ew05totobnZQkD+Q7w3ccFpDI48qsX6mcSmUbLAk7zmG/Y+TRfAi6ATAl4pwIi/fYmXVN6NtAEym6dgyTQ0w725JGkQH01LA3e3no6qBuYEBBAFcrCI8cpD1gTEEi8ybfygRIwwZ48kiVge+TrHQL2tQ+geTjqYBIp0Zm9DfasoNW3bwd0A9O3YAPSQB88Uh7MWRNQgwpy9uX0Ur4E/KvsWcGDC8jm4Q//PgFJX+sKgu7t6T1+/EFUwI8P6AJxIAp1Em8urAvYky8Bbxh074EFBPtaUBwLdy+2f/iCGMIAE+haIfy6bUnAvnwJ+I3h7t21gMUj0UqkxshNk9jovICgJ18CFhdKwOJwINFYGz7aCF7XqbNk8yVgMSIr0JRsvgQsrqBEBOJE5TMy+RKwuCIj0ByZfAlYzAJZcOPMymdE8yVgMUtUoCWi+RKwWIQS5eUzIvkSsFgkItAakXwJWKyyJk+ErXwJWKxSAhbfmhKwOJQSsDiUErA4lBKwOJQSsDiUErA4lBKwOJQSsDiUErA4kM/P/wAXdPS9Q8I7oAAAAABJRU5ErkJggg=="; | |
} | |
//} | |
//{ Entity | |
function Entity_compareY(a, b) { | |
if (a.y < b.y) { | |
return -1; | |
} else if (a.y > b.y) return 1; else return 0; | |
} | |
function Entity(x, y, z) { | |
this.visible = true; | |
this.flicker = 0; | |
this.remove = 0; | |
this.action = 0; | |
this.gravity = 1.0; | |
this.friction = 0.3; | |
this.zspeed = 0; | |
this.yspeed = 0; | |
this.xspeed = 0; | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
} | |
Entity.prototype = { | |
update: function() { | |
if (this.flicker > 0 && --this.flicker <= 0) { | |
this.visible = !this.visible; | |
this.flicker = 2; | |
} | |
this.x += this.xspeed; | |
this.y += this.yspeed; | |
var xyspeed = Math.sqrt(this.xspeed * this.xspeed + this.yspeed * this.yspeed); | |
if (xyspeed > 0) { | |
var mul = Math.max(0, xyspeed - this.friction) / xyspeed; | |
this.xspeed *= mul; | |
this.yspeed *= mul; | |
} | |
if (this.z > 0) this.zspeed -= this.gravity; | |
this.z += this.zspeed; | |
if (this.z < 0) { | |
if (this.zspeed < 0) this.zspeed = -this.zspeed * 0.6 - 0.7; | |
if (this.zspeed < 1) { | |
this.zspeed = 0; | |
this.z = 0; | |
} else this.z = -this.z; | |
} | |
}, | |
getShadowSize: function() { | |
return 24 / (1 + this.z / 20); | |
} | |
} | |
//} | |
//{ Coin | |
function Coin(x, y, z) { | |
Entity.call(this, x, y, z); | |
this.frame = 0 | (Math.random() * 8); | |
this.remove = 40; | |
this.flicker = 20; | |
var dir = Math.random() * Math.PI * 2; | |
var len = 8 + Math.random() * 2; | |
this.xspeed = Math.cos(dir) * len; | |
this.yspeed = Math.sin(dir) * len; | |
this.zspeed = 8; | |
} | |
Coin.prototype = $extend(Entity.prototype, { | |
update: function() { | |
Entity.prototype.update.call(this); | |
this.frame = (this.frame + 1) % 8; | |
}, | |
getShadowSize: function() { | |
return 12 / (1 + (this.z + Math.cos(this.frame / 8 * 2 * Math.PI)) / 20); | |
} | |
}); | |
//} | |
//{ ClosedChest | |
function ClosedChest(x, y) { | |
Entity.call(this, x, y, 64); | |
this.zspeed = -16; | |
this.frame = 8; | |
this.action = 1; | |
} | |
ClosedChest.prototype = $extend(Entity.prototype, { }); | |
//} | |
//{ OpenChest | |
function OpenChest(x, y, z) { | |
Entity.call(this, x, y, z); | |
this.frame = 9; | |
this.remove = 50; | |
this.flicker = 30; | |
} | |
OpenChest.prototype = $extend(Entity.prototype, { }); | |
//} | |
var canvas = window.document.createElement("canvas"); | |
var context = canvas.getContext("2d", null); | |
var texture = []; | |
var entities; | |
main(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment