Cocos2D v3 CCParallaxNode 滚动无法让玩家保持焦点

Posted

技术标签:

【中文标题】Cocos2D v3 CCParallaxNode 滚动无法让玩家保持焦点【英文标题】:Cocos2D v3 CCParallaxNode scrolling can't keep player in focus 【发布时间】:2014-10-11 07:49:45 【问题描述】:

我对游戏开发非常陌生,我需要开发像 NinjaJump 这样的游戏。

我创建了一个 CCParallaxNode 来设置滚动背景,并添加了 CCPhysicsNode 来设置物理世界。我已经创建了如下所示的播放器对象。

// Add a sprite
    _sprite = [CCSprite spriteWithImageNamed:@"Icon.png"];
    _sprite.position  = ccp(self.contentSize.width/2,100);
    _sprite.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect)CGPointZero, _sprite.contentSize cornerRadius:0.0];
    _sprite.physicsBody.friction = 0.0f;
    _sprite.physicsBody.collisionGroup = @"player";
    _sprite.physicsBody.collisionType = @"Player";
    //_sprite.physicsBody.collisionMask = 0;
    //[self addChild:_sprite];
    [foreground addChild:_sprite];

foreground 只是添加到 CCScene 中的一个节点,用于轻松管理焦点玩家。

// code for physics world
_physicsWorld = [CCPhysicsNode node];
    _physicsWorld.gravity = ccp(0,-100);
    _physicsWorld.debugDraw = YES;
    //_physicsWorld.collisionDelegate = self;
    [self addChild:_physicsWorld];

    _foreground = [CCNode node];
    //[self addChild: _foreground];
    [_physicsWorld addChild: _foreground];

为了让播放器始终可见,我们实现了update 方法

- (void) update:(CFTimeInterval)currentTime 
    // Calculate player y offset
    if (_player.position.y > 200.0f) 
        //_midgroundNode.position = CGPointMake(0.0f, -((_player.position.y - 200.0f)/4));
        _foreground.position = CGPointMake(0.0f, -(_player.position.y - 200.0f));
    

我无法理解,但播放器无论如何都会滚出屏幕。代码使用Cocos2d v3编写。

我还设置了一个演示项目来展示我实现的内容:https://www.dropbox.com/s/5s55d00kk80wun4/HumptyJump-Example.zip?dl=0

感谢任何形式的帮助。提前致谢。

【问题讨论】:

【参考方案1】:

我无法运行您的示例代码,但有一件事,我可以肯定地告诉您,这里不需要物理引擎。

您只需将播放器保持在特定高度,然后将对象从右向左移动即可。 应用移动的视差背景图像和对象,让您的角色有一种向上或向下移动的感觉。

作为参考,您可以查看类似Swing Drop 的游戏,使用与上述相同的方法制作。

【讨论】:

谢谢亲爱的,但我还将实施一些障碍,让我的玩家在战斗中穿越,这可能需要物理引擎。但我会尝试实施你说的解决方案。 如果您只使用物理引擎进行碰撞检测,那么我再次不建议使用物理引擎。您可以通过比较精灵的边界来进行碰撞检测。我分享的参考游戏也是如此。即使你也可以使用物理引擎,但至少不像你现在正在做的那样。当您开始移动前景节点并且它离开屏幕时,您的 PlatformNode 会非常努力地推动您的播放器。【参考方案2】:

我已经实现了 2 个固定视图,在物理体下降时改变它们的位置;)。

查看相同的操作

@interface TestScene () 
    CCNode *_background;
    CCNode *_foreground;

    NSArray *grounds; // Keeps track of each of the 2 views
    CCPhysicsNode *_physicsWorld;


@implementation TestScene

- (id)init 
    self = [super init];
    if (!self) return(nil);

    // Enable touch handling on scene node
    self.userInteractionEnabled = YES;

    // Physics world setup
    _physicsWorld = [CCPhysicsNode node];
    _physicsWorld.gravity = ccp(0,-100);
    _physicsWorld.debugDraw = YES;
    _physicsWorld.collisionDelegate = self;
    [self addChild:_physicsWorld];

    // Foreground node in which platforms are there and moves downwards as player goes up
    _foreground = [CCNode node];

    // Adding background images
    CCSprite *default1 = [CCSprite spriteWithImageNamed: @"Default.png"];
    [default1 setAnchorPoint: ccp(0, 0)];
    CCSprite *default2 = [CCSprite spriteWithImageNamed: @"Default.png"];
    [default2 setAnchorPoint: ccp(0, 0)];
    [default2 setPosition: ccp(0, default1.contentSize.height)];
    [_foreground addChild: default1];
    [_foreground addChild: default2];

    // Adding into array
    grounds = @[default1, default2];
    // Adding into physics world
    [_physicsWorld addChild: _foreground];

    // creating player
    _player = [CCSprite spriteWithImageNamed: @"Assets.atlas/Player.png"];
    [_player setPosition: ccp(160.0f, 160.0f)];
    _player.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect)CGPointZero, _player.contentSize cornerRadius:0]; // 1
    _player.physicsBody.collisionGroup = @"playerGroup"; // 2
    _player.physicsBody.collisionType = @"player";
    //[_physicsWorld addChild:_player];
    [_foreground addChild: _player];

    // Multiple platforms can be added into body, they are static entities only
    PlatformNode *platform = (PlatformNode *)[PlatformNode node];
    [platform createPlatformAtPosition:CGPointMake(110, 50) ofType: PLATFORM_NORMAL];
    [_foreground addChild: platform];

    return self;


- (void) update:(CFTimeInterval)currentTime 
    // Take background and physics world down, 163 was Y position of the player
    _physicsWorld.position = ccp(_physicsWorld.position.x, 163 - _player.position.y);

    // loop the ground
    for (CCNode *ground in grounds) 
        // Get the world position
        CGPoint groundWorldPosition = [_physicsWorld convertToWorldSpace: ground.position];
        // Get screen position
        CGPoint groundScreenPosition = [self convertToNodeSpace: groundWorldPosition];
        NSLog(@"Positioning ground ---> world: (%f, %f) & screen: (%f, %f)", groundWorldPosition.x, groundWorldPosition.y, groundScreenPosition.x, groundScreenPosition.y, nil);
        if (groundScreenPosition.y <= -ground.contentSize.height) 
            ground.position = ccp(ground.position.x, ground.position.y + 2 * ground.contentSize.height);
            break;
        
    


-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event 
    // Take the player upside
    [_player.physicsBody applyImpulse: ccp(0, 215)];


@end

这就是我编码背景的方式:)。

【讨论】:

以上是关于Cocos2D v3 CCParallaxNode 滚动无法让玩家保持焦点的主要内容,如果未能解决你的问题,请参考以下文章

Cocos2d V3 - 获取当前精灵位置?

如何在 Cocos2d v3 中设置 CCTextField

Cocos2d V3 和 Spritebuilder - 时间轴动画不运行后续时间

如何在 Cocos2d v3 中获取一个类型的孩子

无法检测到 CCNode 上的触摸 - cocos2d v3.0

如何在Cocos2D v3.x中正确推送和弹出场景