port spine-sfml to cocos2dx

This commit is contained in:
wu shengjin 2013-03-18 11:32:04 +08:00
parent 60d70e3a87
commit fb671c3ce9
15 changed files with 541 additions and 0 deletions

View File

@ -0,0 +1,42 @@
#ifndef SPINE_ATLAS_H_
#define SPINE_ATLAS_H_
#include "cocos2d.h"
#include <spine/BaseAtlas.h>
USING_NS_CC;
namespace spine {
class AtlasPage: public BaseAtlasPage {
public:
~AtlasPage ();
CCTexture2D *texture;
};
//
class AtlasRegion: public BaseAtlasRegion {
public:
AtlasPage *page;
};
//
class Atlas: public BaseAtlas {
public:
Atlas (std::ifstream &file);
Atlas (std::istream &input);
Atlas (const std::string &text);
Atlas (const char *begin, const char *end);
AtlasRegion* findRegion (const std::string &name);
private:
virtual BaseAtlasPage* newAtlasPage (const std::string &name);
virtual BaseAtlasRegion* newAtlasRegion (BaseAtlasPage* page);
};
} /* namespace spine */
#endif /* SPINE_ATLAS_H_ */

View File

@ -0,0 +1,20 @@
#ifndef SPINE_ATLASATTACHMENTLOADER_H_
#define SPINE_ATLASATTACHMENTLOADER_H_
#include <spine/BaseAttachmentLoader.h>
namespace spine {
class Atlas;
class AtlasAttachmentLoader: public BaseAttachmentLoader {
public:
Atlas *atlas;
AtlasAttachmentLoader (Atlas *atlas);
virtual Attachment* newAttachment (AttachmentType type, const std::string &name);
};
} /* namespace spine */
#endif /* SPINE_ATLASATTACHMENTLOADER_H_ */

View File

@ -0,0 +1,26 @@
#ifndef SPINE_REGIONATTACHMENT_H_
#define SPINE_REGIONATTACHMENT_H_
#include "cocos2d.h"
#include <spine/BaseRegionAttachment.h>
USING_NS_CC;
namespace spine {
class Bone;
class AtlasRegion;
class RegionAttachment: public BaseRegionAttachment {
public:
ccV3F_C4B_T2F_Quad vertices;
CCTexture2D *texture;
RegionAttachment (AtlasRegion *region);
virtual void updateWorldVertices (Bone *bone);
virtual void draw (Slot *slot);
};
} /* namespace spine */
#endif /* SPINE_REGIONATTACHMENT_H_ */

View File

@ -0,0 +1,23 @@
#ifndef SPINE_SKELETON_H_
#define SPINE_SKELETON_H_
#include "cocos2d.h"
#include <spine/BaseSkeleton.h>
USING_NS_CC;
namespace spine {
class Skeleton: public BaseSkeleton {
public:
std::vector<ccV3F_C4B_T2F_Quad> vertexArray;
CCTexture2D *texture; // This is a bit ugly and means all region attachments must use the same textures.
CCTextureAtlas* texAtlas;
Skeleton (SkeletonData *skeletonData);
virtual void draw () ;
};
} /* namespace spine */
#endif /* SPINE_SKELETON_H_ */

View File

@ -0,0 +1,18 @@
#ifndef SKELETONJSON_H_
#define SKELETONJSON_H_
#include <spine/BaseSkeletonJson.h>
namespace spine {
class Atlas;
class SkeletonJson: public BaseSkeletonJson {
public:
SkeletonJson (Atlas *atlas);
/** The SkeletonJson owns the attachmentLoader */
SkeletonJson (BaseAttachmentLoader *attachmentLoader);
};
} /* namespace spine */
#endif /* SKELETONJSON_H_ */

View File

@ -0,0 +1,19 @@
#ifndef SPINE_SPINE_H_
#define SPINE_SPINE_H_
#include <spine/SkeletonData.h>
#include <spine/BoneData.h>
#include <spine/SlotData.h>
#include <spine/Skin.h>
#include <spine/Attachment.h>
#include <spine/Animation.h>
#include <spine/Slot.h>
#include <spine/Bone.h>
#include <spine-cc/RegionAttachment.h>
#include <spine-cc/Atlas.h>
#include <spine-cc/AtlasAttachmentLoader.h>
#include <spine-cc/SkeletonJson.h>
#include <spine-cc/Skeleton.h>
#endif /* SF_SPINE_H_ */

View File

@ -0,0 +1,84 @@
//
// CCSpineNode.cpp
// SpineExample
//
// Created by wu shengjin on 13-3-18.
//
//
#include "CCSpineNode.h"
#include <iostream>
#include <fstream>
#define FULL_PATH(a) CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(a)
CCSpineNode* CCSpineNode::createWithFileNames(const char* skeletonFileName, const char* atlasFileName)
{
CCSpineNode* node = new CCSpineNode();
if (node && node->initWithFiles(skeletonFileName, atlasFileName)) {
node->autorelease();
return node;
}
CC_SAFE_DELETE(node);
return NULL;
}
bool CCSpineNode::initWithFiles(const char* skeletonFileName, const char* atlasFileName)
{
std::ifstream atlasFile(FULL_PATH(atlasFileName));
Atlas *atlas = new Atlas(atlasFile);
m_skeletonJson = new SkeletonJson(atlas);
std::ifstream skeletonFile(FULL_PATH(skeletonFileName));
SkeletonData *skeletonData = m_skeletonJson->readSkeletonData(skeletonFile);
m_skeleton = new Skeleton(skeletonData);
m_skeleton->setToBindPose();
m_skeleton->updateWorldTransform();
m_animTimer = 0.0f;
m_animation = 0;
m_loop = true;
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
scheduleUpdate();
return true;
}
void CCSpineNode::playAnimation(const char* fileName, bool loop)
{
CC_SAFE_DELETE(m_animation);
std::ifstream animationFile(FULL_PATH(fileName));
m_animation = m_skeletonJson->readAnimation(animationFile, m_skeleton->data);
m_animTimer = 0.0f;
m_loop = loop;
}
void CCSpineNode::update(float dt)
{
if (m_animation && m_skeleton)
{
m_animTimer += dt;
m_animation->apply(m_skeleton, m_animTimer, m_loop);
m_skeleton->updateWorldTransform();
}
}
void CCSpineNode::draw()
{
CC_NODE_DRAW_SETUP();
if (m_skeleton)
m_skeleton->draw();
CCNode::draw();
}

View File

@ -0,0 +1,38 @@
//
// CCSpineNode.h
// SpineExample
//
// Created by wu shengjin on 13-3-18.
//
//
#ifndef __CCSpineNode__
#define __CCSpineNode__
#include "cocos2d.h"
#include <spine-cc/spine.h>
using namespace spine;
USING_NS_CC;
class CCSpineNode : public CCNode {
public:
static CCSpineNode* createWithFileNames(const char* skeletonFileName, const char* atlasFileName);
bool initWithFiles(const char* skeletonFileName, const char* atlasFileName);
void playAnimation(const char* fileName, bool loop = true);
void update(float dt);
void draw();
private:
SkeletonJson* m_skeletonJson;
Skeleton* m_skeleton;
Animation* m_animation;
float m_animTimer;
bool m_loop;
};
#endif /* defined(__SpineExample__CCSpineNode__) */

View File

@ -0,0 +1,45 @@
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "CCSpineNode.h"
using namespace cocos2d;
using namespace CocosDenshion;
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSpineNode* spineNode = CCSpineNode::createWithFileNames("./data/spineboy-skeleton.json", "./data/spineboy.atlas");
spineNode->playAnimation("./data/spineboy-walk.json");
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
spineNode->setPosition(ccp(winSize.width/2, 0));
addChild(spineNode);
return true;
}

View File

@ -0,0 +1,20 @@
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::CCLayer
{
public:
// Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer)
virtual bool init();
// there's no 'id' in cpp, so we recommend to return the class instance pointer
static cocos2d::CCScene* scene();
// preprocessor macro for "static create()" constructor ( node() deprecated )
CREATE_FUNC(HelloWorld);
};
#endif // __HELLOWORLD_SCENE_H__

View File

@ -0,0 +1,43 @@
#include <spine-cc/Atlas.h>
namespace spine {
AtlasPage::~AtlasPage () {
CC_SAFE_RELEASE(texture);
}
//
Atlas::Atlas (std::ifstream &file) {
load(file);
}
Atlas::Atlas (std::istream &input) {
load(input);
}
Atlas::Atlas (const std::string &text) {
load(text);
}
Atlas::Atlas (const char *begin, const char *end) {
load(begin, end);
}
BaseAtlasPage* Atlas::newAtlasPage (const std::string &name) {
AtlasPage *page = new AtlasPage();
page->texture = CCTextureCache::sharedTextureCache()->addImage(name.c_str());
return page;
}
BaseAtlasRegion* Atlas::newAtlasRegion (BaseAtlasPage* page) {
AtlasRegion *region = new AtlasRegion();
region->page = reinterpret_cast<AtlasPage*>(page);
return region;
}
AtlasRegion* Atlas::findRegion (const std::string &name) {
return reinterpret_cast<AtlasRegion*>(BaseAtlas::findRegion(name));
}
} /* namespace spine */

View File

@ -0,0 +1,24 @@
#include <stdexcept>
#include <spine-cc/AtlasAttachmentLoader.h>
#include <spine-cc/Atlas.h>
#include <spine-cc/RegionAttachment.h>
namespace spine {
AtlasAttachmentLoader::AtlasAttachmentLoader (Atlas *atlas) :
atlas(atlas) {
}
Attachment* AtlasAttachmentLoader::newAttachment (AttachmentType type, const std::string &name) {
switch (type) {
case region: {
AtlasRegion *region = atlas->findRegion(name);
if (!region) throw std::runtime_error("Atlas region not found: " + name);
return new RegionAttachment(region);
}
default:
throw std::runtime_error("Unknown attachment type: " + type);
}
}
} /* namespace spine */

View File

@ -0,0 +1,84 @@
#include <iostream>
#include <spine-cc/RegionAttachment.h>
#include <spine-cc/Atlas.h>
#include <spine-cc/Skeleton.h>
#include <spine/Bone.h>
#include <spine/Slot.h>
namespace spine {
RegionAttachment::RegionAttachment (AtlasRegion *region) {
texture = region->page->texture;
const CCSize& texSize = texture->getContentSizeInPixels();
float u = region->x / texSize.width;
float u2 = (region->x + region->width) / texSize.width;
float v = region->y / texSize.height;
float v2 = (region->y + region->height) / texSize.height;
if (region->rotate) {
vertices.tl.texCoords.u = u;
vertices.tl.texCoords.v = v2;
vertices.tr.texCoords.u = u;
vertices.tr.texCoords.v = v;
vertices.br.texCoords.u = u2;
vertices.br.texCoords.v = v;
vertices.bl.texCoords.u = u2;
vertices.bl.texCoords.v = v2;
} else {
vertices.bl.texCoords.u = u;
vertices.bl.texCoords.v = v2;
vertices.tl.texCoords.u = u;
vertices.tl.texCoords.v = v;
vertices.tr.texCoords.u = u2;
vertices.tr.texCoords.v = v;
vertices.br.texCoords.u = u2;
vertices.br.texCoords.v = v2;
}
}
void RegionAttachment::draw (Slot *slot) {
Skeleton* skeleton = (Skeleton*)slot->skeleton;
GLubyte r = skeleton->r * slot->r * 255;
GLubyte g = skeleton->g * slot->g * 255;
GLubyte b = skeleton->b * slot->b * 255;
GLubyte a = skeleton->a * slot->a * 255;
vertices.bl.colors.r = r;
vertices.bl.colors.g = g;
vertices.bl.colors.b = b;
vertices.bl.colors.a = a;
vertices.tl.colors.r = r;
vertices.tl.colors.g = g;
vertices.tl.colors.b = b;
vertices.tl.colors.a = a;
vertices.tr.colors.r = r;
vertices.tr.colors.g = g;
vertices.tr.colors.b = b;
vertices.tr.colors.a = a;
vertices.br.colors.r = r;
vertices.br.colors.g = g;
vertices.br.colors.b = b;
vertices.br.colors.a = a;
updateWorldVertices(slot->bone);
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
skeleton->texture = texture;
skeleton->vertexArray.push_back(vertices);
}
void RegionAttachment::updateWorldVertices (spine::Bone *bone) {
vertices.bl.vertices.x = offset[0] * bone->m00 + offset[1] * bone->m01 + bone->worldX;
vertices.bl.vertices.y = offset[0] * bone->m10 + offset[1] * bone->m11 + bone->worldY;
vertices.bl.vertices.z = 0;
vertices.tl.vertices.x = offset[2] * bone->m00 + offset[3] * bone->m01 + bone->worldX;
vertices.tl.vertices.y = offset[2] * bone->m10 + offset[3] * bone->m11 + bone->worldY;
vertices.tl.vertices.z = 0;
vertices.tr.vertices.x = offset[4] * bone->m00 + offset[5] * bone->m01 + bone->worldX;
vertices.tr.vertices.y = offset[4] * bone->m10 + offset[5] * bone->m11 + bone->worldY;
vertices.tr.vertices.z = 0;
vertices.br.vertices.x = offset[6] * bone->m00 + offset[7] * bone->m01 + bone->worldX;
vertices.br.vertices.y = offset[6] * bone->m10 + offset[7] * bone->m11 + bone->worldY;
vertices.br.vertices.z = 0;
}
} /* namespace spine */

View File

@ -0,0 +1,39 @@
#include <iostream>
#include <spine-cc/Skeleton.h>
#include <spine/SkeletonData.h>
#include <spine/Slot.h>
#include <spine/Attachment.h>
namespace spine {
Skeleton::Skeleton (SkeletonData *skeletonData) :
BaseSkeleton(skeletonData),
texAtlas(0),
texture(0) {
}
void Skeleton::draw () {
const_cast<Skeleton*>(this)->vertexArray.clear();
for (int i = 0, n = slots.size(); i < n; i++)
if (slots[i]->attachment) slots[i]->attachment->draw(slots[i]);
if (texture == 0)
return;
if (texAtlas == 0)
{
texAtlas = CCTextureAtlas::createWithTexture(texture, vertexArray.size());
texAtlas->retain();
}
for (int i=0; i<vertexArray.size(); i++) {
texAtlas->updateQuad(&vertexArray[i], i);
}
texAtlas->drawQuads();
}
} /* namespace spine */

View File

@ -0,0 +1,16 @@
#include <spine-cc/SkeletonJson.h>
#include <spine-cc/AtlasAttachmentLoader.h>
namespace spine {
SkeletonJson::SkeletonJson (BaseAttachmentLoader *attachmentLoader) :
BaseSkeletonJson(attachmentLoader) {
yDown = false;
}
SkeletonJson::SkeletonJson (Atlas *atlas) :
BaseSkeletonJson(new AtlasAttachmentLoader(atlas)) {
yDown = false;
}
} /* namespace spine */