Skip to content

Commit

Permalink
🏗 Integrates GameplayKit components with the SpriteKit scene editor
Browse files Browse the repository at this point in the history
Closes #29
  • Loading branch information
chsxf committed May 29, 2021
1 parent fe5d1e5 commit ef8a53f
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 153 deletions.
12 changes: 6 additions & 6 deletions SKTetris.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
D9044C452645130F00DB5A13 /* MainTitleScreenNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9044C442645130F00DB5A13 /* MainTitleScreenNode.swift */; };
D9044C47264521DC00DB5A13 /* OptionsScreenNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9044C46264521DC00DB5A13 /* OptionsScreenNode.swift */; };
D9061F6A25FF2DC000540CD8 /* GeometryComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9061F6925FF2DC000540CD8 /* GeometryComponent.swift */; };
D912E2B72605CEF400A6AD88 /* GridBounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = D912E2B62605CEF400A6AD88 /* GridBounds.swift */; };
D921651925F1F935007005E7 /* BlockTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = D921651825F1F935007005E7 /* BlockTools.swift */; };
D9241B6C265A3CF2009B4FBD /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9241B6B265A3CF2009B4FBD /* ViewController.swift */; };
Expand All @@ -35,7 +34,6 @@
D9241B81265A3E41009B4FBD /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9BB3B36263D8D5800FA2707 /* SoundManager.swift */; };
D9241B82265A3E41009B4FBD /* ToggleButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93D7515263CB73600800E8E /* ToggleButtonNode.swift */; };
D9241B83265A3E4F009B4FBD /* BlockTransformComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AB889C25F4322200896FDF /* BlockTransformComponent.swift */; };
D9241B84265A3E4F009B4FBD /* GeometryComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9061F6925FF2DC000540CD8 /* GeometryComponent.swift */; };
D9241B85265A3E4F009B4FBD /* GridBlockContainerComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D94B6197261973EA0044BD34 /* GridBlockContainerComponent.swift */; };
D9241B86265A3E4F009B4FBD /* GridTransformComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9474F3725F4E0300088CAD6 /* GridTransformComponent.swift */; };
D9241B87265A3E4F009B4FBD /* PieceComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AB88A025F4364D00896FDF /* PieceComponent.swift */; };
Expand Down Expand Up @@ -68,6 +66,8 @@
D9884289264815EC0023E8B9 /* GameOverContainerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9884288264815EC0023E8B9 /* GameOverContainerNode.swift */; };
D988428B264817A60023E8B9 /* GameUIContainerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D988428A264817A60023E8B9 /* GameUIContainerNode.swift */; };
D988428D26483F1A0023E8B9 /* FocusManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D988428C26483F1A0023E8B9 /* FocusManager.swift */; };
D990A41926617BD2002864B8 /* BlinkComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D990A41826617BD2002864B8 /* BlinkComponent.swift */; };
D990A41A26617BD2002864B8 /* BlinkComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D990A41826617BD2002864B8 /* BlinkComponent.swift */; };
D99888582654E086002A22EA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D99888572654E086002A22EA /* AppDelegate.swift */; };
D99888642654E087002A22EA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D99888622654E087002A22EA /* LaunchScreen.storyboard */; };
D998886B2654E2CF002A22EA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D945A21425F18B9700FAE62D /* Assets.xcassets */; };
Expand Down Expand Up @@ -106,7 +106,6 @@
/* Begin PBXFileReference section */
D9044C442645130F00DB5A13 /* MainTitleScreenNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTitleScreenNode.swift; sourceTree = "<group>"; };
D9044C46264521DC00DB5A13 /* OptionsScreenNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionsScreenNode.swift; sourceTree = "<group>"; };
D9061F6925FF2DC000540CD8 /* GeometryComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeometryComponent.swift; sourceTree = "<group>"; };
D912E2B62605CEF400A6AD88 /* GridBounds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridBounds.swift; sourceTree = "<group>"; };
D921651825F1F935007005E7 /* BlockTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockTools.swift; sourceTree = "<group>"; };
D9241B6B265A3CF2009B4FBD /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -137,6 +136,7 @@
D9884288264815EC0023E8B9 /* GameOverContainerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameOverContainerNode.swift; sourceTree = "<group>"; };
D988428A264817A60023E8B9 /* GameUIContainerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameUIContainerNode.swift; sourceTree = "<group>"; };
D988428C26483F1A0023E8B9 /* FocusManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusManager.swift; sourceTree = "<group>"; };
D990A41826617BD2002864B8 /* BlinkComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlinkComponent.swift; sourceTree = "<group>"; };
D99888552654E086002A22EA /* SKTetris-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SKTetris-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
D99888572654E086002A22EA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
D99888632654E087002A22EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
Expand Down Expand Up @@ -280,10 +280,10 @@
isa = PBXGroup;
children = (
D9AB889C25F4322200896FDF /* BlockTransformComponent.swift */,
D9061F6925FF2DC000540CD8 /* GeometryComponent.swift */,
D94B6197261973EA0044BD34 /* GridBlockContainerComponent.swift */,
D9474F3725F4E0300088CAD6 /* GridTransformComponent.swift */,
D9AB88A025F4364D00896FDF /* PieceComponent.swift */,
D990A41826617BD2002864B8 /* BlinkComponent.swift */,
);
path = Components;
sourceTree = "<group>";
Expand Down Expand Up @@ -406,8 +406,8 @@
D945A22D25F18DC600FAE62D /* GameScene.swift in Sources */,
D94B61A226199CFC0044BD34 /* GridRow.swift in Sources */,
D945A22825F18C4900FAE62D /* GameView.swift in Sources */,
D990A41926617BD2002864B8 /* BlinkComponent.swift in Sources */,
D9BB3B37263D8D5800FA2707 /* SoundManager.swift in Sources */,
D9061F6A25FF2DC000540CD8 /* GeometryComponent.swift in Sources */,
D94B6198261973EA0044BD34 /* GridBlockContainerComponent.swift in Sources */,
D9044C47264521DC00DB5A13 /* OptionsScreenNode.swift in Sources */,
D9474F2F25F4C6CF0088CAD6 /* GameResolutionState.swift in Sources */,
Expand Down Expand Up @@ -443,13 +443,13 @@
buildActionMask = 2147483647;
files = (
D9241B83265A3E4F009B4FBD /* BlockTransformComponent.swift in Sources */,
D9241B84265A3E4F009B4FBD /* GeometryComponent.swift in Sources */,
D9241B85265A3E4F009B4FBD /* GridBlockContainerComponent.swift in Sources */,
D9241B86265A3E4F009B4FBD /* GridTransformComponent.swift in Sources */,
D9241B87265A3E4F009B4FBD /* PieceComponent.swift in Sources */,
D9241B88265A3E4F009B4FBD /* GameFallingPieceState.swift in Sources */,
D9241B89265A3E4F009B4FBD /* GameIdleState.swift in Sources */,
D9241B8A265A3E4F009B4FBD /* GameOverState.swift in Sources */,
D990A41A26617BD2002864B8 /* BlinkComponent.swift in Sources */,
D9241B8B265A3E4F009B4FBD /* GameResolutionState.swift in Sources */,
D9241B8C265A3E4F009B4FBD /* GameStateMachine.swift in Sources */,
D9241B8D265A3E4F009B4FBD /* GameMainTitleState.swift in Sources */,
Expand Down
Binary file modified Shared/Background.sks
Binary file not shown.
40 changes: 40 additions & 0 deletions Shared/Sources/Components/BlinkComponent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// BlinkComponent.swift
// SKTetris
//
// Created by Christophe SAUVEUR on 28/05/2021.
//

import GameplayKit

class BlinkComponent: GKComponent {

private let BLINK_TIME_INTERVAL = 0.1
private let MAX_BLINK_PHASE = 10

var blinking = false
private var blinkTimeBuffer: TimeInterval = 0
private var blinkPhase = 0

override func update(deltaTime seconds: TimeInterval) {
if blinking {
blinkTimeBuffer += seconds
while blinkTimeBuffer > BLINK_TIME_INTERVAL && blinkPhase < MAX_BLINK_PHASE {
blinkTimeBuffer -= BLINK_TIME_INTERVAL
blinkPhase = min(blinkPhase + 1, MAX_BLINK_PHASE)
}

guard let skNode = entity?.component(ofType: GKSKNodeComponent.self)?.node else {
return
}

if blinkPhase % 2 == 1 {
skNode.alpha = 0.5
}
else {
skNode.alpha = 1
}
}
}

}
6 changes: 5 additions & 1 deletion Shared/Sources/Components/BlockTransformComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class BlockTransformComponent: GKComponent {
}

private func updateNodePosition() -> Void {
entity!.component(ofType: GeometryComponent.self)!.skNode.position = BlockTools.transformCoordinatesFromGridToScene(coordinates)
guard let skNode = entity?.component(ofType: GKSKNodeComponent.self)?.node else {
return
}

skNode.position = BlockTools.transformCoordinatesFromGridToScene(coordinates)
}

}
48 changes: 0 additions & 48 deletions Shared/Sources/Components/GeometryComponent.swift

This file was deleted.

15 changes: 9 additions & 6 deletions Shared/Sources/Components/GridBlockContainerComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@

import GameplayKit

@objc(GridBlockContainerComponent)
class GridBlockContainerComponent: GKComponent {

private var blocks: [GKEntity] = []

override class var supportsSecureCoding: Bool { true }

func addBlocks(_ newBlocks: [GKEntity]) -> Void {
let gridGeometryComponent = entity!.component(ofType: GeometryComponent.self)!
let gridSKNodeComponent = entity!.component(ofType: GKSKNodeComponent.self)!

for block in newBlocks {
let blockGeometryComponent = block.component(ofType: GeometryComponent.self)!
blockGeometryComponent.skNode.removeFromParent()
gridGeometryComponent.skNode.addChild(blockGeometryComponent.skNode)
let blockSKNodeComponent = block.component(ofType: GKSKNodeComponent.self)!
blockSKNodeComponent.node.removeFromParent()
gridSKNodeComponent.node.addChild(blockSKNodeComponent.node)

self.blocks.append(block)
}
Expand All @@ -29,8 +32,8 @@ class GridBlockContainerComponent: GKComponent {

func removeAllBlocks() -> Void {
for block in blocks {
let geometry = block.component(ofType: GeometryComponent.self)!
geometry.skNode.removeFromParent()
let skNodeComponent = block.component(ofType: GKSKNodeComponent.self)!
skNodeComponent.node.removeFromParent()
}
blocks.removeAll()
}
Expand Down
12 changes: 3 additions & 9 deletions Shared/Sources/Components/GridTransformComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@

import GameplayKit

@objc(GridTransformComponent)
class GridTransformComponent: GKComponent {

let size: CGSize
@GKInspectable var size: CGSize = CGSize()

init(size: CGSize) {
self.size = size
super.init()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override class var supportsSecureCoding: Bool { true }

func getAdjustedCoordinates(forPiece piece: GKEntity, at coordinates: GridCoordinates) -> GridCoordinates {
let pieceComponent = piece.component(ofType: PieceComponent.self)!
Expand Down
20 changes: 12 additions & 8 deletions Shared/Sources/Components/PieceComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class PieceComponent: GKComponent {
newCoordinateList.append(newCoordinates + pivotCoordinates)
}

let gridComponent = GameScene.grid.component(ofType: GridBlockContainerComponent.self)!
let gridComponent = GameScene.grid!.component(ofType: GridBlockContainerComponent.self)!
if gridComponent.validateCoordinates(coordinatesList: newCoordinateList) {
for i in 0..<newCoordinateList.count {
blocks[i].component(ofType: BlockTransformComponent.self)!.coordinates = newCoordinateList[i]
Expand All @@ -93,7 +93,7 @@ class PieceComponent: GKComponent {
newCoordinateList.append(newCoordinates + pivotCoordinates)
}

let gridComponent = GameScene.grid.component(ofType: GridBlockContainerComponent.self)!
let gridComponent = GameScene.grid!.component(ofType: GridBlockContainerComponent.self)!
if gridComponent.validateCoordinates(coordinatesList: newCoordinateList) {
for i in 0..<newCoordinateList.count {
blocks[i].component(ofType: BlockTransformComponent.self)!.coordinates = newCoordinateList[i]
Expand Down Expand Up @@ -147,15 +147,18 @@ class PieceComponent: GKComponent {
}

private func generateBlockEntities() -> Void {
let rootNode = entity!.component(ofType: GeometryComponent.self)!.skNode
guard let rootNode = entity?.component(ofType: GKSKNodeComponent.self)?.node else {
return
}

let texture = BlockTools.mainAtlas.textureNamed(model.type.textureName)
for offset in model.gridOffsets {
let sprite = SKSpriteNode(texture: texture)

let blockEntity = GKEntity()
let geometryComponent = GeometryComponent(withNode: sprite)
blockEntity.addComponent(geometryComponent)
let skNodeComponent = GKSKNodeComponent(node: sprite)
blockEntity.addComponent(skNodeComponent)
blockEntity.addComponent(BlinkComponent())
let blockComponent = BlockTransformComponent(atCoordinates: offset)
blockEntity.addComponent(blockComponent)

Expand All @@ -165,7 +168,7 @@ class PieceComponent: GKComponent {
}

override func update(deltaTime seconds: TimeInterval) {
let grid = GameScene.grid.component(ofType: GridBlockContainerComponent.self)!
let grid = GameScene.grid!.component(ofType: GridBlockContainerComponent.self)!
var validUpdate = true

for i in 0..<blocks.count {
Expand Down Expand Up @@ -225,8 +228,9 @@ class PieceComponent: GKComponent {
let entity = GKEntity()

let rootNode = SKNode()
let geometryComponent = GeometryComponent(withNode: rootNode)
entity.addComponent(geometryComponent)

let skNodeComponent = GKSKNodeComponent(node: rootNode)
entity.addComponent(skNodeComponent)

let pieceComponent = PieceComponent(ofType: type)
entity.addComponent(pieceComponent)
Expand Down
Loading

0 comments on commit ef8a53f

Please sign in to comment.