我正在进行2D游戏,其中角色在屏幕的左侧静止不动,物体从右侧飞向他。他需要能够击落这些飞行的敌人。我有一个包含“slap”动画帧的精灵动画。在拍打过程中,他的身体微微移动,他的手臂从地面上移开,完全伸展到头顶,然后向下拍打地面。这是它的样子: SumoSmash Animation GIF
出于这些目的,我有一个名为SumoWarrior
的类,它是一个SKSpriteNode
子类。 SumoWarrior sprite节点有一个名为warriorArm
的子精灵节点。我的想法是让主要的相扑战士精灵节点显示动画,并将此warriorArm
精灵节点仅用于战士手臂形状的物理身体。我需要以某种方式旋转这个手臂身体以遵循精灵动画,以便检测与飞行物体的碰撞。
以下是手臂的创建方式:
sumoWarrior.warriorArm = [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImageNamed:@"warriorArm"]];
sumoWarrior.warriorArm.position = CGPointMake(15, 25);
sumoWarrior.warriorArm.anchorPoint = CGPointMake(0.16, 0.7);
sumoWarrior.warriorArm.texture = nil;
sumoWarrior.warriorArm.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:[sumoWarrior createArmBody]];
sumoWarrior.warriorArm.physicsBody.mass = 9999;
sumoWarrior.warriorArm.physicsBody.categoryBitMask = CollisionPlayer;
sumoWarrior.warriorArm.physicsBody.collisionBitMask = CollisionEnemy;
sumoWarrior.warriorArm.physicsBody.contactTestBitMask = CollisionEnemy | CollisionAlly;
sumoWarrior.warriorArm.physicsBody.allowsRotation = YES;
sumoWarrior.warriorArm.physicsBody.dynamic = YES;
是否有可能以某种方式旋转和伸展此手臂,以使其精确地跟随动画?是否也可以改变战士的主要物理体(它只是身体周围的多边形,没有手臂),以便IT也跟随动画?或者我完全错过了应该这样做的方式吗?
答案 0 :(得分:3)
我使用Texture Packer作为纹理和动画。我创建了一个名为sumoAnimations的Texture Atlas,Texture Packer为我创建了一个.h文件,然后我将其导入到项目中。
如果您还没有免费副本,可以免费获得。
在我启动代码之前,您可能想重新考虑使用您拥有的动画。按照你之前的评论,动画中唯一相关的帧是第15,16和17帧。我甚至不确定第17帧,因为相扑已经放下了手。只给你3帧,你提供的动画相当于0.1秒,因为每帧的时间为0.05秒。
看看我收录的3张照片,看看我的意思。您可能需要考虑获取新动画或在帧之间留出更长时间。我每帧使用0.25秒,所以你可以更清楚地看到它。您可以将其更改为您喜欢的任何内容。
对于失踪和被击中的玩家,你可以在玩家周围(当然是在手臂后面)创建一个clearColor sprite rect来检测错过对象的接触。
#import "MyScene.h"
#import "sumoAnimation.h"
@interface MyScene()<SKPhysicsContactDelegate>
@end
@implementation MyScene
{
SKSpriteNode *sumo;
SKSpriteNode *arm;
SKAction *block0;
SKAction *block1;
SKAction *block2;
SKAction *block3;
SKAction *block4;
SKAction *slapHappy;
SKAction *wait0;
SKAction *wait1;
}
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
sumo = [SKSpriteNode spriteNodeWithTexture:SUMOANIMATION_TEX_SUMO_001];
sumo.anchorPoint = CGPointMake(0, 0);
sumo.position = CGPointMake(0, 0);
[self addChild:sumo];
arm = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(34, 14)];
arm.anchorPoint = CGPointMake(0, 0);
arm.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(34,14) center:CGPointMake(17, 7)];
arm.physicsBody.dynamic = NO;
slapHappy = [SKAction animateWithTextures:SUMOANIMATION_ANIM_SUMO timePerFrame:0.25];
// start the animation
block0 = [SKAction runBlock:^{
[sumo runAction:slapHappy];
}];
// time until frame 15 is reached
wait0 = [SKAction waitForDuration:3.50];
// add arm at frame 15 positon
block1 = [SKAction runBlock:^{
arm.position = CGPointMake(205, 125);
arm.zRotation = 1.3;
[self addChild:arm];
}];
// wait until next frame
wait1 = [SKAction waitForDuration:0.25]; // time in between frames
// move arm and rotate to frame 16 position
block2 = [SKAction runBlock:^{
arm.position = CGPointMake(224, 105);
arm.zRotation = 0.4;
}];
// move arm and rotate to frame 17 position
block3 = [SKAction runBlock:^{
arm.position = CGPointMake(215, 68);
arm.zRotation = -0.65;
}];
// remove arm from view
block4 = [SKAction runBlock:^{
[arm removeFromParent];
}];
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[sumo runAction:[SKAction sequence:@[block0, wait0, block1, wait1, block2, wait1, block3, wait1, block4]]];
}
-(void)update:(CFTimeInterval)currentTime
{
//
}
@end
根据其他评论进行了更新
下面的图片概述了我的建议。为sumo正在拍摄的帧添加物理体rect。这将使您无需处理为精确位置中的每个帧添加正文。它还可以提高拍打效率。
你的物体仍然可以倒在地上,并且可以播放压碎的动画。请记住,您的相扑动画移动速度非常快,玩家将无法看到每帧的精确位置。
你想要拥有手臂&#34;推动&#34;该对象将采用更精确的动画。像手臂的位置改变一个单一的增量。然后你必须精确地将一个身体放在手上。我不是说它不可能,但它肯定很多工作而且很难做到。