ios - 如何在 SpriteKit 中只激活物理体的一侧?

标签 ios sprite-kit

我有英雄、地面和 table 。我想让桌面活跃起来与英雄碰撞和接触。但是英雄应该能够不跳到顶部而只是“穿过”然后跳上它,如果玩家想要它,无论他想要什么。为了更好地说明我正在努力实现的目标——想想马里奥。当你在地面上奔跑时,会出现一些天空平台。你可以在平台中间跳上它并呆在那里。所以我需要物理 body 在英雄从底部接触时不要阻止他,但如果他在它上面就捕获他。 到目前为止,我正在使用带有纹理的主体作为表格:

    self.table.physicsBody = SKPhysicsBody(texture:table.texture, size:self.table.size)
self.table.physicsBody?.dynamic = false
self.table.physicsBody?.categoryBitMask = ColliderType.Table.rawValue
self.table.physicsBody?.contactTestBitMask = ColliderType.Hero.rawValue
self.table.physicsBody?.collisionBitMask = ColliderType.Hero.rawValue

显然,它不起作用。我怎样才能实现这样的事情?

最佳答案

这个问题的答案实际上并不太难,但是将其实现到成熟的游戏中对您来说会困难得多。这不是新手程序员可以开始的事情。

首先是相同的代码项目(点击/单击屏幕跳转):

#import "GameScene.h"

typedef NS_OPTIONS(uint32_t, Level1PhysicsCategory) {
    CategoryPlayer  = 1 << 0,
    CategoryFloor0  = 1 << 1,
    CategoryFloor1  = 1 << 2,
};

@implementation GameScene {
    int playerFloorLevel;
    SKSpriteNode *node0;
    SKSpriteNode *node1;
    SKSpriteNode *node2;
}

-(void)didMoveToView:(SKView *)view {
    self.backgroundColor = [SKColor whiteColor];

    node0 = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(400, 10)];
    node0.position = CGPointMake(300, 200);
    node0.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node0.size];
    node0.physicsBody.dynamic = NO;
    node0.physicsBody.categoryBitMask = CategoryFloor0;
    node0.physicsBody.collisionBitMask = CategoryPlayer;
    [self addChild:node0];

    node1 = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(400, 10)];
    node1.position = CGPointMake(300, 300);
    node1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node1.size];
    node1.physicsBody.dynamic = NO;
    node1.physicsBody.categoryBitMask = CategoryFloor1;
    node1.physicsBody.collisionBitMask = CategoryPlayer;
    [self addChild:node1];

    node2 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 50)];
    node2.position = CGPointMake(300, 250);
    node2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node2.size];
    node2.physicsBody.categoryBitMask = CategoryPlayer;
    node2.physicsBody.collisionBitMask = CategoryFloor0;
    [self addChild:node2];

    playerFloorLevel = 0;
}

-(void)update:(CFTimeInterval)currentTime {
    if(((node2.position.y-25) > (node1.position.y+10)) && (playerFloorLevel == 0)) {
        node2.physicsBody.collisionBitMask = CategoryFloor0 | CategoryFloor1;
        playerFloorLevel = 1;
    }
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     for (UITouch *touch in touches) {
         CGPoint touchLocation = [touch locationInNode:self];
        //SKNode *node = [self nodeAtPoint:touchLocation];

        // change 75 value to 50 to see player jump half way up through floor 1
        [node2.physicsBody applyImpulse:CGVectorMake(0, 75)];
    }
}

代码的要点是玩家节点 (node2) 必须不断检查其相对于其他楼层的 y 位置(更新方法)。在示例中,玩家通过 floor1 跳起来。一旦玩家高于 floor1,玩家节点的物理体修改其碰撞位掩码以包括 floor1。

听起来很简单。但是,在真实游戏中,您将拥有大量楼层,并且所有楼层的间距可能不均匀。编码时必须牢记所有这些。

关于ios - 如何在 SpriteKit 中只激活物理体的一侧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31288367/

相关文章:

ios - SpriteKit : add UIGestureRecognizer and detect which node was swiped

ios - 使用 SprikeKit Contact Delegate 确定当前正在联系

ios - 确定 SpriteNode 何时离开屏幕?

ios - 强制更改 UINavigationController 方向

swift - 检查场景是否包含任何具有名称的节点

ios - SpriteKit : Using SKTextureAtlas causes incorrect Physics Body

ios - 如何使用 SpriteKit 根据点击来上下移动球?

ios - Swift 无法为 UITextField 调用添加目标

ios - iPhone 不可用。请重新连接设备

ios - 没有名为 'UIUserActivityRestoring' 的类型或协议(protocol)