Detect if two objects have the same tint

Hi, I’m making a color match game and I am using tint on my sprite and the collectible item. Currently the sprite collects the object but I want it to only collect the object if their tints match, otherwise you lose a life.

I’ve tried an if statement to no avail. Any ideas to make this work would be greatly appreciated.

What’s the if statement you tried?

Welcome Villan,
Setting a tint on a sprite doesn’t set an overall tint property on the sprite, but instead sets a tint property on each corner of the sprite. Those properties are:

sprite.tintBottomLeft
sprite.tintBottomRight
sprite.tintTopLeft
sprite.tintTopRight

So in order to see if an image has the same tint, you will need to compare either all of the corner’s tints, or just a pair of the corner’s tints, depending on how accurate you want it.


Another way you could do it is you could extend the sprite class and override the set tint method and store your own tint property to check against other extended sprites.

Thanks Jake, I was wondering if I could store the tint as variable, but if I only have to check the corners, that is enough for this simple game.

This is the if statement I’m using, the score goes up on the first collection, but even if the colours match after it only runs the else if part of the code. Any ideas?

if (sprite.tintTopLeft && sprite.tintTopRight && sprite.tintBottomLeft && sprite.tintBottomRight === collectible.tintTopLeft && collectible.tintTopRight && collectible.tintBottomLeft && collectible.tintBottomRight) {
score += 10;
scoreText.setText('Score: ’ + score);
} else if(sprite.tintTopLeft && sprite.tintTopRight && sprite.tintBottomLeft && sprite.tintBottomRight !== collectible.tintTopLeft && collectible.tintTopRight && collectible.tintBottomLeft && collectible.tintBottomRight)
{
attempts–;
attemptsText.setText('Attempts: ’ + attempts);
}

Unfortunately you cannot use that type of syntax within the if statement. As sprite.tintTopLeft may evaluate as false (Especially if the tint is black.).

I would try out the following:

let chkTR = (spr1, spr2) => {return spr1.tintTopRight === spr2.tintTopRight};
let chkBR = (spr1, spr2) => {return spr1.tintBottomRight === spr2.tintBottomRight};
let chkTL = (spr1, spr2) => {return spr1.tintTopLeft === spr2.tintTopLeft};
let chkBL = (spr1, spr2) => {return spr1.tintBottomLeft === spr2.tintBottomLeft};
if (chkTR(sprite, collectible) && chkBR(sprite, collectible) && chkTL(sprite, collectible) && chkBL(sprite, collectible)) 
{
    score += 10;
    scoreText.setText('Score: ' + score);
} 
else
{
    attempts--;
    attemptsText.setText('Attempts: ' + attempts);
}

This doesn’t seem to cut it. It’s still only running the else part of the statement.

The logic is there and working as expected. Go here and paste the following code:

var config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);
var sp1;
var sp2

function preload ()
{
    this.load.image('bunny', 'assets/sprites/bunny.png');
}

function create ()
{
    sp1 = this.add.image(150, 300, 'bunny');
    sp2 = this.add.image(400, 300, 'bunny');
    
    sp1.tint = 0xfb0000;
    sp2.tint = 0xfb0000;
    checkTint(); //EXPECTED: Tint matches

    sp1.tint = 0x000000;
    sp2.tint = 0xfb0000;
    checkTint(); //EXPECTED: Tint does not match

    sp1.tint = 0x000ff0;
    sp2.tint = 0x000ff0;
    checkTint(); //EXPECTED: Tint matches
}

function checkTint()
{
    let chkTR = (spr1, spr2) => { return spr1.tintTopRight === spr2.tintTopRight };
    let chkBR = (spr1, spr2) => { return spr1.tintBottomRight === spr2.tintBottomRight };
    let chkTL = (spr1, spr2) => { return spr1.tintTopLeft === spr2.tintTopLeft };
    let chkBL = (spr1, spr2) => { return spr1.tintBottomLeft === spr2.tintBottomLeft };
    if (chkTR(sp1, sp2) && chkBR(sp1, sp2) && chkTL(sp1, sp2) && chkBL(sp1, sp2)) {
        console.log("Tint matches");
    }
    else {
        console.log("Tint does not match");
    }
}

If it is still not working for you, there is something else wrong elsewhere in your code.

Sorry friend, I figured it out. in my overlap call I had to change sprites to sprite and it worked. Again, thanks so much for your help. Now onto a different question, in my game you click a button to add a red tint to the sprite and a blue button to add blue, it changes when clicked as expected, but what I would like to do is blend the colours together to make purple, but they would still keep their normal function of adding only blue if the sprite is white. So if sprite is white and blue is clicked add blue, when sprite is blue and red is clicked change to purple. I’m assuming its more if statements on my button clicks?

Glad you solved the issue.

In regards to your other problem in mixing colors, you can do that like so:

let col1= Phaser.Display.Color.IntegerToColor(sp1.tintTopRight);
let col2= Phaser.Display.Color.IntegerToColor(sp2.tintTopLeft);
let mixedCol = Phaser.Display.Color.ObjectToColor(Phaser.Display.Color.Interpolate.ColorWithColor(col1, col2, 1, .5)).color;
myButtont.tint = mixedCol;

Sorry I’m kind of a JS noob. Where would I add that code? This is my button code…

let redBtn = this.add.image(50, 80, ‘redButton’);
redBtn.setInteractive();
redBtn.on(‘pointerdown’, () => {
sprite.tint = 0xff0000;

  });

let blueBtn = this.add.image(95, 80, 'blueButton');
  blueBtn.setInteractive();
  blueBtn.on('pointerdown', () => {
    sprite.tint = 0x0000ff;
  });

  let yellowBtn = this.add.image(145, 80, 'yellowButton');
  yellowBtn.setInteractive();
  yellowBtn.on('pointerdown', () => {
    sprite.tint = 0xffff00;
  });

  let whiteBtn = this.add.image(190, 80, 'whiteButton');
  whiteBtn.setInteractive();
  whiteBtn.on('pointerdown', () => {
    sprite.tint = 0xffffff;
  });

I would create a function such as, “MixColors(color1, color2)”, like so:

    MixColors(color1, color2)
    {
        let col1= Phaser.Display.Color.IntegerToColor(color1);
        let col2 = Phaser.Display.Color.IntegerToColor(color2);
        return Phaser.Display.Color.ObjectToColor(Phaser.Display.Color.Interpolate.ColorWithColor(col1, col2, 1, .5)).color;;
    }

Now you can do the following:

  let blueBtn = this.add.image(95, 80, 'blueButton');
  blueBtn.setInteractive();
  blueBtn.on('pointerdown', () => {
    sprite.tint = sprite.tint != 0xffffff ? this.MixColors(sprite.tint, 0x0000ff) : 0x0000ff;
  });

this.MixColors is not a function

You need to add the top function that I supplied above.

Sorry, i have and tried adding it in a few different places, but it still gives me that error.

I got this to work, but if the sprite is white and I click the button it just makes a darker colour, and that messes up the matching function. So when it is white and I click red, it’s a darker red and when I click blue it doesn’t mix red and blue it just becomes a dark blue. So it’s functioning how it already did, but making the colour darker. Thanks for trying.

EDIT: What I’m really trying to do is when the sprite is white and you click red it changes to red, then if you click blue, instead of changing to blue it changes to purple. So is there a way to make the sprite tint change to purple instead of mixing the colour which just made it darker?

RE-EDIT got it working as intended. Had to store tint as variable and used an array for the buttons colours and a second array for the mixed colours. So red = [0] and blue =[1] these combined equal purple[1] and so on.