mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
[cocos2d-objc] Added IK example. Also added SkeletonAnimation preUpdateWorldTransformListener and postUpdateWorldTransformsListener which allow modifying a skeleton pre- and post-calculation of the world transformations. See #1532.
This commit is contained in:
parent
656b08a32e
commit
015de8ed4c
@ -53,9 +53,12 @@
|
||||
|
||||
### Cocos2d-Objc
|
||||
* Added mix-and-match example to demonstrate the new Skin API.
|
||||
* Added `IKExample`.
|
||||
* Added `SkeletonAnimation preUpdateWorldTransformsListener` and `SkeletonAnimation postUpdateWorldTransformsListener`. When set, these callbacks will be invokved before and after the skeleton's `updateWorldTransforms()` method is called. See the `IKExample` how it can be used.
|
||||
|
||||
### SFML
|
||||
* Added mix-and-match example to demonstrate the new Skin API.
|
||||
* Added `IKExample`.
|
||||
|
||||
## C++
|
||||
* **Breaking Changes**
|
||||
@ -88,6 +91,7 @@
|
||||
* Updated to cocos2d-x 3.17.1
|
||||
* Added mix-and-match example to demonstrate the new Skin API.
|
||||
* Exmaple project requires Visual Studio 2019 on Windows
|
||||
* Added `IKExample`.
|
||||
* Added `SkeletonAnimation::setPreUpdateWorldTransformsListener()` and `SkeletonAnimation::setPreUpdateWorldTransformsListener()`. When set, these callbacks will be invokved before and after the skeleton's `updateWorldTransforms()` method is called. See the `IKExample` how it can be used.
|
||||
|
||||
### SFML
|
||||
|
||||
@ -64,7 +64,7 @@ cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
cp -f ../raptor/export/raptor.atlas "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
cp -f ../raptor/export/raptor.png "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
|
||||
cp -f ../spineboy/export/spineboy-ess.json "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
cp -f ../spineboy/export/spineboy-pro.json "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
cp -f ../spineboy/export/spineboy.png "$ROOT/spine-cocos2d-objc/Resources/"
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
#import "cocos2d.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "SpineboyExample.h"
|
||||
#import "IKExample.h"
|
||||
|
||||
@implementation AppController
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
CCSetupShowDebugStats: @YES,
|
||||
}];
|
||||
|
||||
[[CCDirector sharedDirector] runWithScene:[SpineboyExample scene]];
|
||||
[[CCDirector sharedDirector] runWithScene:[IKExample scene]];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -49,6 +49,8 @@
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
4304
spine-cocos2d-objc/Resources/spineboy-pro.json
Normal file
4304
spine-cocos2d-objc/Resources/spineboy-pro.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#import "CoinExample.h"
|
||||
#import "SpineBoyExample.h"
|
||||
#import "IKExample.h"
|
||||
|
||||
@implementation CoinExample
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
else if (skeletonNode.timeScale == 1)
|
||||
skeletonNode.timeScale = 0.3f;
|
||||
else
|
||||
[[CCDirector sharedDirector] replaceScene:[SpineboyExample scene]];
|
||||
[[CCDirector sharedDirector] replaceScene:[IKExample scene]];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
40
spine-cocos2d-objc/example/IKExample.h
Normal file
40
spine-cocos2d-objc/example/IKExample.h
Normal file
@ -0,0 +1,40 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#import "cocos2d.h"
|
||||
#import <spine/spine-cocos2d-objc.h>
|
||||
|
||||
@interface IKExample : CCNode {
|
||||
SkeletonAnimation* skeletonNode;
|
||||
CGPoint position;
|
||||
}
|
||||
|
||||
+ (CCScene*) scene;
|
||||
|
||||
@end
|
||||
118
spine-cocos2d-objc/example/IKExample.m
Normal file
118
spine-cocos2d-objc/example/IKExample.m
Normal file
@ -0,0 +1,118 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#import "IKExample.h"
|
||||
#import "SpineboyExample.h"
|
||||
|
||||
// This example demonstrates how to set the position
|
||||
// of a bone based on the touch position, which in
|
||||
// turn will make an IK chain follow that bone
|
||||
// smoothly.
|
||||
@implementation IKExample
|
||||
|
||||
+ (CCScene*) scene {
|
||||
CCScene *scene = [CCScene node];
|
||||
[scene addChild:[IKExample node]];
|
||||
return scene;
|
||||
}
|
||||
|
||||
-(id) init {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
|
||||
// Load the Spineboy skeleton and create a SkeletonAnimation node from it
|
||||
// centered on the screen.
|
||||
|
||||
skeletonNode = [SkeletonAnimation skeletonWithFile:@"spineboy-pro.json" atlasFile:@"spineboy.atlas" scale:0.4];
|
||||
CGSize windowSize = [[CCDirector sharedDirector] viewSize];
|
||||
[skeletonNode setPosition:ccp(windowSize.width / 2, 20)];
|
||||
[self addChild:skeletonNode];
|
||||
self.userInteractionEnabled = YES;
|
||||
self.contentSize = windowSize;
|
||||
|
||||
// Queue the "walk" animation on the first track.
|
||||
[skeletonNode setAnimationForTrack:0 name:@"walk" loop:YES];
|
||||
|
||||
// Queue the "aim" animation on a higher track.
|
||||
// It consists of a single frame that positions
|
||||
// the back arm and gun such that they point at
|
||||
// the "crosshair" bone. By setting this
|
||||
// animation on a higher track, it overrides
|
||||
// any changes to the back arm and gun made
|
||||
// by the walk animation, allowing us to
|
||||
// mix the two. The mouse position following
|
||||
// is performed in the lambda below.
|
||||
[skeletonNode setAnimationForTrack:1 name:@"aim" loop:YES];
|
||||
|
||||
// Position the "crosshair" bone at the mouse
|
||||
// location.
|
||||
//
|
||||
// When setting the crosshair bone position
|
||||
// to the mouse position, we need to translate
|
||||
// from "skeleton space" to "local bone space".
|
||||
// Note that the local bone space is calculated
|
||||
// using the bone's parent worldToLocal() function!
|
||||
//
|
||||
// After updating the bone position based on the
|
||||
// converted mouse location, we call updateWorldTransforms()
|
||||
// again so the change of the IK target position is
|
||||
// applied to the rest of the skeleton.
|
||||
__weak IKExample* scene = self;
|
||||
skeletonNode.postUpdateWorldTransformsListener = ^(SkeletonAnimation* node) {
|
||||
if (scene != NULL) {
|
||||
__strong IKExample* sceneStrong = scene;
|
||||
spBone* crosshair = [node findBone:@"crosshair"]; // The bone should be cached
|
||||
float localX = 0, localY = 0;
|
||||
spBone_worldToLocal(crosshair->parent, sceneStrong->position.x, sceneStrong->position.y, &localX, &localY);
|
||||
crosshair->x = localX;
|
||||
crosshair->y = localY;
|
||||
crosshair->appliedValid = FALSE;
|
||||
spBone_updateWorldTransform(crosshair);
|
||||
}
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
#if ( TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR )
|
||||
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
|
||||
position = [skeletonNode convertToNodeSpace:touch.locationInWorld];
|
||||
printf("%f %f\n", position.x, position.y);
|
||||
}
|
||||
|
||||
- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
|
||||
position = [skeletonNode convertToNodeSpace:touch.locationInWorld];
|
||||
printf("%f %f\n", position.x, position.y);
|
||||
}
|
||||
|
||||
- (void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
|
||||
[[CCDirector sharedDirector] replaceScene:[SpineboyExample scene]];
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
@ -42,7 +42,7 @@
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
|
||||
skeletonNode = [SkeletonAnimation skeletonWithFile:@"spineboy-ess.json" atlasFile:@"spineboy.atlas" scale:0.4];
|
||||
skeletonNode = [SkeletonAnimation skeletonWithFile:@"spineboy-pro.json" atlasFile:@"spineboy.atlas" scale:0.4];
|
||||
[skeletonNode setMixFrom:@"walk" to:@"jump" duration:0.2f];
|
||||
[skeletonNode setMixFrom:@"jump" to:@"run" duration:0.2f];
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
43C3282F170B0C19004A9460 /* spine-cocos2d-objc.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C3282D170B0C19004A9460 /* spine-cocos2d-objc.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
43C3286C170B0DA6004A9460 /* spineboy-ess.json in Resources */ = {isa = PBXBuildFile; fileRef = 43C32868170B0DA6004A9460 /* spineboy-ess.json */; };
|
||||
43C3286E170B0DA6004A9460 /* spineboy.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 43C3286A170B0DA6004A9460 /* spineboy.atlas */; };
|
||||
43C3286F170B0DA6004A9460 /* spineboy.png in Resources */ = {isa = PBXBuildFile; fileRef = 43C3286B170B0DA6004A9460 /* spineboy.png */; };
|
||||
43C3287D170B0DBE004A9460 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 43C32871170B0DBE004A9460 /* Default-568h@2x.png */; };
|
||||
@ -34,6 +33,8 @@
|
||||
765A2EF61D7D7A08003FB779 /* goblins.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF41D7D7A08003FB779 /* goblins.atlas */; };
|
||||
765A2EF71D7D7A08003FB779 /* goblins.png in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF51D7D7A08003FB779 /* goblins.png */; };
|
||||
76BF7E071E66ED9C00485998 /* GLUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 76BF7E051E66ED9C00485998 /* GLUtils.c */; };
|
||||
76C893BC23672757009D8DC8 /* IKExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 76C893B623672757009D8DC8 /* IKExample.m */; };
|
||||
76C893BF236728A4009D8DC8 /* spineboy-pro.json in Resources */ = {isa = PBXBuildFile; fileRef = 76C893BE236728A4009D8DC8 /* spineboy-pro.json */; };
|
||||
76EE4E461EB36DE6000254F4 /* Array.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E421EB36DE6000254F4 /* Array.c */; };
|
||||
76EE4E471EB36DE6000254F4 /* ClippingAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E431EB36DE6000254F4 /* ClippingAttachment.c */; };
|
||||
76EE4E481EB36DE6000254F4 /* SkeletonClipping.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */; };
|
||||
@ -138,7 +139,6 @@
|
||||
/* Begin PBXFileReference section */
|
||||
43C3282D170B0C19004A9460 /* spine-cocos2d-objc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "spine-cocos2d-objc.m"; path = "src/spine/spine-cocos2d-objc.m"; sourceTree = "<group>"; };
|
||||
43C3282E170B0C19004A9460 /* spine-cocos2d-objc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "spine-cocos2d-objc.h"; path = "src/spine/spine-cocos2d-objc.h"; sourceTree = "<group>"; };
|
||||
43C32868170B0DA6004A9460 /* spineboy-ess.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "spineboy-ess.json"; path = "Resources/spineboy-ess.json"; sourceTree = "<group>"; };
|
||||
43C3286A170B0DA6004A9460 /* spineboy.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = spineboy.atlas; path = Resources/spineboy.atlas; sourceTree = "<group>"; };
|
||||
43C3286B170B0DA6004A9460 /* spineboy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = spineboy.png; path = Resources/spineboy.png; sourceTree = "<group>"; };
|
||||
43C32871170B0DBE004A9460 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "Resources-ios/Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
@ -171,6 +171,9 @@
|
||||
765A2EF51D7D7A08003FB779 /* goblins.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = goblins.png; path = Resources/goblins.png; sourceTree = "<group>"; };
|
||||
76BF7E051E66ED9C00485998 /* GLUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GLUtils.c; path = src/spine/GLUtils.c; sourceTree = "<group>"; };
|
||||
76BF7E061E66ED9C00485998 /* GLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GLUtils.h; path = src/spine/GLUtils.h; sourceTree = "<group>"; };
|
||||
76C893B623672757009D8DC8 /* IKExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IKExample.m; path = example/IKExample.m; sourceTree = "<group>"; };
|
||||
76C893BB23672757009D8DC8 /* IKExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IKExample.h; path = example/IKExample.h; sourceTree = "<group>"; };
|
||||
76C893BE236728A4009D8DC8 /* spineboy-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "spineboy-pro.json"; path = "Resources/spineboy-pro.json"; sourceTree = "<group>"; };
|
||||
76EE4E421EB36DE6000254F4 /* Array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Array.c; path = "../spine-c/spine-c/src/spine/Array.c"; sourceTree = "<group>"; };
|
||||
76EE4E431EB36DE6000254F4 /* ClippingAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ClippingAttachment.c; path = "../spine-c/spine-c/src/spine/ClippingAttachment.c"; sourceTree = "<group>"; };
|
||||
76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonClipping.c; path = "../spine-c/spine-c/src/spine/SkeletonClipping.c"; sourceTree = "<group>"; };
|
||||
@ -282,6 +285,8 @@
|
||||
43C32823170B0BC7004A9460 /* spine-cocos2d-objc */,
|
||||
43F7FF8C1927F96700CA4038 /* SpineboyExample.h */,
|
||||
43F7FF8D1927F96700CA4038 /* SpineboyExample.m */,
|
||||
76C893BB23672757009D8DC8 /* IKExample.h */,
|
||||
76C893B623672757009D8DC8 /* IKExample.m */,
|
||||
43F7FF8A1927F96700CA4038 /* GoblinsExample.h */,
|
||||
43F7FF8B1927F96700CA4038 /* GoblinsExample.m */,
|
||||
76F5BDA81D2BDE67005917E5 /* RaptorExample.h */,
|
||||
@ -364,6 +369,7 @@
|
||||
43C32867170B0C7F004A9460 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
76C893BE236728A4009D8DC8 /* spineboy-pro.json */,
|
||||
76EE4E4E1EB36E53000254F4 /* coin.atlas */,
|
||||
76EE4E4F1EB36E53000254F4 /* coin-pro.json */,
|
||||
76EE4E501EB36E53000254F4 /* coin.png */,
|
||||
@ -376,7 +382,6 @@
|
||||
76F5BDA01D2BDE1C005917E5 /* tank-pro.json */,
|
||||
76F5BDA11D2BDE1C005917E5 /* tank.png */,
|
||||
43F7010D1927FBC700CA4038 /* goblins-pro.json */,
|
||||
43C32868170B0DA6004A9460 /* spineboy-ess.json */,
|
||||
43C3286A170B0DA6004A9460 /* spineboy.atlas */,
|
||||
43C3286B170B0DA6004A9460 /* spineboy.png */,
|
||||
);
|
||||
@ -484,6 +489,7 @@
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = 9A5D248C170A94DA0030D4DD;
|
||||
@ -540,7 +546,6 @@
|
||||
files = (
|
||||
765A2EF61D7D7A08003FB779 /* goblins.atlas in Resources */,
|
||||
76F5BDA51D2BDE1C005917E5 /* tank.atlas in Resources */,
|
||||
43C3286C170B0DA6004A9460 /* spineboy-ess.json in Resources */,
|
||||
43C3286E170B0DA6004A9460 /* spineboy.atlas in Resources */,
|
||||
43C3286F170B0DA6004A9460 /* spineboy.png in Resources */,
|
||||
43C3287D170B0DBE004A9460 /* Default-568h@2x.png in Resources */,
|
||||
@ -557,6 +562,7 @@
|
||||
76EE4E511EB36E53000254F4 /* coin.atlas in Resources */,
|
||||
76F5BDA21D2BDE1C005917E5 /* raptor.atlas in Resources */,
|
||||
43C32883170B0DBE004A9460 /* Icon-Small.png in Resources */,
|
||||
76C893BF236728A4009D8DC8 /* spineboy-pro.json in Resources */,
|
||||
43C32884170B0DBE004A9460 /* Icon-Small@2x.png in Resources */,
|
||||
43C32885170B0DBE004A9460 /* Icon.png in Resources */,
|
||||
76F5BDA71D2BDE1C005917E5 /* tank.png in Resources */,
|
||||
@ -607,6 +613,7 @@
|
||||
76F28D311DEC810300CDE54D /* Slot.c in Sources */,
|
||||
43C32A06170B0F93004A9460 /* main.m in Sources */,
|
||||
76F28D351DEC810300CDE54D /* VertexAttachment.c in Sources */,
|
||||
76C893BC23672757009D8DC8 /* IKExample.m in Sources */,
|
||||
76FAC1961E3FA15E001CCC8C /* Color.c in Sources */,
|
||||
76F28D331DEC810300CDE54D /* TransformConstraint.c in Sources */,
|
||||
43C32A09170B10FF004A9460 /* AppDelegate.m in Sources */,
|
||||
|
||||
@ -39,6 +39,7 @@ typedef void(^spEndListener)(spTrackEntry* entry);
|
||||
typedef void(^spDisposeListener)(spTrackEntry* entry);
|
||||
typedef void(^spCompleteListener)(spTrackEntry* entry);
|
||||
typedef void(^spEventListener)(spTrackEntry* entry, spEvent* event);
|
||||
typedef void(^spUpdateWorldTransformsListener)(SkeletonAnimation* node);
|
||||
|
||||
/** Draws an animated skeleton, providing an AnimationState for applying one or more animations and queuing animations to be
|
||||
* played later. */
|
||||
@ -90,5 +91,7 @@ typedef void(^spEventListener)(spTrackEntry* entry, spEvent* event);
|
||||
@property (nonatomic, copy) spDisposeListener disposeListener;
|
||||
@property (nonatomic, copy) spCompleteListener completeListener;
|
||||
@property (nonatomic, copy) spEventListener eventListener;
|
||||
@property (nonatomic, copy) spUpdateWorldTransformsListener preUpdateWorldTransformsListener;
|
||||
@property (nonatomic, copy) spUpdateWorldTransformsListener postUpdateWorldTransformsListener;
|
||||
|
||||
@end
|
||||
|
||||
@ -80,6 +80,8 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
|
||||
@synthesize endListener = _endListener;
|
||||
@synthesize completeListener = _completeListener;
|
||||
@synthesize eventListener = _eventListener;
|
||||
@synthesize preUpdateWorldTransformsListener = _preUpdateWorldTransformsListener;
|
||||
@synthesize postUpdateWorldTransformsListener = _postUpdateWorldTransformsListener;
|
||||
|
||||
+ (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
||||
return [[[self alloc] initWithData:skeletonData ownsSkeletonData:ownsSkeletonData] autorelease];
|
||||
@ -141,6 +143,8 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
|
||||
[_disposeListener release];
|
||||
[_completeListener release];
|
||||
[_eventListener release];
|
||||
[_preUpdateWorldTransformsListener release];
|
||||
[_postUpdateWorldTransformsListener release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@ -150,7 +154,9 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
|
||||
spSkeleton_update(_skeleton, deltaTime);
|
||||
spAnimationState_update(_state, deltaTime);
|
||||
spAnimationState_apply(_state, _skeleton);
|
||||
if (_preUpdateWorldTransformsListener) _preUpdateWorldTransformsListener(self);
|
||||
spSkeleton_updateWorldTransform(_skeleton);
|
||||
if (_postUpdateWorldTransformsListener) _postUpdateWorldTransformsListener(self);
|
||||
}
|
||||
|
||||
- (void) setAnimationStateData:(spAnimationStateData*)stateData {
|
||||
|
||||
@ -33,6 +33,10 @@
|
||||
USING_NS_CC;
|
||||
using namespace spine;
|
||||
|
||||
// This example demonstrates how to set the position
|
||||
// of a bone based on the touch position, which in
|
||||
// turn will make an IK chain follow that bone
|
||||
// smoothly.
|
||||
Scene* IKExample::scene () {
|
||||
Scene *scene = Scene::create();
|
||||
scene->addChild(IKExample::create());
|
||||
@ -88,7 +92,7 @@ bool IKExample::init () {
|
||||
// again so the change of the IK target position is
|
||||
// applied to the rest of the skeleton.
|
||||
skeletonNode->setPostUpdateWorldTransformsListener([this] (SkeletonAnimation* node) -> void {
|
||||
Bone* crosshair = node->findBone("crosshair");
|
||||
Bone* crosshair = node->findBone("crosshair"); // The bone should be cached
|
||||
float localX = 0, localY = 0;
|
||||
crosshair->getParent()->worldToLocal(position.x, position.y, localX, localY);
|
||||
crosshair->setX(localX);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user