首页 > 代码库 > coco2d-x3.2使用物理引擎Physicals制作Breakout游戏
coco2d-x3.2使用物理引擎Physicals制作Breakout游戏
HelloWorldScene.h
1 #ifndef __HELLOWORLD_SCENE_H__ 2 #define __HELLOWORLD_SCENE_H__ 3 4 #include "cocos2d.h" 5 #include "GameOverScene.h" 6 7 USING_NS_CC; 8 9 class HelloWorld : public cocos2d::Layer10 {11 public:12 static cocos2d::Scene* createScene();13 virtual void onEnter() override;14 virtual bool init(); 15 16 CREATE_FUNC(HelloWorld);17 18 Sprite* ball;//弹射的球19 Sprite* paddle;//玩家控制的可移动碰撞块20 Sprite* edgeSp;//碰撞盒子21 22 PhysicsWorld* m_world;23 24 void setPhyWorld(PhysicsWorld* world){ m_world = world; };25 void tick(float dt);26 27 bool onTouchBegan(Touch* touch, Event* event);28 void onTouchMoved(Touch* touch, Event* event);29 void onTouchEnded(Touch* touch, Event* event);30 31 bool onContactBegin(const PhysicsContact& contact);32 33 };34 35 #endif
HelloWorldScene.cpp
1 #include "HelloWorldScene.h" 2 3 USING_NS_CC; 4 5 Scene* HelloWorld::createScene() 6 { 7 auto scene = Scene::createWithPhysics(); 8 //设置Debug模式,你会看到物体的表面被线条包围,主要为了在调试中更容易地观察 9 scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); 10 11 Vect gravity(0.0f, 0.0f); 12 //设置重力 13 scene->getPhysicsWorld()->setGravity(gravity); 14 15 auto layer = HelloWorld::create(); 16 17 layer->setPhyWorld(scene->getPhysicsWorld()); 18 19 scene->addChild(layer); 20 21 return scene; 22 23 } 24 25 /** 26 PHYSICSBODY_MATERIAL_DEFAULT常量是默认材质,材质是由结构体PhysicsMaterial定义的,结构体PhysicsMaterial成员有:density(密度)、friction(磨擦系数)和restitution(弹性系数)。 27 密度可以用来计算物体的质量,密度可以为零或者为正数。 28 摩擦系数经常会设置在0.0~1.0之间,0.0表示没有摩擦力,1.0会产生强摩擦。 29 弹性系数的值通常设置到0.0~1.0之间,0.0表示物体不会弹起,1.0表示物体会完全反弹,即称为弹性碰撞。 30 **/ 31 bool HelloWorld::init() 32 { 33 if ( !Layer::init() ) 34 { 35 return false; 36 } 37 38 auto visibleSize = Director::getInstance()->getVisibleSize(); 39 auto origin = Director::getInstance()->getVisibleOrigin(); 40 41 edgeSp = Sprite::create(); 42 //创建一个盒子,用来碰撞 43 //矩形的大小、设置材质、设置边的宽度 44 auto boundBody = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3); 45 //设置物体的弹性 0表示完全不反弹。1完全反弹 46 boundBody->getShape(0)->setRestitution(1.0f); 47 //设置摩擦力 48 boundBody->getShape(0)->setFriction(0.0f); 49 //设置密度 50 boundBody->getShape(0)->setDensity(1.0f); 51 edgeSp->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2)); 52 edgeSp->setPhysicsBody(boundBody); 53 this->addChild(edgeSp); 54 edgeSp->setTag(0); 55 56 //CategoryBitmask, 默认值为 0xFFFFFFFF 57 //ContactTestBitmask, 默认值为 0x00000000 58 //CollisionBitmask, 默认值为 0xFFFFFFFF 59 //如果采用默认的数值,碰撞是可以检测的,但是碰撞事件是不会发出的,so我们的onContactBegin就被屏蔽了 60 //果想我们的两个物体即发生碰撞又可以检测到,不让它们&的值不等于0就ok了 61 edgeSp->getPhysicsBody()->setCategoryBitmask(0x01); 62 edgeSp->getPhysicsBody()->setContactTestBitmask(0x01); 63 edgeSp->getPhysicsBody()->setCollisionBitmask(0x01); 64 65 ball = Sprite::create("Ball.png", Rect(0, 0, 52, 52)); 66 ball->setPosition(100, 100); 67 //创建物体,并且物体的形状为圆形,第一参数为半径,第二个参数为物体材质 68 //第三个参数为边的厚度,就是在Debug模式下看到的物体外面线条的厚度,默认为0 69 auto ballBody = PhysicsBody::createCircle(ball->getContentSize().width / 2.); 70 ballBody->getShape(0)->setRestitution(1.0f); 71 ballBody->getShape(0)->setFriction(0.0f); 72 ballBody->getShape(0)->setDensity(1.0f); 73 ballBody->setGravityEnable(false); 74 Vect force = Vect(1000000.0f, 1000000.0f); 75 //是对物体施加一个冲量 76 ballBody->applyImpulse(force); 77 ball->setPhysicsBody(ballBody); 78 ball->setTag(1); 79 this->addChild(ball); 80 81 ball->getPhysicsBody()->setCategoryBitmask(0x01); 82 ball->getPhysicsBody()->setContactTestBitmask(0x01); 83 ball->getPhysicsBody()->setCollisionBitmask(0x01); 84 85 paddle = Sprite::create("Paddle.png"); 86 //创建物体,并且物体的形状为矩形 87 auto paddleBody = PhysicsBody::createBox(paddle->getContentSize(), PHYSICSBODY_MATERIAL_DEFAULT); 88 paddleBody->getShape(0)->setRestitution(1.0f); 89 paddleBody->getShape(0)->setFriction(0.0f); 90 paddleBody->getShape(0)->setDensity(10.0f); 91 paddleBody->setGravityEnable(false); 92 paddleBody->setDynamic(false); 93 paddle->setPosition(visibleSize.width / 2, 50); 94 paddle->setPhysicsBody(paddleBody); 95 paddle->setTag(2); 96 this->addChild(paddle); 97 98 for (int i = 0; i < 4; i++) { 99 100 static int padding = 100;101 102 // 创建方块并添加到层中103 auto block = Sprite::create("blocks.png");104 auto blockBody = PhysicsBody::createBox(block->getContentSize(), PHYSICSBODY_MATERIAL_DEFAULT);105 blockBody->getShape(0)->setDensity(10.0f);106 blockBody->getShape(0)->setFriction(0.0f);107 blockBody->getShape(0)->setRestitution(1.f);108 blockBody->setDynamic(false);109 int xOffset = padding + block->getContentSize().width / 2 +110 ((block->getContentSize().width + padding)*i);111 block->setPosition(xOffset, 450);112 block->setPhysicsBody(blockBody);113 block->setTag(3);114 this->addChild(block);115 116 block->getPhysicsBody()->setCategoryBitmask(0x01);117 block->getPhysicsBody()->setContactTestBitmask(0x01);118 block->getPhysicsBody()->setCollisionBitmask(0x01);119 }120 121 this->schedule(schedule_selector(HelloWorld::tick),0);122 123 return true;124 }125 126 void HelloWorld::onTouchMoved(Touch* touch, Event* event)127 {128 Point touchLocation = this->convertToWorldSpace(this->convertTouchToNodeSpace(touch));129 paddle->setPositionX(touchLocation.x);130 }131 132 bool HelloWorld::onTouchBegan(Touch* touch, Event* event)133 {134 return true;135 }136 137 void HelloWorld::onTouchEnded(Touch* touch, Event* event)138 {139 140 }141 142 bool HelloWorld::onContactBegin(const PhysicsContact& contact)143 {144 if (ball->getPositionY() <= 50)145 {146 auto gameOverScene = GameOverScene::create();147 gameOverScene->getLayer()->getLabel()->setString("You Lose!");148 Director::getInstance()->replaceScene(gameOverScene);149 }150 151 auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode();152 auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode();153 int tagA = spriteA->getTag();154 int tagB = spriteB->getTag();155 156 if (tagA == 3)157 {158 spriteA->removeFromParentAndCleanup(true);159 }160 161 if (tagB == 3)162 {163 spriteB->removeFromParentAndCleanup(true);164 }165 166 return true;167 }168 169 void HelloWorld::tick(float dt)170 {171 bool isWin = true;172 Vector<PhysicsBody*> bodies = m_world->getAllBodies();173 Vector<PhysicsBody*>::iterator iter;174 for (iter=bodies.begin();iter!=bodies.end();iter++) {175 if ((*iter)->getNode()->getTag() == 3)176 {177 isWin = false;178 }179 }180 181 if (isWin == true)182 {183 auto gameOverScene = GameOverScene::create();184 gameOverScene->getLayer()->getLabel()->setString("You Win!");185 Director::getInstance()->replaceScene(gameOverScene);186 }187 }188 189 void HelloWorld::onEnter()190 {191 Layer::onEnter();192 193 auto touchListener = EventListenerTouchOneByOne::create();194 touchListener->setSwallowTouches(true);195 196 touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);197 touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);198 touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);199 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);200 201 //添加监听器202 auto contactListener = EventListenerPhysicsContact::create();203 //设置监听器的碰撞开始函数204 contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);205 206 //添加到事件分发器中207 _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);208 209 }
GameOverScene.h
1 #ifndef __SampleGame1__GameOverScene__ 2 #define __SampleGame1__GameOverScene__ 3 4 #include "cocos2d.h" 5 6 class GameOverLayer : public cocos2d::LayerColor 7 { 8 public: 9 GameOverLayer():_label(NULL) {};10 virtual ~GameOverLayer();11 bool init();12 CREATE_FUNC(GameOverLayer);13 14 void gameOverDone();15 16 CC_SYNTHESIZE_READONLY(cocos2d::LabelTTF*, _label, Label);17 };18 19 class GameOverScene : public cocos2d::Scene20 {21 public:22 GameOverScene():_layer(NULL) {};23 ~GameOverScene();24 bool init();25 CREATE_FUNC(GameOverScene);26 27 CC_SYNTHESIZE_READONLY(GameOverLayer*, _layer, Layer);28 };29 30 #endif
GameOverScene.cpp
1 #include "GameOverScene.h" 2 #include "HelloWorldScene.h" 3 USING_NS_CC; 4 5 6 bool GameOverScene::init() 7 { 8 if( Scene::init() ) 9 {10 this->_layer = GameOverLayer::create();11 this->_layer->retain();12 this->addChild(_layer);13 14 return true;15 }16 else17 {18 return false;19 }20 }21 22 GameOverScene::~GameOverScene()23 {24 if (_layer)25 {26 _layer->release();27 _layer = NULL;28 }29 }30 31 bool GameOverLayer::init()32 {33 if ( LayerColor::initWithColor( Color4B(255,255,255,255) ) )34 {35 auto winSize = Director::getInstance()->getWinSize();36 this->_label = LabelTTF::create("","Artial", 32);37 _label->retain();38 _label->setColor( Color3B(0, 0, 0) );39 _label->setPosition( Point(winSize.width/2, winSize.height/2) );40 this->addChild(_label);41 42 this->runAction( Sequence::create(43 DelayTime::create(3),44 CallFunc::create(CC_CALLBACK_0(GameOverLayer::gameOverDone, this)),45 NULL));46 47 return true;48 }49 else50 {51 return false;52 }53 }54 55 void GameOverLayer::gameOverDone()56 {57 Director::getInstance()->replaceScene( HelloWorld::createScene() );58 }59 60 GameOverLayer::~GameOverLayer()61 {62 if (_label)63 {64 _label->release();65 _label = NULL;66 }67 }
游戏中图片:
游戏运行效果:
coco2d-x3.2使用物理引擎Physicals制作Breakout游戏
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。