cocos2d-x 3.2 物理世界PhysicsWorld
2014-07-02 16:26
169 查看
cocos2d-x-3.2alpha0的物理世界。
hello 大家好,小弟这厢有礼了,我又来写博客了,cocos2d-x果然越来越人性话了。
看一看创建物理世界:
//创建一个物理场景
auto scene =Scene::createWithPhysics();
//设置物理世界的重力
scene->getPhysicsWorld()->setGravity(Vect(0,-(Director::getInstance()->getVisibleSize().height/3)));
//边界盒
auto edge=PhysicsBody::createEdgeBox(visibleSize);
对照一下cocos2d-x 2.2.3的Box2D
当然这是Box2D ,强大的box2d几乎模拟一切,不过当初写的我想杀人,明明很简单的东西完全交给我,一点不封装,蛋疼。
可能是我的屌丝程序猿的冤孽直冲上天,3.2版本那叫一个简单明了,我先把整个源码粘上来,然后再说。
其实真的很简单很方便
step 1:
//创建一个物理场景
auto scene =Scene::createWithPhysics();
//设置物理世界的重力
scene->getPhysicsWorld()->setGravity(Vect(0,-(Director::getInstance()->getVisibleSize().height/3)));
step 2:
创建一个边界盒,关联到一个节点上然后加到物理场景中。
step 3:
创建一个node关联一个body就是刚体,然后看他们撞的玩吧
最最最基本的就是这些,如果你想要自己处理碰撞的话那么
step 4:
//创建一个物理碰撞的事件处理
auto physicsListen=EventListenerPhysicsContact::create();
physicsListen->onContactBegin 自己写自己的处理方法,
contact.getShapeA()->getBody()->getNode();
contact.getShapeB()->getBody()->getNode();
可以得到两个碰撞的节点,(天真我以为撞人的是A,被撞的是B,但是我太天真了,尼玛复杂的物理世界,真心不知道谁是A谁是B,setTag才是王道啊)
返回值为true继续默认碰撞处理,false这次碰撞的处理到此结束。
到这里有一个天大的事情出现了,碰撞时竟然不触发我自己写的处理程序,擦有没有搞错
,耍我研究了一个小时(其实大部分时间在发呆)终于找到罪魁祸首了,
body->setContactTestBitmask(-1);
ContactTestBitmask表示“在我和谁发生碰撞通知我”,默认为值0,这是一个位mask,-1对应的是FFFFFFFF(各种11111.)全开,不管碰到什么都要通知我
。
既然我不能通过A,B来判断谁是谁那怎么办,setTag出马了,你自己设置,自己判断去吧,比如(猪脚/敌人,子弹/敌人,障碍/敌人 敌人各种躺枪)。
今天就这么点东西了,准备写个Flappy brid。
hello 大家好,小弟这厢有礼了,我又来写博客了,cocos2d-x果然越来越人性话了。
看一看创建物理世界:
//创建一个物理场景
auto scene =Scene::createWithPhysics();
//设置物理世界的重力
scene->getPhysicsWorld()->setGravity(Vect(0,-(Director::getInstance()->getVisibleSize().height/3)));
//边界盒
auto edge=PhysicsBody::createEdgeBox(visibleSize);
对照一下cocos2d-x 2.2.3的Box2D
b2Vec2 gravity; gravity.Set(0.0f, -10.0f); //重力 world = new b2World(gravity); //创建世界对象 一切都是映射 world->SetAllowSleeping(true); //允许休眠 world->SetContinuousPhysics(true); //设置检测连续碰撞 //定义地形钢体描述并设置坐标为左下角 b2BodyDef groundBodyDef; groundBodyDef.position.Set(0, 0); //根据钢体的描述创建钢体对象 b2Body* groundBody = world->CreateBody(&groundBodyDef); groundBody->SetType(b2_staticBody); b2EdgeShape groundBox; //定义地面盒形状 //2个点确定一条线,以下分别设置了屏幕的4个边 // bottom groundBox.Set(b2Vec2(0, 0), b2Vec2(480/PTM_RATIO, 0)); groundBody->CreateFixture(&groundBox,0); // top groundBox.Set(b2Vec2(0 ,320/PTM_RATIO), b2Vec2(480/PTM_RATIO,320/PTM_RATIO)); groundBody->CreateFixture(&groundBox,0); // left groundBox.Set(b2Vec2(0, 320/PTM_RATIO), b2Vec2(0 ,0)); groundBody->CreateFixture(&groundBox,0); // right groundBox.Set(b2Vec2(480/PTM_RATIO, 320/PTM_RATIO), b2Vec2(480/PTM_RATIO, 0)); groundBody->CreateFixture(&groundBox,0); CCSpriteBatchNode *blocks=CCSpriteBatchNode::create("blocks.png",100); texture=blocks->getTexture();
当然这是Box2D ,强大的box2d几乎模拟一切,不过当初写的我想杀人,明明很简单的东西完全交给我,一点不封装,蛋疼。
可能是我的屌丝程序猿的冤孽直冲上天,3.2版本那叫一个简单明了,我先把整个源码粘上来,然后再说。
#ifndef __PHYSICS_SCENE_H__ #define __PHYSICS_SCENE_H__ #include "cocos2d.h" class PhysicsScene : public cocos2d::Layer { public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // implement the "static create()" method manually CREATE_FUNC(PhysicsScene); void createPhysicsSpriteWithPosition(cocos2d::Vec2 position); }; #endif // __PHYSICS_SCENE_H__
#include "PhysicsScene.h" #include "cocos2d.h" USING_NS_CC; enum MyType { attacker=1, SB=2 }; Scene* PhysicsScene::createScene() { //很明显 创建一个物理场景 auto scene =Scene::createWithPhysics(); auto layer = PhysicsScene::create(); //显不显示物理节点的外框 调试时用 scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); //设置物理世界的重力 scene->getPhysicsWorld()->setGravity(Vect(0,-(Director::getInstance()->getVisibleSize().height/3))); scene->addChild(layer); //创建一个物理碰撞的事件处理 auto physicsListen=EventListenerPhysicsContact::create(); physicsListen->onContactBegin=[](PhysicsContact& contact)->bool { //contact.getShapeB()->getBody()->getNode()->removeFromParent(); if(contact.getShapeA()->getBody()->getNode()!=nullptr||contact.getShapeB()->getBody()->getNode()!=nullptr) { if(contact.getShapeA()->getBody()->getNode()->getTag()==MyType::attacker) { //移除节点前先把mask设为0 contact.getShapeB()->getBody()->setContactTestBitmask(0); contact.getShapeB()->getBody()->getNode()->removeFromParent(); //碰撞效果消失 不计算后续的碰撞 return false; } if (contact.getShapeB()->getBody()->getNode()->getTag()==MyType::attacker) { contact.getShapeA()->getBody()->setContactTestBitmask(0); contact.getShapeA()->getBody()->getNode()->removeFromParent(); //碰撞效果消失 不计算后续的碰撞 return false; } } //默认碰撞 return true; }; //注册事件处理程序 Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(physicsListen,scene); return scene; } bool PhysicsScene::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); //边界盒 auto edge=PhysicsBody::createEdgeBox(visibleSize); //是按父节点的坐标原点来的 一个偏移量 edge->setPositionOffset(visibleSize/2); //添加边界 this->setPhysicsBody(edge); //触摸事件处理 auto listen=EventListenerTouchOneByOne::create(); listen->onTouchBegan=[this](Touch * touch,Event * event)->bool { this->createPhysicsSpriteWithPosition(touch->getLocation()); return true; }; //注册 Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen,this); return true; } void PhysicsScene::createPhysicsSpriteWithPosition(cocos2d::Vec2 position) { //建的玩的 auto p=LayerColor::create(Color4B::BLUE,40,40); p->ignoreAnchorPointForPosition(false); p->setPosition(position); auto body=PhysicsBody::createBox(CCSizeMake(40,40)); //物理节点默认就是按父节点的原点为中心点来的 p->setPhysicsBody(body); srand(time(NULL)); p->setTag(rand()%2==0?MyType::attacker:MyType::SB); auto label=Label::create(p->getTag()==MyType::attacker?"NB":"SB","Arial",20); label->setPosition(20,20); p->addChild(label); //这句话困了我一个点 body->setContactTestBitmask(-1); this->addChild(p); }
其实真的很简单很方便
step 1:
//创建一个物理场景
auto scene =Scene::createWithPhysics();
//设置物理世界的重力
scene->getPhysicsWorld()->setGravity(Vect(0,-(Director::getInstance()->getVisibleSize().height/3)));
step 2:
创建一个边界盒,关联到一个节点上然后加到物理场景中。
step 3:
创建一个node关联一个body就是刚体,然后看他们撞的玩吧
最最最基本的就是这些,如果你想要自己处理碰撞的话那么
step 4:
//创建一个物理碰撞的事件处理
auto physicsListen=EventListenerPhysicsContact::create();
physicsListen->onContactBegin 自己写自己的处理方法,
contact.getShapeA()->getBody()->getNode();
contact.getShapeB()->getBody()->getNode();
可以得到两个碰撞的节点,(天真我以为撞人的是A,被撞的是B,但是我太天真了,尼玛复杂的物理世界,真心不知道谁是A谁是B,setTag才是王道啊)
返回值为true继续默认碰撞处理,false这次碰撞的处理到此结束。
到这里有一个天大的事情出现了,碰撞时竟然不触发我自己写的处理程序,擦有没有搞错
,耍我研究了一个小时(其实大部分时间在发呆)终于找到罪魁祸首了,
body->setContactTestBitmask(-1);
ContactTestBitmask表示“在我和谁发生碰撞通知我”,默认为值0,这是一个位mask,-1对应的是FFFFFFFF(各种11111.)全开,不管碰到什么都要通知我
。
既然我不能通过A,B来判断谁是谁那怎么办,setTag出马了,你自己设置,自己判断去吧,比如(猪脚/敌人,子弹/敌人,障碍/敌人 敌人各种躺枪)。
今天就这么点东西了,准备写个Flappy brid。
相关文章推荐
- cocos2d-x 3.2 物理小游戏教程2 block it 物理世界 墙壁
- 关于Cocos2d-x中物理世界的物体乱跳的问题的解决
- 关于Cocos2D-X在pause时物理世界物体仍缓慢受重力影响的解决方案
- cocos2d-x 3.2 物理小游戏教程3 block it 小球的运动 墙壁的隐藏
- Cocos2d-x之物理世界(创建静态的物体)
- Cocos2d-x3.0游戏实例之《别救我》第二篇——创建物理世界
- Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检测
- Cocos2d-js官方完整项目教程翻译:六、添加Chipmunk物理引擎在我们的游戏世界里
- Cocos2d-x之物理世界(创建悬浮的物体)
- Quick-cocos2d-x3.3 Study (八)--------- 物理世界
- Cocos2d-x之物理世界(物体之间的碰撞)
- Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检測
- cocos2d-x游戏开发 跑酷(四) 关联与物理世界
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植5:初始化物理世界【Chipmunk】
- cocos2d-x 3.2 物理碰撞机制
- cocos2d-x快乐的做让人快乐的游戏3:cocos-2d 3.x中的物理世界
- cocos2d-x 3.0学习-使用Physicals创建物理世界
- Cocos2d-js官方完整项目教程翻译:六、添加Chipmunk物理引擎在我们的游戏世界里
- cocos2d-x 3.2 物理碰撞机制
- cocos2d-x游戏开发 跑酷(二) 物理世界