SpriteKit Изменить размер SKShapeNode

У меня есть SKShapeNode, созданный shapeNodeWithRect: cornerRadius:. Этот закругленный прямоугольник является дочерним элементом SKEffectNode, поэтому я могу установить shouldRasterize = YES.

Я хотел бы изменить ширину этого узла в зависимости от прикосновения пользователя. т. е. когда они перемещают палец горизонтально вправо, прямоугольник становится больше (и уменьшается, когда они перемещают его влево).

  1. Я могу это сделать, заменив оригинальный SKShapeNode на новый с новым размером (но это плохо).
  2. Я пытался запустить действие изменения размера для SKEffectNode и SKShapeNode (но это не работает, потому что изменение размера работает только для SKSpriteNotes[SKAction Apple Docs — Resize]):

[self runAction:[SKAction resizeToWidth:newSize.width height:newSize.height duration:0]]; [self.shapeNode runAction:[SKAction resizeToWidth:newSize.width height:newSize.height duration:0]];

  1. Я мог бы изменить xScale, как в этом ответе: Изменить высоту SKShapeNode. Но если я это сделаю, SKShapeNode станет пиксельным.

Как мне это сделать?

В UIKit это так просто (просто установите рамку UIView)...


person rizzes    schedule 31.03.2015    source источник
comment
Вы пробовали масштабироваться?   -  person sangony    schedule 31.03.2015
comment
@sangony - я пытался масштабировать (см. № 3 в моем вопросе). Проблема в том, что масштабирование узла от маленького к большому делает его пиксельным.   -  person rizzes    schedule 31.03.2015
comment
Если пикселизация является проблемой, вы мало что можете с этим поделать. Недавно я опубликовал ответ об изменении размера SKLabelNode, который имел дело с очень похожими проблемами. stackoverflow.com/questions/29354494/   -  person sangony    schedule 31.03.2015
comment
1. Что плохого в перерисовке при каждом проходе? Это может быть интенсивно, но если это сработает... 2. Если при растяжении он пикселизируется, создайте фигуру с самым широким x, который вам нужен, и немедленно уменьшите его. Затем, когда они коснутся экрана, увеличьте масштаб, чтобы приблизиться к 1. Уменьшение масштаба вызывает минимальную потерю качества. Масштабирование пикселей. Просто инвертируйте свой процесс.   -  person meisenman    schedule 31.03.2015
comment
@meisenman - 1. Проблема с воссозданием на каждом проходе заключается в анимации изменения. 2. Согласитесь с этим решением как с возможным (хотя оно не очень хорошо работает с моей конкретной реализацией, потому что у меня на экране много этих SKShapeNodes, и я беспокоюсь о уменьшении масштаба такого количества объектов).   -  person rizzes    schedule 01.04.2015
comment
Может я пропустил, но зачем вы ставите shouldRasterize? Как и любой вектор после растеризации, масштабирование становится нечетким. Вероятно, поэтому он пикселизируется. Если это необходимо, то я не вижу другого выхода, кроме безумно большого и масштабирования или воссоздания по мере необходимости. После того, как вы его создадите, вы можете попробовать self.shapeNode.texture.filteringMode = SKTextureFilteringNearest, но не надейтесь, что это сильно поможет.   -  person Skyler Lauren    schedule 01.04.2015


Ответы (1)


Создайте свои SKShapeNode объекты больших размеров, а затем сразу же уменьшите их. Если вы сделаете это, вы не должны столкнуться с размытыми или пикселизированными узлами.

В Свифт 4.0:

class GameScene: SKScene {
    var roundedRect: SKShapeNode!
    didMove(to view: SKView) {
         roundedRect = SKShapeNode(rect: Constants.RoundedRect.largeInitialRect, cornerRadius: Constants.Rect.largeInitialCornerRadius)
         // configure roundedRect
         addChild(roundedRect)
         scaleRoundedRect
    }

    func scaleRoundedRect(to size: CGSize) {
        roundedRect.xScale = roundedRect.xScale / frame.width * size.width
        roundedRect.yScale = roundedRect.yScale / frame.height * size.height
    }
}

В цели-C:

@implementation GameScene

    - (void) didMoveToView:(SKView *)view {
        CGRect largeRect = CGRectMake(0, 0, 0, 0); // replace with your own values
        CGFloat largeCornerRadius = (CGFloat) 0; // replace with your value
        _roundedRect = [SKShapeNode shapeNodeWithRect:largeRect cornerRadius:largeCornerRadius];
        CGSize initialSize = CGSizeMake(0, 0); // replace with your value
        [self scaleRoundedRectToSize:initialSize];
    }

    - (void) scaleRoundedRectToSize:(CGSize)size {
        _roundedRect.xScale = _roundedRect.xScale / _roundedRect.frame.size.width * size.width;
        _roundedRect.yScale = _roundedRect.yScale / _roundedRect.frame.size.height * size.height;
    }


@end
person R. Rincón    schedule 10.12.2017