function Spriter:draw( x, y ) local canvas = self:getCanvas() --Only possible to use sprite batch if we used texture packer structure - default is series of disparate images if self.usingTexturePacker then self.spriteBatch:clear() self.spriteBatch:bind() end local frameData = self:getFrameData() --In my engine I had transformations active during rendering --I had to re-set everything to origin to render at origin of canvas --This should be safe --Draw onto off-screen canvas for flipping --I'm sure there's an algorithmic solution to flipping the animation, but --This was easier to me initially --I'm not sure how to cleanly build a bounding rect to create a good canvas size, so I'm just doing screen w/h for now --All graphics operations from this point forward render to canvas instead of screen --Duh --I believe this is the default, but in case it's set elsewhere:w'alpha') --Loop through framedata and render images (bones are also in array) for i = 1, # frameData do local imageData = frameData[i] if imageData.dataType == "image" then local x, y = self:spriterToScreen( imageData.x, imageData.y ), 255, 255) --Pivot data is stored as 0-1, but actually represents an offset of 0-width or 0-height for rotation purposes local pivotX = imageData.pivotX or 0 local pivotY = imageData.pivotY or 1 if not self.usingTexturePacker then --Rescape pivot data from 0,1 to 0,w/h pivotX = rescale( pivotX, 0, 1, 0, imageData.image:getWidth() ) --Love2D has Y inverted from Spriter behavior -- pivotY is height - pivotY value pivotY = imageData.image:getHeight() - rescale( pivotY, 0, 1, 0, imageData.image:getHeight() ), x, y, -imageData.angle, imageData.scale_x, imageData.scale_y, pivotX, pivotY) else assert(imageData.tile, "No imageData.tile") local w, h = imageData.tile.w, imageData.tile.h assert(w and h, "Error getting dimensions of " .. tostring(imageData.tile.fileName)) pivotX = rescale( pivotX, 0, 1, 0, w ) --Love2D has Y inverted from Spriter behavior -- pivotY is height - pivotY value pivotY = h - rescale( pivotY, 0, 1, 0, h ), imageData.tile.quad, x, y, -imageData.angle, imageData.scale_x, imageData.scale_y, pivotX, pivotY) self.spriteBatch:add(imageData.tile.quad, x, y, -imageData.angle, imageData.scale_x, imageData.scale_y, pivotX, pivotY) end end end --Texturepacker rendering overhead if self.usingTexturePacker then self.spriteBatch:unbind() end if self:getDebug() then self:drawDebugInfo() end --Turn off canvas. Graphics operations now apply to screen -- The rectangle from the Canvas was already alpha blended. -- Use the premultiplied blend mode when drawing the Canvas itself to prevent another blending."multiply", 'premultiplied') --Return to transformations active prior to our draw local scaleX, scaleY = self:getScale() local xOffset, yOffset = self:getOffset() local inversionOffset = self:getInversionOffset() x = x + xOffset y = y + yOffset local canvasOffsetX, canvasOffsetY = self:getCanvasOffset() --We offset things in the canvas purely to avoid clipping of the sprite. If we do so, --We have to un-do the offset prior to rendering the canvas x = x - (canvasOffsetX * scaleX) y = y - (canvasOffsetY * scaleY) local inverted = self:getInverted() --I'm sure there's a more elegant way to handle this, but I'm being lazy. --Handle flips by rendering with -1 x scaling if not inverted then, x, y, 0, scaleX, scaleY) else --Need to offset x position due to scaling, x + inversionOffset, y, 0, -scaleX, scaleY) end --Turn default back on'alpha') end --draw