SKSpriteNode init(texture: atlas!.textureNamed("something") loading incorrectly on iPhone X

0

G'Day,

I have a problem that has appeared in a game I wrote for my kids. After some investigation I have "discovered" the following issue:

In the original game sprite are loaded via

let sprite = SKSpriteNode(texture: atlas!.textureNamed("something")

The texture atlas used has a large number of small textures, "images" in it. This results in a working and happy game on the older devices , iPhone 7, iPad Air, iPad Pro 12.9 inch. However on the iPhone X etc., and on the iPhone X simulator any of the images loaded from the atlas are displayed either as tiny little dots or not at all. There are no compiler errors and no runtime errors. I am assuming this is something to do with screen resolution, but what? If I load the images via an init(imageNamed: "something") call the self same images are correctly scaled and displayed. I have created a small stand alone program that illustrates this issue, code below: I also included two screen grabs showing the self same code loaded and running on an iPad and an iPhone Xsmax. The iPad image shows two platforms and the bunnies whilst the iPhone image shows them missing.

The two atlas files contain the platform and GEM and bunny images, the first atlas also contains about 90 small images in total. As you can see the first atlas images are incorrectly loaded, however if I reduce the number of images contained below about 30 images it all works. Oh and the compiler is not complaining or splitting the atlas files up either. So I suppose the final question is in two parts:

1 What is actually happening?

2 How to fix it?

The code is as follows:

//
//  GameScene.swift
//  SpriteTest
//
//
import SpriteKit

class GameScene: SKScene {

let player = SKSpriteNode(imageNamed: "player")
var atlas :SKTextureAtlas?
var atlas2 :SKTextureAtlas?

var tile : SKNode?
var tile2 : SKNode?

override func didMove(to view: SKView) {
    // White background for visibility


    backgroundColor = SKColor.white

    player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
    addChild(player)


// first platform "does not appear on iPhone X"

    atlas = SKTextureAtlas(named: "Tiles")
    tile = SKSpriteNode(texture: atlas!.textureNamed("platform"))
    tile?.zPosition = 50
    tile?.physicsBody?.isDynamic = true
    tile?.physicsBody?.affectedByGravity = false
    tile?.position = CGPoint(x: size.width * 0.1, y : size.height * 0.2)

    addChild(tile!)
     atlas2 = SKTextureAtlas(named: "Smallatlas")

// Second platform always appears

    tile2 = SKSpriteNode(texture: atlas2!.textureNamed("platform"))
    tile2?.zPosition = 50
    tile2?.physicsBody?.isDynamic = true
    tile2?.physicsBody?.affectedByGravity = false
    tile2?.position = CGPoint(x: size.width * 0.6, y : size.height * 0.2)

    addChild(tile2!)

    run(SKAction.repeatForever(
        SKAction.sequence([
            SKAction.run(addMonster),
            SKAction.wait(forDuration: 1.0)
            ])
    ))



}
func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}

func random(min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max - min) + min
}

func addMonster() {

    // First monster "bunny" does not appear on iPhone X

    let  monster = SKSpriteNode(texture: atlas!.textureNamed("chocolate-bunny150"))

    // Determine where to spawn the monster along the Y axis
    let actualY = random(min: monster.size.height/2, max: size.height - monster.size.height/2)

    // Position the monster slightly off-screen along the right edge,
    // and along a random position along the Y axis as calculated above
    monster.position = CGPoint(x: size.width + monster.size.width/2, y: actualY)

    // Add the monster to the scene
    addChild(monster)

    // Determine speed of the monster
    let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))

    // Create the actions
    let actionMove = SKAction.move(to: CGPoint(x: -monster.size.width/2, y: actualY),
                                   duration: TimeInterval(actualDuration))
    let actionMoveDone = SKAction.removeFromParent()
    monster.run(SKAction.sequence([actionMove, actionMoveDone]))
    addMonster2()
}
func addMonster2() {

    // Second monster always appears

    let  monster2 = SKSpriteNode(texture: atlas2!.textureNamed("gem"))

    // Determine where to spawn the monster along the Y axis
    let actualY = random(min: monster2.size.height/2, max: size.height - monster2.size.height/2)

    // Position the monster slightly off-screen along the right edge,
    // and along a random position along the Y axis as calculated above
    monster2.position = CGPoint(x: size.width + monster2.size.width/2, y: actualY)

    // Add the monster to the scene
    addChild(monster2)

    // Determine speed of the monster
    let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))

    // Create the actions
    let actionMove = SKAction.move(to: CGPoint(x: -monster2.size.width/2, y: actualY),
                                   duration: TimeInterval(actualDuration))
    let actionMoveDone = SKAction.removeFromParent()
    monster2.run(SKAction.sequence([actionMove, actionMoveDone]))
}
}

iPhone XS max screen grab "" iPad Screen grab

ios
iphone
swift
sprite-kit

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0