var assetsPath = "assets/"+conf.assets; var commonPath = "assets/common"; var assets = { imgs: { player: new ImageSource("theme:player"), player_flipped: new ImageSource("theme:player_flipped"), background: new ImageSource("background", null, ".jpg"), wall: new ImageSource("wall"), wall_overlap: new ImageSource("wall-overlap"), }, audio: { hurt: new AudioSource("audio/hurt"), loss: new AudioSource("audio/loss"), flap: new AudioSource("audio/flap"), chomp: new AudioSource("audio/chomp"), }, soundtracks: { soundtrack1: new AudioSource("soundtracks/track1"), soundtrack2: new AudioSource("soundtracks/track2"), soundtrack3: new AudioSource("soundtracks/track3"), }, }; /* * Audio source. */ function AudioSource(src, ext) { makeEventListener(this); var ext = ext || ".mp3"; this.elems = []; for (var i = 0; i < 10; ++i) this.elems[i] = new Audio(commonPath+"/"+src+ext); this.ready = false; this.index = 0; this.elems[0].addEventListener("canplaythrough", function() { if (this.ready) return; this.ready = true; this.emit("load"); }.bind(this)); this.elems[0].addEventListener("ended", function() { this.emit("ended"); }.bind(this)); this.elems[0].onerror = function() { console.error("Error with", src); } } AudioSource.prototype.play = function() { this.elems[this.index++].play(); this.index %= this.elems.length; } AudioSource.prototype.pause = function() { for (var i in this.elems) this.elmes[i].pause(); } /* * Image source. */ function ImageSource(src, frameh, ext) { var ext = ext || ".png"; if (src.indexOf("theme:") == 0) { src = assetsPath+"/images/"+src.split(":")[1]; } else { src = commonPath+"/images/"+src; } this.img = document.createElement("img"); this.ready = false; this.width = 0; this.height = 0; this.frameh = frameh == null ? -1 : frameh; this.steps = 1; this.img.onload = function() { this.ready = true; this.width = this.img.width; this.height = this.img.height; if (this.frameh === -1) this.frameh = this.height; this.steps = this.height / this.frameh; if (this.steps !== Math.round(this.steps)) { this.steps = Math.round(this.steps); console.log( "Warning: '"+src+ext+"': "+ "Height isn't evenly divisible by frame height. "+ "Height: "+this.height+", frame height: "+this.frameh); } }.bind(this); this.img.src = src+ext this.img.onerror = function() { console.error("error with", src); } } ImageSource.prototype.draw = function(ctx, step) { if (!step) step = 0; if (!this.ready) return; ctx.drawImage(this.img, 0, this.frameh * step, this.width, this.frameh, 0, 0, this.width, this.frameh); } function Animation(imgSrc, type, loop, fps) { this.type = type || "forward"; this.loop = loop || false; this.imgSrc = imgSrc; this.fps = fps || 12; this.waitTime = 1000 / this.fps; this.doStep = false; if (type === "forward" || type === "bounce") { this.step = 0; this.direction = 1; } else if (type === "reverse" || type === "bounce-reverse") { this.step = -1; this.direction = -1; } // We don't care about the direction after setting this.direction if (this.type === "bounce-reverse") this.type = "bounce"; else if (this.type === "reverse") this.type = "forward"; } Animation.prototype.nextFrame = function() { if (!this.imgSrc.ready) { return; } else if (this.step === -1) { this.step = this.imgSrc.steps - 1; return; } else if (this.imgSrc.steps === 1) { return; } var next = this.step + this.direction; if (next < 0 || next > this.imgSrc.steps - 1) { if (this.loop) { if (this.type === "bounce") { this.direction = -this.direction; next = this.step + this.direction; } else if (this.type === "forward") { if (next < 0) next = this.imgSrc.steps - 1; else next = 0; } } else { this.doStep = false; return; } } this.step = next; } Animation.prototype.draw = function(ctx) { if (!this.imgSrc.ready) return; this.imgSrc.draw(ctx, this.step); if (this.doStep) { this.nextFrame(); this.doStep = false; setTimeout(function() { this.doStep = true; }.bind(this), this.waitTime); } } Animation.prototype.play = function() { if (this.step !== -1) this.step = 0; this.doStep = true; } Animation.prototype.setStep = function(step) { if (step > this.imgSrc.steps - 1) this.step = this.imgSrc.steps - 1; else if (step < 0) this.step = 0; else this.step = step; }