// Light sprite class enyo.kind({ name: "Sprite", published: { x: 0, y: 0, width: 0, height: 0, heading: 0, images: [], index: -1, sound: "" }, // Create component create: function() { this.inherited(arguments); this.halfWidth = this.width/2; this.halfHeight = this.height/2; this.animating = false; }, // Draw the sprite in the canvas context draw: function(ctx) { // Go to pos and heading and draw current image ctx.save(); ctx.translate(this.x, this.y); var rotate = (90-this.heading) * (Math.PI / 180); ctx.rotate(rotate); ctx.translate(-this.halfWidth,-this.halfHeight); var image = document.getElementById(this.images[this.index]); ctx.drawImage(image, 0, 0); ctx.restore(); }, // Compute min rectangle around sprite computeRect: function() { var rotate = (90-this.heading) * (Math.PI / 180); var wc = this.halfWidth*Math.cos(rotate); var hc = this.halfHeight*Math.cos(rotate); var ws = this.halfWidth*Math.sin(rotate); var hs = this.halfHeight*Math.sin(rotate); var sx0 = this.x-wc+hs; var sy0 = this.y-hc+ws; var sx1 = this.x+wc+hs; var sy1 = this.y-hc-ws; var sx2 = this.x+wc-hs; var sy2 = this.y+hc-ws; var sx3 = this.x-wc-hs; var sy3 = this.y+hc+ws; var x0 = Math.min(sx0, Math.min(sx1, Math.min(sx2, sx3))); var y0 = Math.min(sy0, Math.min(sy1, Math.min(sy2, sy3))); var x1 = Math.max(sx1, Math.max(sx1, Math.max(sx2, sx3))); var y1 = Math.max(sy1, Math.max(sy1, Math.max(sy2, sy3))); return { x: x0, y: y0, dx: x1-x0, dy: y1-y0 }; }, // Draw border around sprite drawBorder: function(ctx) { ctx.save(); ctx.strokeStyle = "blue"; var rect = this.computeRect(); ctx.strokeRect(rect.x, rect.y, rect.dx, rect.dy); ctx.restore(); }, // Undraw the sprite: i.e. clear canvas at the sprite pos unDraw: function(ctx) { var rect = this.computeRect(); ctx.clearRect(rect.x, rect.y, rect.dx, rect.dy); }, // Use first image for sprite firstImage: function() { this.index = 0; }, // Use next image for sprite nextImage: function(max) { this.index = this.index + 1; if (max === undefined) max = this.images.length; if (this.index >= max) this.index = 0; }, // Use a specific image useImage: function(index) { this.index = index; }, // Play sound of the sprite playSound: function() { if (this.sound != "") FoodChain.sound.play(this.sound); }, // Test if the sprite intersect another sprite intersect: function(sprite) { var r1 = this.computeRect(); var r2 = sprite.computeRect(); return !(r2.x > (r1.x+r1.dx) || (r2.x+r2.dx) < r1.x || r2.y > (r1.y+r1.dy) || (r2.y+r2.dy) < r1.y); }, // Compute distance between two sprites distance: function(sprite) { var dx = sprite.x-this.x; var dy = sprite.y-this.y; var dist = Math.sqrt(dx*dx+dy*dy); return dist; }, // Animate the sprite using a list of image and a movement animate: function(ctx, images, dx, dy, action) { if (this.animating) return; this.animating = true; this.animation = {ctx: ctx, index: 0, images: images, dx: dx, dy: dy, action: action }; this.animation.job = window.setInterval(enyo.bind(this, "animateTimer"), 50); }, // Timer use of animation animateTimer: function() { // End of animation ? if (this.animation.index == this.animation.images.length) { this.animating = false; window.clearInterval(this.animation.job); return; } // Draw current frame this.unDraw(this.animation.ctx); if (this.animation.dx != undefined) this.x += this.animation.dx; if (this.animation.dy != undefined) this.y += this.animation.dy; this.useImage(this.animation.images[this.animation.index]); this.draw(this.animation.ctx); // HACK: On Android, force redraw of canvas if (enyo.platform.android && document.location.protocol.substr(0,4) != "http") { document.getElementById('acanvas').style.display='none'; document.getElementById('acanvas').offsetHeight; document.getElementById('acanvas').style.display='block'; } // Action to do at each move if (this.animation.action != undefined) { if (!this.animation.action(this)) { this.animating = false; this.animation.index = this.animation.images.length; window.clearInterval(this.animation.job); return; } } // Next frame this.animation.index = this.animation.index + 1; }, });