swift - 将 UIKit 转换为 SceneKit

标签 swift scenekit

无法将程序从 UIKit 转换为 SceneKit。对我来说最大的困难是理解如何使用 SceneKit 设置委托(delegate)文件、Tile、与数组、Board 同步。这是一个简单的项目。截图:http://imgur.com/9hsv7X5 .它显示一个 3 x 5 阵列。用户点击一个项目,它就会高亮显示。然后点击另一个项目,它变为突出显示,上一个项目,未突出显示。

这是由 3 个文件组成的 UIKit 项目:

View Controller

import UIKit

struct BoardLoc {
    var x: Int
    var y: Int
}

class ViewController: UIViewController, TileDelegate {

    var tile: Tile!

    override func viewDidLoad() {
        super.viewDidLoad()

        let scene = Board()
        tile.tileDelegate = self
        tile.board = scene
    }

    func getTileAtLoc(tile: Tile, _ boardLoc: BoardLoc) {
        tile.boardLoc = boardLoc
    }  
}

董事会

import Foundation

class Board {
    var board: Array<Array<String>> = Array(count:3, repeatedValue:Array(count:5, repeatedValue:"foo"))

    func putTileAt(boardLoc: BoardLoc) -> String {
        return board[boardLoc.x][boardLoc.y]
    }  
}

平铺

import UIKit

protocol TileDelegate {
    func getTileAtLoc(tile: Tile, _ boardLoc: BoardLoc)
}

class Tile: UIView {
    var boardLoc: BoardLoc?
    var board: Board?
    var tileDelegate: TileDelegate?

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        addGestureRecognizer(UITapGestureRecognizer(target: self, action:"handleTap:"))
    }

    override func drawRect(rect: CGRect) {
        for x in 0...2 {
            for y in 0...4 {

                let context = UIGraphicsGetCurrentContext()
                let red = UIColor.redColor().CGColor
                let orange = UIColor.orangeColor().CGColor
                let bigCircle = CGRectMake(CGFloat(106 * x),CGFloat(106 * y), 106, 106)
                let smallCircle = CGRectMake(CGFloat(106 * x) + 3, CGFloat(106 * y) + 3, 100, 100)

                if (boardLoc != nil && boardLoc!.x == x && boardLoc!.y == y) {
                    CGContextSetFillColorWithColor(context, red)
                    CGContextFillEllipseInRect(context, bigCircle)
                }

                if board!.putTileAt(BoardLoc(x: x, y: y)) == "foo" {
                    CGContextSetFillColorWithColor(context, orange)
                    CGContextFillEllipseInRect(context, smallCircle)
                }
            }
        }
    }

    func handleTap(gestureRecognizer: UIGestureRecognizer) {
        let point = gestureRecognizer.locationInView(self)
        let boardLoc = BoardLoc(x: Int(point.x) / 106, y: Int(point.y) / 106)
        tileDelegate!.getTileAtLoc(self, boardLoc)
        setNeedsDisplay()
    }
}

最佳答案

首先推荐大家阅读Apple SceneKit document和一些教程。

Scene Kit is a 3D-rendering Objective-C framework that combines a high-performance rendering engine with a high-level, descriptive API. Scene Kit supports the import, manipulation, and rendering of 3D assets without requiring the exact steps to render a scene the way OpenGL does.

Scene Kit 让您无需 OpenGL ES API 即可轻松渲染 3D 场景。但是,您应该了解 Scene Kit 的工作原理。

基本上,Scene Kit 提供了一个维护动画循环的 View Controller 。此循环遵循游戏和模拟中常见的设计模式,分为两个阶段:更新和渲染。在实现中,Scene Kit 有更多的阶段,如下图(来自 http://www.objc.io/issue-18/scenekit.html ),但基本上是两个阶段,updaterender

Scene Kit phases

那么如何创建Scene Kit项目,基础是

  • 准备SCNView
  • 初始化3D场景
  • 创建触摸事件处理程序
  • 实现更新阶段:使用触摸的对象或触摸的位置更新游戏板,更新对象的动画,或某种东西。
  • 实现渲染阶段:基本上,Scene Kit 会自动渲染注册的 3D 对象和模型。

因此,您应该按以下方式实现。

  • 使用 SCNView 而不是 ViewController
  • 创建一个场景
  • 将 Board 和 Tiles 作为 Scene Kit 3D 对象放置
  • 使用 hitTest 接触 Tile 并在 Update 阶段更新 Tiles

关于swift - 将 UIKit 转换为 SceneKit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27594481/

相关文章:

xcode - 在 GitHub pod 中更改 .scnp 不会对运行产生影响

ios - 在 Swift 中的 WebService 中传递参数

ios - 如何在 Swift 中对 Json 字典数组值进行排序(A-z、0-9 和特殊字符)

ios - 尽管在 Swift 中使用 prepareToPlay(),AVAudioPlayer 仍会产生滞后

swift - 在 Swift Playground 中使用 SceneKit

swift - 在 swift SceneKit 中绘制带有顶点的自定义节点的示例是什么?

ios - 下载 JSON 数据后执行 segue?

ios - 布局约束不起作用

swift - SCNNode 枢轴位置