ios - 我怎样才能 "Fold"沿一条线以 3D 形式显示 UIView?

标签 ios swift uiview core-graphics skview

如果你有一个 UIView
enter image description here
想象一下 View 充满了文本、动画、猫照片、渐变,或者实际上是 UIView 可以充满的任何东西。
在 3D 中很容易将其向左倾斜
enter image description here
或回到右边..
enter image description here
(顺便说一句,我强烈推荐完美的 OHCubeView ohcubeview 当你必须做那种事情时。)
但是我想增加一个 View 沿接缝 , 并且有 一侧向左后退和其他一侧向后向右..
enter image description here
!
我的第一个解决方案很简单:无论 View 是什么(用户正在输入文本、猫的照片等等),只需完美地复制它,然后以显而易见的方式解决问题。
这很不优雅,但确实有效。
但...
我想这样折叠的东西是......一个SKView 里面有发射器 .
粒子发射器当然是随机的,虽然两个相同的发射器看起来很相似,但这并不是真正的解决方案。
本质上,如果有人知道如何将 UIView “复制”到另一个,那么, View 或其他东西......
enter image description here
问题将得到解决。
例如,对于游戏引擎中的此类问题,您只需将“虚拟相机”(无论您最喜欢的游戏引擎中的概念是什么)放在有问题的东西上,然后将另一半或其他任何东西放在您想要的任何地方,但是,我不知道 iOS 中的类比!
有没有人对此有看法:
enter image description here

最佳答案

我可以想到两种方法。

1) 弯道

您可以使用 SKWarpGeometry 弯曲您的场景。从语义上讲,您会在游戏场景中设想一个 2 x 2 象限网格,由 3 x 3 点数据结构描述。你会稍微移动左右边缘,并使它们变小一点。你会让中心垂直边缘更长一点。

Apple 的文档还提到,基本上任何类型的节点(包括 SKEmitterNode)都可以通过将其放入 SKEffectNode 并将其应用于该节点来进行扭曲。见:https://developer.apple.com/documentation/spritekit/skwarpgeometrygrid/animate_the_warping_of_a_sprite?language=objc .

我们所要做的就是让一个效果节点成为一切的根节点,并对其应用变形。现在,这行得通,但只要里面有发射器,经线就会开始像癫痫一样的抽搐。我认为这是一个错误。无论如何,我都会包含代码,以防它稍后修复,因为它应该根据文档工作。

let sourcePoints = [
    // bottom row: left, center, right
    vector_float2(0.0, 0.0),
    vector_float2(0.5, 0.0),
    vector_float2(1.0, 0.0),

    // middle row: left, center, right
    vector_float2(0.0, 0.5),
    vector_float2(0.5, 0.5),
    vector_float2(1.0, 0.5),

    // top row: left, center, right
    vector_float2(0.0, 1.0),
    vector_float2(0.5, 1.0),
    vector_float2(1.0, 1.0)
]

var destinationPoints = sourcePoints

// Bring lefts in, and make the edge shorter
destinationPoints[0] = vector_float2(0.1, 0.1)
destinationPoints[3] = vector_float2(0.1, 0.4)
destinationPoints[6] = vector_float2(0.1, 0.9)

// Bring rights in, and make the edge shorter
destinationPoints[2] = vector_float2(0.9, 0.1)
destinationPoints[5] = vector_float2(0.9, 0.4)
destinationPoints[8] = vector_float2(0.9, 0.9)

// Make the center edge longer
destinationPoints[1] = vector_float2(0.5, -0.2)
destinationPoints[4] = vector_float2(0.5, 0.7)
destinationPoints[7] = vector_float2(0.5, 1.2)

// Need to set the no warp geometry first
effectNode.warpGeometry = SKWarpGeometryGrid(columns: 2, rows: 2)

let newGeometry = SKWarpGeometryGrid(columns: 2, rows: 2,
                                         sourcePositions: sourcePoints,
                                         destinationPositions: destinationPoints)

effectNode.run(SKAction.warp(to: newGeometry, duration: 1.0)!)

使用的来源:

https://www.hackingwithswift.com/example-code/games/how-to-warp-a-sprite-using-skwarpgeometrygrid

http://sound-of-silence.com/?page=blog&sort=recent&count=0

2) Live Copy 方法

这更简单,代码更少,而且用途更广泛;你可以在这个雷曼传奇级别 https://youtu.be/7m5YQrucis8?t=1226 中做类似的事情.此外,它还有效。

基本上,我们的主 SKView 显示主场景。我们将添加一个显示复制场景的副本 SKView。复制场景中只有一个 Sprite 节点。
在主场景的更新循环中,我们将抓取场景的扁平纹理并将其分配给复制场景中的 Sprite 节点。作为场景委托(delegate)的对象可以进入这个更新循环,因此我们将使 View Controller 符合 SKSceneDelegate。
class Playground_VC: UIViewController, SKSceneDelegate {

    var sprite: SKSpriteNode?

    override func loadView() {
        self.view = SKView()
    }

    var skView: SKView {
        return self.view as! SKView
    }

    override func viewWillAppear(_ animated: Bool) {
        let scene = SKScene(size: self.skView.bounds.size)
        scene.backgroundColor = UIColor.clear
        scene.delegate = self
        self.skView.presentScene(scene)

        let e = newEmitter()
        scene.addChild(e)
        e.position = self.skView.midPoint

        self.createCopy()

    }

    func update(_ currentTime: TimeInterval, for scene: SKScene) {
        // Grab the root texture and assign to the sprite that's in the copy scene
        let t = self.skView.texture(from: self.skView.scene!)
        self.sprite?.texture = t
    }

    func createCopy() {

        // Make a new SKView that's 4 times smaller

        var f = self.skView.bounds
        f.size.height *= 0.4
        f.size.width *= 0.4

        let copy = SKView(frame: f)
        copy.presentScene(SKScene(size: f.size))
        self.view.addSubview(copy)

        let sprite = SKSpriteNode(texture: nil, size: f.size)
        copy.scene?.addChild(sprite)
        self.sprite = sprite
        sprite.position = CGPoint(x: f.size.width / 2, y: f.size.height / 2)

    }

    func newEmitter() -> SKEmitterNode {
        return SKEmitterNode(fileNamed: "Particle.sks")!
    }
}

您在主 SKView 上执行的任何操作,例如在 3D 空间中倾斜它,都不应影响副本的外观,因为游戏场景不受这些操作的影响。

enter image description here

关于ios - 我怎样才能 "Fold"沿一条线以 3D 形式显示 UIView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59805261/

相关文章:

ios - 在 iOS 11 中,UIViewController 的 transitionFromViewController 从不调用它的完成 block

ios - 在 iOS 屏幕底部的流式迷你窗口中播放视频

ios - AutoLayout 问题 UITable View 标题部分 : Adding image in the left does not works fine

ios - UIButton 在 setImage : is called 后不更新它的图像

ios - 呈现 View Controller 时无法在 iOS 6,7 上隐藏状态栏

iphone - 由于 iPhone 中的默认调用,UI 受到干扰

ios - 如果在 .h 文件中声明,则需要分配和初始化对象

ios - Swift:TableView,循环文本数组

ios - 快速替换旧式枚举

ios - 缩放任何 View 的内容并允许动画