Using SpriteKit within a Screensaver using TextureAtlases (SWIFT 3)

219 views Asked by At

I've made a simple Screensaver using SWIFT 3 and SpriteKit.

I can get the scene to display but when I try to apply the texture atlas and animate it I get a red X with the animation instead of the actual image.

The debugger has the following error:

2016-12-15 09:35:29.131724 ScreenSaverEngine[1819:52037] Texture Atlas 'Flyers' cannot be found.

I'm stumped -- is it not possible to use texture atlas within SpriteKit that runs within a screensaver?

More details about the project:

  • created a texture atlas using TexturePacker -- confirmed the texture atlas works within iOS test SpriteKit app.
  • using example SWIFT3 code from the TexturePacker site.

UPDATE 12/15/16: Rickster mentioned that the bundle.main of a screensaver/plugin is not my bundle but the host apps bundle. Thus, my issue is I'm trying to load the assets from the screensaverengine.app bundle instead of my own and well, that will give me a "cannot be found".

I believe in Flyer.swift (see code below), I need to reference and load the Flyers.atlasc from my bundle. Anyone know how that syntax needs to look?

From what I gather, I need to reference my app bundle somehow here:

// load texture atlas
let textureAtlas = SKTextureAtlas(named: "Flyers") // << This is trying to find it in the screensaverengine.app bundle and not where it actually lives in my bundle.

Code:

import SpriteKit
import Cocoa

class GameScene: SKScene
{
    let sheet = Flyers()
    var sequence: SKAction?

    override var acceptsFirstResponder: Bool { return false }

    override func didMove(to view: SKView)
    {
        self.resignFirstResponder()
        self.isUserInteractionEnabled=false

        /* Setup your scene here */
        backgroundColor = (NSColor.black)

        // in the first animation CapGuy walks from left to right, in the second one he turns from right to left
        let fly = SKAction.animate(with: sheet.flyer(), timePerFrame: 0.033)

        // to walk over the complete iPad display, we have to repeat the animation
        let flyAnim = SKAction.repeat(fly, count: 6)

        // we define two actions to move the sprite from left to right, and back;
        let moveRight = SKAction.moveTo(x: 900, duration: flyAnim.duration)
        let moveLeft  = SKAction.moveTo(x: 100, duration: flyAnim.duration)

        // as we have only an animation with the CapGuy walking from left to right, we use a 'scale' action
        // to get a mirrored animation.
        let mirrorDirection = SKAction.scaleX(to: -1, y:1, duration:0.0)
        let resetDirection  = SKAction.scaleX(to: 1,  y:1, duration:0.0);

        // Action within a group are executed in parallel:
        let flyAndMoveRight = SKAction.group([resetDirection,  flyAnim, moveRight]);
        let flyAndMoveLeft  = SKAction.group([mirrorDirection, flyAnim, moveLeft]);

        // now we combine the walk+turn actions into a sequence, and repeat it forever
        sequence = SKAction.repeatForever(SKAction.sequence([flyAndMoveRight, flyAndMoveLeft]));

        // each time the user touches the screen, we create a new sprite, set its position, ...
        let sprite = SKSpriteNode(texture: sheet.flyer1())
        sprite.position = CGPoint(x: 100.0, y: CGFloat(arc4random() % 100) + 200.0)

        // ... attach the action with the walk animation, and add it to our scene
        sprite.run(sequence!)
        addChild(sprite)



    }


    override func update(_ currentTime: CFTimeInterval)
    {
        /* Called before each frame is rendered */
        /*self.backgroundColor = NSColor(calibratedHue: 0.0, saturation: 0.0, brightness: CGFloat(0.5 + (sin(currentTime) * 0.5)), alpha: 1.0)*/
    }
}

Here is the Flyers.swift code:

// ---------------------------------------
// Sprite definitions for 'Flyers'
// Generated with TexturePacker 4.3.1
//
// http://www.codeandweb.com/texturepacker
// ---------------------------------------

import SpriteKit


class Flyers {

    // sprite names
    let FLYER1 = "flyer1"
    let FLYER2 = "flyer2"
    let FLYER3 = "flyer3"
    let FLYER4 = "flyer4"
    let TOAST  = "toast"


    // load texture atlas
    let textureAtlas = SKTextureAtlas(named: "Flyers")


    // individual texture objects
    func flyer1() -> SKTexture { return textureAtlas.textureNamed(FLYER1) }
    func flyer2() -> SKTexture { return textureAtlas.textureNamed(FLYER2) }
    func flyer3() -> SKTexture { return textureAtlas.textureNamed(FLYER3) }
    func flyer4() -> SKTexture { return textureAtlas.textureNamed(FLYER4) }
    func toast() -> SKTexture  { return textureAtlas.textureNamed(TOAST) }


    // texture arrays for animations
    func flyer() -> [SKTexture] {
        return [
            flyer1(),
            flyer2(),
            flyer3(),
            flyer4(),
            flyer3(),
            flyer2()
        ]
    }


}

I have a Flyers.atlasc generated by TexturePacker imported into the project as a blue folder.

enter image description here

0

There are 0 answers