当前位置: 首页 > 知识库问答 >
问题:

使用精灵工具包变换物理实体

景信瑞
2023-03-14

我正在制作一个2D游戏,其中一个角色静止地站在屏幕的左侧,物体从右侧飞向他。他需要能够打倒这些飞行的敌人。我有一个包含“拍打”动画帧的精灵动画。在拍打过程中,他的身体轻微移动,手臂从在地面上静止,完全伸展到头顶上方,然后拍打到地面。这是它的样子: 相扑动画GIF

出于这些目的,我有一个名为相扑战士的类,它是SKSpriteNode子类。相扑战士精灵节点有一个名为战士手臂的子精灵节点。我的想法是让主要的相扑战士精灵节点显示动画,并且这个勇士Arm精灵节点仅用于战士手臂形状的物理身体的目的。我需要以某种方式旋转这个手臂身体来跟踪精灵动画,以便检测与飞行物体的碰撞。

以下是手臂的创建方式:

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也跟随动画?还是我完全错过了应该这样做的方式?

共有1个答案

田翔
2023-03-14

我对纹理和动画使用了纹理包装器。我创建了一个名为“相扑动画”的纹理图集,纹理包装器为我创建了一个.h文件,然后将其导入到项目中。

如果你还没有的话,你可以得到一份免费的。

在我开始编写代码之前,您可能需要重新考虑使用您拥有的动画。根据您之前的评论,动画中唯一相关的帧是第15,16和17帧。我甚至不确定第17帧,因为相扑已经把手放下了。这只给你3帧,你提供的动画等于0.1秒,因为每帧的时间是0.05秒。

看看我附上的3张照片,明白我的意思。你可能会考虑获得一个新的动画或允许帧之间有更长的时间。我每帧用了0.25秒,这样你可以看得更清楚。你可以把它改成你喜欢的任何东西。

至于玩家失踪和被击中,你可以在玩家周围(当然是手臂后面)创建一个clearColor精灵矩形来检测错过的物体的接触。

#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

根据其他评论更新

下面的图片概述了我的建议。为相扑正在击打的帧添加物理身体矩形。这将允许你不必处理在精确的位置为每一帧添加一个身体。这也将使拍打更加有效。

您的对象仍然可以落在地上,并播放粉碎的动画。请记住,您的相扑动画移动非常快,玩家不会看到每一帧的精确位置。

让手臂“推动”对象的想法需要更精确的动画。类似于手臂的位置以单个增量变化。然后,你必须精确地将身体放在手上。我并不是说这是不可能的,但这肯定是一项艰巨的工作。

 类似资料:
  • 问题内容: 有什么好的工具可以制作CSS精灵? 理想情况下,我想给它一个图像目录和一个引用这些图像的现有.css文件,并使其创建具有所有小图像优化的大图像,并更改我的.css文件以引用这些图像。 至少我希望它获取一个图像目录,并生成一个大的精灵和将每个精灵用作背景所必需的.css。 有没有很好的photoshop插件或功能完备的应用程序可以做到这一点? 问题答案: 这将为您完成90%的工作:CSS

  • 好的,所以我对精灵工具包相当陌生,我在Swift中工作。我有2个精灵节点,和。有一个物理体,这就是我设置它的方式: 目前没有物理实体: 我需要知道如何在这些对象之间进行碰撞检测(即,如果救世主和小鸡接触,则执行此操作),最好不要使成为物理体。 当我把鸡做成一个物理物体时,它突然变得不稳定,并移动其他物体。 如果没有物理学就无法进行碰撞检测,我怎样才能使成为不受任何影响的物理体,并且直接穿过其他物理

  • 在脚本目录里,看到的几个Sprite_Xxxx名字的脚本也是类。 类 内容 父类 Sprite_Character 人物 RPG:: Sprite Sprite_Battler 战斗 RPG:: Sprite Sprite_Picture 图片 Sprite Sprite_Timer 秒表 Sprite 各类的实例监视与游戏对象相对应的数据变化,一旦那个情况变化了,就自动向系统反映。例如 Spri

  • 父类:BK.Node 精灵类 成员变量 变量 类型 名称 备注 size Object 大小 anchor Object 锚点 cornerRadius number 圆角 单位为像素 例子: var babaTex =new BK.Texture('GameRes://texture/test.png'); var sp =new BK.Sprite(200,200,babaTex,0,1,1

  • 精灵缓存是 Cocos2d-x 为了提高精灵的访问速度,提供的一个精灵的缓存机制。 我们可以创建一个精灵并把精灵放到精灵的缓存对象 SpriteFrameCache 中: // Our .plist file has names for each of the sprites in it. We'll grab // the sprite named, "mysprite" from the s

  • 我将如何在无休止的跑步游戏中使用精灵套件物理? 一个无尽的跑步者通过保持玩家静止,但以设定的速度移动背景和所有其他物体来假装运动。 但是,我想模拟物理。 如果我让我的播放器随着物理引擎移动,通过播放器从原始位置的位移来移动背景,然后将播放器移动回它的原始位置,会怎么样? 这样会不会光滑好看?如果是这样的话,那么我应该使用什么样的sprite kit方法来避免向用户显示视觉错误呢? 正确的解决方案是