Created
January 29, 2019 15:36
-
-
Save SaganRitual/bcca55b671ea2e0125498d8b653de9f8 to your computer and use it in GitHub Desktop.
Another SpriteKit starter, some examples of how to use physics and actions
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 | |
func getColorName(_ color: NSColor) -> String { | |
switch color { | |
case .black: return "black" | |
case .white: return "white" | |
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 "Exotic" | |
} | |
} | |
func getRandomColor() -> NSColor { | |
return [ | |
NSColor.black, NSColor.white, NSColor.gray, NSColor.red, NSColor.green, | |
NSColor.blue, NSColor.cyan, NSColor.magenta, NSColor.yellow | |
].randomElement()! | |
} | |
class Box { | |
static var spinForward = SKAction.rotate(byAngle: 2 * CGFloat.pi, duration: 1.0) | |
static var spinBackward = SKAction.rotate(byAngle: 2 * CGFloat.pi, duration: 1.0).reversed() | |
let pBody: SKPhysicsBody | |
let sprite: SKShapeNode | |
var spinningForward = false | |
var position: CGPoint { | |
get { return sprite.position } | |
set { sprite.position = newValue } | |
} | |
init(dimensions: CGSize, color: SKColor) { | |
self.sprite = SKShapeNode(rectOf: dimensions) | |
self.sprite.fillColor = color | |
self.sprite.strokeColor = color | |
self.pBody = SKPhysicsBody(rectangleOf: dimensions) | |
self.pBody.isDynamic = true | |
self.pBody.categoryBitMask = 1 | |
self.pBody.collisionBitMask = 1 | |
self.pBody.contactTestBitMask = 1 | |
self.pBody.restitution = 1.0 | |
self.sprite.physicsBody = self.pBody | |
self.sprite.userData = ["Box" : self] | |
self.spinningForward = true | |
self.sprite.run(SKAction.repeatForever(Box.spinForward)) | |
self.flySomewhere() | |
} | |
func addToScene(_ scene: SKScene) { | |
scene.addChild(self.sprite) | |
} | |
func contact() { | |
if self.spinningForward { | |
self.sprite.run(SKAction.repeatForever(Box.spinBackward)) | |
} else { | |
self.sprite.run(SKAction.repeatForever(Box.spinForward)) | |
} | |
self.spinningForward = !self.spinningForward | |
flySomewhere() | |
} | |
func contact(by: Box) { | |
let hisPosition = by.sprite.position | |
let hisColor = by.sprite.fillColor | |
let hisSize = by.sprite.frame.size | |
self.sprite.removeAllActions() | |
self.sprite.removeAllChildren() | |
contact() | |
let px = Int(hisPosition.x) | |
let py = Int(hisPosition.y) | |
let sw = Int(hisSize.width) | |
let sh = Int(hisSize.height) | |
let pt = "\(px), \(py)" | |
let ct = getColorName(hisColor) | |
let st = "\(sw), \(sh)" | |
let positionLabel = SKLabelNode(text: pt) | |
let colorLabel = SKLabelNode(text: ct) | |
let sizeLabel = SKLabelNode(text: st) | |
positionLabel.position = CGPoint(x: 0, y: self.sprite.frame.size.height / 4.0) | |
setLabelDefaults(positionLabel) | |
colorLabel.position = CGPoint(x: 0, y: 0) | |
setLabelDefaults(colorLabel) | |
sizeLabel.position = CGPoint(x: 0, y: -self.sprite.frame.size.height / 4.0) | |
setLabelDefaults(sizeLabel) | |
self.sprite.addChild(positionLabel) | |
self.sprite.addChild(colorLabel) | |
self.sprite.addChild(sizeLabel) | |
self.sprite.fillColor = getRandomColor() | |
self.sprite.setScale(CGFloat.random(in: 0.5...1.5)) | |
} | |
func flySomewhere() { | |
let randomImpulseX = CGFloat.random(in: -500...500) | |
let randomImpulseY = CGFloat.random(in: -500...500) | |
self.pBody.velocity = CGVector(dx: randomImpulseX, dy: randomImpulseY) | |
} | |
func setLabelDefaults(_ label: SKLabelNode) { | |
label.fontSize *= 0.75 | |
label.color = .black | |
label.colorBlendFactor = 1.0 | |
label.fontName = "Courier New" | |
} | |
} | |
class Contact: NSObject, SKPhysicsContactDelegate { | |
func didBegin(_ contact: SKPhysicsContact) { | |
let bodyA = contact.bodyA | |
let bodyB = contact.bodyB | |
guard let spriteA = bodyA.node else { return } | |
guard let spriteB = bodyB.node else { return } | |
if let boxA = spriteA.userData?["Box"] as? Box { | |
if let boxB = spriteB.userData?["Box"] as? Box { | |
boxA.contact(by: boxB) | |
boxB.contact(by: boxA) | |
} else { | |
boxA.contact() | |
} | |
} else { | |
if let boxB = spriteB.userData?["Box"] as? Box { | |
boxB.contact() | |
} | |
} | |
} | |
} |
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 | |
class GameScene: SKScene { | |
var box1: Box! | |
var box2: Box! | |
var contact: SKPhysicsContactDelegate! | |
override func didMove(to view: SKView) { | |
self.contact = Contact() | |
let b1 = Box(dimensions: CGSize(width: 200, height: 200), color: .green) | |
let b2 = Box(dimensions: CGSize(width: 200, height: 200), color: .blue) | |
b1.position = CGPoint(x: 0.0, y: 200.0) | |
b2.position = CGPoint(x: 0.0, y: -200.0) | |
self.box1 = b1 | |
self.box2 = b2 | |
let scene = self | |
b1.addToScene(scene) | |
b2.addToScene(scene) | |
scene.physicsWorld.gravity = CGVector(dx: 0, dy: 0) | |
scene.physicsWorld.contactDelegate = contact | |
let boundary = SKPhysicsBody(edgeLoopFrom: scene.frame) | |
let boundaryNode = SKNode() | |
boundaryNode.physicsBody = boundary | |
scene.addChild(boundaryNode) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment