Ver Fonte

Adicionado power-up de aumentar/diminuir raquete

JoaoHL há 7 anos atrás
pai
commit
79963791e6
3 ficheiros alterados com 156 adições e 46 exclusões
  1. 144 41
      Classes/GameScene.cpp
  2. 10 5
      Classes/GameScene.h
  3. 2 0
      Classes/params.h

+ 144 - 41
Classes/GameScene.cpp

@@ -44,14 +44,22 @@ Scene* GameScene::createScene(int level) {
     
     layer->setLevel(level);
     
+    // inicializa os callbacks dos power ups/downs
     auto delay_save_level = DelayTime::create(10.0);
     CallFunc *runCallback_save_level = CallFunc::create(CC_CALLBACK_0(GameScene::saveLevel, layer));
     auto seq_save_level = Sequence::create(delay_save_level, runCallback_save_level, nullptr);
+
     auto delay_triple_balls = DelayTime::create(10.0);
-    CallFunc *runCallback_triple_balls = CallFunc::create(CC_CALLBACK_0(GameScene::tripleBalls, layer));
+    CallFunc *runCallback_triple_balls = CallFunc::create(CC_CALLBACK_0(GameScene::tripleBallsAppearance, layer));
     auto seq_triple_balls = Sequence::create(delay_triple_balls, runCallback_triple_balls, nullptr);
+
+    auto delay_raquete_ball = DelayTime::create(5.0);
+    CallFunc *runCallback_raquete_ball = CallFunc::create(CC_CALLBACK_0(GameScene::raqueteBallAppearance, layer));
+    auto seq_raquete_ball = Sequence::create(delay_raquete_ball, runCallback_raquete_ball, nullptr);
+
     layer->runAction(seq_save_level);
     layer->runAction(seq_triple_balls);
+    layer->runAction(seq_raquete_ball);
     
     return scene;
 }
@@ -91,6 +99,7 @@ bool GameScene::init() {
     ball_count = 1;
     
     raquete = DrawNode::create();
+    raquete_size = RAQUETE_WIDTH;
     float py = RAQUETE_HEIGHT/2.0;
     float pxl = - RAQUETE_WIDTH/2;
     float pxr =  RAQUETE_WIDTH/2;
@@ -172,56 +181,30 @@ bool GameScene::onContactBegin(PhysicsContact& contact) {
             auto audio = CocosDenshion::SimpleAudioEngine::getInstance();
             audio->playEffect("metal.wav");
         } else if (nodeB->getTag() == BOTTOM_TAG && nodeA->getTag() == BALL_TAG) {
-            ball_collision(nodeA);
+            caseBallCollision(nodeA);
         }  else if (nodeB->getTag() == CORE_TAG && nodeA->getTag() == BALL_TAG) {
-            ball_core(nodeB, nodeA);
+            caseBallCore(nodeB, nodeA);
         }  else if (nodeB->getTag() == BALL_TAG && nodeA->getTag() == CORE_TAG) {
-            ball_core(nodeA, nodeB);
+            caseBallCore(nodeA, nodeB);
         }  else if (nodeB->getTag() == SAVE_TAG && nodeA->getTag() == RACKET_TAG) {
-            if (!over) {
-                Size visibleSize = Director::getInstance()->getVisibleSize();
-                // Salva o nivel!
-                UserDefault *userdata = UserDefault::getInstance();
-                userdata->setIntegerForKey("level", this->level);
-                userdata->setDoubleForKey("time", (double) time(NULL));
-                userdata->flush();
-                auto text = Label::createWithTTF("Level Saved!", "fonts/Marker Felt.ttf", 40);
-                text->setPosition(visibleSize.width/2, visibleSize.height/2);
-                this->addChild(text);
-                text->runAction(FadeOut::create(3));
-            }
-            nodeB->removeFromParentAndCleanup(true);
-            
+            caseSaveLevel(nodeB);            
         } else if (nodeB->getTag() == THREE_BALLS_TAG && nodeA->getTag() == RACKET_TAG) {
-            if (!over) {
-                Size visibleSize = Director::getInstance()->getVisibleSize();
-                // Salva na "database" o número de bolas na tela
-                auto text = Label::createWithTTF("Triple Balls!", "fonts/Marker Felt.ttf", 40);
-                text->setPosition(visibleSize.width/2, visibleSize.height/2 + 2);
-                this->addChild(text);
-                text->runAction(FadeOut::create(3));
-            
-                // cria as bolas e as adiciona no cenário
-                for (int i = ball_count; i < 3; i++, ball_count++) {
-                    auto ball = Ball::create();
-                    ball->setPosition(raquete->getPositionX(), RAQUETE_ALTURA+BALL_SIZE+i);
-                    ball->throwBall();
-                    this->addChild(ball, 21);
-                }
-            }
-            nodeB->removeFromParentAndCleanup(true);
-            
+            caseTripleBalls(nodeB);
+        } else if (nodeB->getTag() == RACKET_BALL_TAG && nodeA->getTag() == RACKET_TAG) {
+            caseRaqueteBall(nodeB);
         } else if (nodeB->getTag() == SAVE_TAG && nodeA->getTag() == BOTTOM_TAG) {
             nodeB->removeFromParentAndCleanup(true);
         } else if (nodeB->getTag() == THREE_BALLS_TAG && nodeA->getTag() == BOTTOM_TAG) {
             nodeB->removeFromParentAndCleanup(true);
+        } else if (nodeB->getTag() == RACKET_BALL_TAG && nodeA->getTag() == BOTTOM_TAG) {
+            nodeB->removeFromParentAndCleanup(true);
         }
 
     }
     return true;
 }
 
-void GameScene::ball_collision (Node *ball) {
+void GameScene::caseBallCollision (Node *ball) {
     // Destrói a bola que tocou o fundo
     ball_count--;
     auto audio = CocosDenshion::SimpleAudioEngine::getInstance();
@@ -250,7 +233,7 @@ void GameScene::ball_collision (Node *ball) {
     }
 }
 
-void GameScene::ball_core (Node *core, Node *ball) {
+void GameScene::caseBallCore (Node *core, Node *ball) {
     auto scaleBy = ScaleBy::create(1.0f, 20.0f);
     core->getPhysicsBody()->setEnabled(false);
     core->runAction(scaleBy);
@@ -272,6 +255,23 @@ void GameScene::ball_core (Node *core, Node *ball) {
     ball->removeFromParentAndCleanup(true);
 }
 
+void caseSaveLevel(Node *powerup_ball) {
+    if (!over) {
+        Size visibleSize = Director::getInstance()->getVisibleSize();
+
+        // Salva o nivel!
+        UserDefault *userdata = UserDefault::getInstance();
+        userdata->setIntegerForKey("level", this->level);
+        userdata->setDoubleForKey("time", (double) time(NULL));
+        userdata->flush();
+        auto text = Label::createWithTTF("Level Saved!", "fonts/Marker Felt.ttf", 40);
+        text->setPosition(visibleSize.width/2, visibleSize.height/2);
+        this->addChild(text);
+        text->runAction(FadeOut::create(3));
+    }
+    powerup_ball->removeFromParentAndCleanup(true);
+}
+
 void GameScene::NextLevel(Ref *pSender) {
     auto scene = GameScene::createScene(this->level + 1);
     Director::getInstance()->replaceScene(scene);
@@ -321,8 +321,8 @@ void GameScene::saveLevel() {
     
 }
 
-// Power-up: triplica o número de bolas na tela 
-void GameScene::tripleBalls() {
+// Power-up: deixa 3 bolas na tela ao invés de 1
+void GameScene::tripleBallsAppearance() {
     if (rand_0_1() < DROP_TRIPLE_BALL && this->over == false){
             Size visibleSize = Director::getInstance()->getVisibleSize();
             auto ball_draw = DrawNode::create();
@@ -348,8 +348,111 @@ void GameScene::tripleBalls() {
     }
     
     auto delay = DelayTime::create(rand_0_1()*10.0);
-    CallFunc *runCallback = CallFunc::create(CC_CALLBACK_0(GameScene::tripleBalls, this));
+    CallFunc *runCallback = CallFunc::create(CC_CALLBACK_0(GameScene::tripleBallsAppearance, this));
     auto seq = Sequence::create(delay, runCallback, nullptr);
     this->runAction(seq);
 }
 
+void GameScene::caseTripleBalls(Node *powerup_ball) {
+    if (!over) {
+        Size visibleSize = Director::getInstance()->getVisibleSize();
+        auto text = Label::createWithTTF("Triple Balls!", "fonts/Marker Felt.ttf", 40);
+        text->setPosition(visibleSize.width/2, visibleSize.height/2 + 2);
+        this->addChild(text);
+        text->runAction(FadeOut::create(3));
+            
+        // cria as bolas e as adiciona no cenário
+        for (int i = ball_count; i < 3; i++, ball_count++) {
+            auto ball = Ball::create();
+            ball->setPosition(raquete->getPositionX(), RAQUETE_ALTURA+BALL_SIZE+i);
+            ball->throwBall();
+            this->addChild(ball, 21);
+        }
+    }
+    powerup_ball->removeFromParentAndCleanup(true);
+}
+
+void GameScene::raqueteBallAppearance() {
+    if (rand_0_1() < DROP_RACKET_BALL && this->over == false){
+        Size visibleSize = Director::getInstance()->getVisibleSize();
+        auto ball_draw = DrawNode::create();
+            ball_draw->drawDot(Vec2(0, 0), BALL_SIZE/3.0, Color4F(COLOR_blue));
+        
+        auto material = PHYSICSBODY_MATERIAL_DEFAULT;
+        material.density = 0.0f;
+        material.restitution = 1.0f;
+        material.friction = 0.0f;
+        
+        auto physicsBody = PhysicsBody::createCircle(BALL_SIZE/3.0, material);
+        physicsBody->setGravityEnable(true);
+        physicsBody->setVelocity(Vec2(0,0));
+        physicsBody->setLinearDamping(0.0);
+        physicsBody->setMass(1.0f);
+        physicsBody->setContactTestBitmask(0xFFFFFFFF);
+        physicsBody->setGroup(-1);
+        ball_draw->addComponent(physicsBody);
+        ball_draw->setTag(RACKET_BALL_TAG);
+            
+        ball_draw->setPosition(visibleSize.width * rand_0_1(), visibleSize.height);
+        this->addChild(ball_draw);
+    }
+    
+    auto delay = DelayTime::create(rand_0_1()*10.0);
+    CallFunc *runCallback = CallFunc::create(CC_CALLBACK_0(GameScene::raqueteBallAppearance, this));
+    auto seq = Sequence::create(delay, runCallback, nullptr);
+    this->runAction(seq);
+}
+
+/* Power-up/down: 50% de chance de dobrar o tamanho da raquete, 
+   e 50% de chance de diminuir seu tamanho pela metade.
+   Para não ficar muito fácil/difícil, impusemos tamanho mínimo/máximo da raquete.
+*/
+void GameScene::caseRaqueteBall(Node *powerup_ball) {
+    if (!over) {
+        char* power_text = "";
+
+        if (rand_0_1() < 0.5) {
+            if (raquete_size <= RAQUETE_WIDTH * 4) {
+                power_text = "Doubled racket size!";
+                raquete_size *= 2;
+            }
+        }
+
+        else {
+            if (raquete_size >= RAQUETE_WIDTH / 4) {
+                power_text = "Halved racket size!";
+                raquete_size /= 2;
+            }
+        }
+
+        Size visibleSize = Director::getInstance()->getVisibleSize();
+        auto text = Label::createWithTTF(power_text, "fonts/Marker Felt.ttf", 40);
+        text->setPosition(visibleSize.width/2, visibleSize.height/2 + 2);
+        this->addChild(text);
+        text->runAction(FadeOut::create(3));
+
+        //cria uma nova raquete e substitui a antiga raquete
+        auto new_raquete = DrawNode::create();
+        float py = RAQUETE_HEIGHT/2.0;
+        float pxl = - raquete_size/2;
+        float pxr =  raquete_size/2;
+        new_raquete->drawSegment(Vec2(pxl, py), Vec2(pxr, py), py, Color4F(COLOR_grey));
+        new_raquete->setPositionX(raquete->getPositionX());
+        new_raquete->setPositionY(RAQUETE_ALTURA);
+        
+        auto bsize = Size(raquete_size+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);
+        new_raquete->setTag(RACKET_TAG);
+        new_raquete->addComponent(physicsBody);
+        
+        raquete->removeFromParentAndCleanup(true);
+        raquete = new_raquete;
+        this->addChild(raquete);
+    }
+    powerup_ball->removeFromParentAndCleanup(true);
+}
+

+ 10 - 5
Classes/GameScene.h

@@ -19,15 +19,20 @@ class GameScene : public cocos2d::Layer {
         CREATE_FUNC(GameScene);
         void setLevel(int level);
     private:
-        void ball_collision (cocos2d::Node *ball);
-        void ball_core (cocos2d::Node *core, cocos2d::Node *ball);
+        void caseBallCollision (cocos2d::Node *ball);
+        void caseBallCore (cocos2d::Node *core, cocos2d::Node *ball);
+        void caseSaveLevel(Node *powerup_ball);
         void NextLevel(cocos2d::Ref *pSender);
+        void saveLevel();
+        void tripleBallsAppearance();
+        void caseTripleBalls(Node *powerup_ball);
+        void raqueteBallAppearance();
+        void caseRaqueteBall(Node *powerup_ball);
         int level;
-        void saveLevel ();
-        void tripleBalls();
         bool over; // salva se o jogo acabou!
-        int ball_count;
+        int ball_count; // numero de bolas em jogo
         cocos2d::DrawNode * raquete;
+        int raquete_size; // tamanho atual da raquete
 };
 
 

+ 2 - 0
Classes/params.h

@@ -41,10 +41,12 @@
 
 #define THREE_BALLS_TAG 9
 #define SAVE_TAG 8
+#define RACKET_BALL_TAG 7
 
 // Probabilities
 #define DROP_LEVEL_SAVE 0.1 // deixar em 0.1
 #define DROP_TRIPLE_BALL 0.1
+#define DROP_RACKET_BALL 0.1
 
 // Hours to lose level
 #define LOSE_IS 12