diff --git a/spine-corona/spine-corona/spine.lua b/spine-corona/spine-corona/spine.lua index da3fb758c..f42c76e7f 100644 --- a/spine-corona/spine-corona/spine.lua +++ b/spine-corona/spine-corona/spine.lua @@ -32,11 +32,7 @@ ------------------------------------------------------------------------------ spine = {} - -if (system.getInfo("environment") == "simulator") then - package.path = package.path .. ";".. system.pathForFile("../") .. "/?.lua" -end - + spine.utils = require "spine-lua.utils" spine.SkeletonJson = require "spine-lua.SkeletonJson" spine.SkeletonData = require "spine-lua.SkeletonData" @@ -51,7 +47,7 @@ spine.AttachmentLoader = require "spine-lua.AttachmentLoader" spine.Animation = require "spine-lua.Animation" spine.AnimationStateData = require "spine-lua.AnimationStateData" spine.AnimationState = require "spine-lua.AnimationState" - + spine.utils.readFile = function (fileName, base) if not base then base = system.ResourceDirectory end local path = system.pathForFile(fileName, base) @@ -61,50 +57,53 @@ spine.utils.readFile = function (fileName, base) io.close(file) return contents end - + local json = require "json" spine.utils.readJSON = function (text) return json.decode(text) end - + spine.Skeleton.failed = {} -- Placeholder for an image that failed to load. - + spine.Skeleton.new_super = spine.Skeleton.new function spine.Skeleton.new (skeletonData, group) -- Skeleton extends a group. local self = spine.Skeleton.new_super(skeletonData) self.group = group or display.newGroup() - + self.images = {} -- createImage can customize where images are found. function self:createImage (attachment) return display.newImage(attachment.name .. ".png") end - + -- updateWorldTransform positions images. local updateWorldTransform_super = self.updateWorldTransform function self:updateWorldTransform () updateWorldTransform_super(self) - - if not self.images then self.images = {} end local images = self.images + local skeletonR, skeletonG, skeletonB, skeletonA = self.r, self.g, self.b, self.a for i,slot in ipairs(self.drawOrder) do local attachment = slot.attachment local image = images[slot] - if not attachment then - -- Attachment is gone, remove the image. - if image and image ~= spine.Skeleton.failed then + if not attachment then -- Attachment is gone, remove the image. + if image then image:removeSelf() images[slot] = nil end else - -- Attachment image has changed. - if image and image.attachment ~= attachment and image ~= spine.Skeleton.failed then - image:removeSelf() - image = nil + if image and image.attachment ~= attachment then -- Attachment image has changed. + if self.modifyImage then + self:modifyImage(image, attachment) + image.lastR, image.lastG, image.lastB, image.lastA = nil, nil, nil, nil + image.attachment = attachment + else -- If no modifier supplied just remove the image and it will be recreated. + image:removeSelf() + images[slot] = nil + image = nil + end end - -- Create new image. - if not image then + if not image then -- Create new image. image = self:createImage(attachment) if image then image.attachment = attachment @@ -115,50 +114,81 @@ function spine.Skeleton.new (skeletonData, group) print("Error creating image: " .. attachment.name) image = spine.Skeleton.failed end - print(slot.data.additiveBlending) - if slot.data.additiveBlending then - image.blendMode = "add" - end + if slot.data.additiveBlending then image.blendMode = "add" end images[slot] = image + if i < self.group.numChildren then + self.group:insert(i, image) + else + self.group:insert(image) + end end -- Position image based on attachment and bone. if image ~= spine.Skeleton.failed then - image.x = slot.bone.worldX + attachment.x * slot.bone.m00 + attachment.y * slot.bone.m01 - image.y = -(slot.bone.worldY + attachment.x * slot.bone.m10 + attachment.y * slot.bone.m11) - image.rotation = -(slot.bone.worldRotation + attachment.rotation) + local flipX, flipY = ((self.flipX and -1) or 1), ((self.flipY and -1) or 1) - -- fix scaling when attachment is rotated 90 degrees + local x = slot.bone.worldX + attachment.x * slot.bone.m00 + attachment.y * slot.bone.m01 + local y = -(slot.bone.worldY + attachment.x * slot.bone.m10 + attachment.y * slot.bone.m11) + if not image.lastX then + image.x, image.y = x, y + image.lastX, image.lastY = x, y + elseif image.lastX ~= x or image.lastY ~= y then + image:translate(x - image.lastX, y - image.lastY) + image.lastX, image.lastY = x, y + end + + local xScale = attachment.scaleX * flipX + local yScale = attachment.scaleY * flipY + -- Fix scaling when attachment is rotated 90 or -90. local rotation = math.abs(attachment.rotation) % 180 if (rotation == 90) then - image.xScale = slot.bone.worldScaleY * attachment.scaleX - image.yScale = slot.bone.worldScaleX * attachment.scaleY + xScale = xScale * slot.bone.worldScaleY + yScale = yScale * slot.bone.worldScaleX else - if (rotation ~= 0 and (slot.bone.worldScaleX ~= 1 or slot.bone.worldScaleY ~= 1)) then + xScale = xScale * slot.bone.worldScaleX + yScale = yScale * slot.bone.worldScaleY + if rotation ~= 0 and xScale ~= yScale and not image.rotationWarning then + image.rotationWarning = true print("WARNING: Non-uniform bone scaling with attachments not rotated to\n" .." cardinal angles will not work as expected with Corona.\n" .." Bone: "..slot.bone.data.name..", slot: "..slot.data.name..", attachment: "..attachment.name) end - image.xScale = slot.bone.worldScaleX * attachment.scaleX - image.yScale = slot.bone.worldScaleY * attachment.scaleY + end + if not image.lastScaleX then + image.xScale, image.yScale = xScale, yScale + image.lastScaleX, image.lastScaleY = xScale, yScale + elseif image.lastScaleX ~= xScale or image.lastScaleY ~= yScale then + image:scale(xScale / image.lastScaleX, yScale / image.lastScaleY) + image.lastScaleX, image.lastScaleY = xScale, yScale end - if self.flipX then - image.xScale = -image.xScale - image.rotation = -image.rotation + rotation = -(slot.bone.worldRotation + attachment.rotation) * flipX * flipY + if not image.lastRotation then + image.rotation = rotation + image.lastRotation = rotation + elseif rotation ~= image.lastRotation then + image:rotate(rotation - image.lastRotation) + image.lastRotation = rotation end - if self.flipY then - image.yScale = -image.yScale - image.rotation = -image.rotation + + local r, g, b, a = skeletonR * slot.r, skeletonG * slot.g, skeletonB * slot.b, skeletonA * slot.a + if image.lastR ~= r or image.lastG ~= g or image.lastB ~= b or not image.lastR then + image:setFillColor(r, g, b) + image.lastR, image.lastG, image.lastB = r, g, b + end + if a and (image.lastA ~= a or not image.lastA) then + image.lastA = a / 255 + image.alpha = image.lastA end - image:setFillColor(self.r * slot.r, self.g * slot.g, self.b * slot.b, self.a * slot.a) - self.group:insert(image) end end end if self.debug then for i,bone in ipairs(self.bones) do - if not bone.line then bone.line = display.newLine(0, 0, bone.data.length, 0) end + if not bone.line then + bone.line = display.newLine(0, 0, bone.data.length, 0) + bone.line:setColor(255, 0, 0) + end bone.line.x = bone.worldX bone.line.y = -bone.worldY bone.line.rotation = -bone.worldRotation @@ -174,18 +204,18 @@ function spine.Skeleton.new (skeletonData, group) else bone.line.yScale = 1 end - bone.line:setColor(255, 0, 0) self.group:insert(bone.line) - if not bone.circle then bone.circle = display.newCircle(0, 0, 3) end + if not bone.circle then + bone.circle = display.newCircle(0, 0, 3) + bone.circle:setFillColor(0, 255, 0) + end bone.circle.x = bone.worldX bone.circle.y = -bone.worldY - bone.circle:setFillColor(0, 255, 0) self.group:insert(bone.circle) end end end - return self end