I have the following code:
GameScene.swift
import SpriteKit
import GameKit
class GameScene : SKScene {
var circleHolder:CircleHolder = CircleHolder()
override func didMove(to view: SKView) {
self.addChild(circleHolder)
}
}
CircleHolder.swift
import Foundation
import SpriteKit
class CircleHolder : SKNode {
var circles:[Circle] = [Circle]()
override init() {
super.init()
var image:UIImage = UIImage(named: "Circles")!
let width = Int(image.size.width)
let height = Int(image.size.height)
if let cfData = image.cgImage?.dataProvider?.data, let pointer = CFDataGetBytePtr(cfData) {
for x in 0..<width {
for y in 0..<height {
let pixelAddress = ((Int(image.size.width) * y) + x ) * 4
let r = CGFloat(pointer.advanced(by: pixelAddress).pointee) / CGFloat(255.0)
let g = CGFloat(pointer.advanced(by: pixelAddress + 1).pointee) / CGFloat(255.0)
let b = CGFloat(pointer.advanced(by: pixelAddress + 2).pointee) / CGFloat(255.0)
let a = CGFloat(pointer.advanced(by: pixelAddress + 3).pointee) / CGFloat(255.0)
let color = UIColor(red: r, green: g, blue: b, alpha: a)
var c = Circle(x: CGFloat(x), y: CGFloat(y), color: color)
circles.append(c)
self.addChild(c)
}
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Circle.swift
import Foundation
import SpriteKit
class Circle : SKNode {
var circle:SKShapeNode?
init(x:CGFloat, y:CGFloat, color:UIColor) {
super.init()
circle = SKShapeNode(circleOfRadius: 1)
circle?.fillColor = color
circle?.position.x = x
circle?.position.y = y
circle?.lineWidth = 0
self.addChild(circle!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I'm trying to place solid circles on my scene to 'recreate' the image in UIImage. This is the image I'm trying to recreate:
but I end up with this:
Can anyone point out the error in my logic?
It looks like your image doesn't have the properties you're expecting. It may have an alpha channel or something else that's changing the byte dimensions.
Instead of assuming 4 bytes per pixel, query the image for the actual properties:
let bytesPerRow = image.cgImage!.bytesPerRow
let bitsPerPixel = image.cgImage!.bitsPerPixel
let bitsPerComponent = image.cgImage!.bitsPerComponent
let bytesPerPixel = bitsPerPixel / bitsPerComponent
Then use those properties to calculate the pixel address:
let pixelAddress = y * bytesPerRow + x * bytesPerPixel