《Cocos2D-iPhone 游戏开发之路》第4节 高仿<Flappy Bird>教程(2)

在上一章节中,我们已经将背景添加到了我们的场景中,在本章的教学中,我们将让我们的背景进行视差滚动。

所谓视差滚动就是,当我们的场景移动时,远处的背景移动较慢,而约近的背景移动越快,如此可以给人一种层次分明的感觉,这种技术被广泛用于横版2D游戏中。

cocos2d为我们封装了视差滚动类 CCParallaxNode,不过由于其不能单独改变其子节点的位置,不好实现连续滚动,所以接下来我们将自己来做连续滚动的视差效果。

首先新建一个类,继承于CCSprite,命名为ParallaxRollSprite,并在GameScene中导入其头文件。

在ParallaxRollSprite.h中导入cocos2d.h文件,并添加下列属性及方法:

#import "CCSprite.h"
#import "cocos2d.h"

@interface ParallaxRollSprite : CCSprite
@property (nonatomic,assign) float speed;
@property (nonatomic,assign) CGPoint offSetPoint;
@property (nonatomic,assign) CGPoint jumpPoint;
- (void) setParallaxRollWithSpeed:(float)speed jumpAtPoint:(CGPoint)jumpPoint offSetPoint:(CGPoint)offSetPoint;
@end

让我们了解一下这些属性和方法的作用,speed参数记录了该精灵移动的速度。jumpPoint参数记录了该精灵应该在什么位置进行跳跃,而offSetPoint记录了精灵要如何进行跳跃(例如:精灵A已每帧10的速度移动到了屏幕最左边到达了jumpPoint出发点,然后精灵跳跃至屏幕最右边重新开始向左运动,如此循环);

- (void) setParallaxRollWithSpeed:(float)speed jumpAtPoint:(CGPoint)jumpPoint offSetPoint:(CGPoint)offSetPoint 方法是为了方便我们设置以上参数,在.m文件中只需实现此方法即可,具体实现我相信大家都会的吧!


回到GameScene.m文件中,添加下列代码:

@interface GameScene ()
{
    int speed;
}

@property (nonatomic, strong) NSMutableArray * parallaxRollSpriteBox;

@end

我们创建了一个speed成员变量,方便我们之后调整速度。一个parallaxRollSpriteBox可变数组,其作用将在下列代码中讲解,修改initBackGround方法,


- (void)initBackGround
{

    _parallaxRollSpriteBox = [@[] mutableCopy];
    
    for (int i = 0; i<2; i++) {
        ParallaxRollSprite * cloud = [ParallaxRollSprite spriteWithImageNamed:@"cloud.png"];
        cloud.anchorPoint = ccp(0, 0);
        cloud.position = ccp(i * Screen_Size.width, 150);
        [cloud setParallaxRollWithSpeed:0.01 jumpAtPoint:ccp(- cloud.contentSize.width, 150) offSetPoint:ccp(Screen_Size.width+cloud.contentSize.width, 0)];
        [self addChild:cloud];
        [_parallaxRollSpriteBox addObject:cloud];
    }
    
    
    for (int i = 0; i<6; i++) {
        ParallaxRollSprite * building = [ParallaxRollSprite spriteWithImageNamed:@"buildingShadow.png"];
        building.anchorPoint = ccp(0, 0);
        building.position = ccp(i*180, 220);
        [building setParallaxRollWithSpeed:0.015 jumpAtPoint:ccp(-180, 220) offSetPoint:ccp(180*6, 0)];
        [self addChild:building];
        [_parallaxRollSpriteBox addObject:building];
    }
    
    for (int i = 0; i<5; i++) {
        ParallaxRollSprite * building = [ParallaxRollSprite spriteWithImageNamed:@"building.png"];
        building.anchorPoint = ccp(0, 0);
        building.position = ccp(i*200, 220);
        [building setParallaxRollWithSpeed:0.03 jumpAtPoint:ccp(-200, 220) offSetPoint:ccp(200*5, 0)];
        [self addChild:building];
        [_parallaxRollSpriteBox addObject:building];
    }
    
    for (int i = 0; i<2; i++) {
        ParallaxRollSprite * grass = [ParallaxRollSprite spriteWithImageNamed:@"grass.png"];
        grass.anchorPoint = ccp(0, 0);
        grass.position = ccp(i * Screen_Size.width, 200);
        [grass setParallaxRollWithSpeed:0.06 jumpAtPoint:ccp(- grass.contentSize.width, 200) offSetPoint:ccp(Screen_Size.width + grass.contentSize.width, 0)];
        [self addChild:grass];
        [_parallaxRollSpriteBox addObject:grass];
    }
    
    CCSprite * ground = [CCSprite spriteWithImageNamed:@"ground.png"];
    ground.anchorPoint = ccp(0, 0);
    ground.position = ccp(0, 0);
    [self addChild:ground];
    
    for (int i = 0; i<15; i++) {
        ParallaxRollSprite * groundMove = [ParallaxRollSprite spriteWithImageNamed:@"groundMove.png"];
        groundMove.anchorPoint = ccp(0, 0);
        groundMove.position = ccp(i * 60, 160);
        [groundMove setParallaxRollWithSpeed:0.4 jumpAtPoint:ccp(-60, 160) offSetPoint:ccp(60*15, 0)];
        [self addChild:groundMove];
        [_parallaxRollSpriteBox addObject:groundMove];
        
    }
}

代码比较长让我们直接在代码中来看看我们做了些什么,首先我们初始化了上面提到的可变数组用于存放我们的背景元素,其次每个背景元素都被额外放置了一次,因为如果我们每个背景只填满一个屏幕的话,背景是无法做到连续滚动的,把代码做以上修改以后,运行你的程序你会发现界面和之前还是一样,并没有开始滚动,别急,现在万事俱备只欠东风,东风来也!继续添加下列方法:

- (void)update:(CCTime)delta
{
    int realSpeed = delta/(1/60.0)*speed;
    for (ParallaxRollSprite * parallaxRollSprite in _parallaxRollSpriteBox) {
        parallaxRollSprite.position = ccp(parallaxRollSprite.position.x - parallaxRollSprite.speed * realSpeed, parallaxRollSprite.position.y);
        if (parallaxRollSprite.position.x < parallaxRollSprite.jumpPoint.x) {
            parallaxRollSprite.position = ccpAdd(parallaxRollSprite.position, parallaxRollSprite.offSetPoint);
        }
    }
}

cocos2d v3.x版本中,场景每一帧都会自动调用该方法,我们先使用之前设定的速度speed与当前帧延迟delta计算出当前帧背景移动的速度,然后我们遍历parallaxRollSpriteBox数组,让里面的每个元素都按照其之前设置的速度倍率进行移动,由于我们的背景是水平向左移动,所以只需要查看背景位置的X坐标值是否小于触发点的X坐标值,如果满足条件就让背景当然的位置加上之前设置好的偏移量。这样我们就实现了背景的循环滚动。如果一切顺利,现在运行你的程序,你可以看到你的背景开始以不同的速度开始滚动了!

好了,今晚先写到这里,如有疑问请回复或者站内信!下一章我们将继续完成我们的FlappyBird!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值