Head
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "spine/spine.h"
#include "E:\tesetspine\cocos2d\external\Box2D\Dynamics\b2World.h"
#include "E:\tesetspine\cocos2d\cocos\editor-support\spine\SkeletonAnimation.h"
USING_NS_CC;
using namespace spine;
class HelloWorld : public cocos2d::Layer ,public b2ContactListener
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
void InitSpine();
void InitWorld();
void initPhysics();
static cocos2d::CCScene* scene();
// 重写生命周期函数
virtual void onEnter();
virtual void onEnterTransitionDidFinish();
virtual void onExit();
// 重写CCTargetTouchDelegate
virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void onTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void onTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void onTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
// 重写update回调函数
virtual void update(float delta);
// 重写Bos2D监听函数
virtual void BeginContact(b2Contact* contact);
private:
b2World *world;
b2Body* groundBody;
void addNewSpriteAtPosition(CCPoint &pt);
};
#endif // __HELLOWORLD_SCENE_H__
Cpp
#include "HelloWorldScene.h"
#include "Box2D\Box2D.h"
USING_NS_CC;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
void HelloWorld::InitWorld()
{
}
// on "init" you need to initialize your instance
void HelloWorld::InitSpine()
{
// create menu, it's an autorelease object
auto skeletonNode = new SkeletonAnimation("spineboy.json", "spineboy.atlas");
skeletonNode->setMix("walk", "attack", 0.2f);
skeletonNode->setMix("jump", "walk", 0.4f);
for (int i = 0; i < 100; i++)
{
i % 2 == 0 ? skeletonNode->addAnimation(0, "walk", false) : skeletonNode->addAnimation(0, "jump", false);
}
skeletonNode->setDebugBonesEnabled(false);
skeletonNode->setDebugSlotsEnabled(true);
Size windowSize = Director::getInstance()->getVisibleSize();
skeletonNode->setPosition(windowSize.width / 2, windowSize.height / 2);
skeletonNode->setScale(0.1f);
addChild(skeletonNode);
}
bool HelloWorld::init()
{
//
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// 初始化物理引擎
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
//开始游戏循环
this->scheduleUpdate();
/
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
/
// 3. add your codes below...
// add a label shows "Hello World"
CCSprite *sprite = CCSprite::create("HelloWorld.png");
sprite->setPosition(ccp(visibleSize.width / 2.0, visibleSize.height / 2.0));
this->addChild(sprite);
// create and initialize a label
initPhysics();
InitWorld();
InitSpine();
return true;
}
void HelloWorld::initPhysics()
{
CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();
//重力参数
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
//创建世界
world = new b2World(gravity);
// 允许物体是否休眠
world->SetAllowSleeping(true);
// 开启连续物理测试
world->SetContinuousPhysics(true);
// 设置物理碰撞的监听代理
world->SetContactListener(this);
//地面物体定义
b2BodyDef groundBodyDef;
// 左下角
groundBodyDef.position.Set(winSize.width / 2.0 / 32, winSize.height / 2.0 / 32);
// 设置为静态物体
groundBodyDef.type = b2_staticBody;
// 创建地面物体
groundBody = world->CreateBody(&groundBodyDef);
// 定义一个有边的形状
b2PolygonShape groundBox;
// 底部
groundBox.SetAsBox(winSize.width / 2 / 32, 0, b2Vec2(0, -winSize.height / 2 / 32), 0);
//使用夹具固定形状到物体上
groundBody->CreateFixture(&groundBox, 0);
// 顶部
groundBox.SetAsBox(winSize.width / 2 / 32, 0, b2Vec2(0, winSize.height / 2 / 32), 0);
groundBody->CreateFixture(&groundBox, 0);
// 左边
groundBox.SetAsBox(0, winSize.height / 2 / 32, b2Vec2(-winSize.width / 2 / 32, 0), 0);
groundBody->CreateFixture(&groundBox, 0);
// 右边
groundBox.SetAsBox(0, winSize.height / 2 / 32, b2Vec2(winSize.width / 2 / 32, 0), 0);
groundBody->CreateFixture(&groundBox, 0);
}
void HelloWorld::addNewSpriteAtPosition(CCPoint &pt)
{
CCLOG("Add sprite x:%0.2f y:%02.f", pt.x, pt.y);
//创建物理引擎精灵对象
CCSprite *sprite = CCSprite::create("BoxA.png");
sprite->setPosition(pt);
this->addChild(sprite);
float sprWidth = sprite->getContentSize().width;
float spriHeight = sprite->getContentSize().height;
//物体定义
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(pt.x / 32, pt.y / 32);
bodyDef.userData = sprite;
b2Body *body = world->CreateBody(&bodyDef);
// 定义2米见方的盒子形状
b2PolygonShape dynamicBox;
// 注意这里的宽度和高度都是精灵的一半再除以PTM_RATIO
dynamicBox.SetAsBox(sprWidth / 2 / 32, spriHeight / 2 / 32);
// 夹具定义
b2FixtureDef fixtureDef;
//设置夹具的形状
fixtureDef.shape = &dynamicBox;
//设置密度
fixtureDef.density = 1.0f;
//设置摩擦系数
fixtureDef.friction = 0.3f;
//设置弹力系数
fixtureDef.restitution = 0.5f;
//使用夹具固定形状到物体上
body->CreateFixture(&fixtureDef);
}
void HelloWorld::update(float delta)
{
world->Step(delta, 8, 3);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetType() == b2_dynamicBody)
{
if (b->GetUserData() != NULL)
{
CCSprite* sprite = (CCSprite*)b->GetUserData();
sprite->setPositionY(b->GetPosition().y * 32);
sprite->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
}
}
}
}
void HelloWorld::BeginContact(b2Contact* contact)
{
if (contact->GetFixtureA()->GetBody() == groundBody || contact->GetFixtureB()->GetBody() == groundBody)
{
CCLOG("检测到物理碰撞");
}
}
void HelloWorld::onEnter()
{
CCLOG("HelloWorld::onEnter");
CCLayer::onEnter();
}
void HelloWorld::onEnterTransitionDidFinish()
{
CCLOG("HelloWorld::onEnterTransitionDidFinish");
CCLayer::onEnterTransitionDidFinish();
}
void HelloWorld::onExit()
{
CCLOG("HelloWorld::onExit");
CCLayer::onExit();
}
bool HelloWorld::onTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint pt = pTouch->getLocation();
this->addNewSpriteAtPosition(pt);
return true;
}
void HelloWorld::onTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
}
void HelloWorld::onTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
}
void HelloWorld::onTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
{
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}