scud
scud

Reputation: 21

iPad's mobile safari crashing on canvas-based game (easeljs, soundjs, preloadjs)

I've done quite a bit of searching, so please forgive me if this has been asked before (I couldn't seem to find the right phrasing, if this is the case).

I have converted a quiz game from Flash to html5 using the createjs suite of libraries, and it is functioning suitably well on android devices and iPhones (tested on an iPhone 4s and 5c). However, it appears to be crashing on an iPad whenever I try and load it.

As I am packaging the game in cocoonjs for mobile deployment, I first thought the issue lied somewhere in the conversion process, but the same issue is encountered when I visit the URL on an iPad, leading me to believe the issue must be somewhere in my code.

The code itself uses a loadManifest to preload the image assets for the game and the opening audio file. There are approximately 170 assets loaded in this queue. The files are loaded using an onLoad method from the body tag and call loadFiles(), which looks like this (truncated for the multitude of image assets loaded in the manifest):

    var queue = new createjs.LoadQueue(true);
var manifest = [
    {id:"gameintro", src:"audio/intro.mp3"},
    {src:"images/Path.png"},
    ...
    {src:"images/owl.png"}
];
queue.loadManifest(manifest);
queue.setMaxConnections(5);
queue.addEventListener("complete", loadComplete);

    function loadAll() {
        document.getElementById('canvas').style.backgroundImage="url('images/splash.png')";
        canvas = document.getElementById('canvas');
        canvas.height = H;
        canvas.width = W;
        stage = new createjs.Stage("canvas");
        var loadingText = new createjs.Text("Loading...", "bold 30px Arial", "#9d3202");
        loadingText.x = 350;
        loadingText.y = 585;
        loadingText.textBaseline = "alphabetic";
        stage.addChild(loadingText);
        stage.update();
        while (manifest.length > 0) {
            loadAnother();
        }
        //console.log('done');
    }

    function loadAnother() {
        // Get the next manifest item, and load it
        var item = manifest.shift();
        queue.loadFile(item);

        // If we have no more items, disable the UI.
        if (manifest.length == 0) {
            //do nothing
        }
    }
    function loadComplete()
    {
        stage.removeAllChildren();
        var clickToPlay = new createjs.Bitmap("images/clicktoplay.png");
        clickToPlay.x = 350;
        clickToPlay.y = 565;
        clickToPlay.textBaseline = "alphabetic";
        stage.addChild(clickToPlay);
        stage.update();
        canvas.addEventListener("click", function(event) {
            event.target.removeEventListener(event.type, arguments.callee);
            createjs.Sound.registerSound({id:"gameintro", src:"audio/intro.mp3"});
            createjs.Sound.addEventListener("fileload", function(event){
                    event.target.removeEventListener(event.type, arguments.callee);
                    init(); 
                });

        });
    }

    loadAll();
};

The init function that runs after this loads the remaining audio files (of which there are many ~ 160 mp3's) and starts the opening animation. The code for that section is as follows:

    function init(){
        createjs.Sound.registerSound({id:"meintroduction", src:"audio/Mentor/ME1.mp3"});

        ...

        createjs.Sound.registerSound({id:"jennyfalse3", src:"audio/Pirate_Jenny/PJE10.mp3"});
        document.getElementById('canvas').style.background="#B5D7ED";
        canvas = document.getElementById('canvas');
        canvas.height = H;
        canvas.width = W;
        stage = new createjs.Stage("canvas");
        //add path
        path = new createjs.Bitmap("images/Path.png");
        path.x = 0;
        path.y = 0;
        stage.addChild(path);

        //add sun
        sun = new createjs.Bitmap("images/sun.png");
        sun.x = 800;
        sun.y = 600;
        stage.addChild(sun);

        //add pinkcloud
        pinkcloud = new createjs.Bitmap("images/pinkcloud.png");
        pinkcloud.x = -4;
        pinkcloud.y = 150;
        stage.addChild(pinkcloud);
        //add bluecloud
        bluecloud = new createjs.Bitmap("images/bluecloud.png");
        bluecloud.x = -4;
        bluecloud.y = 250;
        stage.addChild(bluecloud);

        //add farisland
        farisland = new createjs.Bitmap("images/farisland.png");
        farisland.x = 600;
        farisland.y = 180;
        stage.addChild(farisland);
        //add backwave
        backwave = new createjs.Bitmap("images/backwave.png");
        backwave.x = -4;
        backwave.y = 420;
        stage.addChild(backwave);
        //shark
        shark = new createjs.Bitmap("images/shark.png");
        shark.x = 900;
        shark.y = 600;
        stage.addChild(shark);
        //fish3
        fish3 = new createjs.Bitmap("images/fish3.png");
        fish3.x = 800;
        fish3.y = 600;
        stage.addChild(fish3);
        //add middlewave
        middlewave = new createjs.Bitmap("images/middlewave.png");
        middlewave.x = -800;
        middlewave.y = 450;
        stage.addChild(middlewave);
        //add ship
        pirateship = new createjs.Bitmap("images/pirateship.png");
        pirateship.x = -500;
        pirateship.y = 400;//445x384
        pirateship.regX = 445/2;
        pirateship.regY = 384/2;
        stage.addChild(pirateship);
        //fish1
        fish1 = new createjs.Bitmap("images/fish1.png");
        fish1.x = 800;
        fish1.y = 600;
        stage.addChild(fish1);
        //fish1
        fish2 = new createjs.Bitmap("images/fish2.png");
        fish2.x = 900;
        fish2.y = 700;
        stage.addChild(fish2);
        //add frontwave
        frontwave = new createjs.Bitmap("images/frontwave.png");
        frontwave.x = -4;
        frontwave.y = 500;
        stage.addChild(frontwave);
        //bird
        bird1 = new createjs.Bitmap("images/bird.png");
        bird1.x = 0;
        bird1.y = 0;
        bird1.scaleX = -1;
        stage.addChild(bird1);
        bird2 = new createjs.Bitmap("images/bird.png");
        bird2.x = 800;
        bird2.y = 0;
        stage.addChild(bird2);
        //add island
        island = new createjs.Bitmap("images/island.png");
        island.x = 800;
        island.y = 200;
        stage.addChild(island); 
        //add setsail
        setsail = new createjs.Bitmap("images/Setsail.png");
        setsail.x = -358;
        setsail.y = 80;
        createjs.Tween.get(setsail).to({alpha: 0,},0);
        stage.addChild(setsail);
        setsail1 = new createjs.Bitmap("images/Setsail.png");
        setsail1.x = 350;
        setsail1.y = 80;
        //add butwatchout
        butwatchout = new createjs.Bitmap("images/Butwatchout.png");
        butwatchout.x = -358;
        butwatchout.y = 300;
        createjs.Tween.get(butwatchout).to({alpha: 0,},0);
        //stage.addChild(butwatchout);
        butwatchout1 = new createjs.Bitmap("images/Butwatchout.png");
        butwatchout1.x = 200;
        butwatchout1.y = 300;
        setTimeout(function(){createjs.Sound.play("gameintro");},1500);
        fn = createjs.Ticker.on("tick", tick);
        createjs.Ticker.setFPS(80);
        createjs.Ticker.addEventListener("tick", stage );
    }

The ticker then uses some basic rotations and tweens to move things about, and also employs some alpha filters to manage the transparency of certain assets (like the front wave on the ship). After all this is finished, the user then progresses into the actual game, which uses some very basic createjs.Bitmaps to add the elements to the stage, along with Sound.play and some SpriteSheets for the rudimentary animations like blinking and mouth-movements for the quizzers. However, the whole thing doesn't make it past the opening sequence on an iPad.

If anyone could take a look (amateurgamingleague.com/pirates/english) and give me a bit of insight as to where I'm messing up, out would be greatly appreciated!!

Thank you!

Upvotes: 0

Views: 552

Answers (2)

Drizzt
Drizzt

Reputation: 51

I got the same issue. Try to use slash before the directory like

var manifest = [
{id:"gameintro", src:"/audio/intro.mp3"},
{src:"/images/Path.png"},
...
{src:"/images/owl.png"}

];

Upvotes: 0

Ferry Kranenburg
Ferry Kranenburg

Reputation: 2635

I have had the same crashes on Ipad (2). It even did delete all session cookies and my users where logged out...

The problem is the amount of sounds you're preloading (or how big they are, not sure). Change your code to not preload so many audio anymore, and load them on demand (when user clicks on something) if possible. I also needed to start the game with a click/touch/user event before any sound could be played.

Upvotes: 1

Related Questions