alexcurtis Posted June 14, 2014 Share Posted June 14, 2014 Hi, Is it possible to tween a tint? So going from the default 0xFFF to a slightly darker tint 0x757575 over a period of time. Ive tried:tween.to({ tint: 0x757575 }, 5000, Phaser.Easing.Linear.None);But it seems to cycle through R,G,B or something to create some crazy colours until it reaches the end tint. Really all I want to do is darken the sprite over a period of time. Many Thanks,-Alex Link to comment Share on other sites More sharing options...
wayfinder Posted June 14, 2014 Share Posted June 14, 2014 You could have a routine that sets the tint like this tint = '#' + r + g + b; and then tween r,g, and b as separate 2-byte hex values Link to comment Share on other sites More sharing options...
alexcurtis Posted June 14, 2014 Author Share Posted June 14, 2014 You could have a routine that sets the tint like thistint = '#' + r + g + b;and then tween r,g, and b as separate 2-byte hex values Is it possible to plumb a routine callback into a tween? -- or is it on the update method? I could probably just override the sprite update call and pull in the tint. Would that be efficient? EDIT: Thanks wayfinder. I think I have a decent solution using your suggestion. Link to comment Share on other sites More sharing options...
lewster32 Posted June 14, 2014 Share Posted June 14, 2014 The Phaser.Color object has a range of different tools for this kind of thing, such as interpolateColor - with a bit of imagination you can create a function to let you tween colours, like this:function tweenTint(obj, startColor, endColor, time) { // create an object to tween with our step value at 0 var colorBlend = {step: 0}; // create the tween on this object and tween its step property to 100 var colorTween = game.add.tween(colorBlend).to({step: 100}, time); // run the interpolateColor function every time the tween updates, feeding it the // updated value of our tween each time, and set the result as our tint colorTween.onUpdateCallback(function() { obj.tint = Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step); }); // set the object to the start color straight away obj.tint = startColor; // start the tween colorTween.start();}Use like so:tweenTint(sprite, 0xff0000, 0x0000ff, 2000); // tween the tint of sprite from red to blue over 2 seconds (2000ms) webcaetano, totallybueno, nicoloko02 and 3 others 6 Link to comment Share on other sites More sharing options...
alexcurtis Posted June 14, 2014 Author Share Posted June 14, 2014 The Phaser.Color object has a range of different tools for this kind of thing, such as interpolateColor - with a bit of imagination you can create a function to let you tween colours, like this:function tweenTint(obj, startColor, endColor, time) { // create an object to tween with our step value at 0 var colorBlend = {step: 0}; // create the tween on this object and tween its step property to 100 var colorTween = game.add.tween(colorBlend).to({step: 100}, time); // run the interpolateColor function every time the tween updates, feeding it the // updated value of our tween each time, and set the result as our tint colorTween.onUpdateCallback(function() { obj.tint = Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step); }); // set the object to the start color straight away obj.tint = startColor; // start the tween colorTween.start();}Use like so:tweenTint(sprite, 0xff0000, 0x0000ff, 2000); // tween the tint of sprite from red to blue over 2 seconds (2000ms) Very Nice. Thank you so much lewster32. :-) lewster32 1 Link to comment Share on other sites More sharing options...
lewster32 Posted June 14, 2014 Share Posted June 14, 2014 No problem - this functionality should be easy to patch into the tweening system. A little project for someone? sbonavida 1 Link to comment Share on other sites More sharing options...
codart Posted June 19, 2014 Share Posted June 19, 2014 lewster32 is an expert, every thing i searching for, every time he answered sbonavida 1 Link to comment Share on other sites More sharing options...
srobertson421 Posted March 19, 2015 Share Posted March 19, 2015 Hi lewster32. I know this is an older post but I have implemented a version of your color tween but I'm hitting cross-browser issues. Any reason this wouldn't work in Safari or Firefox? Link to comment Share on other sites More sharing options...
st0n3vn Posted January 27, 2016 Share Posted January 27, 2016 Thanks for the cool method, lewster32, it is awesome. It works perfect on Chrome, Firefox and Edge on Phaser 2.4.4. For those of you using TypeScript, here is the code: private tweenTint(spriteToTween:Phaser.Sprite, startColor:number, endColor:number, duration:number):void { var colorBlend = {step: 0}; this.game.add.tween(colorBlend).to({step: 100}, duration, Phaser.Easing.Default, false) .onUpdateCallback(() => { spriteToTween.tint = Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step, 1); }) .start() }; You can also add an onComplete event at the end to nullify the colorBlend object (I am not sure whether it is fully removed from memory). VitaZheltyakov and OneSillyLion 1 1 Link to comment Share on other sites More sharing options...
megmut Posted March 26, 2016 Share Posted March 26, 2016 For anybody looking at this in ES6, it works fine.. I've also added arrow functions for lexical scope. It also defaults time value to 250ms if none set, and will callback if a valid function or method has been passed. Tested and works like a charm!! // in boot state... this.game.animations = new Animations(this.game); // in Animations class export default class Animations { constructor(game) { this.game = game; } tweenTint(obj, startColor, endColor, time = 250, callback = null) { if (obj) { let colorBlend = { step: 0 }; let colorTween = this.game.add.tween(colorBlend).to({ step: 100 }, time); colorTween.onUpdateCallback(() => { obj.tint = Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step); }); obj.tint = startColor; if (callback) { colorTween.onComplete.add(() => { callback(); }); } colorTween.start(); } } } // in any class create() { let sprite = this.game.add.sprite(x, y, key, frame); let tint = this.game.animations.tweenTint(sprite, '0xffffff', '0xff0000', 200, () => { this.tweenCompleteFunction(); }); } tweenCompleteFunction() { console.log('tween has finished'); } Link to comment Share on other sites More sharing options...
mattstyles Posted March 26, 2016 Share Posted March 26, 2016 Just out of interest, why use arrow functions? It makes no sense in your library code and is (currently) far less performant, not to mention it nukes the call stack. This answer from SO addresses some of the dangers of using them liberally like this when they aren't required. The second one, used for the `add`, simply pass `callback` straight into the `onComplete` handler, you dont need any extra function there. Probably worth mentioning that currently your code will only work in Chrome and Firefox and nowhere else, for people that are just trying to copy-paste it into their code. Link to comment Share on other sites More sharing options...
megmut Posted March 27, 2016 Share Posted March 27, 2016 Thanks for the tips on ES6. I'm still fairly new to this all! Thanks for the link on the correct usage of arrow functions. I was toying with the idea of using Phaser's Callback system, however as Rich said he was thinking of scrubbing it from lazer 3.0, I decided to pass a callback function. May I ask how or why it will only work in Chrome and Firefox? Thanks for the help and info!! Link to comment Share on other sites More sharing options...
mattstyles Posted March 27, 2016 Share Posted March 27, 2016 Arrow functions are not supported by Safari or IE and default function parameters are supported only by Chrome & Firefox. Arrows are in Edge and I'd imagine Safari will catch up fairly soon, but default function parameters are going to take a little longer, hopefully not too much longer. Are you using babel (or something else) to transpile? Arrow functions and scope are tricky, trickier than most people assume. Arrow functions actually have no scope, so they grab it from their parent closure, although grab it is a poor term. This is a better explanation. I use them regularly, and not always correctly either, but its worth knowing about the implementational oddities of arrow functions (similar things are known as lambdas in a host of other languages). Link to comment Share on other sites More sharing options...
megmut Posted March 27, 2016 Share Posted March 27, 2016 Thank you for the link! I appreciate the reply! Taking my code to the next 'level', pardon the pun really is the next thing on my list, making sure that the code I write has been written in the best way without affecting performance. I owe you a beer I think Link to comment Share on other sites More sharing options...
mattstyles Posted March 27, 2016 Share Posted March 27, 2016 Ha ha, certainly no beer necessary, but good to hear about people dedicated to improving their craft, as well as their output. Good luck with learning new things! Link to comment Share on other sites More sharing options...
megmut Posted March 28, 2016 Share Posted March 28, 2016 I have a question @mattstyles, I used the arrow functions to keep lexical scope on the callback, if I remove this like so: // replace the code below if (callback) { colorTween.onComplete.add(() => { callback(); }); } // with this if (callback) { colorTween.onComplete.add(callback()); } The callback function is not called, or if it is.. it's lost scope. Would you do this the old fashioned way? if (callback) { colorTween.onComplete.add(function() { callback(); }, this); } Thanks! Link to comment Share on other sites More sharing options...
drhayes Posted March 28, 2016 Share Posted March 28, 2016 @megmut Don't call the callback e.g. "callback()", just pass the name in. if (callback) { colorTween.onComplete.add(callback); // no parenthesis after callback! } Link to comment Share on other sites More sharing options...
mattstyles Posted March 28, 2016 Share Posted March 28, 2016 What the doc said This is an example of passing a function around. As you're in this for the long haul, check out stuff on passing functions. Sometimes you will see something like: mappedList = myList.map( myMapFunction( 'foo' ) ) This is an example of invoking a function, whereby its return will be passed to the callee, in this case `myList.map`. `myMapFunction` would look something like: function myMapFunction( name ) { // `name` is available here return function( item ) { // Do stuff // `name` is available here, for example return item + name } } In this case we are passing a parameter through `myMapFunction` so that it can be used in the array map function. In this case the output of all this jazz is to mutate `myList` into a new list that has `foo` appended to each string in the array. You could achieve the same end result by extracting `name` to a variable and using an anonymous function inside the map, but, crucially, you lose two extremely important things: 1) you lose function purity and 2) you lose the ability to compose functions. This example is probably best known as a `thunk`. You might want to check out thunks, function passing, functional purity (referential transparency) and functional composition. In this case most of this comes from functional programming (or even functional reactive programming) but JS is a great platform for FP/FRP and getting into habits of writing code like this generally makes is more robust, testable, composible and reliable. drhayes 1 Link to comment Share on other sites More sharing options...
megmut Posted March 28, 2016 Share Posted March 28, 2016 Thanks for the tips, I most definitely owe you a beer or 6! I've just ordered some new books on the above topics, figure it's about high time I get on top of this once and for all! Can you recommend any decent online resources? Cheers! Link to comment Share on other sites More sharing options...
mattstyles Posted March 29, 2016 Share Posted March 29, 2016 Addy's book on patterns is a little old now but a great reference, covers the basics and most of the GoF stuff. Other than that I use Github to follow useful projects and poke through code and if I can get hold of the devs (through opening an issue for something specific, or sometimes via Twitter or email) then I'll ask as many questions as I can, many devs are receptive to polite questions and will happily write you back a paragraph or two, obviously good devs are busy so don't take silence as rudeness. Forums like this one are a great place and many devs I follow write technical blogs, or use Medium, so you can pick up a lot about implementation decisions from there, usually their posts have a little advertising swing but its useful to hear them chat about the projects that you want to use anyway. Link to comment Share on other sites More sharing options...
megmut Posted March 29, 2016 Share Posted March 29, 2016 @mattstyles Thanks for the info! I've actually already got that book, it's sat on my shelf, I've not had time to go through it yet! About time I dust it off I think Also, just to clarity, I tried the code in the other browsers and it works fine,then it dawned on me, I forgot to mention the fact I am using Babel, so all the es6 works fine in all browsers! Thanks for taking the time to write decent responses! I greatly appreciate it! drhayes 1 Link to comment Share on other sites More sharing options...
mattstyles Posted March 29, 2016 Share Posted March 29, 2016 @megmut Yeah, that's why I mentioned transpilation Good luck learning new stuff! Link to comment Share on other sites More sharing options...
samme Posted September 8, 2017 Share Posted September 8, 2017 Link to comment Share on other sites More sharing options...
samme Posted September 19, 2017 Share Posted September 19, 2017 samid737 1 Link to comment Share on other sites More sharing options...
Tan Nguyen Posted July 3, 2019 Share Posted July 3, 2019 On 6/14/2014 at 10:32 PM, lewster32 said: The Phaser.Color object has a range of different tools for this kind of thing, such as interpolateColor - with a bit of imagination you can create a function to let you tween colours, like this: function tweenTint(obj, startColor, endColor, time) { // create an object to tween with our step value at 0 var colorBlend = {step: 0}; // create the tween on this object and tween its step property to 100 var colorTween = game.add.tween(colorBlend).to({step: 100}, time); // run the interpolateColor function every time the tween updates, feeding it the // updated value of our tween each time, and set the result as our tint colorTween.onUpdateCallback(function() { obj.tint = Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step); }); // set the object to the start color straight away obj.tint = startColor; // start the tween colorTween.start();} Use like so: tweenTint(sprite, 0xff0000, 0x0000ff, 2000); // tween the tint of sprite from red to blue over 2 seconds (2000ms) I think: obj.tint = Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step); should be: obj.tint = startColor + Phaser.Color.interpolateColor(startColor, endColor, 100, colorBlend.step); Link to comment Share on other sites More sharing options...
Recommended Posts