我刚开始使用SpriteBuilder和cocos2d - v3。 它看起来很有前途,也是一个很好的工具。
但我的问题是,我想创建一个像角色一样的人,所有身体部位都是不同的精灵,并使用关节将它们放入物理身体。我正在努力找到使用spritebuilder或chipmunk的任何例子。
非常感谢这里的任何帮助。 Thx提前。
编辑:这是正文的代码。我使用了来自link的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设置: