0

我刚开始使用带有 cocos2d - v3 的 SpriteBuilder。它看起来很有前途,是一个很好的工具。

但我的问题是我想创建一个像男人一样的角色,所有身体部位都是不同的精灵,并使用关节将它们放入物理体中。我正在努力寻找使用 spritebuilder 或花栗鼠的任何例子。

将非常感谢这里的任何帮助。提前谢谢。

编辑:这是正文的代码。我使用了链接中的 peevedpenquin 示例 这是我的角色主体代码。我只是在企鹅的尾巴上添加了一个块作为身体的一部分。

 #import "PenguinWithBlock.h"

@implementation PenguinWithBlock{
    CCNode *_pBlock;
    CCNode *_penguinB;
    CCPhysicsJoint *_penguinJoint;
    CCPhysicsNode *_penguinNode;
}

- (void)didLoadFromCCB {

    _penguinNode.debugDraw = TRUE;

    [_pBlock.physicsBody setCollisionGroup:_penguinB];
    [_penguinB.physicsBody setCollisionGroup:_penguinB];

    // create a joint to connect the catapult arm with the catapult
    _penguinJoint = [CCPhysicsJoint connectedPivotJointWithBodyA:_penguinB.physicsBody bodyB:_pBlock.physicsBody anchorA:_penguinB.anchorPointInPoints];
}

这是 Gameplay.m 文件

@implementation Gameplay {
    CCPhysicsNode *_physicsNode;
    CCNode *_catapultArm;
    CCNode *_catapult;
    CCNode *_levelNode;
    CCNode *_contentNode;
    CCPhysicsJoint *_catapultJoint;

    CCNode *_pullbackNode;
    CCPhysicsJoint *_pullbackJoint;
    CCNode *_mouseJointNode;
    CCPhysicsJoint *_mouseJoint;

    PenguinWithBlock *_currentPenguin;
    CCPhysicsJoint *_penguinCatapultJoint;

    CCAction *_followPenguin;
}

// is called when CCB file has completed loading
- (void)didLoadFromCCB {
    // tell this scene to accept touches
    self.userInteractionEnabled = TRUE;
    _physicsNode.collisionDelegate = self;

    CCScene *level = [CCBReader loadAsScene:@"Levels/Level1"];
    [_levelNode addChild:level];

    // visualize physics bodies & joints
    //_physicsNode.debugDraw = TRUE;

    // catapultArm and catapult shall not collide
    [_catapultArm.physicsBody setCollisionGroup:_catapult];
    [_catapult.physicsBody setCollisionGroup:_catapult];

    // create a joint to connect the catapult arm with the catapult
    _catapultJoint = [CCPhysicsJoint connectedPivotJointWithBodyA:_catapultArm.physicsBody bodyB:_catapult.physicsBody anchorA:_catapultArm.anchorPointInPoints];

    // nothing shall collide with our invisible nodes
    _pullbackNode.physicsBody.collisionMask = @[];
    // create a spring joint for bringing arm in upright position and snapping back when player shoots
    _pullbackJoint = [CCPhysicsJoint connectedSpringJointWithBodyA:_pullbackNode.physicsBody bodyB:_catapultArm.physicsBody anchorA:ccp(0, 0) anchorB:ccp(34, 138) restLength:60.f stiffness:500.f damping:40.f];

    _mouseJointNode.physicsBody.collisionMask = @[];

}

- (void)update:(CCTime)delta
{
    if (_currentPenguin.launched) {
        // if speed is below minimum speed, assume this attempt is over
        if (ccpLength(_currentPenguin.physicsBody.velocity) < MIN_SPEED){
            [self nextAttempt];
            return;
        }

        int xMin = _currentPenguin.boundingBox.origin.x;

        if (xMin < self.boundingBox.origin.x) {
            [self nextAttempt];
            return;
        }

        int xMax = xMin + _currentPenguin.boundingBox.size.width;

        if (xMax > (self.boundingBox.origin.x + self.boundingBox.size.width)) {
            [self nextAttempt];
            return;
        }
    }
}

- (void)nextAttempt {
    _currentPenguin = nil;
    [_contentNode stopAction:_followPenguin];

    CCActionMoveTo *actionMoveTo = [CCActionMoveTo actionWithDuration:1.f position:ccp(0, 0)];
    [_contentNode runAction:actionMoveTo];
}

// called on every touch in this scene
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [touch locationInNode:_contentNode];

    // start catapult dragging when a touch inside of the catapult arm occurs
    if (CGRectContainsPoint([_catapultArm boundingBox], touchLocation))
    {
        // move the mouseJointNode to the touch position
        _mouseJointNode.position = touchLocation;

        // setup a spring joint between the mouseJointNode and the catapultArm
        _mouseJoint = [CCPhysicsJoint connectedSpringJointWithBodyA:_mouseJointNode.physicsBody bodyB:_catapultArm.physicsBody anchorA:ccp(0, 0) anchorB:ccp(34, 138) restLength:0.f stiffness:3000.f damping:150.f];

        // create a penguin from the ccb-file
        _currentPenguin = (PenguinWithBlock*)[CCBReader load:@"PenguinWithBlock"];
        // initially position it on the scoop. 34,138 is the position in the node space of the _catapultArm
        CGPoint penguinPosition = [_catapultArm convertToWorldSpace:ccp(34, 138)];
        // transform the world position to the node space to which the penguin will be added (_physicsNode)
        _currentPenguin.position = [_physicsNode convertToNodeSpace:penguinPosition];
        // add it to the physics world
        [_physicsNode addChild:_currentPenguin];
        // we don't want the penguin to rotate in the scoop
        _currentPenguin.physicsBody.allowsRotation = FALSE;

        // create a joint to keep the penguin fixed to the scoop until the catapult is released
        _penguinCatapultJoint = [CCPhysicsJoint connectedPivotJointWithBodyA:_currentPenguin.physicsBody bodyB:_catapultArm.physicsBody anchorA:_currentPenguin.anchorPointInPoints];
    }
}

- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    // whenever touches move, update the position of the mouseJointNode to the touch position
    CGPoint touchLocation = [touch locationInNode:_contentNode];
    _mouseJointNode.position = touchLocation;
}

- (void)launchPenguin {
    // loads the Penguin.ccb we have set up in Spritebuilder
    CCNode* penguin = [CCBReader load:@"PenguinWithBlock"];
    // position the penguin at the bowl of the catapult
    penguin.position = ccpAdd(_catapultArm.position, ccp(16, 50));

    // add the penguin to the physicsNode of this scene (because it has physics enabled)
    [_physicsNode addChild:penguin];

    // manually create & apply a force to launch the penguin
    CGPoint launchDirection = ccp(1, 0);
    CGPoint force = ccpMult(launchDirection, 8000);
    [penguin.physicsBody applyForce:force];

    // ensure followed object is in visible are when starting
    self.position = ccp(0, 0);
    CCActionFollow *follow = [CCActionFollow actionWithTarget:penguin worldBoundary:self.boundingBox];
    [_contentNode runAction:follow];
}

-(void) touchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    // when touches end, meaning the user releases their finger, release the catapult
    [self releaseCatapult];
}

-(void) touchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
    // when touches are cancelled, meaning the user drags their finger off the screen or onto something else, release the catapult
    [self releaseCatapult];
}

- (void)releaseCatapult {
    if (_mouseJoint != nil)
    {
        // releases the joint and lets the catapult snap back
        [_mouseJoint invalidate];
        _mouseJoint = nil;

        // releases the joint and lets the penguin fly
        [_penguinCatapultJoint invalidate];
        _penguinCatapultJoint = nil;

        // after snapping rotation is fine
        _currentPenguin.physicsBody.allowsRotation = TRUE;
        _currentPenguin.launched = TRUE;


        // follow the flying penguin
        _followPenguin = [CCActionFollow actionWithTarget:_currentPenguin worldBoundary:self.boundingBox];
        [_contentNode runAction:_followPenguin];
    }
}

-(void)ccPhysicsCollisionPostSolve:(CCPhysicsCollisionPair *)pair seal:(CCNode *)nodeA wildcard:(CCNode *)nodeB
{
    float energy = [pair totalKineticEnergy];

    // if energy is large enough, remove the seal
    if (energy > 5000.f)
    {
        [self sealRemoved:nodeA];
    }
}

- (void)sealRemoved:(CCNode *)seal {
    // load particle effect
    CCParticleSystem *explosion = (CCParticleSystem *)[CCBReader load:@"SealExplosion"];
    // make the particle effect clean itself up, once it is completed
    explosion.autoRemoveOnFinish = TRUE;
    // place the particle effect on the seals position
    explosion.position = seal.position;
    // add the particle effect to the same node the seal is on
    [seal.parent addChild:explosion];

    // finally, remove the destroyed seal
    [seal removeFromParent];
}

- (void)retry {
    // reload this level
    [[CCDirector sharedDirector] replaceScene: [CCBReader loadAsScene:@"Gameplay"]];
}

SpriteBuilder 中的 PenguinWithBlock 设置: 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

4

1 回答 1

1

您可以使用“空白”CCNode,身体的所有其他部位都是它的孩子,甚至可能有另一个身体部位的孩子。节点树将在很大程度上取决于主体设计。

看看这个教程,因为它教授了这样做的基础知识。此外,SpriteBuilder 仍然没有在其中创建关节的功能,但您可以像教程一样以编程方式轻松完成此操作。

编辑:可以帮助你

于 2014-03-14T14:42:20.363 回答