Подтвердить что ты не робот

Можно ли вращать a Node вокруг произвольной точки в SpriteKit?

Есть ли способ повернуть Node в SpriteKit вокруг произвольной точки? Теперь я могу манипулировать anchorPoint моего Node, но этого недостаточно, если точка вращения, которую я хочу использовать, лежит вне Node.

enter image description here

Каков наилучший способ достижения такого рода вращения в SpriteKit?

4b9b3361

Ответ 1

Поскольку вы запрашиваете лучший способ, который работает хорошо (лучше всего субъективен):

Создайте SKNode и установите его положение в центр вращения. Добавьте node, который должен вращаться вокруг этого центра как дочерний элемент в центре node. Установите дочернюю позицию node на нужный сдвиг (т.е. Радиус, например x + 100). Измените свойство вращения центра node, чтобы ребенок node (s) вращался вокруг центральной точки. То же самое работает для cocos2d btw.

Ответ 2

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

Вместо этого я придумал два решения, оба из которых работают, если настроить. Первому заняло много времени, чтобы совершенствоваться и до сих пор не идеально. Он включает в себя вычисление определенного количества точек вокруг смещения центра по заданному радиусу, а затем, если определенный объект находится на определенном расстоянии от центральной точки, он будет постоянно использовать физику для отправки объекта по траектории траектории вдоль "окружности" круга, указывает, что он рассчитан (см. выше).

Существует два способа вычисления точек с радиусом

Первая использует теорему пифагора, а вторая в конечном счете использует собственно тригонометрию. В первом случае вы увеличиваете цикл for на определенную величину, тогда как меньше 361 (градус) и для каждой итерации цикла вычисляете с помощью синуса и косинуса точку с этим углом в определенном радиусе от центральной точки.

Вторая использует теорему пифагора, а ее код ниже:

После вычисления точек вы должны создать запланированный селектор [<object> scheduled selector...]; или таймер в вашем файле didMoveToView или использовать фиксированный метод обновления в дополнение к переменной экземпляра с именем int, которая будет удерживать индекс следующего местоположения, к которому будет перемещаться ваш объект. Каждый раз, когда вызывается метод таймера, он перемещает объект в следующую точку в вашем массиве точек подсчета, используя ваш собственный или ниже код с надписью physicalMovement; Вы можете играть с физическими значениями и даже с частотой ttimer для различных эффектов движения. Просто убедитесь, что вы правильно указали индекс. Кроме того, для большего реализма я использовал метод, который вычисляет ближайшую точку в массиве вычисленной точки к объекту, который вызывается только после начала столкновения. Он также находится под надписью nearPointGoTo. Если вам нужна дополнительная помощь, просто скажите это в комментариях. Храните взлом!

Я использовал второй, и вот для него исходный код:

Ответ 3

Сам код не прошел через

Вариант расчета второй точки

+(NSArray *)calculatePoints:(CGPoint)point withRadius:(CGFloat)radius numberOfPoints:    (int)numberOfPoints{ //or sprite kit equivalent thereof 
//                [drawNode clear];


NSMutableArray *points = [[NSMutableArray alloc]init];
for (int j = 1; j < 5; j++) {
    float currentDistance;
    float myRadius = radius;
    float xAdd;
    float yAdd;
    int xMultiplier;
    int yMultiplier;
    CCColor *color = [[CCColor alloc]init]; //Will be used later to draw the position of the node, for debugging only 
    for (int i = 0; i < numberOfPoints; i += 1){ 
        //You also have to change the if (indextogoto == <value>) in the moveGumliMethod;
    float opposite = sqrtf( powf(myRadius, 2) - powf(currentDistance, 2) );
    currentDistance = i;

    switch (j) {
        case 1:
            xMultiplier = 1;
            yMultiplier = 1;
            xAdd = currentDistance;
            yAdd = opposite;
            color = [CCColor blueColor];
            break;
        case 2:
           xMultiplier = 1;
            yMultiplier = -1;
            xAdd = opposite;
            yAdd = currentDistance;
            color = [CCColor orangeColor];
            break;
        case 3:
            xMultiplier = -1;
            yMultiplier = -1;
            xAdd = currentDistance;
            yAdd = opposite;
            color = [CCColor redColor];
            break;
        case 4:
            xMultiplier = -1;
            yMultiplier = 1;
            xAdd = opposite;
            yAdd = currentDistance;
            color = [CCColor purpleColor];
            break;
        default:
            break;
    }
   int x = (CGFloat)(point.x + xAdd * xMultiplier); //or sprite kit equivalent thereof 
   int y = (CGFloat)(point.y + yAdd * yMultiplier); //or sprite kit equivalent thereof 
   CGPoint newPoint = CGPointMake((CGFloat)x,(CGFloat)y); //or sprite kit equivalent thereof 


   NSValue *pointWrapper = [NSValue valueWithCGPoint:newPoint]; //or sprite kit equivalent thereof 
   NSLog(@"Point is %@",pointWrapper);
  [points addObject:pointWrapper];
    }
}
return points;
}

Вычисление ближайшей точки к объекту

-(CGPoint)calculateNearestGumliPoint:(CGPoint)search point { // MY Character is named    Gumli
    float closestDist = 2000;
    CGPoint closestPt = ccp(0,0);
    for (NSValue *point in points) {
        CGPoint cgPoint = [point CGPointValue];
        float dist = sqrt(pow( (cgPoint.x - searchpoint.x), 2) + pow( (cgPoint.y - searchpoint.y), 2));
    if (dist < closestDist) {
        closestDist = dist;
        closestPt = cgPoint;

        }
    }

    return closestPt;
}

Ответ 4

Я думаю, что лучший способ выполнить эту работу - через два SKNode и соединить их с SKPhysicsJointPin (посмотрите ниже пример pin)

введите описание изображения здесь

Я попытался повесить дверной знак (SKSpriteNode) на моей двери (`SkScene) и хотел бы повернуть вокруг на висячем месте, когда кто-то коснулся его

То, что я сделал, это сделать 1x1 SKNode с массой HUGH и отключить гравитационные эффекты.

var doorSignAnchor = SKSpriteNode(color: myUIColor, size: CGSize(width: 1, height: 1))
doorSignAnchor.physicsBody = SKPhysicsBody(rectangleOf: doorSignAnchor.frame.size)
doorSignAnchor.physicsBody!.affectedByGravity = false // MAGIC PART
doorSignAnchor.physicsBody!.mass = 9999999999 // MAGIC PART

var doorSignNode = SKSpriteNode(imageNamed:"doorSign")
doorSignNode.physicsBody = SKPhysicsBody(rectangleOf: doorSignNode.frame.size)

и создал SKPhysicsJointPin, чтобы соединить их все

let joint = SKPhysicsJointPin.joint(
      withBodyA:  doorSignAnchor.physicsBody!,
      bodyB: doorSignNode.physicsBody!,
      anchor: doorSignAnchor.position)
mySkScene.physicsWorld.add(joint)

Таким образом, он будет перемещаться, как фактический знак двери, вращаться вокруг произвольной точки (doorSignAnchor)

Ссылка: