1
\$\begingroup\$

I'm trying to make a vertical shooter, using Cocos2D and a few tutorials. Unfortunately, most tutorials only show how to make an horizontal shooter.

Still, I tried to adapt the code from a horizontal shooter to a vertical one, but am having a few problems. Mainly, my ship keeps moving right, even when the iPhone is sitting perfectly still.

Seeing as I'm a beginner, I'm having trouble pinpointing the exact issue and I'd love if anyone could help me.

Here's my accelerometer method:

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

    define kFilteringFactor 0.1

    define kRestAccelX -0.6

    define kShipMaxPointsPerSec (winSize.width*0.5)  

    define kMaxDiffX 0.2

    UIAccelerationValue rollingX;

    rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));

    float accelX = acceleration.x - rollingX;

    CGSize winSize = [CCDirector sharedDirector].winSize;

    float accelDiff = accelX - kRestAccelX;
    float accelFraction = accelDiff / kMaxDiffX;
    float pointsPerSec = kShipMaxPointsPerSec * accelFraction;

    _shipPointsPerSecX = pointsPerSec;


}

And my update method:

-(void)update:(ccTime)dt {

    CGSize winSize = [CCDirector sharedDirector].winSize;
    float maxX = winSize.width - _ship.contentSize.width/2;
    float minX = _ship.contentSize.width/2;

    float newX = _ship.position.x + (_shipPointsPerSecX * dt);
    newX = MIN(MAX(newX, minX), maxX);
    _ship.position = ccp(newX, _ship.position.y);

}

What could be causing this?

\$\endgroup\$
  • \$\begingroup\$ Did you notice that your rollingX variable is read while not initialized? \$\endgroup\$ – Chris Burt-Brown Mar 4 '12 at 8:51
3
\$\begingroup\$

You don't really need this much code to do sliding across the ground.

Try simply:

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
     _shipPointsPerSecX = acceleration.x * 10;
}

To get the ship to accelerate and decelerate you could try

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
     float targetSpeed = acceleration.x * 10;
     _shipPointsPerSecX = (_shipPointsPerSecX * .8f) + (targetSpeed * .2f);
}

But this isn't really accurate, a more realistic response might involve sliding towards the target value:

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    float targetSpeed = acceleration.x * 10;
    if(_shipPointsPerSecX < targetSpeed) {
        _shipPointsPerSecX = MIN(_shipPointsPerSecX + 2, targetSpeed);
    } else {
        _shipPointsPerSecX = MAX(_shipPointsPerSecX - 2, targetSpeed);
    }
}
\$\endgroup\$
  • \$\begingroup\$ Thanks! Managed to tweak your code in order to fit my game and it's all working perfectly now! \$\endgroup\$ – Henrique Sousa Mar 5 '12 at 1:41
  • \$\begingroup\$ @HenriqueSousa: if this answer helped you, mark it as correct (tick mark it from left) \$\endgroup\$ – Adil Soomro May 29 '12 at 8:41
0
\$\begingroup\$

Move the sprite from top to bottom and left to right using Accelerometer:

CCScene* PhysicsGame::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    PhysicsGame *layer = PhysicsGame::create();

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

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool PhysicsGame::init()
{

    // 1. super init first
    if ( !CCLayer::init())
    {
        return false;
    }

    winSize=CCDirector::sharedDirector()->getWinSize();

    BG=CCSprite::create("Yellowbg.png");
    BG->setPosition(ccp(winSize.width/2,winSize.height/2));
    this->addChild(BG,1);

//    _backgroundNode = CCParallaxNodeExtras::node();
//    this->addChild(_backgroundNode,-1);

    asteroid = CCSprite::create("Ball_image.png");
    asteroid->setPosition(ccp(winSize.width*0.1,winSize.height/2));
    this->addChild(asteroid,1);

    this->scheduleUpdate();

    this->setAccelerometerEnabled(true);

    return true;

}

void PhysicsGame::update(float dt)
{

    winSize = CCDirector::sharedDirector()->getWinSize();

    float maxY = winSize.height - asteroid->getContentSize().height/2;
    float minY = asteroid->getContentSize().height/2;

    float diff = (_shipPointsPerSecY * dt);
    float newY = asteroid->getPosition().y + diff;
    newY = MIN(MAX(newY, minY), maxY);

    asteroid->setPosition(ccp(asteroid->getPosition().x, newY));


    float minX=asteroid->getContentSize().width/2;

    float maxX = winSize.width - asteroid->getContentSize().width/2;

    float diff1 = (_shipPointsPerSecX * dt);

    float newX=asteroid->getPosition().x + diff1;

    newX=MIN(MAX(newX, minX), maxX);

    asteroid->setPosition(ccp(newX, asteroid->getPosition().y));

}


void PhysicsGame::didAccelerate(CCAcceleration *pAccelerationValue)
{


#define KFILTERINGFACTOR 0.1
#define KRESTACCELX -0.6
#define KSHIPMAXPOINTSPERSEC (winSize.height*0.5)
#define KMAXDIFFX 0.2


    double rollingX;

    // Cocos2DX inverts X and Y accelerometer depending on device orientation
    // in landscape mode right x=-y and y=x !!! (Strange and confusing choice)

    rollingX = (pAccelerationValue->x * KFILTERINGFACTOR) + (rollingX * (1.0 - KFILTERINGFACTOR));

    float accelX = pAccelerationValue->x - rollingX;

    float accelDiff = accelX - KRESTACCELX;

    float accelFraction = accelDiff / KMAXDIFFX;

    float pointsPerSec = KSHIPMAXPOINTSPERSEC * accelFraction;

    _shipPointsPerSecX = pointsPerSec;


#define KFILTERINGFACTOR1 0.1
#define KRESTACCELY -0.6
#define KSHIPMAXPOINTSPERSEC1 (winSize.width*0.5)
#define KMAXDIFFX1 0.2

    double rollingY;

    rollingY = (pAccelerationValue->y * KFILTERINGFACTOR) + (rollingY * (1.0 - KFILTERINGFACTOR1));

    float accelY = pAccelerationValue->y - rollingY;

    float accelDiff1= accelY - KRESTACCELY;

    float accelFraction1 = accelDiff1 / KMAXDIFFX1;

    float pointsPerSec1 = KSHIPMAXPOINTSPERSEC1 * accelFraction1;

    _shipPointsPerSecY = pointsPerSec1;

}
\$\endgroup\$
  • \$\begingroup\$ This is posted by Ashwin from Jean Martin \$\endgroup\$ – Ashwin Dec 22 '15 at 9:44
  • \$\begingroup\$ It works perfectly in IPAD \$\endgroup\$ – Ashwin Dec 22 '15 at 9:44
  • \$\begingroup\$ Keep in Mind, accelerometer did not work in Simulator \$\endgroup\$ – Ashwin Dec 22 '15 at 9:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.