【问题标题】:How can I stop walking of a man if there is a wall in Sprite Kit?如果 Sprite Kit 中有墙,我怎样才能停止一个人的行走?
【发布时间】:2013-11-27 12:38:15
【问题描述】:

我正在 iOS 7 中使用 Sprite Kit 练习。

现在我遇到了一个问题,当一个人通过 SKAction moveTo 从一个点走到另一个点时。
如果画面中有墙,我想在墙前停下脚步。

我使用了 skscen.h 文件中的代码,如下所示:

typedef NS_ENUM(uint32_t, CollisionType)
{
    CollisionTypePlayer      = 0x1 << 0,
    CollisionTypeWall        = 0x1 << 1,
    CollisionTypeRiver       = 0x1 << 3,
    CollisionTypeBush        = 0x1 << 4
};

#import <SpriteKit/SpriteKit.h>

@interface THMyScene : SKScene <SKPhysicsContactDelegate>

@property (nonatomic) SKSpriteNode *manContainer;

//Wall sprite
@property (nonatomic) SKSpriteNode *wallNode1;

@end

在下面给出的scene.m文件中:

#import "THMyScene.h"

@interface THMyScene()

@property (nonatomic) SKTextureAtlas *manAtlas;
@property (nonatomic) NSMutableArray *manImagesArray;

@end

@implementation THMyScene

-(id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */

        // Configure physics for the world.
        self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f); // no gravity
        self.physicsWorld.contactDelegate = self;

        [self createWall];
        [self createMan];
    }
    return self;
}

-(void) createMan
{
    _manAtlas = [SKTextureAtlas atlasNamed:@"secondLevelMan"];
    _manImagesArray = [[NSMutableArray alloc]init];
    for(int i = 1; i <= _manAtlas.textureNames.count ; i++)
    {
        NSString *imageName = [NSString stringWithFormat:@"man%d.png",i];
        SKTexture *tmpTexture = [SKTexture textureWithImageNamed:imageName];
        [_manImagesArray addObject:tmpTexture];
    }
    _manContainer = [SKSpriteNode spriteNodeWithTexture:[_manImagesArray objectAtIndex:0]];
    _manContainer.position = CGPointMake(50, 250);
    [self addChild:_manContainer];

    _manContainer.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_manContainer.size];
    _manContainer.physicsBody.allowsRotation = YES;
    _manContainer.physicsBody.dynamic = YES;
    _manContainer.physicsBody.usesPreciseCollisionDetection = YES;
    _manContainer.physicsBody.categoryBitMask = CollisionTypePlayer;
    _manContainer.physicsBody.contactTestBitMask = CollisionTypeWall;
    _manContainer.physicsBody.collisionBitMask = CollisionTypeRiver;
}

-(void) createWall
{
    //Create wall 1
    _wallNode1 = [SKSpriteNode spriteNodeWithImageNamed:@"rock-1"];
    _wallNode1.name = @"stonewall";
    _wallNode1.position = CGPointMake(400 , 700);
    [self addChild:_wallNode1];

    _wallNode1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_wallNode1.size];
    _wallNode1.physicsBody.dynamic = NO;
    _wallNode1.physicsBody.categoryBitMask = CollisionTypeWall;
    _wallNode1.physicsBody.contactTestBitMask = 0;
    _wallNode1.physicsBody.collisionBitMask = CollisionTypePlayer;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint locationTouch = [touch locationInNode:self];
    CGPoint manLocation = _manContainer.position;
    CGFloat rotatingAngle = [self pointPairToBearingDegrees:manLocation secondPoint:locationTouch];
    CGFloat distance = [self distanceBetweenTwoPoints:manLocation andSecondpoint:locationTouch];
    SKAction *animationAction = [SKAction repeatActionForever:[SKAction animateWithTextures:_manImagesArray timePerFrame: 0.0833]];
    float duration = distance / 300;
    SKAction *movePoint = [SKAction moveTo:locationTouch  duration:duration];
    SKAction *rotate = [SKAction rotateToAngle:rotatingAngle duration:0.0f];
    SKAction *sequenceAction = [SKAction sequence:@[rotate, movePoint]];
    [_manContainer runAction:[SKAction group:@[sequenceAction, animationAction]] withKey:@"runAnimation"];
}

- (CGFloat) pointPairToBearingDegrees:(CGPoint)startingPoint secondPoint:(CGPoint) endingPoint
{
    CGPoint originPoint = CGPointMake(endingPoint.x - startingPoint.x, endingPoint.y - startingPoint.y); // get origin point to origin by subtracting end from start
    float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
    return bearingRadians;
}

-(CGFloat)distanceBetweenTwoPoints:(CGPoint)firstPoint andSecondpoint:(CGPoint)secondPoint
{
    CGFloat dx = secondPoint.x - firstPoint.x;
    CGFloat dy = secondPoint.y - firstPoint.y;
    return sqrt(dx*dx + dy*dy );
}

- (void) didBeginContact:(SKPhysicsContact *)contact
{
    SKPhysicsBody *firstBody, *secondBody;

    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
    {
        firstBody = contact.bodyA;
        secondBody = contact.bodyB;
    }
    else
    {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    }
}

@end

【问题讨论】:

  • 使用物理时不要使用移动动作,而是改变身体速度或施加力
  • 那么在上面给出的示例中我应该在哪里更改我的代码?

标签: ios ios7 sprite-kit


【解决方案1】:

试试这样的:

-(void)update:(CFTimeInterval)currentTime {

int distance = 10; // distance to wall when to stop  

if ((man.position.x > wall.position.x + wall.size.width/2 + distance) &&
    (man.position.x < wall.position.x - wall.size.width/2 - distance) 

if ((man.position.y > wall.position.y + wall.size.height/2 + distance) &&
    (man.position.y < wall.position.y - wall.size.height/2 - distance) 

//do what you want like remove some or all actions of man 


} }

【讨论】:

    【解决方案2】:

    //改变你的代码这样就可以了

     - (void) didBeginContact:(SKPhysicsContact *)contact
     {
          SKPhysicsBody *firstBody, *secondBody;
    
         if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
          {
                firstBody = contact.bodyA;
                secondBody = contact.bodyB;
    
              [firstBody.node removeAllActions];
             firstBody.node.speed=0;
    
         }
    else
    {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
       [secondBody.node removeAllActions];
        secondBody.node.speed=0;
    }
    

    } // 记住 spritekit 中的每个节点都有 speed 属性来控制精灵动画的速度

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-20
      • 2014-06-05
      • 1970-01-01
      • 2020-10-26
      • 2018-11-25
      • 1970-01-01
      • 2011-09-06
      • 2020-06-20
      相关资源
      最近更新 更多