SpriteKit - 改变 SKShapeNode 的大小

4
我有一个通过shapeNodeWithRect: cornerRadius:创建的SKShapeNode。这个圆角矩形是SKEffectNode的子节点,所以我可以设置shouldRasterize = YES
我想根据用户的触摸更改此节点的宽度。例如,当他们向右水平移动手指时,矩形变大(并且向左移动时变小)。
以下是做法:
  1. 通过新的大小替换原始的SKShapeNode(但这很糟糕)。
  2. 我已尝试在SKEffectNodeSKShapeNode上运行调整大小的操作(但这不起作用,因为调整大小仅适用于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]];

这段代码是改变大小的。它使用了SKAction类中的resizeToWidth:height:duration:方法来改变大小。保留了HTML标签。
  1. 我可以像更改SKShapeNode的高度答案中所示那样更改xScale。但是如果我这样做,SKShapeNode会变得像素化。

我该怎么做?

在UIKit中这很容易(只需设置UIView的框架)...


你尝试过进行扩展吗? - sangony
@sangony -- 我已经尝试过缩放(请参见我的问题中的#3)。问题在于将节点从小缩放到大会使其变得像素化。 - rizzes
如果像素化是一个问题,那么你几乎无能为力。我最近发布了一个关于调整SKLabelNode大小的答案,它处理了非常类似的问题。http://stackoverflow.com/questions/29354494/how-should-i-resize-label-nodes-in-spritekit/29354830#29354830 - sangony
  1. 每个阶段都重新绘制它有什么问题吗?这可能会很耗费资源,但如果它可以使用就行了...
  2. 如果拉伸时出现像素化,请将形状创建为您需要的最宽x,并立即缩小它。然后,当它们接触屏幕时,增加缩放以接近1。缩小会导致最少的质量损失。放大会使其像素化。只需反转您的过程即可。
- meisenman
@meisenman -- 1. 在每次遍历时重新创建的问题在于动画变化。2. 我同意这个可能的解决方案(尽管它在我的具体实现中效果不是很好,因为我屏幕上有很多这些SKShapeNodes,并担心缩小那么多对象)。 - rizzes
也许我错过了,但是你为什么要设置shouldRasterize呢?就像任何矢量图形在光栅化后缩放会变得模糊一样。这很可能是它出现像素化的原因。如果需要它,那么我认为除了疯狂地放大和缩小或根据需要重新创建之外,没有其他解决方法。创建完成后,您可以尝试self.shapeNode.texture.filteringMode = SKTextureFilteringNearest,但不太希望能有太大帮助。 - Skyler Lauren
1个回答

3

使用较大的尺寸创建SKShapeNode对象,然后立即将其缩小。这样做,您就不会遇到模糊或像素化的节点。

在Swift 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
    }
}

在Objective-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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接