// // GameScene.cpp // RedCore2 // // Created by Gabriel Capella on 31/05/17. // // #include "GameScene.h" #include "SimpleAudioEngine.h" #include "BlocksLayer.h" #include "Ball.h" #include "params.h" USING_NS_CC; Scene* GameScene::createScene(int level) { auto scene = Scene::createWithPhysics(); Size visibleSize = Director::getInstance()->getVisibleSize(); //choose whitch part need to draw, Joint, Shape, Contact, None or All // scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); GameScene* layer = GameScene::create(); scene->addChild(layer); auto material = PHYSICSBODY_MATERIAL_DEFAULT; material.density = 1.0f; material.restitution = 1.0f; material.friction = 0.0f; // the edge of the screen auto body = PhysicsBody::createEdgeBox(visibleSize, material); auto edgeNode = Node::create(); edgeNode->setPosition(Point(visibleSize.width/2,visibleSize.height/2)); body->setDynamic(false); edgeNode->setPhysicsBody(body); scene->addChild(edgeNode); auto blocks = BlocksLayer::create(); blocks->setLevel(level); blocks->setPosition(visibleSize.width/2, visibleSize.height); layer->addChild(blocks, 20); layer->setLevel(level); return scene; } // on "init" you need to initialize your instance bool GameScene::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } // https://www.freesound.org/people/schademans/sounds/13290/ FileUtils::getInstance()->addSearchPath("res"); auto audio = CocosDenshion::SimpleAudioEngine::getInstance(); audio->preloadEffect("pipe.wav"); audio->preloadEffect("metal.wav"); audio->preloadEffect("bomb.wav"); audio->preloadEffect("win.wav"); auto visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); // Adiona o fundo auto bg = LayerColor::create(COLOR_back); this->addChild(bg); auto ball = Ball::create(); ball->setPosition(visibleSize.width / 2, RAQUETE_ALTURA+BALL_SIZE); ball->throwBall(); this->addChild(ball, 21); auto raquete = DrawNode::create(); float py = RAQUETE_HEIGHT/2.0; float pxl = - RAQUETE_WIDTH/2; float pxr = RAQUETE_WIDTH/2; raquete->drawSegment(Vec2(pxl, py), Vec2(pxr, py), py, Color4F(COLOR_grey)); raquete->setPositionX(visibleSize.width/2); raquete->setPositionY(RAQUETE_ALTURA); auto bsize = Size(RAQUETE_WIDTH+RAQUETE_HEIGHT, RAQUETE_HEIGHT); auto physicsBody = PhysicsBody::createBox(bsize, PhysicsMaterial(0.1f, 1.0f, 0.0f)); physicsBody->setPositionOffset(Vec2(0, RAQUETE_HEIGHT/2)); physicsBody->setGravityEnable(false); physicsBody->setDynamic(false); physicsBody->setContactTestBitmask(0xFFFFFFFF); raquete->addComponent(physicsBody); this->addChild(raquete); auto listener1 = EventListenerTouchOneByOne::create(); // trigger when you push down listener1->onTouchBegan = [=](Touch* touch, Event* event){ raquete->setPositionX(touch->getLocation().x); float px = touch->getLocation().x; if (px >= RAQUETE_WIDTH/2 && px < visibleSize.width - RAQUETE_WIDTH/2) raquete->setPositionX(touch->getLocation().x); return true; // if you are consuming it }; // trigger when moving touch listener1->onTouchMoved = [=](Touch* touch, Event* event){ float px = touch->getLocation().x; if (px >= RAQUETE_WIDTH/2 && px <= visibleSize.width - RAQUETE_WIDTH/2) raquete->setPositionX(touch->getLocation().x); }; // Add listener _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this); // the edge of bottom auto body = PhysicsBody::createEdgeBox(Size(visibleSize.width, 0)); auto edgeNode = Node::create(); edgeNode->setPosition(Point(visibleSize.width/2, 0)); body->setDynamic(false); edgeNode->setTag(BOTTOM_TAG); body->setContactTestBitmask(0xFFFFFFFF); edgeNode->setPhysicsBody(body); this->addChild(edgeNode); // Evento no contato das bolas auto contactListener = EventListenerPhysicsContact::create(); contactListener->onContactBegin = CC_CALLBACK_1(GameScene::onContactBegin, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this); UserDefault *userdata = UserDefault::getInstance(); //int level = userdata->getIntegerForKey("level"); userdata->setIntegerForKey("level", 0); userdata->flush(); return true; } bool GameScene::onContactBegin(PhysicsContact& contact) { auto nodeA = contact.getShapeA()->getBody()->getNode(); auto nodeB = contact.getShapeB()->getBody()->getNode(); if (nodeA && nodeB && nodeA->getTag() != nodeB->getTag()) { //CCLOG("%d %d", nodeB->getTag(), nodeA->getTag()); // sempre B < A if (nodeB->getTag() == BLOCK_TAG) { auto audio = CocosDenshion::SimpleAudioEngine::getInstance(); audio->playEffect("pipe.wav"); nodeB->removeFromParentAndCleanup(true); } else if (nodeB->getTag() == INDESTRUCTIBLE_BLOCK_TAG) { auto audio = CocosDenshion::SimpleAudioEngine::getInstance(); audio->playEffect("metal.wav"); } else if (nodeB->getTag() == BOTTOM_TAG && nodeA->getTag() == BALL_TAG) { ball_collision(nodeA); } else if (nodeB->getTag() == CORE_TAG && nodeA->getTag() == BALL_TAG) { ball_core(nodeB, nodeA); } else if (nodeB->getTag() == BALL_TAG && nodeA->getTag() == CORE_TAG) { ball_core(nodeA, nodeB); } } return true; } void GameScene::ball_collision (Node *ball) { auto visibleSize = Director::getInstance()->getVisibleSize(); auto text = Label::createWithTTF("Game Over...", "fonts/Marker Felt.ttf", 40); text->setPosition(visibleSize.width/2, visibleSize.height/2); this->addChild(text); this->level = -1; auto menu_item_start = MenuItemFont::create("Restart", CC_CALLBACK_1(GameScene::NextLevel, this)); menu_item_start->setPosition(text->getPosition()); menu_item_start->setPositionY(menu_item_start->getPositionY()-50); auto *menu = Menu::create(menu_item_start, NULL); menu->setPosition(Point(0, 0)); this->addChild(menu, 30); auto audio = CocosDenshion::SimpleAudioEngine::getInstance(); audio->playEffect("bomb.wav"); ParticleSun* m_emitter = ParticleSun::create(); m_emitter->setPosition(ball->getPosition()); m_emitter->setDuration(1); this->getScene()->addChild(m_emitter); ball->removeFromParentAndCleanup(true); } void GameScene::ball_core (Node *core, Node *ball) { auto scaleBy = ScaleBy::create(1.0f, 20.0f); core->getPhysicsBody()->setEnabled(false); core->runAction(scaleBy); auto audio = CocosDenshion::SimpleAudioEngine::getInstance(); audio->playEffect("win.wav"); auto callbackRotate = CallFunc::create([=](){ auto visibleSize = Director::getInstance()->getVisibleSize(); auto menu_item_start = MenuItemFont::create("Next Level", CC_CALLBACK_1(GameScene::NextLevel, this)); menu_item_start->setPosition(Point(visibleSize.width / 2, (visibleSize.height / 2))); auto *menu = Menu::create(menu_item_start, NULL); menu->setPosition(Point(0, 0)); this->addChild(menu, 30); }); // create a sequence with the actions and callbacks auto seq = Sequence::create(scaleBy, callbackRotate, nullptr); core->runAction(seq); ball->removeFromParentAndCleanup(true); } void GameScene::NextLevel(cocos2d::Ref *pSender) { auto scene = GameScene::createScene(this->level + 1); Director::getInstance()->replaceScene(scene); //Director::getInstance()->end(); } void GameScene::setLevel(int level) { this->level = level; char level_text[256]; sprintf(level_text,"Level %d", this->level); auto text = Label::createWithTTF(level_text, "fonts/Marker Felt.ttf", 30); text->setAnchorPoint(Vec2()); text->setPosition(10, 10); this->addChild(text); }