cocos2d-x 物理世界与spine骨骼的运用

    xiaoxiao2021-03-25  90

    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:.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 }

    转载请注明原文地址: https://ju.6miu.com/read-26024.html

    最新回复(0)