wayfinder Posted July 14, 2014 Share Posted July 14, 2014 Ahh! The dragon changes the pivot point of its elements, which is never given over to the bridge... Quote Link to comment Share on other sites More sharing options...
wayfinder Posted July 14, 2014 Share Posted July 14, 2014 Found another little bug about the stripping of the file extension. changes:dragonBones.makeBonesAtlas = function (atlasJson, name, partsList) { var bonesAtlas = {}; bonesAtlas.name = name; bonesAtlas.SubTexture = []; var subTextures = atlasJson.frames; var n = partsList.length; var k = subTextures.length; var partName; var txData; var filename; var subTexture; var frame; var hasExtension = false; for (var i = 0; i < n; i++) { partName = partsList[i]; hasExtension = partName.match(/.png/i) !== null; if(hasExtension){ filename = partName; partName = partName.slice(0, -4); } else { filename = partName + ".png"; } for (var j = 0; j < k; j++) { txData = subTextures[j]; if (txData.filename === filename) { frame = txData.frame; subTexture = {name: partName}; subTexture.x = frame.x; subTexture.y = frame.y; subTexture.width = frame.w; subTexture.height = frame.h; bonesAtlas.SubTexture[i] = subTexture; break } } } return bonesAtlas}; PhaserBonesFactory.prototype._generateDisplay = function (textureAtlas, frameName, pivotX, pivotY) { //get reference to the image object var imageRef = textureAtlas.image; //fetch the id of the atlas image var imgName = textureAtlas.atlasId; //create a sprite var image = new Phaser.DragonBonesSprite(dragonBones.game, 0, 0, imgName); //set the sprite frame from the texture atlas image.animations.loadFrameData(image.game.cache.getFrameData(imgName)); //and the frameName... (restoring the .png that was stripped earlier) image.frameName = frameName;// + ".png"; //set anchor point // image.anchor.setTo(pivotX / image.width, pivotY / image.height); image.pivot.setTo(pivotX, pivotY); return image }; Quote Link to comment Share on other sites More sharing options...
klanco Posted July 15, 2014 Share Posted July 15, 2014 This look awesome! I was hoping someone to port the Dragon Bones JS version to Pixi.js. I would love to see how this works on mobile (without an accelerator of course)! Can I ask you if does this support nested skeletons like the Create.js counterpart? Quote Link to comment Share on other sites More sharing options...
alex_h Posted July 15, 2014 Author Share Posted July 15, 2014 I've only been using it on mobile with a single armature but so far it works just fine for me. The Pixi support is ported directly from the create.js factory so it should support any features that the create.js one does (minus the skewing for now, as discussed above!) Quote Link to comment Share on other sites More sharing options...
klanco Posted July 17, 2014 Share Posted July 17, 2014 That sounds impressive, I'll check it out whenever I can.I've been making some things with Create js + dragonbones+ cocoonjs, with Cocoonjs everything was alright, but in mobile browsers performance was very slow. I was hoping someone to port the library to pixi because it's really fast on browsers. Quote Link to comment Share on other sites More sharing options...
wayfinder Posted July 27, 2014 Share Posted July 27, 2014 I've been working with this some more, and other than the support for changing pivots that's not in there yet, tints also don't work yet. What DOES work however is turning bones on and off per keyframe! Quote Link to comment Share on other sites More sharing options...
wayfinder Posted August 7, 2014 Share Posted August 7, 2014 Found another little bug in phaser_dragonbones.js: getChildIndex() --> getIndex() PhaserDisplayBridge.prototype.setDisplay = function (value) { if (this._display == value) { return } if (this._display) { var parent = this._display.parent; if (parent) { var index = this._display.parent.getIndex(this._display) } this.removeDisplay() } this._display = value; this.addDisplay(parent, index) }; Quote Link to comment Share on other sites More sharing options...
wayfinder Posted August 8, 2014 Share Posted August 8, 2014 And here's how to make tints work: PhaserDisplayBridge.prototype.updateColor = function (aOffset, rOffset, gOffset, bOffset, aMultiplier, rMultiplier, gMultiplier, bMultiplier) { if (this._display) { this._display.alpha = aMultiplier; this._display.tint = Phaser.Color.getColor(255 * (rMultiplier + (rOffset / 100)), 255 * (gMultiplier + (gOffset / 100)), 255 * (bMultiplier + (bOffset / 100))); } }; Quote Link to comment Share on other sites More sharing options...
wayfinder Posted November 10, 2014 Share Posted November 10, 2014 Apparently Pixi2.0 broke this, at least my implementation of it. Investigating... Quote Link to comment Share on other sites More sharing options...
alex_h Posted November 10, 2014 Author Share Posted November 10, 2014 PIXI.DisplayObject.prototype.updateTransform was one of the things that got changed in Pixi 2.0, so perhaps some of the changes you made for skewing support are no longer compatible. Quote Link to comment Share on other sites More sharing options...
wayfinder Posted November 12, 2014 Share Posted November 12, 2014 Looks like some fixes were made to updateTransform in pixi 2.1, gonna wait until that trickles down into phaser before tackling the issue (if it still presents itself) Quote Link to comment Share on other sites More sharing options...
wayfinder Posted November 13, 2014 Share Posted November 13, 2014 *sigh* unfortunately, I'll have to go bughunt (phaser 2.2.0 rc5 has all these latest pixi changes implemented and my stuff still looks wrong). I'll keep this thread updated with what I find Quote Link to comment Share on other sites More sharing options...
wayfinder Posted November 13, 2014 Share Posted November 13, 2014 Has your implementation suffered, btw? Quote Link to comment Share on other sites More sharing options...
TheTrope Posted November 13, 2014 Share Posted November 13, 2014 I'll be glad to work on it too.I really want to use skeletal animations in Phaser, but the examples are broken :/Maybe i can help you . I worked a lot on the updateTransform function ( here)Can you share your current version ? I'll try to track bugs too.Please keep that thread updated Quote Link to comment Share on other sites More sharing options...
alex_h Posted November 13, 2014 Author Share Posted November 13, 2014 Hi, I just did a quick test with PIXI 2.1 and the armature was animated as normal for me. Here is the adapter code I'm using, it's more or less the same as in my original post I thinkvar __extends = this.__extends || function (d, { for (var p in if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } __.prototype = b.prototype; d.prototype = new __();};var dragonBones;(function (dragonBones) { (function (display) { var PixiDisplayBridge = (function () { function PixiDisplayBridge() { } PixiDisplayBridge.prototype.getVisible = function () { return this._display ? this._display.visible : false; }; PixiDisplayBridge.prototype.setVisible = function (value) { if (this._display) { this._display.visible = value; } }; PixiDisplayBridge.prototype.getDisplay = function () { return this._display; }; PixiDisplayBridge.prototype.setDisplay = function (value) { if (this._display == value) { return; } var index = -1; if (this._display) { var parent = this._display.parent; if (parent) { index = this._display.parent.children.indexOf(this._display); } this.removeDisplay(); } this._display = value; this.addDisplay(parent, index); }; PixiDisplayBridge.prototype.dispose = function () { this._display = null; }; PixiDisplayBridge.prototype.updateTransform = function (matrix, transform) { this._display.x = matrix.tx; this._display.y = matrix.ty; this._display.rotation = transform.skewX; this._display.scale.x = transform.scaleX; this._display.scale.y = transform.scaleY; }; PixiDisplayBridge.prototype.updateColor = function (aOffset, rOffset, gOffset, bOffset, aMultiplier, rMultiplier, gMultiplier, bMultiplier) { if (this._display) { this._display.alpha = aMultiplier; } }; PixiDisplayBridge.prototype.addDisplay = function (container, index) { var parent = container; if (parent && this._display) { if (index < 0) { parent.addChild(this._display); } else { parent.addChildAt(this._display, Math.min(index, parent.children.length)); } } }; PixiDisplayBridge.prototype.removeDisplay = function () { if (this._display && this._display.parent) { this._display.parent.removeChild(this._display); } }; PixiDisplayBridge.RADIAN_TO_ANGLE = 180 / Math.PI; return PixiDisplayBridge; })(); display.PixiDisplayBridge = PixiDisplayBridge; })(dragonBones.display || (dragonBones.display = {})); var display = dragonBones.display; (function (textures) { var PixiTextureAtlas = (function () { function PixiTextureAtlas(image, textureAtlasRawData, scale) { if (typeof scale === "undefined") { scale = 1; } this._regions = {}; this.image = image; this.scale = scale; this.parseData(textureAtlasRawData); } PixiTextureAtlas.prototype.dispose = function () { this.image = null; this._regions = null; }; PixiTextureAtlas.prototype.getRegion = function (subTextureName) { return this._regions[subTextureName]; }; PixiTextureAtlas.prototype.parseData = function (textureAtlasRawData) { var textureAtlasData = dragonBones.objects.DataParser.parseTextureAtlasData(textureAtlasRawData, this.scale); this.name = textureAtlasData.__name; delete textureAtlasData.__name; for (var subTextureName in textureAtlasData) { this._regions[subTextureName] = textureAtlasData[subTextureName]; } }; return PixiTextureAtlas; })(); textures.PixiTextureAtlas = PixiTextureAtlas; })(dragonBones.textures || (dragonBones.textures = {})); var textures = dragonBones.textures; (function (factorys) { var PixiFactory = (function (_super) { __extends(PixiFactory, _super); function PixiFactory() { _super.call(this); } PixiFactory.prototype._generateArmature = function () { var armature = new dragonBones.Armature(new PIXI.DisplayObjectContainer()); return armature; }; PixiFactory.prototype._generateSlot = function () { var slot = new dragonBones.Slot(new display.PixiDisplayBridge()); return slot; }; PixiFactory.prototype._generateDisplay = function (textureAtlas, fullName, pivotX, pivotY) { var texture = PIXI.Texture.fromFrame(fullName + ".png"); //pixi sprite var image = new PIXI.Sprite(texture); image.pivot.x = pivotX; image.pivot.y = pivotY; // return image; }; return PixiFactory; })(factorys.BaseFactory); factorys.PixiFactory = PixiFactory; })(dragonBones.factorys || (dragonBones.factorys = {})); var factorys = dragonBones.factorys;})(dragonBones || (dragonBones = {}));/* generate a dragonbones atlas out of a TexturePacker JSONArray or Hash format atlas */dragonBones.parseJSONAtlas = function(atlasJson,name,partsList){ var bonesAtlas = {}; bonesAtlas.name = name; bonesAtlas.SubTexture = []; var n = partsList.length; var subTextures = atlasJson.frames; var isArray = Array.isArray(subTextures); var k = 0; if(isArray) k = subTextures.length; // var partName; var txData; var filename; var hasExtension; function createFrame(txData, p_partName){ var frame = txData.frame; //make a subTexture var subTexture = {name:p_partName}; subTexture.x = frame.x; subTexture.y = frame.y; subTexture.width = frame.w; subTexture.height = frame.h; // bonesAtlas.SubTexture[i] = subTexture; } for(var i = 0; i < n; i++){ partName = partsList[i]; hasExtension = partName.match(/.png/i) !== null; if(hasExtension){ filename = partName; partName = filename.substr(-4); } else { filename = partName + ".png"; } //find the subtexture if(isArray){ for(var j = 0; j < k; j++){ txData = subTextures[j]; if(txData.filename == filename){ createFrame(txData, partName); break; } } } else { for(var s in subTextures){ if(s == filename){ createFrame(subTextures[s], partName); break; } } } } return bonesAtlas;};dragonBones.makeArmaturePIXI = function(config, skeletonJSON, atlasJson, texture){ var skeletonId = config.skeletonId; var armatureName = config.armatureName; var animationId = config.animationId; var partsList = config.partsList; var textureData = dragonBones.parseJSONAtlas(atlasJson,skeletonId,partsList); var factory = new dragonBones.factorys.PixiFactory(); factory.addSkeletonData(dragonBones.objects.DataParser.parseSkeletonData(skeletonJSON)); var atlas = new dragonBones.textures.PixiTextureAtlas(texture, textureData); factory.addTextureAtlas(atlas); var armature = factory.buildArmature(armatureName,animationId,skeletonId); //updateAnimation(); dragonBones.animation.WorldClock.clock.add(armature); armature.animation.gotoAndPlay(animationId, 0); return armature;} Quote Link to comment Share on other sites More sharing options...
wayfinder Posted December 2, 2014 Share Posted December 2, 2014 I finally, finally had the time to look at this properly - very simple fix for me: Phaser.DragonBonesSprite.prototype.updateTransform = function(matrix, transform){ var parentTransform = this.parent.worldTransform; var worldTransform = this.worldTransform; var px = this.pivot.x; var py = this.pivot.y; var a00 = this.scale.x * Math.cos(this.rotation + this.skewY), a01 = this.scale.y * Math.sin(-this.rotation - this.skewX), a10 = this.scale.x * Math.sin(this.rotation + this.skewY), a11 = this.scale.y * Math.cos(this.rotation + this.skewX), a02 = this.position.x - a00 * px - py * a01, a12 = this.position.y - a11 * py - px * a10, b00 = parentTransform.a, b01 = parentTransform.c, b10 = parentTransform.b, b11 = parentTransform.d; worldTransform.a = b00 * a00 + b01 * a10; worldTransform.c = b00 * a01 + b01 * a11; worldTransform.tx = b00 * a02 + b01 * a12 + parentTransform.tx; worldTransform.b = b10 * a00 + b11 * a10; worldTransform.d = b10 * a01 + b11 * a11; worldTransform.ty = b10 * a02 + b11 * a12 + parentTransform.ty; this.worldAlpha = this.alpha * this.parent.worldAlpha; }; Quote Link to comment Share on other sites More sharing options...
alex_h Posted December 2, 2014 Author Share Posted December 2, 2014 Wow, and that updateTransform supports skewing as well as rotation does it? Quote Link to comment Share on other sites More sharing options...
wayfinder Posted December 2, 2014 Share Posted December 2, 2014 yup Quote Link to comment Share on other sites More sharing options...
alex_h Posted December 2, 2014 Author Share Posted December 2, 2014 I can't believe how simple it looks after all the complicated stuff we were trying before! Quote Link to comment Share on other sites More sharing options...
alex_h Posted December 9, 2014 Author Share Posted December 9, 2014 To create DragonBones animation you need to use the DragonBones Design Panel extension for Flash Pro http://dragonbones.effecthub.com/ This generates the timeline data and texture atlas for your animation. volstro 1 Quote Link to comment Share on other sites More sharing options...
volstro Posted December 11, 2014 Share Posted December 11, 2014 To create DragonBones animation you need to use the DragonBones Design Panel extension for Flash Pro http://dragonbones.effecthub.com/ This generates the timeline data and texture atlas for your animation.Thank you very much. Do you know any other open source design tool. I don't have a Flash pro to try Dragon Bones Design panel. I am looking to port the tool to the Browser or Gimp or inkscape. What you say? Any suggestions? Quote Link to comment Share on other sites More sharing options...
boolhaze Posted January 7, 2015 Share Posted January 7, 2015 I can see wayfinder posted a solution on the skewing problem, but I thought I would post my solution anyway.This one also support nested skeletons. First the DragonBonesSprite:Phaser.DragonBonesSprite = function (game, x, y, name) { Phaser.Sprite.call(this, game, x, y, name); this.skewX = 0; this.skewY = 0;};Phaser.DragonBonesSprite.prototype = Object.create(Phaser.Sprite.prototype);Phaser.DragonBonesSprite.prototype.constructor = Phaser.DragonBonesSprite;Phaser.DragonBonesSprite.prototype.updateTransform = function(){ // create some matrix refs for easy access var pt = this.parent.worldTransform; var wt = this.worldTransform; // temporary matrix variables var a, b, c, d, tx, ty; // so if rotation is between 0 then we can simplify the multiplication process.. if(this.rotation % PIXI.PI_2 || this.skewY % PIXI.PI_2) { a = Math.cos(this.skewY)* this.scale.x; b = Math.sin(this.skewY) * this.scale.x; c = Math.sin(- this.skewX)* this.scale.y; d = Math.cos(this.skewX) * this.scale.y; tx = this.position.x; ty = this.position.y; // check for pivot.. not often used so geared towards that fact! if(this.pivot.x || this.pivot.y) { tx -= this.pivot.x * a + this.pivot.y * c; ty -= this.pivot.x * b + this.pivot.y * d; } // concat the parent matrix with the objects transform. wt.a = a * pt.a + b * pt.c; wt.b = a * pt.b + b * pt.d; wt.c = c * pt.a + d * pt.c; wt.d = c * pt.b + d * pt.d; wt.tx = tx * pt.a + ty * pt.c + pt.tx; wt.ty = tx * pt.b + ty * pt.d + pt.ty; } else { // lets do the fast version as we know there is no rotation.. a = this.scale.x; d = this.scale.y; tx = this.position.x - this.pivot.x * a; ty = this.position.y - this.pivot.y * d; wt.a = pt.a * a; wt.b = pt.b * d; wt.c = pt.c * a; wt.d = pt.d * d; wt.tx = tx * pt.a + ty * pt.c + pt.tx; wt.ty = tx * pt.b + ty * pt.d + pt.ty; } // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha;};Then create a DragonBonesGroup that extends Phaser.Group:Phaser.DragonBonesGroup = function (game, parent, name, addToStage, enableBody, physicsBodyType) { Phaser.Group.call(this, game, parent, name, addToStage, enableBody, physicsBodyType); this.skewX = 0; this.skewY = 0;};Phaser.DragonBonesGroup.prototype = Object.create(Phaser.Group.prototype);Phaser.DragonBonesGroup.prototype.constructor = Phaser.DragonBonesGroup;Phaser.DragonBonesGroup.prototype.updateTransform = function(){ // create some matrix refs for easy access var pt = this.parent.worldTransform; var wt = this.worldTransform; // temporary matrix variables var a, b, c, d, tx, ty; // so if rotation is between 0 then we can simplify the multiplication process.. if(this.rotation % PIXI.PI_2 || this.skewY % PIXI.PI_2) { a = Math.cos(this.skewY)* this.scale.x; b = Math.sin(this.skewY) * this.scale.x; c = Math.sin(- this.skewX)* this.scale.y; d = Math.cos(this.skewX) * this.scale.y; tx = this.position.x; ty = this.position.y; // check for pivot.. not often used so geared towards that fact! if(this.pivot.x || this.pivot.y) { tx -= this.pivot.x * a + this.pivot.y * c; ty -= this.pivot.x * b + this.pivot.y * d; } // concat the parent matrix with the objects transform. wt.a = a * pt.a + b * pt.c; wt.b = a * pt.b + b * pt.d; wt.c = c * pt.a + d * pt.c; wt.d = c * pt.b + d * pt.d; wt.tx = tx * pt.a + ty * pt.c + pt.tx; wt.ty = tx * pt.b + ty * pt.d + pt.ty; } else { // lets do the fast version as we know there is no rotation.. a = this.scale.x; d = this.scale.y; tx = this.position.x - this.pivot.x * a; ty = this.position.y - this.pivot.y * d; wt.a = pt.a * a; wt.b = pt.b * d; wt.c = pt.c * a; wt.d = pt.d * d; wt.tx = tx * pt.a + ty * pt.c + pt.tx; wt.ty = tx * pt.b + ty * pt.d + pt.ty; } // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; for(var i=0,j=this.children.length; i<j; i++) { this.children[i].updateTransform(); }};Make sure to use them:PhaserBonesFactory.prototype._generateDisplay = function (textureAtlas, frameName, pivotX, pivotY) { //fetch the id of the atlas image var imgName = textureAtlas.atlasId; //create a sprite var image = new Phaser.DragonBonesSprite(dragonBones.game, 0, 0, imgName); //set the sprite frame from the texture atlas image.animations.loadFrameData(image.game.cache.getFrameData(imgName)); //and the frameName... (restoring the .png that was stripped earlier) image.frameName = frameName + ".png"; image.pivot.setTo(pivotX, pivotY); return image;};PhaserBonesFactory.prototype._generateArmature = function () { var display = new Phaser.DragonBonesGroup(dragonBones.game); var armature = new dragonBones.Armature(display); return armature; };And finally make sure to update skewing in PhaserDisplayBridge:PhaserDisplayBridge.prototype.updateTransform = function (matrix, transform) { // apply the matrix to the phaser / pixi display object this._display.x = matrix.tx; this._display.y = matrix.ty; this._display.skewX = transform.skewX; this._display.skewY = transform.skewY; this._display.rotation = transform.skewX; this._display.scale.x = transform.scaleX; this._display.scale.y = transform.scaleY; };This is only tested on Phaser v2.1.3 using Pixi.js v2.0.0, but should hopefully work on newer releases too. Quote Link to comment Share on other sites More sharing options...
alex_h Posted January 8, 2015 Author Share Posted January 8, 2015 Cool, thanks for sharing! Quote Link to comment Share on other sites More sharing options...
olehakimov Posted April 18, 2015 Share Posted April 18, 2015 Hi everybody and Alex_h!i am trying to run pixidragonbones with my animations and have some questions and troubles:1) Where i need to get the "skeletonId"?function createDragon(){ var partsList = [ "Bubbles.png", "cauldron.png", "oldie.png", "young.png" ]; var texture = PIXI.TextureCache["folder/texture.png"]; var skeletonJSON = loadedData["folder/skeleton.json"]; var atlasJson = loadedData["folder/texture.json"]; var config = { armatureName: "GameFieldAnimation", skeletonId: "Dragon", animationId: "idle", partsList: partsList };2 The example of pixidragonbones i change to load my own animation and every time i get the error:"Uncaught TypeError: Cannot read property 'frames' of undefined"The animation is correct and well works with createjs.I use last pixijs build and try export 2.4 and 3.0 dragonbones. Quote Link to comment Share on other sites More sharing options...
alex_h Posted April 20, 2015 Author Share Posted April 20, 2015 Hi Olehakimov, 1) if you look in the skeleton json file the first property you see should be called "name". The value of this property is what I have referred to as the skeletonId. 2) Because I initially put this together for my own purposes I only configured the adapter to work with TexturePacker JSON format, not dragonbones json format. I'm guessing that your texture content is exported directly from the dragonbones design tool. You'll need to re-export it as individual pngs and then add those to a texturepacker atlas in either JSON Array or JSON hash format in order for this to work. Good luck! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.