はじめに
SpriteKit でなにか表示したい場合はとりあえず SKNode を使います。下記のようにいろいろある SKNode の簡単なまとめです。
- SKCameraNode
- SKReferenceNode
- SKSpriteNode
- SKShapeNode
- SKEmitterNode
- SKLabelNode
- SKVideoNode
- SKTileMapNode
- SK3DNode
- SKAudioNode
- SKLightNode
- SKFieldNode
- SKEffectNode
- SKCropNode
- SKTransformNode
ちなみに SKScene も下記のように SKNode のサブクラスの模様。
1 |
class SKScene : SKEffectNode |
SKCameraNode
カメラ。
簡易実装。
1 2 3 4 5 6 7 8 |
final class HogeScene: SKScene { private let cameraNode = SKCameraNode() override func didMove(to view: SKView) { camera = cameraNode camera?.position = .init(x: 100, y: frame.midY) } } |
SKScene.camera は weak なので下記のように生成するのはだめな模様。ちゃんとインスタンスを保持して代入してやる必要がある。
1 |
camera = .init() |
カメラをキャラクターに追従させれば横スクロールアクションとかで使えそう。常に画面に表示したいものがある場合は camera の子ノードに設定する必要がある。
SKReferenceNode
きっと Xcode のシーンエディタ使うときに便利なやつ(よくわからなかった)。
SKSpriteNode
画像表示ができるやつ(たぶん一番よく使う)。
簡易実装。
1 2 3 4 5 |
override func didMove(to view: SKView) { let node = SKSpriteNode(imageNamed: "frog_green") node.position = .init(x: frame.midX, y: frame.midY) addChild(node) } |
texture は変更可能なので touchesBegan
などで下記のように表示を変えることができる。
1 |
node.texture = .init(imageNamed: "frog_red") |
SKShapeNode
円や四角など図形を表示できるやつ。
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
override func didMove(to view: SKView) { // 円 let circle = SKShapeNode(circleOfRadius: 20) circle.fillColor = .systemRed circle.strokeColor = .white circle.position = .init(x: 30, y: frame.midY) addChild(circle) // 四角 let rect = SKShapeNode(rectOf: .init(width: 60, height: 30)) rect.fillColor = .systemBlue rect.strokeColor = .white rect.position = .init(x: 100, y: frame.midY) addChild(rect) // 四角(角丸) let rect2 = SKShapeNode(rectOf: .init(width: 60, height: 30), cornerRadius: 5) rect2.fillColor = .systemGreen rect2.strokeColor = .white rect2.position = .init(x: 200, y: frame.midY) addChild(rect2) // 楕円 let elipse = SKShapeNode(ellipseOf: .init(width: 60, height: 30)) elipse.fillColor = .systemYellow elipse.strokeColor = .white elipse.position = .init(x: 280, y: frame.midY) addChild(elipse) // 三角 let path = UIBezierPath() path.move(to: CGPoint(x: 0, y: 20)) path.addLine(to: CGPoint(x: 20, y: -20)) path.addLine(to: CGPoint(x: -20, y: -20)) path.addLine(to: CGPoint(x: 0, y: 20)) let triangle = SKShapeNode(path: path.cgPath) triangle.fillColor = .systemOrange triangle.strokeColor = .white triangle.position = .init(x: 360, y: frame.midY) addChild(triangle) } |
SKEmitterNode
炎などパーティクル表示するやつ。
デフォルトパーティクル全部のせ😎 pic.twitter.com/abMOnwrmEv
— am10 (@am103141592) August 2, 2022
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
override func didMove(to view: SKView) { let spark = SKEmitterNode(fileNamed: "Spark.sks")! spark.position = .init(x: frame.midX, y: frame.midY) addChild(spark) let snow = SKEmitterNode(fileNamed: "Snow.sks")! snow.position = .init(x: frame.midX, y: frame.midY) addChild(snow) let rain = SKEmitterNode(fileNamed: "Rain.sks")! rain.position = .init(x: frame.midX, y: frame.midY) addChild(rain) let smoke = SKEmitterNode(fileNamed: "Smoke.sks")! smoke.position = .init(x: frame.midX, y: frame.midY) addChild(smoke) let magic = SKEmitterNode(fileNamed: "Magic.sks")! magic.position = .init(x: frame.midX, y: frame.midY) addChild(magic) let fireflies = SKEmitterNode(fileNamed: "Fireflies.sks")! fireflies.position = .init(x: frame.midX, y: frame.midY) addChild(fireflies) let fire = SKEmitterNode(fileNamed: "Fire.sks")! fire.position = .init(x: frame.midX, y: frame.midY) addChild(fire) let bokeh = SKEmitterNode(fileNamed: "Bokeh.sks")! bokeh.position = .init(x: frame.midX, y: frame.midY) addChild(bokeh) } |
上記の sks ファイルは SpriteKit Particle File で追加したものです。
SKLabelNode
文字表示するやつ(ほぼ UILabel)。
(改行するとめっちゃ隙間できた)
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 |
override func didMove(to view: SKView) { let label = SKLabelNode() label.text = "ほげ\nふがふが" label.fontName = "Zapfino" label.fontColor = .systemRed label.fontSize = 24 label.horizontalAlignmentMode = .left label.verticalAlignmentMode = .center label.numberOfLines = 0 label.position = .init(x: frame.midX, y: frame.midY) addChild(label) } |
サイズは自動計算されるらしくこちらで設定はできない模様。
SKVideoNode
動画が再生できるやつ。
簡易実装。
1 2 3 4 5 6 7 |
override func didMove(to view: SKView) { let video = SKVideoNode(fileNamed: "frog.MP4") video.size = .init(width: 200, height: 400) video.position = .init(x: frame.midX, y: frame.midY) addChild(video) video.play() } |
play() と pause() だけ用意されており細かい操作をしたい場合は下記イニシャライザで AVPlayer
を使えばできそう。
1 |
init(avPlayer player: AVPlayer) |
SKTileMapNode
格子状に配置するためのやつ(基本はシーンエディタで使うっぽい)。
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
final class HogeScene: SKScene { enum TileType { case normal case rock } private let tilePositions: [(column: Int, row: Int, tile: TileType)] = [ (0, 0, .rock), (0, 1, .normal), (0, 2, .normal), (0, 3, .normal), (1, 0, .normal), (1, 1, .normal), (1, 2, .normal), (1, 3, .normal), (2, 0, .normal), (2, 1, .normal), (2, 2, .rock), (2, 3, .normal), (3, 0, .normal), (3, 1, .normal), (3, 2, .normal), (3, 3, .rock) ] override func didMove(to view: SKView) { let tileSize = CGSize(width: 32, height: 32) let groupNormal = SKTileGroup(tileDefinition: .init(texture: .init(imageNamed: "tile"), size: tileSize)) let groupRock = SKTileGroup(tileDefinition: .init(texture: .init(imageNamed: "tile_rock"), size: tileSize)) let tileSet = SKTileSet(tileGroups: [groupNormal, groupRock]) let tileMap = SKTileMapNode(tileSet: tileSet, columns: 4, rows: 4, tileSize: tileSize) tilePositions.forEach { tileMap.setTileGroup($0.tile == .normal ? groupNormal : groupRock, forColumn: $0.column, row: $0.row) } tileMap.position = .init(x: frame.midX, y: frame.midY) addChild(tileMap) } } |
SKTileSetType は下記があるのでグリッド以外に六角形とかもできる模様。
1 2 3 4 |
case grid case hexagonalFlat case hexagonalPointy case isometric |
こちらの記事が参考になりました。
- 【Swift】SpriteKitの使い方。SKTileMapNodeで碁盤の目にタイルを配置してマップを作成する。(Swift 3.0、XCode 8.0)
- 【Swift】SpriteKitの使い方。SKTileMapNodeをソースコードで操作する。(Swift 3.0、XCode 8.0)
SK3DNode
SceneKit のオブジェクトを表示できるやつ。
簡易実装。
1 2 3 4 5 6 |
override func didMove(to view: SKView) { let threeD = SK3DNode(viewportSize: .init(width: 200, height: 200)) threeD.position = .init(x: frame.midX, y: frame.midY) threeD.scnScene = SCNScene(named: "dog") addChild(threeD) } |
SKAudioNode
音声再生ができるやつ。
簡易実装。
1 2 3 4 5 |
override func didMove(to view: SKView) { let audio = SKAudioNode(fileNamed: "sound.mp3") audio.autoplayLooped = true addChild(audio) } |
SKLightNode
SKSpriteNode に光を当てるやつ。
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
override func didMove(to view: SKView) { let back = SKSpriteNode(color: .white, size: size) back.position = .init(x: frame.midX, y: frame.midY) back.lightingBitMask = 1 addChild(back) let light = SKLightNode() light.position = .init(x: frame.midX, y: frame.midY) light.categoryBitMask = 1 addChild(light) let red = SKSpriteNode(imageNamed: "frog_red") red.position = .init(x: frame.midX, y: frame.midY) red.lightingBitMask = 1 addChild(red) let blue = SKSpriteNode(imageNamed: "frog_blue") blue.position = .init(x: frame.midX - 100, y: frame.midY - 60) blue.shadowedBitMask = 1 addChild(blue) let green = SKSpriteNode(imageNamed: "frog_green") green.position = .init(x: frame.midX + 100, y: frame.midY - 60) green.shadowCastBitMask = 1 addChild(green) } |
BitMask によりどのノードが影響を受けるか設定する必要があり下記の BitMask がある。
- lightingBitMask
光に照らされるかどうか? - shadowedBitMask
影ができるかどうか?(あんまわかってない) - shadowCastBitMask
光を遮るかどうか?
光と影の色も設定できる模様。
1 2 3 |
var ambientColor: UIColor var lightColor: UIColor var shadowColor: UIColor |
SKFieldNode
磁場など物理効果を与えるやつ?(よくわかってない)
SKFieldNode.springField()を与えた🐸 pic.twitter.com/JUAwHPm6Z4
— am10 (@am103141592) August 2, 2022
簡易実装。
1 2 3 4 5 6 7 8 9 10 |
override func didMove(to view: SKView) { let green = SKSpriteNode(imageNamed: "frog_green") green.physicsBody = .init(texture: green.texture!, size: green.texture!.size()) green.position = .init(x: frame.midX, y: frame.midY) addChild(green) let field = SKFieldNode.springField() field.position = .init(x: frame.midX, y: frame.midY) field.strength = 5 addChild(field) } |
バネ以外にも色々あるみたいです。
1 2 3 4 5 6 7 8 9 10 11 12 |
class func dragField() -> SKFieldNode class func electricField() -> SKFieldNode class func linearGravityField(withVector: vector_float3) -> SKFieldNode class func magneticField() -> SKFieldNode class func noiseField(withSmoothness: CGFloat, animationSpeed: CGFloat) -> SKFieldNode class func radialGravityField() -> SKFieldNode class func springField() -> SKFieldNode class func turbulenceField(withSmoothness: CGFloat, animationSpeed: CGFloat) -> SKFieldNode class func velocityField(with: SKTexture) -> SKFieldNode class func velocityField(withVector: vector_float3) -> SKFieldNode class func vortexField() -> SKFieldNode class func customField(evaluationBlock: SKFieldForceEvaluator) -> SKFieldNode |
SKEffectNode
CIFileter を使って色々効果をつけらられるやつ。
簡易実装。
1 2 3 4 5 6 7 8 |
override func didMove(to view: SKView) { let frog = SKSpriteNode(imageNamed: "frog_red") let effect = SKEffectNode() effect.position = .init(x: frame.midX, y: frame.midY) effect.filter = CIFilter(name: "CIMotionBlur") effect.addChild(frog) addChild(effect) } |
こちらの記事にいろいろ載ってました。
【Swift】SpriteKitの使い方。SKEffectNodeを使って画像をぼかす。(Swift 2.2、XCode 7.3)
SKCropNode
指定のノードの形で子ノードをくり抜くやつ。
(オレンジ正方形のノードをカエルでくり抜いたやつ)
簡易実装。
1 2 3 4 5 6 7 8 9 10 |
override func didMove(to view: SKView) { let frog = SKSpriteNode(imageNamed: "frog_green") let crop = SKCropNode() crop.maskNode = frog let mask = SKShapeNode(rectOf: .init(width: 200, height: 200)) mask.fillColor = .systemOrange crop.addChild(mask) crop.position = .init(x: frame.midX, y: frame.midY) addChild(crop) } |
SKTransformNode
子ノードを 3D 回転させるやつ?(あんまわかってない)
簡易実装。
1 2 3 4 5 6 7 8 9 |
override func didMove(to view: SKView) { let frog = SKSpriteNode(imageNamed: "frog_red") let transform = SKTransformNode() transform.position = .init(x: frame.midX, y: frame.midY) transform.xRotation = .pi transform.yRotation = .pi transform.addChild(frog) addChild(transform) } |
このへん使って回転させるらしい。
1 2 3 4 5 |
var xRotation: CGFloat var yRotation: CGFloat func setEulerAngles(vector_float3) func setQuaternion(simd_quatf) func setRotationMatrix(matrix_float3x3) |
おわりに
これで SpriteKit で色々表示できるようになりました!もうなんか作れそうな気がしてきます!
コメント