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::Layer 10 { 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::Scene 20 { 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 else 17 { 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 else 50 { 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 }
游戏中图片:
游戏运行效果:
时间: 2024-10-31 18:52:23