以上是vs racing2賽車遊戲,我借他的圖片來說明,仔細看看就發現車永遠是在那個位置。
這周過得挺充實的,白天上課,晚上開發遊戲,玩過不少的賽車遊戲,感覺挺爽,非常喜歡超速的刺激感。通過仔細的發現,賽車類的遊戲中玩家操控的精靈都是在屏幕中央,而且無論怎樣變動,都在屏幕中的某個位置不動,動的是背景,背景反方向移動,在肉眼看是主角是在動。
如何做到除了主角不動其他都在反方向動呢?這就需要用到CCSpriteBatchNode這個類,用過這個類的人都知道是什麼,不妨讓我再解析一次,這類與CCSprite類相似都是精靈,但是CCSpriteBatchNode可以一次渲染多個精靈,就像是CCSprite的數組,它可以加快渲染速度。
講到這不得不提這一個軟件zwoptex(在官網上下載FLASH版本),這個軟件是製作出CCSpriteBatchNode需要用到的圖片資源*.plist 和 *.png,zwoptex是一個圖片合併的工具,遊戲製作需要大量的圖片,如果每一張圖片都單獨存放,就使得讀取不方便,文件數多,不好管理。這個工具就可以將有共性的圖片放在一起,導出png格式,plist格式就包含該png格式上的所有信息,爲CCSpriteBatchNode這個類所用。代碼如下:
[ [ CCSpriteFrameCache sharedSpriteFrameCache ] addSpriteFramesWithFile: @"Enemy.plist" ];
enemySheet = [ CCSpriteBatchNode batchNodeWithFile: @"Enemy.png" ];
[ self addChild: enemySheet z: 100 ];
以下就解析一下,爲什麼可以做到主角不動,背景動。以上述事例爲例,enemySheet 這個類被新建出來,該屬性position就默認爲cpp(0,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 ];
}
缺少了它,你就用不了重力計了,小弟解析不好請多多包含!