tricksty77 Posted July 23, 2018 Share Posted July 23, 2018 Hi, I have found a strange behavior while updating some text there is a different behavior if the text is cached(i need to cache it to change the tint) or not In particular i have 1 button that switch between 2 images one images is alpha 0 and the other is alpha 1 when i press the button i change the alpha from 1 to 0 and from 0 to 1 until now all is ok. these two sprites have 2 other child sprites and also these works like expected those 2 other sprites have two text attached and here is where the problems lies when i update the text property that is in these 2 texts, if the texts is set to cached, only the text that is shown is updated. the other become an empty sprite with nothing inside this is the starting behavior this is the expected behavior now if i press the refresh button, the refresh button change the content of the two textboxes and now upon pressing the button i get this empty text box (the class inside has the correct text property but the cached image is wrong) game.module( 'game.main' ) // Required Plugins .require( 'plugin.essentials', ) .body(function() { // Required Assets // Title Screen game.addAsset('button1.png'); game.addAsset('button2.png'); game.addAsset('energyBut.png'); game.addAsset('click1.wav'); game.addAsset('click2.wav'); game.addAsset('Patrick.fnt'); // Main Menu Scene game.createScene('MainMenu', { backgroundColor: '#ffce53', playerInfo: {}, contextInfo: {}, init: function() { // UI initialization this.startButton11 = new game.ForgeButton('button1.png','button2.png',0.5 * game.width, 0.2*game.height, 'Refresh', {}, 100, 1, '#000000','#FFFFFF', function() { game.scene.updateEnergyText(game.scene.energyText); game.scene.updateEnergyText(game.scene.energyText1); }); this.startButton11.addTo(this.stage) this.startButton11.scaleAmount=0; this.startButton = new game.ForgeButton('button1.png','button2.png',0.5 * game.width, 0.4*game.height, 'Test Button', {}, 100, 1, '#000000','#FFFFFF', function() { }); this.startButton.addTo(this.stage) this.startButton.scaleAmount=0; this.energyText = this.createEnergyText(this.startButton.sprite2, this.energyText, 300); this.energyText1 = this.createEnergyText(this.startButton.sprite, this.energyText1, 150); }, createEnergyText: function(hook, etext, xx) { var sprite2 = new game.Sprite('energyBut.png'); sprite2.anchorCenter(); sprite2.position.x = xx; sprite2.position.y = -100; sprite2.addTo(hook); etext = new game.Text("x", {}); etext.addTo(sprite2); etext.anchorCenter(); etext.fontClass.letterSpacing=0; var size = 120; var factor = etext.height / size; etext.height = size; etext.width = etext.width / factor; etext.position.y=-(size/7); etext.position.x=0; this.updateEnergyText(etext); return etext; }, updateEnergyText: function(etext) { etext.text = 'x'; etext.updateText(); etext.cache = true; etext._cachedSprite.tint = '#000000'; etext._cachedSprite.tintAlpha = 1; }, }); // Custom Classes game.createClass('ForgeButton', 'Button', { //We extend the standard button staticInit: function(texture1, texture2, x, y, text, textProps, size, letterSpacing, tint1, tint2, callback) { this.super(texture2, x, y, callback); this.callback = callback; this.sprite.alpha=0; this.sprite2 = new game.Sprite(texture1); this.sprite2.anchorCenter(); this.sprite2.alpha=1; this.sprite2.buttonMode = true; this.sprite2.position.x = x; this.sprite2.position.y = y; this.sprite2.interactive = true; this.sprite2.mousedown = this.mousedown.bind(this); this.sprite2.mouseup = this.mouseup.bind(this); this.sprite2.mouseupoutside = this.mouseup.bind(this); this.text1 = new game.Text(text, textProps); this.text1.anchorCenter(); this.text1.addTo(this.sprite2); this.text2 = new game.Text(text, textProps); this.text2.anchorCenter(); this.text2.addTo(this.sprite); var factor = this.text1.height / size; this.text1.height = size; this.text1.width /= factor; this.text1.position.y=-(size/7); this.text1.fontClass.letterSpacing=letterSpacing; this.text1.updateText(); this.text1.cache = true; this.text1._cachedSprite.tint = tint1; this.text1._cachedSprite.tintAlpha = 1; this.text2.height = size; this.text2.width /= factor; this.text2.position.y=-(size/7); this.text2.fontClass.letterSpacing=letterSpacing; this.text2.updateText(); this.text2.cache = true; this.text2._cachedSprite.tint = tint2; this.text2._cachedSprite.tintAlpha = 1; this.sprite2.click = this.click.bind(this); }, addTo: function(container) { this.super(container); container.addChild(this.sprite2); }, scaleIn: function(delay) { delay = delay || 0; this.sprite2.scale.set(0); game.Tween.add(this.sprite2.scale, { x: 1, y: 1 }, this.scaleSpeed, { easing: this.scaleEasing, delay: delay, onStart: this._onScaleInStart.bind(this), onComplete: this._scaleInEnd.bind(this) }).start(); }, rotate: function(random) { this.super(random), this.sprite2.rotation = -this.rotateAmount; this.rotateTween = game.Tween.add(this.sprite2, { rotation: this.rotateAmount }, this.rotateSpeed, { repeat: Infinity, yoyo: true, easing: this.rotateEasing }).start(); if (random) this.rotateTween.currentTime = this.rotateTween.duration.random(); }, setPosition: function(x,y) { this.sprite.position.x = x; this.sprite.position.y = y; this.sprite2.position.x = x; this.sprite2.position.y = y; }, mousedown: function() { if (this.clickSound) game.audio.playSound(this.clickSound); this.sprite2.alpha=0; this.sprite.alpha=1; this.sprite.mousedown(); }, mouseup: function() { if (this.clickSound1) game.audio.playSound(this.clickSound1); this.sprite2.alpha=1; this.sprite.alpha=0; this.sprite.mouseup(); }, click: function() { //if (this.clickSound) game.audio.playSound(this.clickSound); if (typeof this.callback === 'function') { this.callback(); } } }); }); Many thanks Quote Link to comment Share on other sites More sharing options...
enpu Posted July 23, 2018 Share Posted July 23, 2018 It is a bit hard to understand and follow your code, so i'm not sure what the actual issue is. I did find few things that did not look right: this.energyText1 = this.createEnergyText(this.startButton.sprite, this.energyText1, 150); You are creating new variable energyText1 but also using that as a parameter in a same line. At that point that variable would be still undefined, so you should not do that. I would change your code to this: .... this.energyText = this.createEnergyText(this.startButton.sprite2, 300); this.energyText1 = this.createEnergyText(this.startButton.sprite, 150); }, createEnergyText: function(hook, xx) { var sprite2 = new game.Sprite('energyBut.png'); sprite2.anchorCenter(); sprite2.position.x = xx; sprite2.position.y = -100; sprite2.addTo(hook); var etext = new game.Text('x'); etext.addTo(sprite2); etext.anchorCenter(); var size = 120; var factor = etext.height / size; etext.height = size; etext.width = etext.width / factor; etext.position.y = -(size / 7); etext.position.x = 0; this.updateEnergyText(etext); return etext; }, Also i really don't understand your updateEnergyText function. updateEnergyText: function(etext) { etext.text = 'x'; etext.updateText(); etext.cache = true; etext._cachedSprite.tint = '#000000'; etext._cachedSprite.tintAlpha = 1; }, You are settings text value to 'x' that has already text value 'x'? What are you trying to achieve there? If you want to change your text, you should use setText function. Quote Link to comment Share on other sites More sharing options...
tricksty77 Posted July 24, 2018 Author Share Posted July 24, 2018 Ok i understand that the code is not so clean. even with the set text the problem remain updateEnergyText: function(etext) { etext.setText('XX'); etext.cache = true; etext._cachedSprite.tint = '#000000'; etext._cachedSprite.tintAlpha = 1; }, If you can try to run the code it will be clear what is the problem. after you have pressed the refresh button the pressed text over the text button will be empty (even if there is XX inside the text property) the etext parameter is not used unitialized the first line i use is etext= new blah blah but i realized that this is not passed by ref value so i had to add the return etext (but still this had no impact on the behavior i see) Quote Link to comment Share on other sites More sharing options...
tricksty77 Posted July 24, 2018 Author Share Posted July 24, 2018 (edited) I have cleaned the sample a little bit more and I attach all the files needed to run please run this sample and try the behavior 1 press and hold test button 2 press refresh 3 press and hold the test button see the difference between 1 and 3 game.module( 'game.main' ) // Required Plugins .require( 'plugin.essentials', ) .body(function() { // Required Assets // Title Screen game.addAsset('button1.png'); game.addAsset('button2.png'); game.addAsset('energyBut.png'); game.addAsset('Arial.fnt'); // Main Menu Scene game.createScene('MainMenu', { backgroundColor: '#ffce53', playerInfo: {}, contextInfo: {}, init: function() { // UI initialization this.startButton11 = new game.ForgeButton('button1.png','button2.png',0.5 * game.width, 0.2*game.height, 'Refresh', {}, 100, 1, '#000000','#FFFFFF', function() { game.scene.updateEnergyText(game.scene.energyText); game.scene.updateEnergyText(game.scene.energyText1); }); this.startButton11.addTo(this.stage) this.startButton11.scaleAmount=0; this.startButton = new game.ForgeButton('button1.png','button2.png',0.5 * game.width, 0.4*game.height, 'Test Button', {}, 100, 1, '#000000','#FFFFFF', function() { }); this.startButton.addTo(this.stage) this.startButton.scaleAmount=0; this.energyText = this.createEnergyText(this.startButton.sprite2, 300); this.energyText1 = this.createEnergyText(this.startButton.sprite, 150); }, createEnergyText: function(hook, xx) { var sprite2 = new game.Sprite('energyBut.png'); sprite2.anchorCenter(); sprite2.position.x = xx; sprite2.position.y = -100; sprite2.addTo(hook); etext = new game.Text("x", {}); etext.addTo(sprite2); etext.anchorCenter(); etext.fontClass.letterSpacing=0; var size = 120; var factor = etext.height / size; etext.height = size; etext.width = etext.width / factor; etext.position.y=-(size/7); etext.position.x=0; this.updateEnergyText(etext); return etext; }, updateEnergyText: function(etext) { etext.setText('xx'); etext.cache = true; etext._cachedSprite.tint = '#000000'; etext._cachedSprite.tintAlpha = 1; }, }); // Custom Classes game.createClass('ForgeButton', 'Button', { //We extend the standard button staticInit: function(texture1, texture2, x, y, text, textProps, size, letterSpacing, tint1, tint2, callback) { this.super(texture2, x, y, callback); this.callback = callback; this.sprite.alpha=0; this.sprite2 = new game.Sprite(texture1); this.sprite2.anchorCenter(); this.sprite2.alpha=1; this.sprite2.buttonMode = true; this.sprite2.position.x = x; this.sprite2.position.y = y; this.sprite2.interactive = true; this.sprite2.mousedown = this.mousedown.bind(this); this.sprite2.mouseup = this.mouseup.bind(this); this.sprite2.mouseupoutside = this.mouseup.bind(this); this.text1 = new game.Text(text, textProps); this.text1.anchorCenter(); this.text1.addTo(this.sprite2); this.text2 = new game.Text(text, textProps); this.text2.anchorCenter(); this.text2.addTo(this.sprite); var factor = this.text1.height / size; this.text1.height = size; this.text1.width /= factor; this.text1.position.y=-(size/7); this.text1.fontClass.letterSpacing=letterSpacing; this.text1.updateText(); this.text1.cache = true; this.text1._cachedSprite.tint = tint1; this.text1._cachedSprite.tintAlpha = 1; this.text2.height = size; this.text2.width /= factor; this.text2.position.y=-(size/7); this.text2.fontClass.letterSpacing=letterSpacing; this.text2.updateText(); this.text2.cache = true; this.text2._cachedSprite.tint = tint2; this.text2._cachedSprite.tintAlpha = 1; this.sprite2.click = this.click.bind(this); }, addTo: function(container) { this.super(container); container.addChild(this.sprite2); }, mousedown: function() { if (this.clickSound) game.audio.playSound(this.clickSound); this.sprite2.alpha=0; this.sprite.alpha=1; this.sprite.mousedown(); }, mouseup: function() { if (this.clickSound1) game.audio.playSound(this.clickSound1); this.sprite2.alpha=1; this.sprite.alpha=0; this.sprite.mouseup(); }, click: function() { //if (this.clickSound) game.audio.playSound(this.clickSound); if (typeof this.callback === 'function') { this.callback(); } } }); }); Arial.fnt Edited July 24, 2018 by tricksty77 added resources Quote Link to comment Share on other sites More sharing options...
enpu Posted July 24, 2018 Share Posted July 24, 2018 Could you zip all the assets into one file? Would be a lot easier. Quote Link to comment Share on other sites More sharing options...
tricksty77 Posted July 24, 2018 Author Share Posted July 24, 2018 yes here it is media.zip Quote Link to comment Share on other sites More sharing options...
Wolfsbane Posted July 24, 2018 Share Posted July 24, 2018 updateEnergyText: function(etext) { etext.cache = true; console.log('alpha = ' + etext.alpha); etext.setText('xx'); etext.alpha=1; etext._cachedSprite.tint = '#000000'; etext._cachedSprite.tintAlpha = 1; } The problem is resulting from the combination of 1: the alpha of the sprite, and 2: the setText('xx') and 3: the cache=true I tried to dig a little into the engine, but I'm still unfamiliar with how it all ties together, so please bare with me, this is a messy response. In text.js, setText() calls -> this._generateText() which calls container.js->updateTransform(). In container.js->updateTransform (at around line 511) it sets alpha: this._worldAlpha = this.parent._worldAlpha * this.alpha; If you hard-code this._worldAlpha=1 here, then your issue 'disappears', so I think this is a key point in the problem. So I think the this.alpha (from the sprite/etext) is simply passed in as zero, gets rendered somehow, but if alpha is zero, it's rendered (And cached) as empty. I can't see in the engine where this is happening, and I've got to dash, soon. To test: You can hard-code the parent _worldAlpha_ into your method like this: updateEnergyText: function(etext) { etext.parent._worldAlpha = 1; etext.setText('xx'); etext.cache = true; etext.alpha=1; etext._cachedSprite.tint = '#000000'; etext._cachedSprite.tintAlpha = 1; } That should now *work* (i.e. looks like it's doing the right thing.). But I don't really understand this caching that you're trying to be doing, and I still don't understand how Panda does all it's rendering, so.. don't consider this reply a solution by any means! Quote Link to comment Share on other sites More sharing options...
tricksty77 Posted July 24, 2018 Author Share Posted July 24, 2018 Thanks, this workaround apparently resolve the issue i have. The caching I am doing is becouse I want to change the color of the text and this seems to be the only way to go for now. Probably this is not the most perfect way but at least it works. Many thanks Quote Link to comment Share on other sites More sharing options...
Wolfsbane Posted July 24, 2018 Share Posted July 24, 2018 Well, this is just debugging the root cause, not really a fix. I don't quite understand caching, so I don't know if this is a bug or it's expected that you can't cache a 0 alpha sprite/text. (If you want to go with it so you can keep making your game, as a precaution, I would do something like until we have a better idea of what is happening, because I have no idea about the rendering at the moment ( @enpu , help? ) var temp = etext.parent._worldAlpha; etext.parent._worldAlpha = 1; //drawing stuff etext.parent._worldAlpha = temp; Just in case _worldAlpha is important for the drawing of the other sprites in the render engine, and we're messing it all up. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.