Cocos2d 3.0 + Chipmunk + CCAnimation:用动画对象移动物理体。怎么样?

时间:2014-04-09 22:09:31

标签: ios cocos2d-iphone physics chipmunk

我有一条附有物理身体的船。这艘船是静态物理机构。船从CCAnimateMoveTo从左向右移动。当我点击屏幕时,我的角色掉了下来。我很好地发现了碰撞。但是我希望碰撞后我的角色只是落在船上并随身携带。性格是动态的身体。链接到示例视频:Sample video

我在这里创造一艘船:

- (void)createBoat
{
    currentBoat = [CCSprite spriteWithImageNamed:@"Boat.png"];
    currentBoat.position  = ccp(0 - currentBoat.boundingBox.size.width, winSize.height * 0.2);
//    currentBoat.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){0, 0, currentBoat.contentSize.width, currentBoat.contentSize.height * 0.5} cornerRadius:0];


    CGPoint shape[6];
    shape[0] = ccp(0, 30);
    shape[1] = ccp(64, 10);
    shape[2] = ccp(128, 30);
    shape[3] = ccp(128, 0);
    shape[4] = ccp(0, 0);
    shape[5] = ccp(0, 30);


    currentBoat.physicsBody = [CCPhysicsBody bodyWithPolylineFromPoints:shape count:6 cornerRadius:0 looped:NO];
    currentBoat.physicsBody.type = CCPhysicsBodyTypeStatic;
    currentBoat.physicsBody.collisionGroup = @"BoatGroup";
    currentBoat.physicsBody.collisionType = @"BoatCollision";
    [physicsWorld addChild:currentBoat z:PHYSICS_Z+3];

    id actionMoveBoat = [[CCActionMoveTo alloc] initWithDuration:5.0f position:ccp(winSize.width + currentBoat.boundingBox.size.width, currentBoat.position.y)];
    id actionMethod = [CCActionCallFunc actionWithTarget:self selector:@selector(createBoat)];


    [currentBoat runAction:[CCActionSequence actions:actionMoveBoat, [[CCActionRemove alloc] init], actionMethod, nil]];
}

角色创作:

- (void)createCharacter
{
    if (needCharacter)
    {
        CCSprite *newCharacter = [CCSprite spriteWithImageNamed:@"Character.png"];
        newCharacter.opacity = 0;
        newCharacter.position  = ccp(winSize.width * 0.5, winSize.height * 0.76);
        newCharacter.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){CGPointZero, newCharacter.contentSize} cornerRadius:0];
        newCharacter.physicsBody.affectedByGravity = NO;
        newCharacter.physicsBody.allowsRotation = YES;
        newCharacter.physicsBody.collisionGroup = @"playerGroup";
        newCharacter.physicsBody.collisionType = @"playerCollision";
        [physicsWorld addChild:newCharacter z:PHYSICS_Z+4];


        id actionFadeIn = [[CCActionFadeIn alloc] initWithDuration:0.5];
        [newCharacter runAction:actionFadeIn];


        [allCharacters addObject:newCharacter];


        needCharacter = false;
        touchDone = false;
    }
}

然后检测触碰和碰撞:

- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CCNode *lastCharacter = [allCharacters lastObject];


    if (!touchDone)
    {
        [lastCharacter.physicsBody applyImpulse:ccp(0, 300)];
        lastCharacter.physicsBody.type = CCPhysicsBodyTypeDynamic;
        lastCharacter.physicsBody.affectedByGravity = YES;
        touchDone = true;
    }

}

- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair playerCollision:(CCNode *)currentCharacterC BoatCollision:(CCNode *)currentBoatC {


    currentCharacterC.physicsBody.collisionType = @"tmpCollision";



    CCLOG(@"score++");
    if ([allCharacters containsObject:currentCharacterC])
    {
        score++;
        [scores setString:[NSString stringWithFormat:@"%d", score]];
        [allCharacters removeAllObjects];


        if (lives != 0)
        {
            needCharacter = true;
            [self createCharacter];
        }
    }


    CCLOG(@"allCharacters = %@", allCharacters);


    return YES;
}

2 个答案:

答案 0 :(得分:2)

我也遇到了同样的问题,尝试增加摩擦/表面速度等,但它并没有真正起作用。 最后必须以我自己的方式解决它,每当玩家落在任何身体上时,你保持一个指向该身体的指针,如玩家对象的_bodyUnderFeet。 现在,在更新循环中,将_bodyUnderFeet的速度添加到玩家计算的速度。请参阅zeroVel_x

的使用

示例代码在这里:

void Player::update(float dt)
{
    float zeroVel_x = 0;
    if(_bodyUnderFeet != NULL)
    {
        zeroVel_x = _bodyUnderFeet->v.x;
    }
    cpBody *bd = getCPBody();
    assert(bd);
    //log("Body angle %f", bd->a);
    //check forward backward or at rest
    float accel = _accelGround;
    if(_onGroundBoost < UP_BOOST)
    {
        accel = _accelAir;
    }
    if(_touchPressedB)
    {
        if(!isFlippedX())
        {
            setFlippedX(true);
        }
        //cpBodySetVel(bd, cpv(cpBodyGetVel(bd).x - accel*0.25, 0));
        cpVect bdv = cpBodyGetVel(bd);
        bdv.x = bdv.x - zeroVel_x;
        if(bdv.x > 0) bdv.x = 0;
        if(bdv.x > -_maxVelocity.x)
            cpBodySetVel(bd, cpv(zeroVel_x + bdv.x - accel*0.25, bdv.y));
    }
    else if(_touchPressedF)
    {
        if(isFlippedX())
        {
            setFlippedX(false);
        }
        //cpBodySetVel(bd, cpv(cpBodyGetVel(bd).x + accel*0.25, 0));
        cpVect bdv = cpBodyGetVel(bd);
        bdv.x = bdv.x - zeroVel_x;
        if(bdv.x < 0) bdv.x = 0;
        if(bdv.x < _maxVelocity.x)
            cpBodySetVel(bd, cpv(zeroVel_x+bdv.x + accel*0.25, bdv.y));
    }
    else
    {
        cpFloat bd_x = cpBodyGetVel(bd).x;
        bd_x = bd_x - zeroVel_x;
        if(bd_x>0)
        {
            if(bd_x > accel*0.25)
            {
                cpBodySetVel(bd, cpv(zeroVel_x+bd_x - accel*0.25, cpBodyGetVel(bd).y));
            }
            else
            {
                cpBodySetVel(bd, cpv(zeroVel_x+0, cpBodyGetVel(bd).y));
            }
        }
        else if(bd_x < 0)
        {
            if(bd_x < accel*0.25)
            {
                cpBodySetVel(bd, cpv(zeroVel_x+bd_x + accel*0.25, cpBodyGetVel(bd).y));
            }
            else
            {
                cpBodySetVel(bd, cpv(zeroVel_x+0, cpBodyGetVel(bd).y));
            }
        }
    }

    //check jump
    if(_touchPressedJ)
    {
        if(_onGroundBoost)
        {
            cpVect bdv = cpBodyGetVel(bd);
            if(bdv.y < 0) bdv.y = 0;
            if((bdv.y + _accelUp) < _maxVelocity.y)
            {
                cpBodySetVel(bd, cpv(bdv.x, bdv.y + _accelUp));
                --_onGroundBoost;
            }
            else
            {
                cpBodySetVel(bd, cpv(bdv.x, _maxVelocity.y));
                _onGroundBoost = 0;
            }
        }
    }

    //check shots
    if(_touchPressedS)
    {
        if(!_bulletFired)
        {

        }
    }

    //check home
    if(_touchPressedH)
    {

    }

    boundRotation(bd);
}

答案 1 :(得分:0)

我想, 你跌倒后可以增加人与船之间的摩擦力。并降低弹性。然后船可以“采取”#39;那个男人一起去......

只是一招。