Meshes, FFD and skinning for spine-cocos2d-iphone.

Also, AnimationState listeners are done using blocks.

This is for cocos2d 2.1.0. Version 3.0 and 3.1 is coming soon.
This commit is contained in:
NathanSweet 2014-05-17 22:28:24 +02:00
parent d0c417e850
commit b0279701e4
62 changed files with 7311 additions and 5090 deletions

6
.gitignore vendored
View File

@ -33,10 +33,8 @@ spine-cocos2dx/3.1/cocos2dx/
spine-cocos2dx/3.1/example/proj.win32/Debug
xcuserdata
spine-cocos2d-iphone/libs/*
!spine-cocos2d-iphone/libs/cocos2d/Place cocos2d here.txt
!spine-cocos2d-iphone/libs/CocosDenshion/Place CocosDenshion here.txt
!spine-cocos2d-iphone/libs/kazmath/Place kazmath here.txt
spine-cocos2d-iphone/2/cocos2d/*
!spine-cocos2d-iphone/2/cocos2d/Place cocos2d here.txt
spine-csharp/bin
spine-csharp/obj

View File

@ -0,0 +1,20 @@
# spine-cocos2d-iphone
The spine-cocos2d-iphone runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [cocos2d-iphone](http://www.cocos2d-iphone.org/). spine-cocos2d-iphone is based on [spine-c](https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-c).
## Setup
1. Download the Spine Runtimes source using [git](https://help.github.com/articles/set-up-git) or by downloading it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip).
1. Place the contents of a cocos2d version 2.1.0 distribution into the `spine-cocos2d-iphone/2/cocos2d` directory.
1. Open the XCode project file for iOS or Mac from the `spine-cocos2d-iphone/2` directory.
Alternatively, the contents of the `spine-c/src`, `spine-c/include` and `spine-cocos2d-iphone/2/src` directories can be copied into your project. Be sure your header search path will find the contents of the `spine-c/include` and `spine-cocos2d-iphone/2/src` directories. Note that the includes use `spine/Xxx.h`, so the `spine` directory cannot be omitted when copying the files.
## Examples
[Spineboy](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-cocos2d-iphone/2/example/SpineboyExample.cpp)
[Golbins](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-cocos2d-iphone/2/example/GoblinsExample.cpp)
## Links
[podspec](https://github.com/ldomaradzki/spine-runtimes/blob/master/Spine-Cocos2d-iPhone.podspec) (maintained externally)

View File

@ -1,7 +1,7 @@
#import "cocos2d.h"
#import "AppDelegate.h"
#import "ExampleLayer.h"
#import "SpineboyExample.h"
@implementation MyNavigationController
@ -36,7 +36,7 @@
if(director.runningScene == nil) {
// Add the first scene to the stack. The director will draw it immediately into the framebuffer. (Animation is started automatically when the view is displayed.)
// and add the scene to the stack. The director will run it when it automatically when the view is displayed.
[director runWithScene: [ExampleLayer scene]];
[director runWithScene: [SpineboyExample scene]];
}
}
@end

View File

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

View File

Before

Width:  |  Height:  |  Size: 464 KiB

After

Width:  |  Height:  |  Size: 464 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 357 KiB

After

Width:  |  Height:  |  Size: 357 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,6 +1,6 @@
#import "AppDelegate.h"
#import "ExampleLayer.h"
#import "SpineboyExample.h"
@implementation spine_cocos2d_iphoneAppDelegate
@synthesize window=window_, glView=glView_;
@ -15,7 +15,7 @@
[window_ setAcceptsMouseMovedEvents:NO];
[window_ center];
[director runWithScene:[ExampleLayer scene]];
[director runWithScene:[SpineboyExample scene]];
}
- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *) theApplication {

View File

@ -1,285 +1,292 @@
goblins.png
goblins-ffd.png
format: RGBA8888
filter: Linear,Linear
repeat: none
spear
rotate: false
xy: 2, 142
size: 22, 368
orig: 22, 368
offset: 0, 0
index: -1
goblingirl/head
rotate: false
xy: 26, 429
size: 103, 81
orig: 103, 81
offset: 0, 0
index: -1
goblin/head
rotate: false
xy: 26, 361
size: 103, 66
orig: 103, 66
offset: 0, 0
index: -1
goblin/torso
rotate: false
xy: 131, 414
size: 68, 96
orig: 68, 96
offset: 0, 0
index: -1
goblingirl/torso
rotate: false
xy: 26, 263
size: 68, 96
orig: 68, 96
offset: 0, 0
index: -1
dagger
rotate: false
xy: 26, 153
rotate: true
xy: 372, 100
size: 26, 108
orig: 26, 108
offset: 0, 0
index: -1
goblin/right-lower-leg
rotate: false
xy: 201, 434
size: 36, 76
orig: 36, 76
offset: 0, 0
index: -1
goblingirl/right-lower-leg
rotate: false
xy: 54, 185
size: 36, 76
orig: 36, 76
offset: 0, 0
index: -1
goblin/left-upper-leg
rotate: false
xy: 96, 286
size: 33, 73
orig: 33, 73
offset: 0, 0
index: -1
goblin/pelvis
rotate: false
xy: 131, 369
size: 62, 43
orig: 62, 43
offset: 0, 0
index: -1
goblingirl/pelvis
rotate: false
xy: 131, 324
size: 62, 43
orig: 62, 43
offset: 0, 0
index: -1
goblin/right-foot
rotate: false
xy: 131, 289
size: 63, 33
orig: 63, 33
offset: 0, 0
index: -1
goblin/left-lower-leg
rotate: false
xy: 2, 70
size: 33, 70
orig: 33, 70
offset: 0, 0
index: -1
goblin/right-upper-leg
rotate: false
xy: 2, 5
size: 34, 63
orig: 34, 63
offset: 0, 0
index: -1
goblingirl/left-lower-leg
rotate: false
xy: 195, 342
size: 33, 70
orig: 33, 70
offset: 0, 0
index: -1
goblingirl/left-upper-leg
rotate: false
xy: 37, 81
size: 33, 70
orig: 33, 70
offset: 0, 0
index: -1
goblingirl/right-upper-leg
rotate: false
xy: 38, 16
size: 34, 63
orig: 34, 63
offset: 0, 0
index: -1
goblin/eyes-closed
rotate: false
xy: 38, 2
xy: 2, 7
size: 34, 12
orig: 34, 12
offset: 0, 0
index: -1
goblin/undies
goblin/head
rotate: false
xy: 54, 154
size: 36, 29
orig: 36, 29
offset: 0, 0
index: -1
goblin/right-arm
rotate: false
xy: 72, 102
size: 23, 50
orig: 23, 50
offset: 0, 0
index: -1
goblin/left-foot
rotate: false
xy: 131, 256
size: 65, 31
orig: 65, 31
offset: 0, 0
index: -1
goblingirl/right-arm
rotate: false
xy: 196, 290
size: 28, 50
orig: 28, 50
offset: 0, 0
index: -1
goblingirl/left-shoulder
rotate: false
xy: 226, 294
size: 28, 46
orig: 28, 46
xy: 107, 36
size: 103, 66
orig: 103, 66
offset: 0, 0
index: -1
goblin/left-arm
rotate: false
xy: 198, 253
xy: 901, 56
size: 37, 35
orig: 37, 35
offset: 0, 0
index: -1
goblin/left-foot
rotate: false
xy: 929, 95
size: 65, 31
orig: 65, 31
offset: 0, 0
index: -1
goblin/left-hand
rotate: false
xy: 452, 2
size: 36, 41
orig: 36, 41
offset: 0, 0
index: -1
goblin/left-lower-leg
rotate: true
xy: 713, 93
size: 33, 70
orig: 33, 70
offset: 0, 0
index: -1
goblin/left-shoulder
rotate: false
xy: 610, 44
size: 29, 44
orig: 29, 44
offset: 0, 0
index: -1
goblin/left-upper-leg
rotate: true
xy: 638, 93
size: 33, 73
orig: 33, 73
offset: 0, 0
index: -1
goblin/neck
rotate: false
xy: 490, 2
size: 36, 41
orig: 36, 41
offset: 0, 0
index: -1
goblin/pelvis
rotate: false
xy: 482, 45
size: 62, 43
orig: 62, 43
offset: 0, 0
index: -1
goblin/right-arm
rotate: true
xy: 690, 2
size: 23, 50
orig: 23, 50
offset: 0, 0
index: -1
goblin/right-foot
rotate: false
xy: 771, 58
size: 63, 33
orig: 63, 33
offset: 0, 0
index: -1
goblin/right-hand
rotate: false
xy: 940, 56
size: 36, 37
orig: 36, 37
offset: 0, 0
index: -1
goblin/right-lower-leg
rotate: true
xy: 482, 90
size: 36, 76
orig: 36, 76
offset: 0, 0
index: -1
goblin/right-shoulder
rotate: true
xy: 602, 3
size: 39, 45
orig: 39, 45
offset: 0, 0
index: -1
goblin/right-upper-leg
rotate: true
xy: 641, 57
size: 34, 63
orig: 34, 63
offset: 0, 0
index: -1
goblin/torso
rotate: true
xy: 212, 34
size: 68, 96
orig: 68, 96
offset: 0, 0
index: -1
goblin/undie-straps
rotate: false
xy: 380, 5
size: 55, 19
orig: 55, 19
offset: 0, 0
index: -1
goblin/undies
rotate: false
xy: 174, 5
size: 36, 29
orig: 36, 29
offset: 0, 0
index: -1
goblingirl/eyes-closed
rotate: false
xy: 269, 11
size: 37, 21
orig: 37, 21
offset: 0, 0
index: -1
goblingirl/head
rotate: false
xy: 2, 21
size: 103, 81
orig: 103, 81
offset: 0, 0
index: -1
goblingirl/left-arm
rotate: true
xy: 978, 56
size: 37, 35
orig: 37, 35
offset: 0, 0
index: -1
goblingirl/left-foot
rotate: false
xy: 92, 223
xy: 107, 3
size: 65, 31
orig: 65, 31
offset: 0, 0
index: -1
goblingirl/right-foot
rotate: false
xy: 92, 188
size: 63, 33
orig: 63, 33
offset: 0, 0
index: -1
goblin/undie-straps
rotate: false
xy: 92, 167
size: 55, 19
orig: 55, 19
offset: 0, 0
index: -1
goblingirl/left-arm
rotate: false
xy: 159, 219
size: 37, 35
orig: 37, 35
offset: 0, 0
index: -1
goblin/right-shoulder
rotate: false
xy: 97, 120
size: 39, 45
orig: 39, 45
offset: 0, 0
index: -1
goblingirl/right-shoulder
rotate: false
xy: 198, 206
size: 39, 45
orig: 39, 45
offset: 0, 0
index: -1
goblin/left-hand
rotate: false
xy: 157, 176
size: 36, 41
orig: 36, 41
offset: 0, 0
index: -1
goblin/neck
rotate: false
xy: 195, 163
size: 36, 41
orig: 36, 41
offset: 0, 0
index: -1
goblingirl/undie-straps
rotate: false
xy: 97, 99
size: 55, 19
orig: 55, 19
offset: 0, 0
index: -1
goblingirl/neck
rotate: false
xy: 138, 120
size: 35, 41
orig: 35, 41
offset: 0, 0
index: -1
goblingirl/left-hand
rotate: false
xy: 175, 121
xy: 565, 2
size: 35, 40
orig: 35, 40
offset: 0, 0
index: -1
goblin/left-shoulder
rotate: false
xy: 212, 117
size: 29, 44
orig: 29, 44
goblingirl/left-lower-leg
rotate: true
xy: 785, 93
size: 33, 70
orig: 33, 70
offset: 0, 0
index: -1
goblingirl/eyes-closed
rotate: false
xy: 154, 97
size: 37, 21
orig: 37, 21
goblingirl/left-shoulder
rotate: true
xy: 690, 27
size: 28, 46
orig: 28, 46
offset: 0, 0
index: -1
goblin/right-hand
goblingirl/left-upper-leg
rotate: true
xy: 857, 93
size: 33, 70
orig: 33, 70
offset: 0, 0
index: -1
goblingirl/neck
rotate: false
xy: 193, 78
size: 36, 37
orig: 36, 37
xy: 528, 2
size: 35, 41
orig: 35, 41
offset: 0, 0
index: -1
goblingirl/pelvis
rotate: false
xy: 546, 45
size: 62, 43
orig: 62, 43
offset: 0, 0
index: -1
goblingirl/right-arm
rotate: false
xy: 452, 48
size: 28, 50
orig: 28, 50
offset: 0, 0
index: -1
goblingirl/right-foot
rotate: false
xy: 836, 58
size: 63, 33
orig: 63, 33
offset: 0, 0
index: -1
goblingirl/right-hand
rotate: false
xy: 74, 39
rotate: true
xy: 771, 20
size: 36, 37
orig: 36, 37
offset: 0, 0
index: -1
goblingirl/right-lower-leg
rotate: true
xy: 560, 90
size: 36, 76
orig: 36, 76
offset: 0, 0
index: -1
goblingirl/right-shoulder
rotate: false
xy: 649, 10
size: 39, 45
orig: 39, 45
offset: 0, 0
index: -1
goblingirl/right-upper-leg
rotate: true
xy: 706, 57
size: 34, 63
orig: 34, 63
offset: 0, 0
index: -1
goblingirl/torso
rotate: false
xy: 310, 2
size: 68, 96
orig: 68, 96
offset: 0, 0
index: -1
goblingirl/undie-straps
rotate: false
xy: 212, 13
size: 55, 19
orig: 55, 19
offset: 0, 0
index: -1
goblingirl/undies
rotate: false
xy: 74, 8
xy: 810, 27
size: 36, 29
orig: 36, 29
offset: 0, 0
index: -1
shield
rotate: false
xy: 380, 26
size: 70, 72
orig: 70, 72
offset: 0, 0
index: -1
spear
rotate: true
xy: 2, 104
size: 22, 368
orig: 22, 368
offset: 0, 0
index: -1

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

View File

@ -0,0 +1,194 @@
spineboy.png
format: RGBA8888
filter: Linear,Linear
repeat: none
eye_indifferent
rotate: true
xy: 389, 5
size: 56, 53
orig: 56, 53
offset: 0, 0
index: -1
eye_surprised
rotate: false
xy: 580, 34
size: 56, 53
orig: 56, 53
offset: 0, 0
index: -1
front_bracer
rotate: false
xy: 732, 85
size: 35, 48
orig: 35, 48
offset: 0, 0
index: -1
front_fist_closed
rotate: false
xy: 556, 91
size: 45, 49
orig: 45, 49
offset: 0, 0
index: -1
front_fist_open
rotate: false
xy: 668, 32
size: 52, 52
orig: 52, 52
offset: 0, 0
index: -1
front_foot
rotate: false
xy: 924, 201
size: 76, 41
orig: 76, 41
offset: 0, 0
index: -1
front_foot_bend1
rotate: false
xy: 845, 200
size: 77, 42
orig: 77, 42
offset: 0, 0
index: -1
front_foot_bend2
rotate: false
xy: 778, 186
size: 65, 56
orig: 65, 56
offset: 0, 0
index: -1
front_shin
rotate: true
xy: 444, 91
size: 49, 110
orig: 49, 110
offset: 0, 0
index: -1
front_thigh
rotate: true
xy: 603, 89
size: 29, 67
orig: 29, 67
offset: 0, 0
index: -1
front_upper_arm
rotate: true
xy: 672, 86
size: 32, 58
orig: 32, 58
offset: 0, 0
index: -1
goggles
rotate: false
xy: 444, 142
size: 157, 100
orig: 157, 100
offset: 0, 0
index: -1
gun
rotate: false
xy: 603, 120
size: 126, 122
orig: 126, 122
offset: 0, 0
index: -1
head
rotate: false
xy: 279, 63
size: 163, 179
orig: 163, 179
offset: 0, 0
index: -1
mouth_grind
rotate: false
xy: 845, 163
size: 56, 35
orig: 56, 35
offset: 0, 0
index: -1
mouth_oooo
rotate: false
xy: 842, 126
size: 56, 35
orig: 56, 35
offset: 0, 0
index: -1
mouth_smile
rotate: false
xy: 769, 97
size: 56, 35
orig: 56, 35
offset: 0, 0
index: -1
muzzle
rotate: false
xy: 2, 2
size: 275, 240
orig: 277, 240
offset: 0, 0
index: -1
neck
rotate: false
xy: 903, 173
size: 22, 25
orig: 22, 25
offset: 0, 0
index: -1
rear_bracer
rotate: false
xy: 722, 40
size: 34, 43
orig: 34, 43
offset: 0, 0
index: -1
rear_foot
rotate: false
xy: 444, 11
size: 68, 36
orig: 68, 36
offset: 0, 0
index: -1
rear_foot_bend1
rotate: false
xy: 444, 49
size: 70, 40
orig: 70, 40
offset: 0, 0
index: -1
rear_foot_bend2
rotate: false
xy: 778, 134
size: 62, 50
orig: 62, 50
offset: 0, 0
index: -1
rear_shin
rotate: false
xy: 731, 135
size: 45, 107
orig: 45, 107
offset: 0, 0
index: -1
rear_thigh
rotate: true
xy: 516, 50
size: 39, 62
orig: 39, 62
offset: 0, 0
index: -1
rear_upper_arm
rotate: false
xy: 638, 35
size: 28, 52
orig: 28, 52
offset: 0, 0
index: -1
torso
rotate: true
xy: 279, 2
size: 59, 108
orig: 59, 108
offset: 0, 0
index: -1

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

View File

@ -0,0 +1,12 @@
#import "cocos2d.h"
#import <spine/spine-cocos2d-iphone.h>
@interface GoblinsExample : CCLayerColor {
SkeletonAnimation* skeletonNode;
}
+ (CCScene*) scene;
@end

View File

@ -0,0 +1,50 @@
#import "GoblinsExample.h"
#import "SpineboyExample.h"
@implementation GoblinsExample
+ (CCScene*) scene {
CCScene *scene = [CCScene node];
[scene addChild:[GoblinsExample node]];
return scene;
}
-(id) init {
self = [super initWithColor:ccc4(128, 128, 128, 255)];
if (!self) return nil;
skeletonNode = [SkeletonAnimation skeletonWithFile:@"goblins-ffd.json" atlasFile:@"goblins-ffd.atlas" scale:1];
[skeletonNode setSkin:@"goblin"];
[skeletonNode setAnimationForTrack:0 name:@"walk" loop:YES];
CGSize windowSize = [[CCDirector sharedDirector] winSize];
[skeletonNode setPosition:ccp(windowSize.width / 2, 20)];
[self addChild:skeletonNode];
#if __CC_PLATFORM_MAC
[self setMouseEnabled:YES];
#else
[self setTouchEnabled:YES];
#endif
return self;
}
#if __CC_PLATFORM_MAC
- (BOOL) ccMouseDown:(NSEvent*)event {
#else
- (void) ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
#endif
if (!skeletonNode.debugBones)
skeletonNode.debugBones = true;
else if (skeletonNode.timeScale == 1)
skeletonNode.timeScale = 0.3f;
else
[[CCDirector sharedDirector] replaceScene:[SpineboyExample scene]];
#if __CC_PLATFORM_MAC
return YES;
#endif
}
@end

View File

@ -0,0 +1,12 @@
#import "cocos2d.h"
#import <spine/spine-cocos2d-iphone.h>
@interface SpineboyExample : CCLayerColor {
SkeletonAnimation* skeletonNode;
}
+ (CCScene*) scene;
@end

View File

@ -0,0 +1,75 @@
#import "SpineboyExample.h"
#import "GoblinsExample.h"
@implementation SpineboyExample
+ (CCScene*) scene {
CCScene *scene = [CCScene node];
[scene addChild:[SpineboyExample node]];
return scene;
}
-(id) init {
self = [super initWithColor:ccc4(128, 128, 128, 255)];
if (!self) return nil;
skeletonNode = [SkeletonAnimation skeletonWithFile:@"spineboy.json" atlasFile:@"spineboy.atlas" scale:0.6];
[skeletonNode setMixFrom:@"walk" to:@"jump" duration:0.2f];
[skeletonNode setMixFrom:@"jump" to:@"run" duration:0.2f];
skeletonNode.startListener = ^(int trackIndex) {
spTrackEntry* entry = spAnimationState_getCurrent(skeletonNode.state, trackIndex);
const char* animationName = (entry && entry->animation) ? entry->animation->name : 0;
CCLOG(@"%d start: %s", trackIndex, animationName);
};
skeletonNode.endListener = ^(int trackIndex) {
CCLOG(@"%d end", trackIndex);
};
skeletonNode.completeListener = ^(int trackIndex, int loopCount) {
CCLOG(@"%d complete: %d", trackIndex, loopCount);
};
skeletonNode.eventListener = ^(int trackIndex, spEvent* event) {
CCLOG(@"%d event: %s, %d, %f, %s", trackIndex, event->data->name, event->intValue, event->floatValue, event->stringValue);
};
[skeletonNode setAnimationForTrack:0 name:@"walk" loop:YES];
TrackEntry* jumpEntry = [skeletonNode addAnimationForTrack:0 name:@"jump" loop:NO afterDelay:3];
[skeletonNode addAnimationForTrack:0 name:@"run" loop:YES afterDelay:0];
[skeletonNode setListenerForEntry:jumpEntry onStart:^(int trackIndex) {
CCLOG(@"jumped!");
}];
// [skeletonNode setAnimationForTrack:1 name:@"test" loop:YES];
CGSize windowSize = [[CCDirector sharedDirector] winSize];
[skeletonNode setPosition:ccp(windowSize.width / 2, 20)];
[self addChild:skeletonNode];
#if __CC_PLATFORM_MAC
[self setMouseEnabled:YES];
#else
[self setTouchEnabled:YES];
#endif
return self;
}
#if __CC_PLATFORM_MAC
- (BOOL) ccMouseDown:(NSEvent*)event {
#else
- (void) ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
#endif
if (!skeletonNode.debugBones)
skeletonNode.debugBones = true;
else if (skeletonNode.timeScale == 1)
skeletonNode.timeScale = 0.3f;
else
[[CCDirector sharedDirector] replaceScene:[GoblinsExample scene]];
#if __CC_PLATFORM_MAC
return YES;
#endif
}
@end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 <spine/spine-cocos2d-iphone.h>
@interface PolygonBatch : NSObject {
int _capacity;
ccV2F_C4B_T2F* _vertices;
int _verticesCount;
GLushort* _triangles;
int _trianglesCount;
CCTexture2D* _texture;
}
+ (id) createWithCapacity:(int)capacity;
- (id) initWithCapacity:(int)capacity;
- (void) add:(CCTexture2D*)texture vertices:(const float*)vertices uvs:(const float*)uvs
verticesCount:(int)verticesCount triangles:(const int*)triangles trianglesCount:(int)trianglesCount
color:(ccColor4B*)color;
- (void) flush;
@end

View File

@ -0,0 +1,106 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 <spine/PolygonBatch.h>
#import <spine/spine-cocos2d-iphone.h>
#import <spine/extension.h>
@implementation PolygonBatch
+ (id) createWithCapacity:(int)capacity {
return [[(PolygonBatch*)[self alloc] initWithCapacity:capacity] autorelease];
}
- (id) initWithCapacity:(int)capacity {
// 32767 is max index, so 32767 / 3 - (32767 / 3 % 3) = 10920.
NSAssert(capacity <= 10920, @"capacity cannot be > 10920");
NSAssert(capacity >= 0, @"capacity cannot be < 0");
self = [super init];
if (!self) return nil;
_capacity = capacity;
_vertices = MALLOC(ccV2F_C4B_T2F, capacity);
_triangles = MALLOC(GLushort, capacity * 3);
return self;
}
- (void) dealloc {
FREE(_vertices);
FREE(_triangles);
[super dealloc];
}
- (void) add:(CCTexture2D*)addTexture vertices:(const float*)addVertices uvs:(const float*)uvs
verticesCount:(int)addVerticesCount triangles:(const int*)addTriangles trianglesCount:(int)addTrianglesCount
color:(ccColor4B*)color {
if (
addTexture != _texture
|| _verticesCount + (addVerticesCount >> 1) > _capacity
|| _trianglesCount + addTrianglesCount > _capacity * 3) {
[self flush];
_texture = addTexture;
}
for (int i = 0; i < addTrianglesCount; ++i, ++_trianglesCount)
_triangles[_trianglesCount] = addTriangles[i] + _verticesCount;
for (int i = 0; i < addVerticesCount; i += 2, ++_verticesCount) {
ccV2F_C4B_T2F* vertex = _vertices + _verticesCount;
vertex->vertices.x = addVertices[i];
vertex->vertices.y = addVertices[i + 1];
vertex->colors = *color;
vertex->texCoords.u = uvs[i];
vertex->texCoords.v = uvs[i + 1];
}
}
- (void) flush {
if (!_verticesCount) return;
ccGLBindTexture2D(_texture.name);
glEnableVertexAttribArray(kCCVertexAttrib_Position);
glEnableVertexAttribArray(kCCVertexAttrib_Color);
glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), &_vertices[0].vertices);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ccV2F_C4B_T2F), &_vertices[0].colors);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), &_vertices[0].texCoords);
glDrawElements(GL_TRIANGLES, _trianglesCount, GL_UNSIGNED_SHORT, _triangles);
_verticesCount = 0;
_trianglesCount = 0;
CHECK_GL_ERROR_DEBUG();
}
@end

View File

@ -30,27 +30,26 @@
#define SPINE_SHORT_NAMES
#import <spine/spine.h>
#import <spine/CCSkeleton.h>
#import <spine/SkeletonRenderer.h>
#import "cocos2d.h"
@class CCSkeletonAnimation;
@class SkeletonAnimation;
@protocol CCSkeletonAnimationDelegate <NSObject>
@optional
- (void) animationDidStart:(CCSkeletonAnimation*)animation track:(int)trackIndex;
- (void) animationWillEnd:(CCSkeletonAnimation*)animation track:(int)trackIndex;
- (void) animationDidTriggerEvent:(CCSkeletonAnimation*)animation track:(int)trackIndex event:(Event*)event;
- (void) animationDidComplete:(CCSkeletonAnimation*)animation track:(int)trackIndex loopCount:(int)loopCount;
@end
typedef void(^StartListener)(int trackIndex);
typedef void(^EndListener)(int trackIndex);
typedef void(^CompleteListener)(int trackIndex, int loopCount);
typedef void(^EventListener)(int trackIndex, spEvent* event);
/** Draws an animated skeleton, providing an AnimationState for applying one or more animations and queuing animations to be
* played later. */
@interface CCSkeletonAnimation : CCSkeleton {
@interface SkeletonAnimation : SkeletonRenderer {
AnimationState* _state;
bool _ownsAnimationStateData;
id<CCSkeletonAnimationDelegate> _delegate;
bool _delegateStart, _delegateEnd, _delegateEvent, _delegateComplete;
StartListener _startListener;
EndListener _endListener;
CompleteListener _completeListener;
EventListener _eventListener;
}
+ (id) skeletonWithData:(SkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
@ -64,15 +63,24 @@
- (void) setAnimationStateData:(AnimationStateData*)stateData;
- (void) setMixFrom:(NSString*)fromAnimation to:(NSString*)toAnimation duration:(float)duration;
- (void) setDelegate:(id<CCSkeletonAnimationDelegate>)delegate;
- (TrackEntry*) setAnimationForTrack:(int)trackIndex name:(NSString*)name loop:(bool)loop;
- (TrackEntry*) addAnimationForTrack:(int)trackIndex name:(NSString*)name loop:(bool)loop afterDelay:(int)delay;
- (TrackEntry*) getCurrentForTrack:(int)trackIndex;
- (void) clearTracks;
- (void) clearTrack:(int)trackIndex;
- (void) setListenerForEntry:(spTrackEntry*)entry onStart:(StartListener)listener;
- (void) setListenerForEntry:(spTrackEntry*)entry onEnd:(EndListener)listener;
- (void) setListenerForEntry:(spTrackEntry*)entry onComplete:(CompleteListener)listener;
- (void) setListenerForEntry:(spTrackEntry*)entry onEvent:(EventListener)listener;
- (void) onAnimationStateEvent:(int)trackIndex type:(EventType)type event:(Event*)event loopCount:(int)loopCount;
- (void) onTrackEntryEvent:(int)trackIndex type:(EventType)type event:(Event*)event loopCount:(int)loopCount;
@property (nonatomic, readonly) AnimationState* state;
@property (nonatomic, copy) StartListener startListener;
@property (nonatomic, copy) EndListener endListener;
@property (nonatomic, copy) CompleteListener completeListener;
@property (nonatomic, copy) EventListener eventListener;
@end

View File

@ -28,20 +28,58 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#import <spine/CCSkeletonAnimation.h>
#import <spine/SkeletonAnimation.h>
#import <spine/spine-cocos2d-iphone.h>
#import <spine/extension.h>
static void callback (AnimationState* state, int trackIndex, EventType type, Event* event, int loopCount) {
[(CCSkeletonAnimation*)state->context onAnimationStateEvent:trackIndex type:type event:event loopCount:loopCount];
static void animationCallback (AnimationState* state, int trackIndex, EventType type, Event* event, int loopCount) {
[(SkeletonAnimation*)state->rendererObject onAnimationStateEvent:trackIndex type:type event:event loopCount:loopCount];
}
@interface CCSkeletonAnimation (Private)
void trackEntryCallback (spAnimationState* state, int trackIndex, spEventType type, spEvent* event, int loopCount) {
[(SkeletonAnimation*)state->rendererObject onTrackEntryEvent:trackIndex type:type event:event loopCount:loopCount];
}
typedef struct _TrackEntryListeners {
StartListener startListener;
EndListener endListener;
CompleteListener completeListener;
EventListener eventListener;
} _TrackEntryListeners;
static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
if (!entry->rendererObject) {
entry->rendererObject = NEW(_TrackEntryListeners);
entry->listener = trackEntryCallback;
}
return (_TrackEntryListeners*)entry->rendererObject;
}
void disposeTrackEntry (spAnimationState* self, spTrackEntry* entry) {
if (entry->rendererObject) {
_TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject;
[listeners->startListener release];
[listeners->endListener release];
[listeners->completeListener release];
[listeners->eventListener release];
FREE(listeners);
}
_spTrackEntry_dispose(entry);
}
//
@interface SkeletonAnimation (Private)
- (void) initialize;
@end
@implementation CCSkeletonAnimation
@implementation SkeletonAnimation
@synthesize state = _state;
@synthesize startListener = _startListener;
@synthesize endListener = _endListener;
@synthesize completeListener = _completeListener;
@synthesize eventListener = _eventListener;
+ (id) skeletonWithData:(SkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
return [[[self alloc] initWithData:skeletonData ownsSkeletonData:ownsSkeletonData] autorelease];
@ -58,8 +96,11 @@ static void callback (AnimationState* state, int trackIndex, EventType type, Eve
- (void) initialize {
_ownsAnimationStateData = true;
_state = AnimationState_create(AnimationStateData_create(_skeleton->data));
_state->context = self;
_state->listener = callback;
_state->rendererObject = self;
_state->listener = animationCallback;
_spAnimationState* stateInternal = (_spAnimationState*)_state;
stateInternal->disposeTrackEntry = disposeTrackEntry;
}
- (id) initWithData:(SkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
@ -93,6 +134,11 @@ static void callback (AnimationState* state, int trackIndex, EventType type, Eve
if (_ownsAnimationStateData) AnimationStateData_dispose(_state->data);
AnimationState_dispose(_state);
[_startListener release];
[_endListener release];
[_completeListener release];
[_eventListener release];
[super dealloc];
}
@ -113,22 +159,14 @@ static void callback (AnimationState* state, int trackIndex, EventType type, Eve
_ownsAnimationStateData = false;
_state = AnimationState_create(stateData);
_state->context = self;
_state->listener = callback;
_state->rendererObject = self;
_state->listener = animationCallback;
}
- (void) setMixFrom:(NSString*)fromAnimation to:(NSString*)toAnimation duration:(float)duration {
AnimationStateData_setMixByName(_state->data, [fromAnimation UTF8String], [toAnimation UTF8String], duration);
}
- (void) setDelegate:(id<CCSkeletonAnimationDelegate>)delegate {
_delegate = delegate;
_delegateStart = [delegate respondsToSelector:@selector(animationDidStart:track:)];
_delegateEnd = [delegate respondsToSelector:@selector(animationWillEnd:track:)];
_delegateEvent = [delegate respondsToSelector:@selector(animationDidTriggerEvent:track:event:)];
_delegateComplete = [delegate respondsToSelector:@selector(animationDidComplete:track:loopCount:)];
}
- (TrackEntry*) setAnimationForTrack:(int)trackIndex name:(NSString*)name loop:(bool)loop {
Animation* animation = SkeletonData_findAnimation(_skeleton->data, [name UTF8String]);
if (!animation) {
@ -160,21 +198,56 @@ static void callback (AnimationState* state, int trackIndex, EventType type, Eve
}
- (void) onAnimationStateEvent:(int)trackIndex type:(EventType)type event:(Event*)event loopCount:(int)loopCount {
if (!_delegate) return;
switch (type) {
case ANIMATION_START:
if (_delegateStart) [_delegate animationDidStart:self track:trackIndex];
break;
case ANIMATION_END:
if (_delegateEnd) [_delegate animationWillEnd:self track:trackIndex];
break;
case ANIMATION_COMPLETE:
if (_delegateComplete) [_delegate animationDidComplete:self track:trackIndex loopCount:loopCount];
break;
case ANIMATION_EVENT:
if (_delegateEvent) [_delegate animationDidTriggerEvent:self track:trackIndex event:event];
break;
case SP_ANIMATION_START:
if (_startListener) _startListener(trackIndex);
break;
case SP_ANIMATION_END:
if (_endListener) _endListener(trackIndex);
break;
case SP_ANIMATION_COMPLETE:
if (_completeListener) _completeListener(trackIndex, loopCount);
break;
case SP_ANIMATION_EVENT:
if (_eventListener) _eventListener(trackIndex, event);
break;
}
}
- (void) onTrackEntryEvent:(int)trackIndex type:(EventType)type event:(Event*)event loopCount:(int)loopCount {
spTrackEntry* entry = spAnimationState_getCurrent(_state, trackIndex);
if (!entry->rendererObject) return;
_TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject;
switch (type) {
case SP_ANIMATION_START:
if (listeners->startListener) listeners->startListener(trackIndex);
break;
case SP_ANIMATION_END:
if (listeners->endListener) listeners->endListener(trackIndex);
break;
case SP_ANIMATION_COMPLETE:
if (listeners->completeListener) listeners->completeListener(trackIndex, loopCount);
break;
case SP_ANIMATION_EVENT:
if (listeners->eventListener) listeners->eventListener(trackIndex, event);
break;
}
}
- (void) setListenerForEntry:(spTrackEntry*)entry onStart:(StartListener)listener {
getListeners(entry)->startListener = [listener copy];
}
- (void) setListenerForEntry:(spTrackEntry*)entry onEnd:(EndListener)listener {
getListeners(entry)->endListener = [listener copy];
}
- (void) setListenerForEntry:(spTrackEntry*)entry onComplete:(CompleteListener)listener {
getListeners(entry)->completeListener = [listener copy];
}
- (void) setListenerForEntry:(spTrackEntry*)entry onEvent:(EventListener)listener {
getListeners(entry)->eventListener = [listener copy];
}
@end

View File

@ -32,18 +32,22 @@
#import <spine/spine.h>
#import "cocos2d.h"
@class PolygonBatch;
/** Draws a skeleton. */
@interface CCSkeleton : CCNodeRGBA<CCBlendProtocol> {
@interface SkeletonRenderer : CCNodeRGBA<CCBlendProtocol> {
Skeleton* _skeleton;
Bone* _rootBone;
float _timeScale;
bool _debugSlots;
bool _debugBones;
bool _premultipliedAlpha;
ccBlendFunc _blendFunc;
bool _ownsSkeletonData;
Atlas* _atlas;
PolygonBatch* batch;
float* worldVertices;
}
+ (id) skeletonWithData:(SkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
@ -54,7 +58,9 @@
- (id) initWithFile:(NSString*)skeletonDataFile atlas:(Atlas*)atlas scale:(float)scale;
- (id) initWithFile:(NSString*)skeletonDataFile atlasFile:(NSString*)atlasFile scale:(float)scale;
- (CCTextureAtlas*) getTextureAtlas:(RegionAttachment*)regionAttachment;
- (CCTexture2D*) getTextureForRegion:(RegionAttachment*)attachment;
- (CCTexture2D*) getTextureForMesh:(MeshAttachment*)attachment;
- (CCTexture2D*) getTextureForSkinnedMesh:(SkinnedMeshAttachment*)attachment;
// --- Convenience methods for common Skeleton_* functions.
- (void) updateWorldTransform;
@ -70,7 +76,8 @@
- (Slot*) findSlot:(NSString*)slotName;
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
* attached if the corresponding attachment from the old skin was attached. Returns false if the skin was not found.
* attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's setup mode
* attachment is attached from the new skin. Returns false if the skin was not found.
* @param skin May be 0.*/
- (bool) setSkin:(NSString*)skinName;

View File

@ -28,14 +28,18 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#import <spine/CCSkeleton.h>
#import <spine/SkeletonRenderer.h>
#import <spine/spine-cocos2d-iphone.h>
#import <spine/extension.h>
#import <spine/PolygonBatch.h>
@interface CCSkeleton (Private)
static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
@interface SkeletonRenderer (Private)
- (void) initialize:(SkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
@end
@implementation CCSkeleton
@implementation SkeletonRenderer
@synthesize skeleton = _skeleton;
@synthesize rootBone = _rootBone;
@ -58,6 +62,12 @@
- (void) initialize:(SkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
_ownsSkeletonData = ownsSkeletonData;
_timeScale = 1;
worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
batch = [[PolygonBatch createWithCapacity:2000] retain]; // Max number of vertices and triangles per batch.
_skeleton = Skeleton_create(skeletonData);
_rootBone = _skeleton->bones[0];
@ -65,8 +75,6 @@
_blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
[self setOpacityModifyRGB:YES];
_timeScale = 1;
[self setShaderProgram:[[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTextureColor]];
[self scheduleUpdate];
}
@ -102,7 +110,7 @@
self = [super init];
if (!self) return nil;
_atlas = Atlas_readAtlasFile([atlasFile UTF8String]);
_atlas = Atlas_createFromFile([atlasFile UTF8String], 0);
NSAssert(_atlas, ([NSString stringWithFormat:@"Error reading atlas file: %@", atlasFile]));
if (!_atlas) return 0;
@ -122,6 +130,8 @@
if (_ownsSkeletonData) SkeletonData_dispose(_skeleton->data);
if (_atlas) Atlas_dispose(_atlas);
Skeleton_dispose(_skeleton);
[batch release];
FREE(worldVertices);
[super dealloc];
}
@ -132,68 +142,99 @@
- (void) draw {
CC_NODE_DRAW_SETUP();
ccGLBlendFunc(_blendFunc.src, _blendFunc.dst);
ccColor3B color = self.color;
_skeleton->r = color.r / (float)255;
_skeleton->g = color.g / (float)255;
_skeleton->b = color.b / (float)255;
ccColor3B nodeColor = self.color;
_skeleton->r = nodeColor.r / (float)255;
_skeleton->g = nodeColor.g / (float)255;
_skeleton->b = nodeColor.b / (float)255;
_skeleton->a = self.opacity / (float)255;
int additive = 0;
CCTextureAtlas* textureAtlas = 0;
ccV3F_C4B_T2F_Quad quad;
quad.tl.vertices.z = 0;
quad.tr.vertices.z = 0;
quad.bl.vertices.z = 0;
quad.br.vertices.z = 0;
int additive = -1;
ccColor4B color;
const float* uvs = 0;
int verticesCount = 0;
const int* triangles = 0;
int trianglesCount = 0;
float r = 0, g = 0, b = 0, a = 0;
for (int i = 0, n = _skeleton->slotCount; i < n; i++) {
Slot* slot = _skeleton->drawOrder[i];
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
RegionAttachment* attachment = (RegionAttachment*)slot->attachment;
CCTextureAtlas* regionTextureAtlas = [self getTextureAtlas:attachment];
if (slot->data->additiveBlending != additive) {
if (textureAtlas) {
[textureAtlas drawQuads];
[textureAtlas removeAllQuads];
if (!slot->attachment) continue;
CCTexture2D *texture = 0;
switch (slot->attachment->type) {
case SP_ATTACHMENT_REGION: {
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
spRegionAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot->bone, worldVertices);
texture = [self getTextureForRegion:attachment];
uvs = attachment->uvs;
verticesCount = 8;
triangles = quadTriangles;
trianglesCount = 6;
r = attachment->r;
g = attachment->g;
b = attachment->b;
a = attachment->a;
break;
}
case SP_ATTACHMENT_MESH: {
spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
spMeshAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot, worldVertices);
texture = [self getTextureForMesh:attachment];
uvs = attachment->uvs;
verticesCount = attachment->verticesCount;
triangles = attachment->triangles;
trianglesCount = attachment->trianglesCount;
r = attachment->r;
g = attachment->g;
b = attachment->b;
a = attachment->a;
break;
}
case SP_ATTACHMENT_SKINNED_MESH: {
spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
spSkinnedMeshAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot, worldVertices);
texture = [self getTextureForSkinnedMesh:attachment];
uvs = attachment->uvs;
verticesCount = attachment->uvsCount;
triangles = attachment->triangles;
trianglesCount = attachment->trianglesCount;
r = attachment->r;
g = attachment->g;
b = attachment->b;
a = attachment->a;
break;
}
default: ;
}
if (texture) {
if (slot->data->additiveBlending != additive) {
[batch flush];
ccGLBlendFunc(_blendFunc.src, slot->data->additiveBlending ? GL_ONE : _blendFunc.dst);
additive = slot->data->additiveBlending;
}
additive = !additive;
ccGLBlendFunc(_blendFunc.src, additive ? GL_ONE : _blendFunc.dst);
} else if (regionTextureAtlas != textureAtlas && textureAtlas) {
[textureAtlas drawQuads];
[textureAtlas removeAllQuads];
color.a = _skeleton->a * slot->a * a * 255;
float multiplier = _premultipliedAlpha ? color.a : 255;
color.r = _skeleton->r * slot->r * r * multiplier;
color.g = _skeleton->g * slot->g * g * multiplier;
color.b = _skeleton->b * slot->b * b * multiplier;
[batch add:texture vertices:worldVertices uvs:uvs verticesCount:verticesCount
triangles:triangles trianglesCount:trianglesCount color:&color];
}
textureAtlas = regionTextureAtlas;
if (textureAtlas.capacity == textureAtlas.totalQuads) {
[textureAtlas drawQuads];
[textureAtlas removeAllQuads];
if (![textureAtlas resizeCapacity:textureAtlas.capacity * 2]) return;
}
RegionAttachment_updateQuad(attachment, slot, &quad, _premultipliedAlpha);
[textureAtlas updateQuad:&quad atIndex:textureAtlas.totalQuads];
}
if (textureAtlas) {
[textureAtlas drawQuads];
[textureAtlas removeAllQuads];
}
[batch flush];
if (_debugSlots) {
// Slots.
ccDrawColor4B(0, 0, 255, 255);
glLineWidth(1);
CGPoint points[4];
ccV3F_C4B_T2F_Quad quad;
for (int i = 0, n = _skeleton->slotCount; i < n; i++) {
Slot* slot = _skeleton->drawOrder[i];
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
RegionAttachment* attachment = (RegionAttachment*)slot->attachment;
RegionAttachment_updateQuad(attachment, slot, &quad, _premultipliedAlpha);
points[0] = ccp(quad.bl.vertices.x, quad.bl.vertices.y);
points[1] = ccp(quad.br.vertices.x, quad.br.vertices.y);
points[2] = ccp(quad.tr.vertices.x, quad.tr.vertices.y);
points[3] = ccp(quad.tl.vertices.x, quad.tl.vertices.y);
spRegionAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot->bone, worldVertices);
points[0] = ccp(worldVertices[0], worldVertices[1]);
points[1] = ccp(worldVertices[2], worldVertices[3]);
points[2] = ccp(worldVertices[4], worldVertices[5]);
points[3] = ccp(worldVertices[6], worldVertices[7]);
ccDrawPoly(points, 4, true);
}
}
@ -218,8 +259,16 @@
}
}
- (CCTextureAtlas*) getTextureAtlas:(RegionAttachment*)regionAttachment {
return (CCTextureAtlas*)((AtlasRegion*)regionAttachment->rendererObject)->page->rendererObject;
- (CCTexture2D*) getTextureForRegion:(RegionAttachment*)attachment {
return (CCTexture2D*)((AtlasRegion*)attachment->rendererObject)->page->rendererObject;
}
- (CCTexture2D*) getTextureForMesh:(MeshAttachment*)attachment {
return (CCTexture2D*)((AtlasRegion*)attachment->rendererObject)->page->rendererObject;
}
- (CCTexture2D*) getTextureForSkinnedMesh:(SkinnedMeshAttachment*)attachment {
return (CCTexture2D*)((AtlasRegion*)attachment->rendererObject)->page->rendererObject;
}
- (CGRect) boundingBox {

View File

@ -31,17 +31,5 @@
#define SPINE_SHORT_NAMES
#import <spine/spine.h>
#import "cocos2d.h"
#import "CCSkeleton.h"
#import "CCSkeletonAnimation.h"
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, ccV3F_C4B_T2F_Quad* quad, bool premultipliedAlpha);
#ifdef __cplusplus
}
}
#endif
#import <spine/SkeletonRenderer.h>
#import <spine/SkeletonAnimation.h>

View File

@ -28,78 +28,21 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <spine/spine-cocos2d-iphone.h>
#include <spine/extension.h>
#import <spine/spine-cocos2d-iphone.h>
#import <spine/extension.h>
void _AtlasPage_createTexture (AtlasPage* self, const char* path) {
CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:@(path)];
CCTextureAtlas* textureAtlas = [[CCTextureAtlas alloc] initWithTexture:texture capacity:128];
self->rendererObject = textureAtlas;
CCTexture2D* texture = [[[CCTextureCache sharedTextureCache] addImage:@(path)] retain];
self->rendererObject = texture;
CGSize size = texture.contentSizeInPixels;
self->width = size.width;
self->height = size.height;
}
void _AtlasPage_disposeTexture (AtlasPage* self) {
[(CCTextureAtlas*)self->rendererObject release];
[(CCTexture2D*)self->rendererObject release];
}
char* _Util_readFile (const char* path, int* length) {
return _readFile([[[CCFileUtils sharedFileUtils] fullPathForFilename:@(path)] UTF8String], length);
}
/**/
void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, ccV3F_C4B_T2F_Quad* quad, bool premultipliedAlpha) {
float vertices[8];
RegionAttachment_computeWorldVertices(self, slot->skeleton->x, slot->skeleton->y, slot->bone, vertices);
GLubyte r = slot->skeleton->r * slot->r * 255;
GLubyte g = slot->skeleton->g * slot->g * 255;
GLubyte b = slot->skeleton->b * slot->b * 255;
float normalizedAlpha = slot->skeleton->a * slot->a;
if (premultipliedAlpha) {
r *= normalizedAlpha;
g *= normalizedAlpha;
b *= normalizedAlpha;
}
GLubyte a = normalizedAlpha * 255;
quad->bl.colors.r = r;
quad->bl.colors.g = g;
quad->bl.colors.b = b;
quad->bl.colors.a = a;
quad->tl.colors.r = r;
quad->tl.colors.g = g;
quad->tl.colors.b = b;
quad->tl.colors.a = a;
quad->tr.colors.r = r;
quad->tr.colors.g = g;
quad->tr.colors.b = b;
quad->tr.colors.a = a;
quad->br.colors.r = r;
quad->br.colors.g = g;
quad->br.colors.b = b;
quad->br.colors.a = a;
quad->bl.vertices.x = vertices[VERTEX_X1];
quad->bl.vertices.y = vertices[VERTEX_Y1];
quad->tl.vertices.x = vertices[VERTEX_X2];
quad->tl.vertices.y = vertices[VERTEX_Y2];
quad->tr.vertices.x = vertices[VERTEX_X3];
quad->tr.vertices.y = vertices[VERTEX_Y3];
quad->br.vertices.x = vertices[VERTEX_X4];
quad->br.vertices.y = vertices[VERTEX_Y4];
quad->bl.texCoords.u = self->uvs[VERTEX_X1];
quad->bl.texCoords.v = self->uvs[VERTEX_Y1];
quad->tl.texCoords.u = self->uvs[VERTEX_X2];
quad->tl.texCoords.v = self->uvs[VERTEX_Y2];
quad->tr.texCoords.u = self->uvs[VERTEX_X3];
quad->tr.texCoords.v = self->uvs[VERTEX_Y3];
quad->br.texCoords.u = self->uvs[VERTEX_X4];
quad->br.texCoords.v = self->uvs[VERTEX_Y4];
}
#ifdef __cplusplus
}
#endif

View File

@ -1,19 +0,0 @@
# spine-cocos2d-iphone
The spine-cocos2d-iphone runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [cocos2d-iphone](http://www.cocos2d-iphone.org/). spine-cocos2d-iphone is based on [spine-c](https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-c).
## Setup
1. Download the Spine Runtimes source using [git](https://help.github.com/articles/set-up-git) or by downloading it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip).
1. Place the `cocos2d`, `CocosDenshion`, and `kazmath` directories from a cocos2d-iphone (v2.1-rc1 or later) distribution into the `spine-cocos2d-iphone/libs` directory. Also place `LICENSE_cocos2d.txt`, `LICENSE_CocosDenshion.txt`, and `LICENSE_Kazmath.txt` into the `spine-cocos2d-iphone/libs` directory.
1. Open the XCode project file for iOS or Mac from the `spine-cocos2d-iphone` directory.
Alternatively, the contents of the `spine-c/src`, `spine-c/include` and `spine-cocos2d-iphone/src` directories can be copied into your project. Be sure your header search path will find the contents of the `spine-c/include` and `spine-cocos2d-iphone/src` directories. Note that the includes use `spine/Xxx.h`, so the `spine` directory cannot be omitted when copying the files.
## Examples
[Simple example](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-cocos2d-iphone/example/ExampleLayer.m#L13)
## Links
[podspec](https://github.com/ldomaradzki/spine-runtimes/blob/master/Spine-Cocos2d-iPhone.podspec)

View File

@ -1,162 +0,0 @@
#import "cocos2d.h"
#import "AppDelegate.h"
#import "ExampleLayer.h"
@implementation MyNavigationController
// The available orientations should be defined in the Info.plist file.
// And in iOS 6+ only, you can override it in the Root View controller in the "supportedInterfaceOrientations" method.
// Only valid for iOS 6+. NOT VALID for iOS 4 / 5.
-(NSUInteger)supportedInterfaceOrientations {
// iPhone only
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone )
return UIInterfaceOrientationMaskLandscape;
// iPad only
return UIInterfaceOrientationMaskLandscape;
}
// Supported orientations. Customize it for your own needs
// Only valid on iOS 4 / 5. NOT VALID for iOS 6.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// iPhone only
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone )
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
// iPad only
// iPhone only
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
// This is needed for iOS4 and iOS5 in order to ensure
// that the 1st scene has the correct dimensions
// This is not needed on iOS6 and could be added to the application:didFinish...
-(void) directorDidReshapeProjection:(CCDirector*)director {
if(director.runningScene == nil) {
// Add the first scene to the stack. The director will draw it immediately into the framebuffer. (Animation is started automatically when the view is displayed.)
// and add the scene to the stack. The director will run it when it automatically when the view is displayed.
[director runWithScene: [ExampleLayer scene]];
}
}
@end
@implementation AppController
@synthesize window=window_, navController=navController_, director=director_;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Create the main window
window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Create an CCGLView with a RGB565 color buffer, and a depth buffer of 0-bits
CCGLView *glView = [CCGLView viewWithFrame:[window_ bounds]
pixelFormat:kEAGLColorFormatRGB565 //kEAGLColorFormatRGBA8
depthFormat:0 //GL_DEPTH_COMPONENT24_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
director_.wantsFullScreenLayout = YES;
// Display FSP and SPF
[director_ setDisplayStats:YES];
// set FPS at 60
[director_ setAnimationInterval:1.0/60];
// attach the openglView to the director
[director_ setView:glView];
// 2D projection
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director_ enableRetinaDisplay:YES] )
CCLOG(@"Retina Display Not supported");
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change this setting at any time.
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// If the 1st suffix is not found and if fallback is enabled then fallback suffixes are going to searched. If none is found, it will try with the name without suffix.
// On iPad HD : "-ipadhd", "-ipad", "-hd"
// On iPad : "-ipad", "-hd"
// On iPhone HD: "-hd"
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO]; // Default: NO. No fallback suffixes are going to be used
[sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"]; // Default on iPhone RetinaDisplay is "-hd"
[sharedFileUtils setiPadSuffix:@"-ipad"]; // Default on iPad is "ipad"
[sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"]; // Default on iPad RetinaDisplay is "-ipadhd"
// Assume that PVR images have premultiplied alpha
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
// Create a Navigation Controller with the Director
navController_ = [[MyNavigationController alloc] initWithRootViewController:director_];
navController_.navigationBarHidden = YES;
// for rotation and other messages
[director_ setDelegate:navController_];
// set the Navigation Controller as the root view controller
[window_ setRootViewController:navController_];
// make main window visible
[window_ makeKeyAndVisible];
return YES;
}
// getting a call, pause the game
-(void) applicationWillResignActive:(UIApplication *)application {
if( [navController_ visibleViewController] == director_ )
[director_ pause];
}
// call got rejected
-(void) applicationDidBecomeActive:(UIApplication *)application {
[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
if( [navController_ visibleViewController] == director_ )
[director_ resume];
}
-(void) applicationDidEnterBackground:(UIApplication*)application {
if( [navController_ visibleViewController] == director_ )
[director_ stopAnimation];
}
-(void) applicationWillEnterForeground:(UIApplication*)application {
if( [navController_ visibleViewController] == director_ )
[director_ startAnimation];
}
// application will be killed
- (void)applicationWillTerminate:(UIApplication *)application {
CC_DIRECTOR_END();
}
// purge memory
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
[[CCDirector sharedDirector] purgeCachedData];
}
// next delta time will be zero
-(void) applicationSignificantTimeChange:(UIApplication *)application {
[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
}
- (void) dealloc {
[window_ release];
[navController_ release];
[super dealloc];
}
@end

View File

@ -1,499 +0,0 @@
{
"bones": [
{ "name": "root" },
{ "name": "hip", "parent": "root", "x": 0.64, "y": 114.41 },
{ "name": "left upper leg", "parent": "hip", "length": 50.39, "x": 14.45, "y": 2.81, "rotation": -89.09 },
{ "name": "left lower leg", "parent": "left upper leg", "length": 49.89, "x": 56.34, "y": 0.98, "rotation": -16.65 },
{ "name": "left foot", "parent": "left lower leg", "length": 46.5, "x": 58.94, "y": -7.61, "rotation": 102.43 },
{ "name": "right upper leg", "parent": "hip", "length": 42.45, "x": -20.07, "y": -6.83, "rotation": -97.49 },
{ "name": "right lower leg", "parent": "right upper leg", "length": 58.52, "x": 42.99, "y": -0.61, "rotation": -14.34 },
{ "name": "right foot", "parent": "right lower leg", "length": 45.45, "x": 64.88, "y": 0.04, "rotation": 110.3 },
{ "name": "torso", "parent": "hip", "length": 85.82, "x": -6.42, "y": 1.97, "rotation": 93.92 },
{ "name": "neck", "parent": "torso", "length": 18.38, "x": 81.67, "y": -6.34, "rotation": -1.51 },
{ "name": "head", "parent": "neck", "length": 68.28, "x": 20.93, "y": 11.59, "rotation": -13.92 },
{ "name": "right shoulder", "parent": "torso", "length": 37.24, "x": 76.02, "y": 18.14, "rotation": 133.88 },
{ "name": "right arm", "parent": "right shoulder", "length": 36.74, "x": 37.6, "y": 0.31, "rotation": 36.32 },
{ "name": "right hand", "parent": "right arm", "length": 15.32, "x": 36.9, "y": 0.34, "rotation": 2.35 },
{ "name": "left shoulder", "parent": "torso", "length": 35.43, "x": 74.04, "y": -20.38, "rotation": -156.96 },
{ "name": "left arm", "parent": "left shoulder", "length": 35.62, "x": 37.85, "y": -2.34, "rotation": 28.16 },
{ "name": "left hand", "parent": "left arm", "length": 11.52, "x": 35.62, "y": 0.07, "rotation": 2.7 },
{ "name": "pelvis", "parent": "hip", "x": 1.41, "y": -6.57 }
],
"slots": [
{ "name": "left shoulder", "bone": "left shoulder", "attachment": "left shoulder" },
{ "name": "left arm", "bone": "left arm", "attachment": "left arm" },
{ "name": "left hand item", "bone": "left hand", "attachment": "spear" },
{ "name": "left hand", "bone": "left hand", "attachment": "left hand" },
{ "name": "left foot", "bone": "left foot", "attachment": "left foot" },
{ "name": "left lower leg", "bone": "left lower leg", "attachment": "left lower leg" },
{ "name": "left upper leg", "bone": "left upper leg", "attachment": "left upper leg" },
{ "name": "neck", "bone": "neck", "attachment": "neck" },
{ "name": "torso", "bone": "torso", "attachment": "torso" },
{ "name": "pelvis", "bone": "pelvis", "attachment": "pelvis" },
{ "name": "right foot", "bone": "right foot", "attachment": "right foot" },
{ "name": "right lower leg", "bone": "right lower leg", "attachment": "right lower leg" },
{ "name": "undie straps", "bone": "pelvis", "attachment": "undie straps" },
{ "name": "undies", "bone": "pelvis", "attachment": "undies" },
{ "name": "right upper leg", "bone": "right upper leg", "attachment": "right upper leg" },
{ "name": "head", "bone": "head", "attachment": "head" },
{ "name": "eyes", "bone": "head" },
{ "name": "right shoulder", "bone": "right shoulder", "attachment": "right shoulder" },
{ "name": "right arm", "bone": "right arm", "attachment": "right arm" },
{ "name": "right hand item", "bone": "right hand", "attachment": "dagger" },
{ "name": "right hand", "bone": "right hand", "attachment": "right hand" }
],
"skins": {
"default": {
"left hand item": {
"dagger": { "x": 7.88, "y": -23.45, "rotation": 10.47, "width": 26, "height": 108 },
"spear": { "x": -4.55, "y": 39.2, "rotation": 13.04, "width": 22, "height": 368 }
},
"right hand item": {
"dagger": { "x": 6.51, "y": -24.15, "rotation": -8.06, "width": 26, "height": 108 }
}
},
"goblin": {
"neck": {
"neck": { "name": "goblin/neck", "x": 10.1, "y": 0.42, "rotation": -93.69, "width": 36, "height": 41 }
},
"undies": {
"undies": { "name": "goblin/undies", "x": 6.3, "y": 0.12, "rotation": 0.91, "width": 36, "height": 29 }
},
"right hand": {
"right hand": { "name": "goblin/right-hand", "x": 7.88, "y": 2.78, "rotation": 91.96, "width": 36, "height": 37 }
},
"right arm": {
"right arm": { "name": "goblin/right-arm", "x": 16.44, "y": -1.04, "rotation": 94.32, "width": 23, "height": 50 }
},
"head": {
"head": { "name": "goblin/head", "x": 25.73, "y": 2.33, "rotation": -92.29, "width": 103, "height": 66 }
},
"left shoulder": {
"left shoulder": { "name": "goblin/left-shoulder", "x": 15.56, "y": -2.26, "rotation": 62.01, "width": 29, "height": 44 }
},
"left arm": {
"left arm": {
"name": "goblin/left-arm",
"x": 16.7,
"y": -1.69,
"scaleX": 1.057,
"scaleY": 1.057,
"rotation": 33.84,
"width": 37,
"height": 35
}
},
"left hand": {
"left hand": {
"name": "goblin/left-hand",
"x": 3.47,
"y": 3.41,
"scaleX": 0.892,
"scaleY": 0.892,
"rotation": 31.14,
"width": 36,
"height": 41
}
},
"right lower leg": {
"right lower leg": { "name": "goblin/right-lower-leg", "x": 25.68, "y": -3.15, "rotation": 111.83, "width": 36, "height": 76 }
},
"right upper leg": {
"right upper leg": { "name": "goblin/right-upper-leg", "x": 20.35, "y": 1.47, "rotation": 97.49, "width": 34, "height": 63 }
},
"pelvis": {
"pelvis": { "name": "goblin/pelvis", "x": -5.61, "y": 0.76, "width": 62, "height": 43 }
},
"left lower leg": {
"left lower leg": { "name": "goblin/left-lower-leg", "x": 23.58, "y": -2.06, "rotation": 105.75, "width": 33, "height": 70 }
},
"left upper leg": {
"left upper leg": { "name": "goblin/left-upper-leg", "x": 29.68, "y": -3.87, "rotation": 89.09, "width": 33, "height": 73 }
},
"torso": {
"torso": { "name": "goblin/torso", "x": 38.09, "y": -3.87, "rotation": -94.95, "width": 68, "height": 96 }
},
"right shoulder": {
"right shoulder": { "name": "goblin/right-shoulder", "x": 15.68, "y": -1.03, "rotation": 130.65, "width": 39, "height": 45 }
},
"right foot": {
"right foot": { "name": "goblin/right-foot", "x": 23.56, "y": 9.8, "rotation": 1.52, "width": 63, "height": 33 }
},
"left foot": {
"left foot": { "name": "goblin/left-foot", "x": 24.85, "y": 8.74, "rotation": 3.32, "width": 65, "height": 31 }
},
"undie straps": {
"undie straps": { "name": "goblin/undie-straps", "x": -3.87, "y": 13.1, "scaleX": 1.089, "width": 55, "height": 19 }
},
"eyes": {
"eyes closed": { "name": "goblin/eyes-closed", "x": 32.21, "y": -21.27, "rotation": -88.92, "width": 34, "height": 12 }
}
},
"goblingirl": {
"left upper leg": {
"left upper leg": { "name": "goblingirl/left-upper-leg", "x": 30.21, "y": -2.95, "rotation": 89.09, "width": 33, "height": 70 }
},
"left lower leg": {
"left lower leg": { "name": "goblingirl/left-lower-leg", "x": 25.02, "y": -0.6, "rotation": 105.75, "width": 33, "height": 70 }
},
"left foot": {
"left foot": { "name": "goblingirl/left-foot", "x": 25.17, "y": 7.92, "rotation": 3.32, "width": 65, "height": 31 }
},
"right upper leg": {
"right upper leg": { "name": "goblingirl/right-upper-leg", "x": 19.69, "y": 2.13, "rotation": 97.49, "width": 34, "height": 63 }
},
"right lower leg": {
"right lower leg": { "name": "goblingirl/right-lower-leg", "x": 26.15, "y": -3.27, "rotation": 111.83, "width": 36, "height": 76 }
},
"right foot": {
"right foot": { "name": "goblingirl/right-foot", "x": 23.46, "y": 9.66, "rotation": 1.52, "width": 63, "height": 33 }
},
"torso": {
"torso": { "name": "goblingirl/torso", "x": 36.28, "y": -5.14, "rotation": -95.74, "width": 68, "height": 96 }
},
"left shoulder": {
"left shoulder": { "name": "goblingirl/left-shoulder", "x": 19.8, "y": -0.42, "rotation": 61.21, "width": 28, "height": 46 }
},
"left arm": {
"left arm": { "name": "goblingirl/left-arm", "x": 19.64, "y": -2.42, "rotation": 33.05, "width": 37, "height": 35 }
},
"left hand": {
"left hand": {
"name": "goblingirl/left-hand",
"x": 4.34,
"y": 2.39,
"scaleX": 0.896,
"scaleY": 0.896,
"rotation": 30.34,
"width": 35,
"height": 40
}
},
"neck": {
"neck": { "name": "goblingirl/neck", "x": 6.16, "y": -3.14, "rotation": -98.86, "width": 35, "height": 41 }
},
"head": {
"head": { "name": "goblingirl/head", "x": 27.71, "y": -4.32, "rotation": -85.58, "width": 103, "height": 81 }
},
"right shoulder": {
"right shoulder": { "name": "goblingirl/right-shoulder", "x": 14.46, "y": 0.45, "rotation": 129.85, "width": 39, "height": 45 }
},
"right arm": {
"right arm": { "name": "goblingirl/right-arm", "x": 16.85, "y": -0.66, "rotation": 93.52, "width": 28, "height": 50 }
},
"right hand": {
"right hand": { "name": "goblingirl/right-hand", "x": 7.21, "y": 3.43, "rotation": 91.16, "width": 36, "height": 37 }
},
"pelvis": {
"pelvis": { "name": "goblingirl/pelvis", "x": -3.87, "y": 3.18, "width": 62, "height": 43 }
},
"undie straps": {
"undie straps": { "name": "goblingirl/undie-straps", "x": -1.51, "y": 14.18, "width": 55, "height": 19 }
},
"undies": {
"undies": { "name": "goblingirl/undies", "x": 5.4, "y": 1.7, "width": 36, "height": 29 }
},
"eyes": {
"eyes closed": { "name": "goblingirl/eyes-closed", "x": 28, "y": -25.54, "rotation": -87.04, "width": 37, "height": 21 }
}
}
},
"animations": {
"walk": {
"bones": {
"left upper leg": {
"rotate": [
{ "time": 0, "angle": -26.55 },
{ "time": 0.1333, "angle": -8.78 },
{ "time": 0.2333, "angle": 9.51 },
{ "time": 0.3666, "angle": 30.74 },
{ "time": 0.5, "angle": 25.33 },
{ "time": 0.6333, "angle": 26.11 },
{ "time": 0.7333, "angle": -7.7 },
{ "time": 0.8666, "angle": -21.19 },
{ "time": 1, "angle": -26.55 }
],
"translate": [
{ "time": 0, "x": -1.32, "y": 1.7 },
{ "time": 0.3666, "x": -0.06, "y": 2.42 },
{ "time": 1, "x": -1.32, "y": 1.7 }
]
},
"right upper leg": {
"rotate": [
{ "time": 0, "angle": 42.45 },
{ "time": 0.1333, "angle": 52.1 },
{ "time": 0.2333, "angle": 8.53 },
{ "time": 0.5, "angle": -16.93 },
{ "time": 0.6333, "angle": 1.89 },
{
"time": 0.7333,
"angle": 28.06,
"curve": [ 0.462, 0.11, 1, 1 ]
},
{
"time": 0.8666,
"angle": 58.68,
"curve": [ 0.5, 0.02, 1, 1 ]
},
{ "time": 1, "angle": 42.45 }
],
"translate": [
{ "time": 0, "x": 6.23, "y": 0 },
{ "time": 0.2333, "x": 2.14, "y": 2.4 },
{ "time": 0.5, "x": 2.44, "y": 4.8 },
{ "time": 1, "x": 6.23, "y": 0 }
]
},
"left lower leg": {
"rotate": [
{ "time": 0, "angle": -22.98 },
{ "time": 0.1333, "angle": -63.5 },
{ "time": 0.2333, "angle": -73.76 },
{ "time": 0.5, "angle": 5.11 },
{ "time": 0.6333, "angle": -28.29 },
{ "time": 0.7333, "angle": 4.08 },
{ "time": 0.8666, "angle": 3.53 },
{ "time": 1, "angle": -22.98 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0 },
{ "time": 0.2333, "x": 2.55, "y": -0.47 },
{ "time": 0.5, "x": 0, "y": 0, "curve": "stepped" },
{ "time": 1, "x": 0, "y": 0 }
]
},
"left foot": {
"rotate": [
{ "time": 0, "angle": -3.69 },
{ "time": 0.1333, "angle": -10.42 },
{ "time": 0.2333, "angle": -5.01 },
{ "time": 0.3666, "angle": 3.87 },
{ "time": 0.5, "angle": -3.87 },
{ "time": 0.6333, "angle": 2.78 },
{ "time": 0.7333, "angle": 1.68 },
{ "time": 0.8666, "angle": -8.54 },
{ "time": 1, "angle": -3.69 }
]
},
"right shoulder": {
"rotate": [
{
"time": 0,
"angle": 5.29,
"curve": [ 0.264, 0, 0.75, 1 ]
},
{ "time": 0.6333, "angle": 6.65 },
{ "time": 1, "angle": 5.29 }
]
},
"right arm": {
"rotate": [
{
"time": 0,
"angle": -4.02,
"curve": [ 0.267, 0, 0.804, 0.99 ]
},
{
"time": 0.6333,
"angle": 19.78,
"curve": [ 0.307, 0, 0.787, 0.99 ]
},
{ "time": 1, "angle": -4.02 }
]
},
"right hand": {
"rotate": [
{ "time": 0, "angle": 8.98 },
{ "time": 0.6333, "angle": 0.51 },
{ "time": 1, "angle": 8.98 }
]
},
"left shoulder": {
"rotate": [
{
"time": 0,
"angle": 6.25,
"curve": [ 0.339, 0, 0.683, 1 ]
},
{
"time": 0.5,
"angle": -11.78,
"curve": [ 0.281, 0, 0.686, 0.99 ]
},
{ "time": 1, "angle": 6.25 }
],
"translate": [
{ "time": 0, "x": 1.15, "y": 0.23 }
]
},
"left hand": {
"rotate": [
{
"time": 0,
"angle": -21.23,
"curve": [ 0.295, 0, 0.755, 0.98 ]
},
{
"time": 0.5,
"angle": -27.28,
"curve": [ 0.241, 0, 0.75, 0.97 ]
},
{ "time": 1, "angle": -21.23 }
]
},
"left arm": {
"rotate": [
{
"time": 0,
"angle": 28.37,
"curve": [ 0.339, 0, 0.683, 1 ]
},
{
"time": 0.5,
"angle": 60.09,
"curve": [ 0.281, 0, 0.686, 0.99 ]
},
{ "time": 1, "angle": 28.37 }
]
},
"torso": {
"rotate": [
{ "time": 0, "angle": -10.28 },
{
"time": 0.1333,
"angle": -15.38,
"curve": [ 0.545, 0, 0.818, 1 ]
},
{
"time": 0.3666,
"angle": -9.78,
"curve": [ 0.58, 0.17, 0.669, 0.99 ]
},
{
"time": 0.6333,
"angle": -15.75,
"curve": [ 0.235, 0.01, 0.795, 1 ]
},
{
"time": 0.8666,
"angle": -7.06,
"curve": [ 0.209, 0, 0.816, 0.98 ]
},
{ "time": 1, "angle": -10.28 }
],
"translate": [
{ "time": 0, "x": -1.29, "y": 1.68 }
]
},
"right foot": {
"rotate": [
{ "time": 0, "angle": -5.25 },
{ "time": 0.2333, "angle": -1.91 },
{ "time": 0.3666, "angle": -6.45 },
{ "time": 0.5, "angle": -5.39 },
{ "time": 0.7333, "angle": -11.68 },
{ "time": 0.8666, "angle": 0.46 },
{ "time": 1, "angle": -5.25 }
]
},
"right lower leg": {
"rotate": [
{
"time": 0,
"angle": -3.39,
"curve": [ 0.316, 0.01, 0.741, 0.98 ]
},
{
"time": 0.1333,
"angle": -45.53,
"curve": [ 0.229, 0, 0.738, 0.97 ]
},
{ "time": 0.2333, "angle": -4.83 },
{ "time": 0.5, "angle": -19.53 },
{ "time": 0.6333, "angle": -64.8 },
{
"time": 0.7333,
"angle": -82.56,
"curve": [ 0.557, 0.18, 1, 1 ]
},
{ "time": 1, "angle": -3.39 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
{ "time": 0.5, "x": 0, "y": 0 },
{ "time": 0.6333, "x": 2.18, "y": 0.21 },
{ "time": 1, "x": 0, "y": 0 }
]
},
"hip": {
"rotate": [
{ "time": 0, "angle": 0, "curve": "stepped" },
{ "time": 1, "angle": 0 }
],
"translate": [
{ "time": 0, "x": 0, "y": -4.16 },
{
"time": 0.1333,
"x": 0,
"y": -7.05,
"curve": [ 0.359, 0.47, 0.646, 0.74 ]
},
{ "time": 0.3666, "x": 0, "y": 6.78 },
{ "time": 0.5, "x": 0, "y": -6.13 },
{
"time": 0.6333,
"x": 0,
"y": -7.05,
"curve": [ 0.359, 0.47, 0.646, 0.74 ]
},
{ "time": 0.8666, "x": 0, "y": 6.78 },
{ "time": 1, "x": 0, "y": -4.16 }
]
},
"neck": {
"rotate": [
{ "time": 0, "angle": 3.6 },
{ "time": 0.1333, "angle": 17.49 },
{ "time": 0.2333, "angle": 6.1 },
{ "time": 0.3666, "angle": 3.45 },
{ "time": 0.5, "angle": 5.17 },
{ "time": 0.6333, "angle": 18.36 },
{ "time": 0.7333, "angle": 6.09 },
{ "time": 0.8666, "angle": 2.28 },
{ "time": 1, "angle": 3.6 }
]
},
"head": {
"rotate": [
{
"time": 0,
"angle": 3.6,
"curve": [ 0, 0, 0.704, 1.17 ]
},
{ "time": 0.1333, "angle": -0.2 },
{ "time": 0.2333, "angle": 6.1 },
{ "time": 0.3666, "angle": 3.45 },
{
"time": 0.5,
"angle": 5.17,
"curve": [ 0, 0, 0.704, 1.61 ]
},
{ "time": 0.6666, "angle": 1.1 },
{ "time": 0.7333, "angle": 6.09 },
{ "time": 0.8666, "angle": 2.28 },
{ "time": 1, "angle": 3.6 }
]
}
},
"slots": {
"eyes": {
"attachment": [
{ "time": 0.7, "name": "eyes closed" },
{ "time": 0.8, "name": null }
]
}
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

View File

@ -1,166 +0,0 @@
spineboy.png
format: RGBA8888
filter: Linear,Linear
repeat: none
head
rotate: false
xy: 1, 122
size: 121, 132
orig: 121, 132
offset: 0, 0
index: -1
torso
rotate: false
xy: 1, 28
size: 68, 92
orig: 68, 92
offset: 0, 0
index: -1
left-pant-bottom
rotate: false
xy: 1, 4
size: 44, 22
orig: 44, 22
offset: 0, 0
index: -1
right-pant-bottom
rotate: false
xy: 47, 8
size: 46, 18
orig: 46, 18
offset: 0, 0
index: -1
right-upper-leg
rotate: false
xy: 71, 50
size: 44, 70
orig: 44, 70
offset: 0, 0
index: -1
pelvis
rotate: false
xy: 95, 1
size: 63, 47
orig: 63, 47
offset: 0, 0
index: -1
left-upper-leg
rotate: false
xy: 117, 53
size: 33, 67
orig: 33, 67
offset: 0, 0
index: -1
right-foot
rotate: false
xy: 160, 224
size: 67, 30
orig: 67, 30
offset: 0, 0
index: -1
left-shoulder
rotate: false
xy: 124, 201
size: 34, 53
orig: 34, 53
offset: 0, 0
index: -1
left-ankle
rotate: false
xy: 229, 222
size: 25, 32
orig: 25, 32
offset: 0, 0
index: -1
left-foot
rotate: false
xy: 160, 192
size: 65, 30
orig: 65, 30
offset: 0, 0
index: -1
neck
rotate: false
xy: 124, 171
size: 34, 28
orig: 34, 28
offset: 0, 0
index: -1
right-arm
rotate: false
xy: 124, 124
size: 21, 45
orig: 21, 45
offset: 0, 0
index: -1
right-ankle
rotate: false
xy: 227, 190
size: 25, 30
orig: 25, 30
offset: 0, 0
index: -1
left-hand
rotate: false
xy: 147, 131
size: 35, 38
orig: 35, 38
offset: 0, 0
index: -1
left-arm
rotate: false
xy: 184, 161
size: 35, 29
orig: 35, 29
offset: 0, 0
index: -1
eyes-closed
rotate: false
xy: 221, 161
size: 34, 27
orig: 34, 27
offset: 0, 0
index: -1
right-lower-leg
rotate: false
xy: 152, 65
size: 51, 64
orig: 51, 64
offset: 0, 0
index: -1
right-foot-idle
rotate: false
xy: 184, 131
size: 53, 28
orig: 53, 28
offset: 0, 0
index: -1
left-lower-leg
rotate: false
xy: 205, 65
size: 49, 64
orig: 49, 64
offset: 0, 0
index: -1
right-shoulder
rotate: false
xy: 160, 12
size: 52, 51
orig: 52, 51
offset: 0, 0
index: -1
eyes
rotate: false
xy: 214, 36
size: 34, 27
orig: 34, 27
offset: 0, 0
index: -1
right-hand
rotate: false
xy: 214, 2
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,12 +0,0 @@
#import "cocos2d.h"
#import <spine/spine-cocos2d-iphone.h>
@interface ExampleLayer : CCLayer<CCSkeletonAnimationDelegate> {
CCSkeletonAnimation* animationNode;
}
+(CCScene*) scene;
@end

View File

@ -1,71 +0,0 @@
#import "ExampleLayer.h"
@implementation ExampleLayer
+ (CCScene*) scene {
CCScene *scene = [CCScene node];
[scene addChild:[ExampleLayer node]];
return scene;
}
-(id) init {
self = [super init];
if (!self) return nil;
// A scale of zero will use 1 / CC_CONTENT_SCALE_FACTOR().
animationNode = [CCSkeletonAnimation skeletonWithFile:@"spineboy.json" atlasFile:@"spineboy.atlas" scale:0];
[animationNode setMixFrom:@"walk" to:@"jump" duration:0.2f];
[animationNode setMixFrom:@"jump" to:@"walk" duration:0.4f];
[animationNode setDelegate:self];
[animationNode setAnimationForTrack:0 name:@"walk" loop:NO];
[animationNode addAnimationForTrack:0 name:@"jump" loop:NO afterDelay:0];
[animationNode addAnimationForTrack:0 name:@"walk" loop:YES afterDelay:0];
[animationNode addAnimationForTrack:0 name:@"jump" loop:YES afterDelay:4];
// [animationNode setAnimationForTrack:1 name:@"drawOrder" loop:YES];
animationNode.timeScale = 0.3f;
animationNode.debugBones = true;
CGSize windowSize = [[CCDirector sharedDirector] winSize];
[animationNode setPosition:ccp(windowSize.width / 2, 20)];
[self addChild:animationNode];
#if __CC_PLATFORM_MAC
[self setMouseEnabled:YES];
#endif
return self;
}
- (void) animationDidStart:(CCSkeletonAnimation*)animation track:(int)trackIndex {
CCLOG(@"%d start: %s", trackIndex, AnimationState_getCurrent(animation.state, trackIndex)->animation->name);
}
- (void) animationWillEnd:(CCSkeletonAnimation*)animation track:(int)trackIndex {
CCLOG(@"%d end: %s", trackIndex, AnimationState_getCurrent(animation.state, trackIndex)->animation->name);
}
- (void) animationDidTriggerEvent:(CCSkeletonAnimation*)animation track:(int)trackIndex event:(Event*)event {
CCLOG(@"%d event: %s, %s: %d, %f, %s", trackIndex, AnimationState_getCurrent(animation.state, trackIndex)->animation->name,
event->data->name, event->intValue, event->floatValue, event->stringValue);
}
- (void) animationDidComplete:(CCSkeletonAnimation*)animation track:(int)trackIndex loopCount:(int)loopCount {
CCLOG(@"%d complete: %s, %d", trackIndex, AnimationState_getCurrent(animation.state, trackIndex)->animation->name, loopCount);
}
#if __CC_PLATFORM_MAC
- (BOOL) ccMouseDown:(NSEvent*)event {
CCDirector* director = [CCDirector sharedDirector];
NSPoint location = [director convertEventToGL:event];
location.x -= [[director runningScene]position].x;
location.y -= [[director runningScene]position].y;
location.x -= animationNode.position.x;
location.y -= animationNode.position.y;
if (CGRectContainsPoint(animationNode.boundingBox, location)) NSLog(@"Clicked!");
return YES;
}
#endif
@end

View File

@ -1 +0,0 @@
cocos2d-iphone v2.1-rc1 or later.