2014-09-08 4 views
0

Я делаю небольшую игру SpriteKit, где враги следуют за UIBezierPath. (Есть ли какой-либо другой способ сделать это? Кажется довольно непродуктивным)Почему UIBezierPath ведет себя так?

Так или иначе, мой враг ведет себя очень странно. Вот код для простого круга с диаметром 300:

enemy.position = CGPointMake(0, 0); 

    UIBezierPath* circlePath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0, 0, 300, 300)]; 

    CGPathRef pathRef = [cicrlePath CGPath]; 


    SKAction *followPath = [SKAction followPath:pathRef 
             asOffset:NO 
            orientToPath:NO 
             duration: pathSpeed]; 




    SKAction *forever = [SKAction repeatActionForever:followPath]; 


    [enemy runAction:forever]; 

Теперь посмотрим, как я определил позицию врагов и положение circlePath в точке (0,0)?

Каким-то образом это дает мне этот результат: http://www.gfycat.com/DistinctSnarlingAracari

Это на самом деле не делает смысла, так как это путь к месту, я думаю? Или я чего-то не хватает?

О, как я уже упоминал, как я мог сделать вражеские движения для своей игры наиболее эффективным/продуктивным способом? В настоящее время я использую PaintCode с UIBeziers, но это всегда дает мне странный результат. Я с нетерпением жду ваших ответов.

+0

Что именно не так в вашем GIF? Если вы считаете, что значок «1» находится не в том месте, где вы ожидаете его? –

+0

Ну, так как опорная точка по умолчанию для сцены с набором Sprite находится в левом нижнем углу (см. Здесь: https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Nodes/Nodes.html # // apple_ref/doc/uid/TP40013043-CH3-SW19) Я ожидаю, что 1 будет видна только в левом нижнем углу EDIT: Я только что осознал свою ошибку: я думал, что он будет использовать центр BezierPath чтобы расположить его путь. –

ответ

1

Я думаю, вы не понимаете -[UIBezierPath bezierPathWithOvalInRect:] или, может быть, CGRectMake. Ваш 0, 0 - это верхний левый угол ограничительной рамки овального, а не центра, а 300, 300 - ширина и высота этого ограничивающего прямоугольника. Если вы хотите овал быть сосредоточены на 0, 0, попробуйте следующее:

UIBezierPath* circlePath = [UIBezierPath bezierPathWithOvalInRect: 
    CGRectMake(-150, -150, 300, 300)]; 
+0

Да, теперь имеет смысл. Однако знаете ли вы, что лучший способ создать вражеские пути для моей игры? Кажется, это немного хлопот, как я это делаю сейчас. –

+0

У меня мало опыта работы с инструментами разработки игр. –

+1

В любом случае, что означает «хлопот»?Это всего лишь расплывчатый, трогательный, бессмысленный вопрос. – matt

1

центре овального пути UIBezier находится в (х + ширина/2, у + высота/2). Начиная с угла = 0 (самая правая точка на овале, т. Е. (X + ширина, y + высота/2)), овалы рисуются против часовой стрелки в координатах сцены. Поэтому спрайт будет следовать овальному пути в направлении против часовой стрелки, потому что он перемещается в том же направлении, в котором был нарисован путь.

Вот код, который может быть полезным для Вас:

Этот метод создает овальное путь, который центрируется в позиции (происхождения) указанного CGRect.

- (CGPathRef) ovalInRect:(CGRect)rect 
{ 
    CGFloat width = rect.size.width; 
    CGFloat height = rect.size.height; 
    CGFloat x = rect.origin.x-rect.size.width/2; 
    CGFloat y = rect.origin.y-rect.size.height/2; 

    return[UIBezierPath bezierPathWithOvalInRect: CGRectMake(x, y, width, height)].CGPath; 
} 

Этот метод создает SKAction, который перемещает узел по круговой траектории. Параметры определяют центр, радиус и направление (YES = по часовой стрелке и NO = против часовой стрелки) пути.

- (SKAction *) createCircularPathActionAtLocation:(CGPoint)center 
             withRadius:(CGFloat)radius 
            andDirectionCW:(BOOL)directionCW 

{ 
    CGRect rect = CGRectMake(center.x, center.y, radius*2, radius*2); 
    CGPathRef ovalPath = [self ovalInRect:rect]; 
    SKAction *circlePathAction = [SKAction followPath:ovalPath asOffset:NO orientToPath:YES duration:5]; 
    SKAction *action; 

    if (directionCW) { 
     // Reverse the action to follow the path in the opposite direction 
     action = [SKAction repeatActionForever:[circlePathAction reversedAction]]; 
    } 
    else { 
     action = [SKAction repeatActionForever:circlePathAction]; 
    } 
    return action; 
} 

Side Примечание: Если вы используете PaintCode 2, вы можете обобщать код он производит с помощью переменных вместо абсолютных значений.

+0

Спасибо за ваше объяснение! Вы упомянули, что PaintCode 2 может обобщать код с помощью переменных, как это будет отличаться (от использования абсолютных значений) и где я могу найти эту опцию? –

+0

Это последний элемент на панели слева под изображениями. – 0x141E

Смежные вопросы