Created
February 4, 2019 14:37
-
-
Save SaganRitual/b962d8e1757409e55493b25df2f3d787 to your computer and use it in GitHub Desktop.
SpriteKit starter, draw grid, detect touches on sprites, cause neighboring sprites to react
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import SpriteKit | |
class Box { | |
let sprite: SKShapeNode | |
let cellAddress: XYPair | |
var position: CGPoint { | |
get { return sprite.position } | |
set { sprite.position = newValue } | |
} | |
init(position: CGPoint, cellAddress: XYPair, dimensions: CGSize) { | |
self.cellAddress = cellAddress | |
self.sprite = SKShapeNode(rectOf: dimensions) | |
self.sprite.position = position | |
self.sprite.strokeColor = .black | |
let label = SKLabelNode(text: "Click me!") | |
label.fontColor = .black | |
label.fontName = "Courier New" | |
label.fontSize = 16.0 * (10.0 / CGFloat(max(gridWidth, gridHeight))) | |
self.sprite.addChild(label) | |
} | |
func addToScene(_ scene: SKScene) { | |
scene.addChild(self.sprite) | |
} | |
func beFancy() { | |
sprite.alpha = 0 | |
sprite.fillColor = getRandomColor() | |
sprite.children[0].alpha = 0 | |
let direction: CGFloat = Bool.random() ? 2.0 : -2.0 | |
let rotate = SKAction.rotate(byAngle: direction * CGFloat.pi, duration: 0.5) | |
let fade = SKAction.fadeAlpha(to: 1.0, duration: 0.5) | |
sprite.run(SKAction.group([rotate, fade])) { self.sprite.children[0].alpha = 1 } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import SpriteKit | |
// Change these to see different grid sizes | |
let gridWidth = 10 | |
let gridHeight = 10 | |
class CellGrid { | |
let boxes: [[Box]] | |
init(_ scene: SKScene) { | |
let boxWidth = scene.size.width / CGFloat(gridWidth) | |
let boxHeight = scene.size.height / CGFloat(gridHeight) | |
let boxDimensions = CGSize(width: boxWidth, height: boxHeight) | |
let b: [[Box]] = (0..<gridWidth).map { gridX in | |
let sceneX = (CGFloat(gridX) + 0.5) * boxWidth | |
return (0..<gridHeight).map { gridY in | |
let sceneY = (CGFloat(gridY) + 0.5) * boxHeight | |
return Box( | |
position: CGPoint(x: sceneX, y: sceneY), | |
cellAddress: XYPair(gridX, gridY), | |
dimensions: boxDimensions | |
) | |
} | |
} | |
self.boxes = b | |
self.boxes.joined().forEach { box in | |
box.sprite.userData = ["Box" : box] | |
scene.addChild(box.sprite) | |
} | |
} | |
subscript(_ x: Int, _ y: Int) -> Box { return self.boxes[x][y] } | |
subscript(_ cellAddress: XYPair) -> Box { return self.boxes[cellAddress.x][cellAddress.y] } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AppKit | |
import Foundation | |
func getColorName(_ color: NSColor) -> String { | |
switch color { | |
case .black: return "black" | |
case .blue: return "blue" | |
case .brown: return "brown" | |
case .white: return "white" | |
case .darkGray: return "darkGray" | |
case .lightGray: return "lightGray" | |
case .orange: return "orange" | |
case .purple: return "purple" | |
case .gray: return "gray" | |
case .red: return "red" | |
case .green: return "green" | |
case .blue: return "blue" | |
case .cyan: return "cyan" | |
case .magenta: return "magenta" | |
case .yellow: return "yellow" | |
default: return String(describing: color) | |
} | |
} | |
func getRandomColor() -> NSColor { | |
return [ | |
NSColor.black, NSColor.white, NSColor.gray, NSColor.red, NSColor.green, | |
NSColor.blue, NSColor.cyan, NSColor.magenta, NSColor.yellow, NSColor.brown, | |
NSColor.darkGray, NSColor.lightGray, NSColor.orange, NSColor.purple | |
].randomElement()! | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SpriteKit | |
import GameplayKit | |
struct XYPair { | |
let x: Int | |
let y: Int | |
init(_ x: Int, _ y: Int) { self.x = x; self.y = y } | |
static func + (_ lhs: XYPair, _ rhs: XYPair) -> XYPair { | |
return XYPair(lhs.x + rhs.x, lhs.y + rhs.y) | |
} | |
} | |
class GameScene: SKScene { | |
var cellGrid: CellGrid! | |
private func box(at position: CGPoint) -> Box? { | |
var someNode = nodes(at: position).first | |
if someNode is SKLabelNode { someNode = someNode!.parent } | |
guard let theSprite = someNode as? SKShapeNode else { return nil } | |
guard let theBox = theSprite.userData?["Box"] as? Box else { return nil } | |
return theBox | |
} | |
override func didMove(to view: SKView) { | |
self.anchorPoint = CGPoint(x: 0.0, y: 0.0) | |
self.backgroundColor = .white | |
cellGrid = CellGrid(self) | |
} | |
override func mouseUp(with event: NSEvent) { | |
self.touchUp(atPoint: event.location(in: self)) | |
} | |
func secondaryTouch(from primaryTouch: Box) { | |
let neighborOffsets = [ | |
XYPair(+0, +1), // North | |
XYPair(+1, +1), // Northeast | |
XYPair(+1, +0), // East | |
XYPair(+1, -1), // Southeast | |
XYPair(+0, -1), // South | |
XYPair(-1, -1), // Southwest | |
XYPair(-1, +0), // West | |
XYPair(-1, +1), // Northwest | |
] | |
neighborOffsets.forEach { | |
let neighborCellAddress = primaryTouch.cellAddress + $0 | |
if neighborCellAddress.x < 0 || neighborCellAddress.x >= gridWidth || | |
neighborCellAddress.y < 0 || neighborCellAddress.y >= gridHeight { | |
return | |
} | |
let neighborBox = cellGrid[neighborCellAddress] | |
neighborBox.beFancy() | |
} | |
} | |
func touchUp(atPoint pos : CGPoint) { | |
guard let clickedBox = box(at: pos) else { return } | |
clickedBox.sprite.fillColor = .blue | |
clickedBox.sprite.blendMode = .replace | |
secondaryTouch(from: clickedBox) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment