맛동산이

SpriteKit) SpriteKit과 scene에 대해서 [SwiftUI] 본문

앱/SwiftUI

SpriteKit) SpriteKit과 scene에 대해서 [SwiftUI]

진ddang 2023. 8. 28. 15:06

Untitled.png

Apple Document에는 다음과 같이 스프라이트킷을 정의하고 있다.

하지만 게임을 만들기 위해서 라는 부분이 좀 많이 안와닿았는데, 다음과 같이 좀더 명확하게 설명해준다.

💡 SpriteKit은 도형을 그리거나, 글, 이미지 등을 2차원에서 다양한 애니메이션과 물리법칙을 적용하여 쉽게 게임과 같은 graphic-intensive app을 만들때 사용하는 프레임워크이다.

Scene

Spritekit에서 제공하는 컨텐츠를 보여주기 위해서는 스프라이트킷에서 제공하는 뷰에서 해당 컨텐츠를 그려야한다. 제공하는 뷰는 다음과 같다.

  • SKView : 스프라이트킷의 컨텐츠만 보여줄때 사용하는 뷰
  • SKRender : Metal과 스프라이트킷 컨텐츠를 섞어서 보여줄때 사용하는 뷰

Metal이란?

metal이란 apple에서 만든 2차원 3차원의 그래픽 라이브러리이다.

해당 metal 라이브러리를 사용하면, 기존의 openGL이나, openCL의 기능처럼 3차원의 물 혹은 입체감을 줄수있다. 해당 객체의 이동에 따라서 그림자가 변화한다던지, 등의 연산을 대신해주는것이다.

Content

스프라이트킷에서 모든 객체는 node로 표현이 된다.

또한 노드는 모두 트리형태를 띄고있다.

SKScene: 최상단의 노드로, 모든 노드객체를 관리하는 루트노드

let image = SKSpriteNode(imageNamed: "myImage.png")  // Add the image to the scene. scene.addChild(image) 

bookmark

노드의 종류는 위의 링크를 타고가면 확인할수 있다.

위의 예시코드에서는 이미지를 사용하기 때문에 SKSpriteNode를 사용하였다.

SwiftIU에서 Spritekit 사용하기

스프라이트킷의 기본적인 사용방법은 다음과 같다.

  • Spritekit Scean정의 하기
  • 노드생성 로직 짜기
  • SwiftUI에 뷰로 얹기
  • 탭이벤트로 이벤트 발생시키기 ( 액션이 존재한다면 )

1. Scean정의하기

Untitled.png

class SpriteKitScean: SKScene { 	init() } 

보통 이렇게 init할수도 있겠지만, 그냥 viewDidLoad와 같은 didMove를 쓰자.

class SpriteKitScean: SKScene { 	didmove(to view: SKView) { 	} } 

2. 노드생성 로직짜기

func createNode(for size: CGSize) { 	let node = SKShapeNode(circleRadious: 50) 	node.fillColor = .black 	node.position = CGPoint() 	addChild(node) } 

여기에서 중요한점은 spriteKit은 기존의 UIkit과 같이 Scene에 컴포넌트를 추가하는 식의 화면그리기인 점이다.

스프라이트킷은 기존의 UIkit과 비슷하게 tree형식의 구조인것

따라서 self.addChild()의 메소드를 통해서 해당 뷰에 node를 추가하는 과정과, 해당 노드에 다양한 text혹은 추가적인 node를 추가하는 것은 node.addChild(설정된 node)로 추가할수있게 된다.

3. SwiftUI에 뷰 얹기

struct ContentView: View {   var body: some View {     GeometryReader { geometry in       let size = geometry.size        SpriteView(scene: SpriteKitScene(size: size))         .frame(width: size.width, height: size.height)     }     .ignoresSafeArea()   } } 

이런식으로 SwiftUI에서는 SpriteView로 추가할수있게 된다.

여기에서 중요한점은 해당 SpriteView를 왜 GeometryReader로 감싸고 있는지에 대한 점인데,

이는 SpriteKit에서는 초기 init시 CGSize를 추가해줘야 하기 때문에 해당 CGSize에 대한 데이터를 받아오기 위해서 GometryReader를 사용하는 것이다.

추가적인 기능에 대하여

Untitled.png

SpriteKit을 사용하는 다양한 이유가 있겠지만, 그 중에서도 중력이나, 현실에 적용되는 다양한 물리엔진을 사용하기 위함이라고 생각한다.

해당 기능은 SKPhysicsBody라는 class를사용해서 Scean을 정의하게 되면 해당 씬 위에서는 물리엔진을 적용할수 있으며, 이러한 물리엔진이 적용된 node를 생성하게 되면 중력이나, 충돌과 같은 node들 사이의 액션을 감지하거나 반응하게 만들수 있다.

SKPhysicsBody를 사용한 코드

class GameScean: SKScean {  override func didMove(to view: SKView) { 		physicsBody = SKPhysicsBody(edgeLoopFrom: frame) 	} 	 	func createNode() { 		let box = SKSpriteNode(color: .red, size: CGsize()) 		box.physicsBody = SKPhysicsBody(size: CGSize()) 		addchild(box) 	} } 

조금 불필요한 값들은 제거했습니다 .

이런방식으로 node에 물리엔진이 적용되는 범위를 추가하여서 해당 노드가 물리엔진이 적용되도록 할수가 있다.


참고자료

bookmark

반응형