Cocos2d遊戲學習之主角不動


以上是vs racing2賽車遊戲,我借他的圖片來說明,仔細看看就發現車永遠是在那個位置。

這周過得挺充實的,白天上課,晚上開發遊戲,玩過不少的賽車遊戲,感覺挺爽,非常喜歡超速的刺激感。通過仔細的發現,賽車類的遊戲中玩家操控的精靈都是在屏幕中央,而且無論怎樣變動,都在屏幕中的某個位置不動,動的是背景,背景反方向移動,在肉眼看是主角是在動。

如何做到除了主角不動其他都在反方向動呢?這就需要用到CCSpriteBatchNode這個類,用過這個類的人都知道是什麼,不妨讓我再解析一次,這類與CCSprite類相似都是精靈,但是CCSpriteBatchNode可以一次渲染多個精靈,就像是CCSprite的數組,它可以加快渲染速度。

講到這不得不提這一個軟件zwoptex(在官網上下載FLASH版本),這個軟件是製作出CCSpriteBatchNode需要用到的圖片資源*.plist 和 *.pngzwoptex是一個圖片合併的工具,遊戲製作需要大量的圖片,如果每一張圖片都單獨存放,就使得讀取不方便,文件數多,不好管理。這個工具就可以將有共性的圖片放在一起,導出png格式,plist格式就包含該png格式上的所有信息,爲CCSpriteBatchNode這個類所用。代碼如下:

[ [ CCSpriteFrameCache sharedSpriteFrameCache ] addSpriteFramesWithFile: @"Enemy.plist" ];

    enemySheet = [ CCSpriteBatchNode batchNodeWithFile: @"Enemy.png" ];

    [ self addChild: enemySheet z: 100 ];

 

以下就解析一下,爲什麼可以做到主角不動,背景動。以上述事例爲例,enemySheet 這個類被新建出來,該屬性position就默認爲cpp0,0)。再看一下代碼

CGSize screenSize = [ [ CCDirector sharedDirector ] winSize ];

    

    CCSprite* bullet = [ CCSprite spriteWithSpriteFrameName: @"Bullet.png" ];

    bullet.anchorPoint = ccp( 0.5 , 0 );

    bullet.tag = 98;

    bullet.position = ccp( player.position.x - backgroundScene.position.x , player.position.y );

    [ enemySheet addChild: bullet ];

    

    CCMoveBy* bulletMoveUp = [ CCMoveBy actionWithDuration: 2.0f position: ccp( 0 , screenSize.height - player.position.y ) ];

    id bulletMoveEnd = [ CCCallFuncND actionWithTarget: self selector: @selector(bulletMoveEndedWithAction:Sprite:) data: bullet ];

    

    [bullet runAction:[CCSequence actions:bulletMoveUp,bulletMoveEnd,nil]];

 

這是一個子彈精靈,有初始位置,有運動方式,爲直線向上運動,這子彈只是在enemySheet 這個節點上纔是直線運動,如果在enemySheet 上加上左右運動的動作,那麼子彈就不是在直線運動了,怎樣才能做到呢?其實很簡單,就是在每一幀改變enemySheet 的屬性position的值就行了,這就是做到主角不動,背景動的原理。

究竟代碼怎樣寫呢?我以重力感應爲例,代碼如下:

 

/*********************************

 scheduleUpdate 

 *********************************/

- (void) updateGame:(ccTime)delta

{

    CGPoint pos = backgroundScene.position;

    pos.x += backgroundPoint.x;

    

    float leftBorderLimit = -80;//imageWidthHalved;

    float rightBorderLimit = 80;

    

    // preventing the player sprite from moving outside the screen

    if ( pos.x < leftBorderLimit )

    {

        pos.x = leftBorderLimit;

        backgroundPoint = CGPointZero;

    }

    else if ( pos.x > rightBorderLimit )

    {

        pos.x = rightBorderLimit;

        backgroundPoint = CGPointZero;

    }

 

    backgroundScene.position = pos;

    

    // enemy position

    enemySheet.position = pos;

    

}

 

#pragma mark Accelerometer Input

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

{

    // controls how quickly velocity decelerates (lower = quicker to change direction )

    float deceleration = 0.4f;

    // determines how sensitive the accelerometer reacts ( higher = more sensitive )

    float sensitivity = 30.0f;

    // how fast the velocity can be at most

    float maxVelocity = 100;

    // adjust velocity based on current accelerometer acceleration

    backgroundPoint.x = backgroundPoint.x * deceleration + ( - acceleration.y ) * sensitivity;

    

    // we must limit the maximum velocity of the player sprites , in both directions

    if ( backgroundPoint.x > maxVelocity )

    {

        backgroundPoint.x = maxVelocity;

    }

    else if ( backgroundPoint.x < -maxVelocity )

    {

        backgroundPoint.x = -maxVelocity;

    }

}

 

不要漏了

- (void) onEnter

{

    [ super onEnter ];

    [ self setAccelerometerEnabled: YES ];

}

 

缺少了它,你就用不了重力計了,小弟解析不好請多多包含!

發佈了140 篇原創文章 · 獲贊 10 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章