以上是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 ];
}
缺少了它,你就用不了重力计了,小弟解析不好请多多包含!