Skip to content

Instantly share code, notes, and snippets.

@SaganRitual
Created February 4, 2019 14:37
Show Gist options
  • Save SaganRitual/b962d8e1757409e55493b25df2f3d787 to your computer and use it in GitHub Desktop.
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
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 }
}
}
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] }
}
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()!
}
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