Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Last active May 1, 2025 00:09
Show Gist options
  • Save jweinst1/d4a06d90784d632353dab896b814fe5a to your computer and use it in GitHub Desktop.
Save jweinst1/d4a06d90784d632353dab896b814fe5a to your computer and use it in GitHub Desktop.
img atlas based game swift
//
// GameScene.swift
// FunScape
//
// Created by Joshua Weinstein on 4/26/25.
//
import SpriteKit
import GameplayKit
class GameScene: SKScene {
private var label : SKLabelNode?
private var spinnyNode : SKShapeNode?
private var playerNode : SKSpriteNode!
private var rockNode: SKSpriteNode!
private var upImgs : [SKTexture]!
private var downImgs : [SKTexture]!
private var rightImgs : [SKTexture]!
private var leftImgs : [SKTexture]!
private var miningImgs : [SKTexture]!
override func didMove(to view: SKView) {
let atlas = SKTextureAtlas(named: "player")
let f1 = atlas.textureNamed("tile_0_0.png")
let f2 = atlas.textureNamed("tile_0_1.png")
let f3 = atlas.textureNamed("tile_0_2.png")
let f4 = atlas.textureNamed("tile_0_3.png")
let f5 = atlas.textureNamed("tile_0_4.png")
let f6 = atlas.textureNamed("tile_0_5.png")
let f7 = atlas.textureNamed("tile_0_6.png")
let f8 = atlas.textureNamed("tile_0_7.png")
let f9 = atlas.textureNamed("tile_0_8.png")
let f10 = atlas.textureNamed("tile_0_9.png")
let f11 = atlas.textureNamed("tile_0_10.png")
let f12 = atlas.textureNamed("tile_0_11.png")
let f13 = atlas.textureNamed("tile_0_12.png")
let f14 = atlas.textureNamed("tile_0_13.png")
let f15 = atlas.textureNamed("tile_0_14.png")
let f16 = atlas.textureNamed("tile_0_15.png")
let m1 = atlas.textureNamed("mining1.png")
let m2 = atlas.textureNamed("mining2.png")
downImgs = [f1, f2, f3, f4]
rightImgs = [f5, f6, f7, f8]
upImgs = [f9, f10, f11, f12]
leftImgs = [f13, f14, f15, f16]
miningImgs = [m1, m2]
playerNode = SKSpriteNode(texture: f1)
playerNode.position = CGPoint(x: 0, y: 0)
playerNode.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 16, height: 16))
playerNode.physicsBody!.affectedByGravity = false
playerNode.physicsBody!.allowsRotation = false
playerNode.scale(to: CGSize(width: 64, height: 64))
addChild(playerNode)
rockNode = SKSpriteNode(imageNamed: "rock")
rockNode.position = CGPoint(x: 100, y:100)
rockNode.name = "rock"
rockNode.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 16, height: 16))
rockNode.physicsBody!.affectedByGravity = false
rockNode.physicsBody!.allowsRotation = false
rockNode.physicsBody!.isDynamic = false
rockNode.scale(to: CGSize(width: 64, height: 64))
addChild(rockNode)
// Get label node from scene and store it for use later
self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
if let label = self.label {
label.alpha = 0.0
label.run(SKAction.fadeIn(withDuration: 2.0))
}
// Create shape node to use during mouse interaction
let w = (self.size.width + self.size.height) * 0.05
self.spinnyNode = SKShapeNode.init(rectOf: CGSize.init(width: w, height: w), cornerRadius: w * 0.3)
if let spinnyNode = self.spinnyNode {
spinnyNode.lineWidth = 2.5
spinnyNode.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat(Double.pi), duration: 1)))
spinnyNode.run(SKAction.sequence([SKAction.wait(forDuration: 0.5),
SKAction.fadeOut(withDuration: 0.5),
SKAction.removeFromParent()]))
}
}
func touchDown(atPoint pos : CGPoint) {
foobar()
if let n = self.spinnyNode?.copy() as! SKShapeNode? {
n.position = pos
n.strokeColor = SKColor.green
self.addChild(n)
}
var tpos = pos
var isMining = false
for node in nodes(at: pos) {
if node.name == "rock" {
// target pos should be left of the rock
tpos = CGPoint(x:node.position.x - 20, y:node.position.y)
isMining = true
break
}
}
let posDiff = CGPoint(x: playerNode.position.x - tpos.x, y: playerNode.position.y - tpos.y)
var imgSet:[SKTexture] = []
//print(posDiff)
if posDiff.x < 0 {
if posDiff.y < 0 {
imgSet = upImgs
} else {
imgSet = rightImgs
}
} else {
if posDiff.y < 0 {
imgSet = leftImgs
} else {
imgSet = downImgs
}
}
let moving = SKAction.move(to: tpos, duration: 2)
let animate = SKAction.repeatForever(.animate(with: imgSet,
timePerFrame: 0.2,
resize: false,
restore: true))
playerNode.run(animate, withKey: "animate")
let block = SKAction.run {
self.playerNode.removeAction(forKey: "animate")
}
var acts = [moving, block]
let mining = SKAction.repeatForever(.animate(with: miningImgs, timePerFrame: 0.1, resize: false, restore: true))
let miningAct = SKAction.run {
self.playerNode.run(mining, withKey: "mining")
}
let miningRemove = SKAction.run {
let result = Int.random(in: 0...10)
if result % 2 == 0 {
print("Got an ore!")
self.playerNode.removeAction(forKey: "mining")
self.playerNode.removeAction(forKey: "mining_state")
} else {
print("No ore!")
}
}
let miningLoop = SKAction.repeatForever(.sequence([SKAction.wait(forDuration: 0.5), miningRemove]))
let miningLoopAct = SKAction.run {
self.playerNode.run(miningLoop, withKey: "mining_state")
}
let miningLoopGroup = SKAction.group([miningAct, miningLoopAct])
if isMining {
acts.append(miningLoopGroup)
}
playerNode.run(SKAction.sequence(acts))
}
func touchMoved(toPoint pos : CGPoint) {
if let n = self.spinnyNode?.copy() as! SKShapeNode? {
n.position = pos
n.strokeColor = SKColor.blue
self.addChild(n)
}
}
func touchUp(atPoint pos : CGPoint) {
if let n = self.spinnyNode?.copy() as! SKShapeNode? {
n.position = pos
n.strokeColor = SKColor.red
self.addChild(n)
}
}
override func mouseDown(with event: NSEvent) {
self.touchDown(atPoint: event.location(in: self))
}
override func mouseDragged(with event: NSEvent) {
self.touchMoved(toPoint: event.location(in: self))
}
override func mouseUp(with event: NSEvent) {
self.touchUp(atPoint: event.location(in: self))
}
override func keyDown(with event: NSEvent) {
switch event.keyCode {
case 0x31:
if let label = self.label {
label.run(SKAction.init(named: "Pulse")!, withKey: "fadeInOut")
}
default:
print("keyDown: \(event.characters!) keyCode: \(event.keyCode)")
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment