Sixmorphugus Posted March 29, 2015 Share Posted March 29, 2015 This stuff started happening when I added some UI stuff to our game, such as these window objects:// Message boxMsgBox = function (game, spawnX, spawnY, mWidth, type, var0, var1, callback, callbackObj) { spawnX = Math.floor(spawnX); spawnY = Math.floor(spawnY); this.timePlaced = game.time.time; this.destroyAfter = 0; this.advanceSound = game.add.audio("speach"); this.origin = new Phaser.Point(spawnX, spawnY); if(this.origin.x < (mWidth / 2) + 10) { this.origin.x = (mWidth / 2) + 10; } this.game = game; this.rect = this.game.add.sprite(spawnX, spawnY, "whiteout"); this.rect.alpha = 1; this.rect.tint = 0x111111; this.boarders = []; this.boarders.push(this.game.add.sprite(spawnX, spawnY, "whiteout")); this.boarders.push(this.game.add.sprite(spawnX, spawnY, "whiteout")); this.boarders.push(this.game.add.sprite(spawnX, spawnY, "whiteout")); this.boarders.push(this.game.add.sprite(spawnX, spawnY, "whiteout")); this.boarders[0].alpha = 0; this.boarders[1].alpha = 0; this.boarders[2].alpha = 0; this.boarders[3].alpha = 0; this.rect.width = 0; this.rect.height = 0; this.rect.alpha = 0; this.boxType = type; this.boxPerams1 = var0; this.boxPerams2 = var1; this.result = -1; this.deleteMe = false; this.referenceText = []; this.visibleText = []; this.maxWidth = mWidth; this.callback = callback; this.callbackObj = callbackObj; this.selectedOp = 0; this.opChange = false; this.opDown = true; this.calculateAppearence();}MsgBox.prototype.constructor = MsgBox;MsgBox.prototype.skipFade = function() { this.rect.alpha = 0.9; this.boarders[0].alpha = 0.9; this.boarders[1].alpha = 0.9; this.boarders[2].alpha = 0.9; this.boarders[3].alpha = 0.9;}MsgBox.prototype.prepareDelete = function() { this.deleteMe = true; // tell the uiManager to get rid of us in the next update tick // remove shared this.rect.destroy(); //this.advanceSound.destroy(); this.boarders[0].destroy(); this.boarders[1].destroy(); this.boarders[2].destroy(); this.boarders[3].destroy(); if(this.continuer != null) { this.continuer.destroy(); } // remove any text lines for(var i = 0; i < this.referenceText.length; i++) { this.referenceText[i].destroy(); this.visibleText[i].destroy(); } // call callbacks if(this.callback != null) { if(this.result != -1) { this.callback.call(this.callbackObj, this.result); } else { this.callback.call(this.callbackObj); } }}MsgBox.prototype.calculateTextLines = function() { var string = this.boxPerams1; var assumedLetterWidth = 12; var lettersToFillBox = Math.floor(this.maxWidth / assumedLetterWidth); var lCount = 0; for(var i = 0; i < string.length; i++) { lCount += 1; if(lCount > lettersToFillBox) { insertNewLineAt = i; while(string[insertNewLineAt] != " ") { insertNewLineAt -= 1; } string = string.replaceAt(insertNewLineAt, "#"); lCount = 0; } } var linesToCreate = string.split("#"); for(var i = 0; i < linesToCreate.length; i++) { this.referenceText.push(this.game.add.bitmapText(this.rect.x + 4, this.rect.y + 4 + (i * 22), "goldfishWhite", linesToCreate[i], 18)); this.visibleText.push(this.game.add.bitmapText(this.rect.x + 4, this.rect.y + 4 + (i * 22), "goldfishWhite", "", 18)); this.referenceText[i].updateTransform(); this.visibleText[i].updateTransform(); this.visibleText[i].stage = 0; this.referenceText[i].alpha = 0; }}MsgBox.prototype.calculateOptionLines = function() { var linesToCreate = this.boxPerams1; for(var i = 0; i < linesToCreate.length; i++) { this.referenceText.push(this.game.add.bitmapText(this.rect.x + 4, this.rect.y + 4 + (i * 22), "goldfishWhite", linesToCreate[i], 18)); this.visibleText.push(this.game.add.bitmapText(this.rect.x + 4, this.rect.y + 4 + (i * 22), "goldfishWhite", "", 18)); this.referenceText[i].updateTransform(); this.visibleText[i].updateTransform(); this.visibleText[i].stage = 0; this.referenceText[i].alpha = 0; // check if disabled if(this.boxPerams2[i] == -1) { // menu art this.visibleText[i].alpha = 0.1; this.referenceText[i].noSelect = true; } if(this.boxPerams2[i] == 0) { // disabled option this.visibleText[i].alpha = 0.5; this.referenceText[i].noSelect = true; } }}MsgBox.prototype.calculateAppearence = function() { if(this.boxType == 0) { // text box this.calculateTextLines(); // calculate the size that the box will be with the text inside. var width = this.maxWidth; //this.textLines[0].textWidth + 6; var height = (this.referenceText.length * 22) + 4; this.rect.width = width; this.rect.height = height; // calculate the position of the top left var boxX = this.origin.x - (Math.floor(width/2)); var boxY = this.origin.y - (height); this.rect.position.set(boxX, boxY); // add boarders this.boarders[0].position.set(boxX, boxY-2); this.boarders[0].width = width; this.boarders[0].height = 2; this.boarders[1].position.set(boxX, boxY + height); this.boarders[1].width = width; this.boarders[1].height = 2; this.boarders[2].position.set(boxX-2, boxY); this.boarders[2].width = 2; this.boarders[2].height = height; this.boarders[3].position.set(boxX + width, boxY); this.boarders[3].width = 2; this.boarders[3].height = height; // move all text into the new position for(var i = 0; i < this.referenceText.length; i++) { this.referenceText[i].position.set(boxX + 3, boxY + 3 + (i * 22)); this.visibleText[i].position.set(boxX + 3, boxY + 3 + (i * 22)); } if(this.boxPerams2 == 0) { // "press to continue" message box // place the continuer this.continuer = this.game.add.sprite(boxX, boxY, "speachCont"); this.continuer.alpha = 0; this.continuer.animations.add("flash", [0, 1], 2, true); this.continuer.animations.play("flash"); this.continuer.position.set((boxX + width) - 30, (boxY + height) - 5); } else if(this.boxPerams2 > 0) { // forever message box (must be removed manually) // schedule the destruction of this box. this.destroyAfter = this.boxPerams2; } // boxes with negative times stay forever and must be removed manually } else if(this.boxType == 1) { // do an options box this.calculateOptionLines(); // calculate the size that the box will be with the text inside. var width = this.maxWidth; //this.textLines[0].textWidth + 6; var height = (this.referenceText.length * 32) + 4; this.rect.width = width; this.rect.height = height; // calculate the position of the top left var boxX = this.origin.x - (Math.floor(width/2)); var boxY = this.origin.y - (height); this.rect.position.set(boxX, boxY); // add boarders this.boarders[0].position.set(boxX, boxY-2); this.boarders[0].width = width; this.boarders[0].height = 2; this.boarders[1].position.set(boxX, boxY + height); this.boarders[1].width = width; this.boarders[1].height = 2; this.boarders[2].position.set(boxX-2, boxY); this.boarders[2].width = 2; this.boarders[2].height = height; this.boarders[3].position.set(boxX + width, boxY); this.boarders[3].width = 2; this.boarders[3].height = height; // move all text into the new position for(var i = 0; i < this.referenceText.length; i++) { // center texts var xPos = (boxX + (width / 2)) - ((this.referenceText[i].text.length * 12) / 2) + 2; xPos = Math.floor(xPos); this.referenceText[i].position.set(xPos, boxY + 6 + (i * 32)); this.visibleText[i].position.set(xPos, boxY + 6 + (i * 32)); } // place the continuer - except NOW IT'S A SELECTOR OMFG MLG M8 WTFBBQ this.continuer = this.game.add.sprite(boxX, boxY, "speachSel"); this.continuer.animations.add("flash", [0, 1], 2, true); this.continuer.animations.play("flash"); }}MsgBox.prototype.inputUpdate = function() { if(this.deleteMe) { return; } if(this.boxType == 0) { // text box if(this.continuer == null) { return; } if(this.continuer.alpha == 1 && this.game.input.keyboard.downDuration(Phaser.Keyboard.ENTER, 1)) { // remove message this.prepareDelete(); return; } else if(this.game.input.keyboard.downDuration(Phaser.Keyboard.ENTER, 1)) { // autocomplete message for(var i = 0; i < this.referenceText.length; i++) { while(this.visibleText[i].stage < this.referenceText[i].text.length) { this.visibleText[i].stage += 1; this.visibleText[i].text = this.referenceText[i].text.slice(0, this.visibleText[i].stage); } } } } else if(this.boxType == 1) { if(this.game.input.keyboard.downDuration(Phaser.Keyboard.UP, 1) || this.game.input.keyboard.downDuration(Phaser.Keyboard.W, 1)) { this.opChange = true; this.opDown = false; if(BasicGame.playSFX) this.advanceSound.play('', 0, BasicGame.sfxVol); } else if(this.game.input.keyboard.downDuration(Phaser.Keyboard.DOWN, 1) || this.game.input.keyboard.downDuration(Phaser.Keyboard.S, 1)) { this.opChange = true; this.opDown = true; if(BasicGame.playSFX) this.advanceSound.play('', 0, BasicGame.sfxVol); } if(this.game.input.keyboard.downDuration(Phaser.Keyboard.ENTER, 1)) { this.result = this.selectedOp; this.prepareDelete(); } }}MsgBox.prototype.update = function() { // handle fade in if(this.rect.alpha < 0.8) { this.rect.alpha += 0.1; this.boarders[0].alpha += 0.1; this.boarders[1].alpha += 0.1; this.boarders[2].alpha += 0.1; this.boarders[3].alpha += 0.1; } if(this.deleteMe) { return; } // delete now? if(this.destroyAfter != 0) { if(this.game.time.elapsedSince(this.timePlaced) > this.destroyAfter) { this.prepareDelete(); } } if(this.boxType == 0) { // msg box // scroll the text in according to referenceText for(var i = 0; i < this.referenceText.length; i++) { if(this.visibleText[i].stage < this.referenceText[i].text.length) { for(var j = 0; j < BasicGame.dialogSpeed && this.visibleText[i].stage < this.referenceText[i].text.length; j++) { this.visibleText[i].stage += 1; this.visibleText[i].text = this.referenceText[i].text.slice(0, this.visibleText[i].stage); } if(!this.advanceSound.isPlaying) if(BasicGame.playSFX) this.advanceSound.play('', 0, BasicGame.sfxVol); return; } } if(this.continuer != null) { this.continuer.alpha = 1; } } else if(this.boxType == 1) { // all text appears immediately for(var i = 0; i < this.referenceText.length; i++) { if(this.visibleText[i].stage < this.referenceText[i].text.length) { this.visibleText[i].stage = this.referenceText[i].text.length; this.visibleText[i].text = this.referenceText[i].text.slice(0, this.visibleText[i].stage); } } // make sure the continuer selects a valid option while(this.referenceText[this.selectedOp].noSelect || this.opChange) { this.opChange = false; if(this.opDown) { this.selectedOp += 1; } else { this.selectedOp -= 1; } if(this.selectedOp > this.referenceText.length-1) { this.selectedOp = 0; } if(this.selectedOp < 0) { this.selectedOp = this.referenceText.length-1; } } // move continuer to selection this.continuer.position.set(this.rect.position.x - 8, this.referenceText[this.selectedOp].position.y); }}// UI Object - manages message boxes with unique lines of text + option selectionuiObject = function(game) { this.game = game; this.activeDialogs = []; this.sequenceData = []; this.sequenceStringCache = ""; this.sequenceLocation = new Phaser.Point(); this.sequenceCallback = null; this.sequenceCallbackObj = null;}uiObject.prototype.constructor = uiObject;uiObject.prototype.update = function() { // update active dialog if(this.activeDialogs.length > 0) { this.getActiveBox().inputUpdate(); // only the topmost dialog can take input } // make sure all the boxes do their normal thing for(var i = 0; i < this.activeDialogs.length; i++) { // if a dialog is done doing stuff, destroy it if(this.activeDialogs[i].deleteMe) { this.activeDialogs.splice(i, 1); continue; } this.activeDialogs[i].update(); } // sequences if(this.sequenceData.length > 0) { var advanceToNext = false; if(this.activeDialogs.length > 0) { // crowbar in an sanity check to prevent the otherwise inevitable crash var dlg = this.getActiveBox(); if(dlg.boxPerams1 != this.sequenceStringCache) { advanceToNext = true; // this box is irrelevant to us, we can continue our sequence } } else { // no dialogs are open but several are waiting to open. Open them! advanceToNext = true; } if(advanceToNext) { this.sequenceStringCache = this.sequenceData.pop(); // pop next msg off the array; if(this.sequenceFirst) { this.newMessageBox(this.sequenceLocation.x, this.sequenceLocation.y, this.sequenceStringCache, 0); this.sequenceFirst = false; } else if(this.sequenceData.length == 0) { // finish the sequence by calling the sequence callbacks box = this.newMessageBox(this.sequenceLocation.x, this.sequenceLocation.y, this.sequenceStringCache, 0, this.sequenceCallback, this.sequenceCallbackObj); box.skipFade(); } else { // otherwise, just display the message box = this.newMessageBox(this.sequenceLocation.x, this.sequenceLocation.y, this.sequenceStringCache, 0); box.skipFade(); } } }}uiObject.prototype.closeActiveBox = function() { this.activeDialogs[this.activeDialogs.length-1].prepareDelete();}uiObject.prototype.getActiveBox = function() { return this.activeDialogs[this.activeDialogs.length-1];}uiObject.prototype.newMessageBox = function(spawnX, spawnY, message, timeToVanish, callback, callbackObject) { boxLength = (message.length * 12) + 6; if(boxLength > 550) { boxLength = 550; } // timeToVanish can be set to 0 to make an advancable dialog, or -1 to make a static one. var box = new MsgBox(this.game, spawnX, spawnY, boxLength, 0, message, timeToVanish, callback, callbackObject); this.activeDialogs.push(box); return box;} uiObject.prototype.newOptionsBox = function(spawnX, spawnY, optionsArray, optionTypesArray, callback, callbackObject, selectedOp) { // which option is longest curLongestStringSize = 0; for(var i = 0; i < optionsArray.length; i++) { if(optionsArray[i].length > curLongestStringSize) { curLongestStringSize = optionsArray[i].length; } } boxLength = (curLongestStringSize * 12) + 6; var box = new MsgBox(this.game, spawnX, spawnY, boxLength, 1, optionsArray, optionTypesArray, callback, callbackObject); this.activeDialogs.push(box); if(selectedOp != null) { box.selectedOp = selectedOp; box.update(); } return box;}uiObject.prototype.sequenceMessageBox = function(spawnX, spawnY, messagesArray, callback, callbackObject) { this.sequenceData = messagesArray.reverse(); this.sequenceStringCache = ""; this.sequenceLocation.x = spawnX; this.sequenceLocation.y = spawnY; this.sequenceCallback = callback; this.sequenceCallbackObj = callbackObject; this.sequenceFirst = true;}And this splash screen:create: function () { if(!this.fail) { this.bootLogo = this.add.sprite(this.game.canvas.width / 2, this.game.canvas.height / 2, "mmLogo"); this.bootLogo.anchor.set(0.5, 0.5); this.bootLogo.alpha = 0; this.logoIn = true; } else { this.bootLogo = this.add.sprite(this.game.canvas.width / 2, this.game.canvas.height / 2, "mmNope"); this.bootLogo.anchor.set(0.5, 0.5); } }, update: function() { if(this.fail) { return; } if(this.logoIn) { if(this.bootLogo.alpha < 1) { this.bootLogo.alpha += 0.005; } else { this.logoIn = false; } } else { if(this.bootLogo.alpha > 0.1) { this.bootLogo.alpha -= 0.005; } else { this.game.state.start('Preloader'); } } if(this.game.input.keyboard.isDown(Phaser.Keyboard.ENTER)) { this.game.state.start('Preloader'); } }The problems themselves vary and I was only able to capture two. They happen in both WebGL mode and Canvas mode, with WebGL exhibiting the most stability.According to my tester, the following can also manifest:Ethnikoi: HOMEthnikoi: plus flickeringEthnikoi: plus framerapeEthnikoi: plus tile taeringSixsmorphugus: holy shitEthnikoi: plus missing backgroundEthnikoi: plus random artifactingI feel I should probably say I'm very new to Phaser and there are probably better ways to do a lot of the things I'm doing. I am very much willing to consider alternative methods in order to fix the problem. gingerbeardman 1 Link to comment Share on other sites More sharing options...
rich Posted March 30, 2015 Share Posted March 30, 2015 It's impossible to tell from this post alone what is going on. There's too much code which no-one here can run, and too little info. What size are your assets? (pixel dimensions, not file size). Does it work fine UNTIL you add the UI or was it messing up before that? What devices are you testing it on? etc. Link to comment Share on other sites More sharing options...
Sixmorphugus Posted March 30, 2015 Author Share Posted March 30, 2015 It's impossible to tell from this post alone what is going on. There's too much code which no-one here can run, and too little info. Sorry about that. Our project was very big when the bugs started happening, and for all I know it might not be the things I've included that cause them. I can send you the entire project file or parts of it if you need more information. What size are your assets? (pixel dimensions, not file size).Sizes vary. The mmLogo and mmNope sprites are 546x150 pixels. The speachSel sprites are each 32x16 and have animation frames that are 16x16. The goldfishWhite font is a bitmap font created via a texture atlas, and "whiteout" is simply a 1x1 image that is stretched and recoloured to form the boarders of dialog windows. The tileset of the world shown in the picture is 768x960 (each tile in it is 32x32), Does it work fine UNTIL you add the UI or was it messing up before that?When I test the game and do not instantuate any UI, no issues are present in the menu screen. The Game state always has issues, however, even if I remove the UI object; these issues seem much worse in Canvas mode. Occasionally, the game will crash completely and the message "Uncaught TypeError: Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'" will appear in the console, originating from PIXI. I have no idea what it means. Notably, upon crashing, all graphics glitches will revert just before the frame freezes; the background will correct itself, split tiles will rejoin etc. What devices are you testing it on? This game is for keyboard-and-mouse based systems only. If you try and run it on a mobile, it will display a message telling the user that the game is not compatible with mobile devices and not start. We are testing primarily on Windows 7, Windows 8 and Ubuntu using the Chrome browser. Sorry to be a bother. The project files are so big that I don't know how to give you everything without flooding the topic with information. Link to comment Share on other sites More sharing options...
Sixmorphugus Posted April 2, 2015 Author Share Posted April 2, 2015 Bump. Upgrading to Phaser 2.3 didn't fix anything. I don't know what I could have done to make the engine start acting like this. I've googled for examples of other Phaser games having issues like this one and can't find anything. Link to comment Share on other sites More sharing options...
rich Posted April 3, 2015 Share Posted April 3, 2015 Getting an error in 'createPattern' is interesting - that would come from the TilingSprite class in Pixi. Are you sure you're not doing something really expensive in a main loop? Like creating a TileSprite that is stupidly big, or using something like generateTexture or cacheBitmap on an object over and over? Link to comment Share on other sites More sharing options...
Sixmorphugus Posted April 3, 2015 Author Share Posted April 3, 2015 I think I found the cause. I created a state that shows a menu (one of the objects that will cause the glitches when present) and tracked the bug to a part of my uiObjectthis.rect = this.game.add.sprite(spawnX, spawnY, "whiteout");this.rect.alpha = 0;this.rect.tint = 0x111111;This sprite serves as the "background" of a GUI window or message box. It is 1x1 and I stretch it to the size it needs to be, calculating that size automatically (boarders of windows are created in a similar way but do not cause the bug for reasons I will give below). Text and buttons are laid on top. I found that:- Not rendering this perticular sprite at all would cause the bug not to happen.- Removing the tint on this sprite would prevent the bug.- Skipping the window creation phase that stretches this sprite to the window size would prevent the bug. Looking at other parts of the game where the rendering issues kick in, I have found that they all feature a Phaser.sprite that is tinted and stretched at the same time. Examples of this are backgrounds and screen fade transition surfaces. My current workaround is to manually create the base images the color I want instead of tinting them manually. I've tested this in a sandboxed project as well, with a transparent white sprite and a cyan tinted + stretched sprite on a white background. When the tinted + stretched sprite was being rendered, the transparent sprite would become opaque and have Hall Of Mirrors esque rendering issues. But yeah. Not sure if you can reproduce any of this, but for me (Phaser 3.3) very wierd stuff happens when I tint and stretch a sprite at the same time. EDIT: I just managed to get it to happen with a 1x1 tinted sprite without any stretching, too. This is all in Canvas mode, by the way. Link to comment Share on other sites More sharing options...
Sixmorphugus Posted April 3, 2015 Author Share Posted April 3, 2015 Oh, damn it. It still happens in the Game state when I create a MessWorld (wrapper for a tilemap)// World Object - special object that holds the world and all its layers, as well as storing collision data for objects such as actors to useMessWorld = function (game) { this.game = game; this.manager = null; this.data = null; this.musicData = null; this.music = ""; this.name = ""; this.loadedKey = ""; this.backgroundGroup = new Phaser.Group(game); this.colLayer = null; this.bgImage = null; this.lvlText = null; this.layer1 = null; this.layer2 = null; this.layer3 = null; this.layer4 = null; this.loaded = false;}MessWorld.prototype.constructor = MessWorld;MessWorld.prototype.setDebug = function(dbg) { this.layer4.debug = dbg;}MessWorld.prototype.loadArea = function(name) { console.log("[MESS] loading map " + name); if(this.manager != null) { this.unloadArea(); } if(this.name == null) { this.musicData.destroy(); this.musicData = null; this.music = ""; this.name = ""; return; } this.loaded = true; // load tilemap this.manager = this.game.add.tilemap(name); this.data = this.manager.properties; // load tileset this.manager.addTilesetImage("WorldTiles"); // load background image /* if(this.data.bgImage != null) { this.bgImage = this.game.add.tileSprite(0, 0, this.game.canvas.width, this.game.canvas.height, this.data.bgImage); this.bgImage.fixedToCamera = true; this.backgroundGroup.add(this.bgImage); } */ // load layers - don't bother with the paralax layer on phones if (BasicGame.parallaxEnabled) { //this.layer1 = this.manager.createLayer("backgroundParalax"); } //this.layer2 = this.manager.createLayer("backgroundFixed"); //this.layer3 = this.manager.createLayer("noCol"); this.layer4 = this.manager.createLayer("col"); //this.layer5 = this.manager.createLayer("foregroundFixed"); if (BasicGame.parallaxEnabled) { //this.backgroundGroup.add(this.layer1); } //this.backgroundGroup.add(this.layer2); //this.backgroundGroup.add(this.layer3); this.layer4.resizeWorld(); if (BasicGame.parallaxEnabled) { // don't bother with paralax on phones as it lags them to death if(this.data.xParalaxShift != null) { //this.layer1.scrollFactorX = this.data.xParalaxShift; } if(this.data.yParalaxShift != null) { //this.layer1.scrollFactorY = this.data.yParalaxShift; } } // setup COL layer this.manager.setCollisionBetween(0, 720, true, this.layer4); this.colLayer = this.layer4; if(BasicGame.displayColliders) //this.layer4.debug = true; // load map data this.game.stage.backgroundColor = this.data.bgcol; if(this.name != this.data.areaName) { this.name = this.data.areaName; this.lastNameUpdate = this.game.time.time; } // music! if(this.music != this.data.music) { this.music = this.data.music; if(this.musicData != null) { this.musicData.destroy(); this.musicData = null; } if(this.music != "") { this.musicData = this.game.add.audio(this.music); if(BasicGame.playMusic) this.musicData.play('', 0, BasicGame.musicVol, true); } } this.loadedKey = name;};MessWorld.prototype.unloadArea = function() { if (BasicGame.parallaxEnabled) { this.layer1.destroy(); // no paralax layer on phones } this.layer2.destroy(); this.layer3.destroy(); this.layer4.destroy(); this.layer5.destroy(); this.manager.destroy(); this.manager = null; if(this.bgImage != null) { this.bgImage.destroy(); this.bgImage = null; } this.loaded = false; this.loadedKey = "";};MessWorld.prototype.getInteractData = function(posX, posY) { for(var i = 0; i < this.data.interactableTiles.length; i++) { var tile = this.data.interactableTiles[i]; if(tile.posX == posX && tile.posY == posY) { // found return tile; } } // found nothing! fuck! return null;}MessWorld.prototype.doCollisionCheck = function(colObj) { if(this.manager == null) { return; } this.game.physics.arcade.collide(colObj, this.colLayer);}(note: currently commented to only load in 1 layer of the world for debugging - glitch still happens) Link to comment Share on other sites More sharing options...
Krummelz Posted April 5, 2015 Share Posted April 5, 2015 Hey guys, I'm getting the same thing, all of a sudden. My JS console logs this message: It seems to be a tileSprite problem. I have multiple game states - a tileSprite is used in one state to create a background for an input screen, and when the user clicks a button, they are taken to the next game state, which also creates the same tileSprite for the same background effect. The code I use in both states are the same: create: function () { game.add.tileSprite(0, 0, game.world.width, game.world.height, 'grass'); // .... etc}The error occurs when the user clicks the button to move from the first to the second state. If I comment out the line that creates the tileSprite in the second state, I don't get that error. I set my chrome dev tools to pause on exceptions, and on that line 11090 (as below), the source property on the baseTexture is null. The grass.png file is loaded once inside a preload state when the game starts, before any state uses it.this.__tilePattern = context.createPattern(this.tilingTexture.baseTexture.source, 'repeat');It's worth mentioning that I have just tried to upgrade from Phaser v2.2.0 to v2.3.0, when this started happening.My grass.png file is 32x32. Link to comment Share on other sites More sharing options...
Sixmorphugus Posted April 9, 2015 Author Share Posted April 9, 2015 Bump. Still have been unable to resolve the rendering issues with Tilemaps. Any help you can offer is appreciated. Notable: Some computers have no issues at all. Me and my friend's computers both have rendering bugs, but my laptop will run the game fine. Link to comment Share on other sites More sharing options...
jerejigga Posted April 10, 2015 Share Posted April 10, 2015 I have encountered the exact same issue as Krummelz! I too use identical TileSprites on separate Stages and when I transition from the first of these stages to the next, I get the same stack trace that Krummelz shows above. I also narrowed my problem down to the same source code line:this.__tilePattern = context.createPattern(this.tilingTexture.baseTexture.source, 'repeat');Taking a closer look, I found that this.tilingTexture.baseTexture.source is null when the second stage gets loaded. I tracked it down even further to the following stack trace. In the screenshot below, you will see exactly where this value gets set to null! I have compared the source code for 2.2.2 to 2.3.0 and found that the problem lies in a substantial change to Phaser.TileSprite.prototype.destroy. In 2.2.2, this method had a lot of custom Phaser code in it. In 2.3.0, it calls two other methods: Phaser.Component.Destroy.prototype.destroy.call(this, destroyChildren); and PIXI.TilingSprite.prototype.destroy.call(this); It's the call to the underlying PIXI code that is the problem. Calling destroy on PIXI.TilingSprite results in the underlying tilingTexture.baseTexture being destroyed too and then it can't be used again! I don't know what the correct solution is but I found that changing the code as follows actually solves the problem. Change this:Phaser.TileSprite.prototype.destroy = function(destroyChildren) { Phaser.Component.Destroy.prototype.destroy.call(this, destroyChildren); PIXI.TilingSprite.prototype.destroy.call(this);};to this:Phaser.TileSprite.prototype.destroy = function(destroyChildren) { Phaser.Component.Destroy.prototype.destroy.call(this, destroyChildren); //PIXI.TilingSprite.prototype.destroy.call(this); PIXI.Sprite.prototype.destroy.call(this); this.tileScale = null; this.tileScaleOffset = null; this.tilePosition = null;};The new code above was copied from PIXI.TilingSprite.prototype.destroy but I have excluded the lines where the tilingTexture is destroyed. This might have unexpected side effects but it's as far as I can get on my own. In fact, in my game it removes the physics body from one of my TileSprites so I know something is not right!Hopefully, Richard and his team can use this info to fix the issue permanently. MichaelD, abshinri and danbolt 3 Link to comment Share on other sites More sharing options...
MichaelD Posted April 27, 2015 Share Posted April 27, 2015 I'm having the same issue is this fix going to be included in the 2.3.1 release? Thanks. Link to comment Share on other sites More sharing options...
saibotlive Posted May 7, 2015 Share Posted May 7, 2015 I am having these same issues whenever I try to restart my game which uses a continuous tilesprite. Link to comment Share on other sites More sharing options...
danbolt Posted July 13, 2015 Share Posted July 13, 2015 Hey guys. I've been using Phaser for hobby projects for the past year or so and I've loved it. Thanks so much for putting the time and effort into such a polished library. Just wanted to say that I ran into the same bug as @jrejigga with TileSprites crashing after changing game state. Doing the fix @jrejigga did solved the problem. This happened when I upgraded from 2.2.2 to 2.3.0. Another problem with upgrading to 2.3.0 is that TileSprite instances no longer seem to be working in Arcade Physics. Their body hitboxes appear when rendered via debug.body(), but they don't seem to block anything or respond to Arcade.collide(). Upgrading isn't a critical issue for me right now, so I'm going to stick to 2.2.2. I thought I'd let you know, regardless! Link to comment Share on other sites More sharing options...
rich Posted July 14, 2015 Share Posted July 14, 2015 Just to say that both the state swap TileSprite destroy bug and the issue with it no colliding with physics are both fixed in 2.4 (although there's a little more work to do with it yet, I'm still hopeful for a release this week). goyeneche 1 Link to comment Share on other sites More sharing options...
danbolt Posted July 22, 2015 Share Posted July 22, 2015 @rich, Looks good! I'll try upgrading soon! 2.4 looks like a crazy new release! Link to comment Share on other sites More sharing options...
Recommended Posts