cocos2d-iphonecocos2d-xcocos2d-x-3.0cocos2d-android

I'm trying to make a clone of game just for practice. But I'm not able to put the right gameloop


I'm a beginner and started with cocos2d-x. I want to make a clone of the game -

https://play.google.com/store/apps/details?id=com.addictivegames.angryalcohol&hl=en

It seemed really easy but turns out the logic I have been using at "Update function" (game loop) isn't working. This is my code -

#include "MainGameScene.h"
#include "MainMenuScene.h"
#include "GameOverScene.h"
#include "Constants.h"

USING_NS_CC;

Scene* MainGameScene::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto layer  = MainGameScene::create();
    auto layer2 = MainGameScene::create();


    // add layer as a child to scene
    scene->addChild(layer);
    scene->addChild(layer2); 

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool MainGameScene::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }

    Size visibleSize  = Director::getInstance()->getVisibleSize();
    Vec2 origin        = Director::getInstance()->getVisibleOrigin();

     // this will now place the sprite in the middle of the viewport
sprite = Sprite::create("top.png");
sprite->setPosition(Point( visibleSize.width/2 + origin.x, visibleSize.height/3 + origin.y));
sprite->setAnchorPoint( Vec2( 0.5, 0 ));
this->addChild( sprite );

     //Accelerometer Setup here...
   Device::setAccelerometerEnabled(true);
   auto acclistener = EventListenerAcceleration::create(CC_CALLBACK_2(MainGameScene::onAcceleration, this));
   Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(acclistener, this);

   this->scheduleUpdate();

    return true;
}

void MainGameScene::onAcceleration(cocos2d::Acceleration *acc, cocos2d::Event *event) {

    //Position constraints
    Size winSize         = Director::getInstance()->getWinSize(); 

    float rotX        = sprite->getRotation();
    float w           = winSize.width ;
    float h           = winSize.height;
    float center      = winSize.width/2 ;
     currentPos  = sprite->getPositionX();
    float   y         = sprite->getPositionY();
    float spriteWidth = sprite->getContentSize().width;
    //Filters for acceleration
    float sensitivity       = 0.3;
    float kFilteringFactor  = 0.4;



     //Accelerometer To control natural movement (GAME_LOOP_CONTROL)
      float accelX = ( acc->x * kFilteringFactor ) + ( accelX * (1.0 - kFilteringFactor ));

      rotX         = accelX - acc->x ; 
      currentPos   +=  acc->x * w * sensitivity;



    sprite->setPosition(currentPos, y);
    //sprite->setRotationX(rotX);


}


void MainGameScene::update( float dt ){

Size winSize      = Director::getInstance()->getWinSize(); 
 float w           = winSize.width ;
if (currentPos > winSize.width/2){ // IF on right side from middle

currentPos +=  50 * w ;

} else if (currentPos < winSize.width/2 ){ // IF on left side from middle

currentPos -=  50 * w  ;    

}   



sprite->setPosition(currentPos, sprite->getPositionY());

}

The player movement by accelerometer is fine.
I'm sure, something is wrong in the gameloop. Any kind of help will be appreciated. Thanks in advance !

Also, I'm thinking to switch from cocos2d-x to unity. Will this decision be promising ?


Solution

  • The problem is that you are updating the location of the sprite in each frame abruptly, hence the sprite will not be visible at any position. You have to make sprite stay at some point for some time or update its position smoothly (like using MoveTo). Here is a sample. And you should not ask for the solution rather how to solve the problem.

     bool MainGameScene::init()
        {
        //////////////////////////////
        // 1. super init first
        if ( !Layer::init() )
        {
            return false;
        }
    
        Size visibleSize  = Director::getInstance()->getVisibleSize();
        Vec2 origin        = Director::getInstance()->getVisibleOrigin();
    
         // this will now place the sprite in the middle of the viewport
    sprite = Sprite::create("top.png");
    sprite->setPosition(Point( visibleSize.width/2 + origin.x, visibleSize.height/3 + origin.y));
    sprite->setAnchorPoint( Vec2( 0.5, 0 ));
    this->addChild( sprite );
    
         //Accelerometer Setup here...
       Device::setAccelerometerEnabled(true);
       auto acclistener = EventListenerAcceleration::create(CC_CALLBACK_2(MainGameScene::onAcceleration, this));
       Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(acclistener, this);
    
       //this->scheduleUpdate();
    schedule(schedule_selector(MainGameScene::gameUpdate),2);
        return true;
    }
    void MainGameScene::gameUpdate( float dt ){
    
    Size winSize      = Director::getInstance()->getWinSize(); 
     float w           = winSize.width ;
    if (currentPos > winSize.width/2){ // IF on right side from middle
    
    currentPos +=  50 * w ;
    
    } else if (currentPos < winSize.width/2 ){ // IF on left side from middle
    
    currentPos -=  50 * w  ;    
    float moveDuration=2;//Change this according to difficulty
            sprite->runAction(MoveTo::create(moveDuration, Vec2(currentPos, sprite->getPositionY())));
    
    }