Как перевести SKPhysicsContact contactPoint в мою позицию SKSpriteNode

Я потратил слишком много времени на это. Кто-то уже решил это, пожалуйста, помогите.

Враг стреляет по моему кораблю. SKPhysicsContact вступает во владение, и я получаю contactPoint. Я взрываю выпущенную ракету в точке контакта, в мировых координатах. Все хорошо. Теперь я хотел бы использовать точку не в координатах сцены, возвращаемых contactPoint, а в координатах моего корабля, чтобы начать испускать дым от корабля, где я был поражен. Раньше я успешно использовал функцию convertPoint, но я не могу понять это прямо здесь... Документы говорят, что contactPoint выражается в координатах сцены, в то время как у myShip есть свои координаты, живущие как дочерний элемент мирового узла, который является дочерним элементом узла сцены. Они находятся в одной иерархии узлов. Я думаю... У меня есть Scene->World->Camera, где myShip является потомком World. Мой код, я думаю, говорит о преобразовании contactPoint из координат сцены в координаты в myShip. Но это не работает. И никакая другая комбинация. Что мне не хватает? Я подозреваю иерархию камеры, но не уверен. Числа, возвращаемые в smoke.position, выходят из строя...

- (SKEmitterNode *) newSmokeEmitter: (SKPhysicsContact *) contact
{
    NSString *smokePath = [[NSBundle mainBundle] pathForResource:@"ShipSmoke" ofType:@"sks"];
    SKEmitterNode *smoke = [NSKeyedUnarchiver unarchiveObjectWithFile:smokePath];

    smoke.targetNode = myShip;
    smoke.name = @"shipSmoke";
    smoke.position = [self convertPoint:contact.contactPoint toNode:myShip];

    //my temporary kludge that places the smoke on the ship, randomly

    //smoke.position = CGPointMake(skRand(-25,25), skRand(-25,+25));

    NSLog(@"Ship at world pos: %f,%f", myShip.position.x, myShip.position.y);
    NSLog(@"Contact at scene pos: %f,%f", contact.contactPoint.x, contact.contactPoint.y);
    NSLog(@"Smoke position at ship pos: %f,%f", smoke.position.x, smoke.position.y);
    [myShip addChild:smoke];
    return smoke;
}

person julius patta    schedule 10.06.2015    source источник


Ответы (2)


Если вы еще не решили это, ответ состоит в том, чтобы преобразовать сцену узла:

smoke.position = [self convertPoint:contact.contactPoint fromNode:self.scene];

Или в Свифте:

smoke.position = convertPoint(contact.contactPoint, fromNode: scene)
person SwampThingTom    schedule 01.12.2015
comment
не уверен, почему это не был принятый ответ. это решение (за исключением некоторых деталей, характерных для этой конкретной ситуации) - person Will Von Ullrich; 16.02.2016

Если я правильно понимаю вашу иерархию узлов, это может решить проблему.

CGPoint contact = [self convertPoint:contact.contactPoint toNode:self.world];
smoke.position = [self.world convertPoint:contact toNode:myShip];

Я не думаю, что вы можете конвертировать точку прямо в корабль. Вы должны преобразовать его вниз по иерархии, пока не доберетесь до нужного узла.

Надеюсь, это поможет.

Изменить

Чтобы убедиться, что фактическая точка контакта находится на месте происшествия, где, как я ожидаю, вы могли бы попробовать это.

SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(50, 50)];
sprite.position = contact.contactPoint;
[self addChild:sprite];

Это должно добавить спрайт именно туда, где находится точка контакта, если возвращаемая точка находится в системе координат сцены. Если он появляется в нужном месте, то он действительно сводится к правильному преобразованию очков.

person Skyler Lauren    schedule 10.06.2015
comment
Я понял, куда вы направлялись, спасибо. Неудачно. С небольшой поправкой в ​​коде (мое «я» — это сцена) я попробовал: CGPoint contactW = [self convertPoint:contact.contactPoint toNode:world]; smoke.position = [world convertPoint:contactW toNode:myShip]; - person julius patta; 11.06.2015
comment
@juliuspatta Я обновил свой ответ советом по отладке. Если у вас есть возможность, попробуйте это и посмотрите, появится ли зеленый квадрат в нужном месте. - person Skyler Lauren; 11.06.2015
comment
Привет: еще раз спасибо за подсказку. Это на самом деле просто вопрос правильного преобразования. Использую контактпоинт для других нужд, и все работает как надо. - person julius patta; 12.06.2015
comment
Моя проблема с преобразованием в координаты myShip началась после того, как я ввел (рефакторил свой код) иерархию узлов сцена-›мир-›камера. Все, что я делаю с мировой иерархией, прекрасно. Всякий раз, когда я использую сгенерированные системой координаты (например, contactPoint от SKphysics), я больше не могу найти правильный путь преобразования, чтобы получить координаты myShip (дочерний элемент мира). Моя игра полностью функциональна, с большим количеством действий, взаимодействий и спрайтов... - person julius patta; 12.06.2015
comment
Я просто не могу заставить дым выходить на основе фактического физического контакта, распознанного системой, поэтому пока я его забиваю :) (см. мой комментарий), хотя он достаточно близко, это не элегантно и не правильно ... - person julius patta; 12.06.2015