Samina
Samina

Reputation: 45

How to pick a random value from an array without the value constantly changing in p5/javascript?

I am creating colorful "confetti" with p5.js and choosing a random color from an array.

var colors = ['red', 'green', 'blue', 'orange', 'yellow', 'purple', 'pink'];

I want the random function to just choose one and not loop through the array over and over making the colors change. If I put the confettiColor variable in setup it makes all of the particles the same. In other words, how do I pick one random color for each particle from the array without looping through them all?

else if (changeConfetti.checked) {
  //var confettiSize = random(1,8);

  confettiColor = colors[Math.floor(Math.random() * colors.length)];
  stroke(confettiColor);
  strokeWeight(3);
  line(this.x,this.y,this.x+5,this.y-10);
}

My full code is on CodePen https://codepen.io/Fragile404/pen/gzbzXv

Upvotes: 0

Views: 2827

Answers (2)

Dan Oswalt
Dan Oswalt

Reputation: 2189

This worked for me:

var rainDrop = function()
{
    this.x = random(canvasWidth+1000);
    this.y = random(-100,-50);
    this.confettiColor = colors[Math.floor(Math.random() * colors.length)]; 
};

And then in display, use stroke(this.confettiColor); instead of stroke(confettiColor)

Upvotes: 0

CRice
CRice

Reputation: 32226

It seems the issue is that the color is re-selected every time the particle moves. The offending area being:

rainDrop.prototype.display = function()
{
    if (changeSeason.checked)
    {
        // ...
    }
    else if (changeConfetti.checked)
    {
        //var confettiSize = random(1,8);

        confettiColor = colors[Math.floor(Math.random() * colors.length)];
        stroke(confettiColor);
        // ...
    }
    // ...
}

With the note that this color selection takes place as part of the display call. Instead, I think you want to select the color once, when the raindrop is created, and then use that same color each time the drop is re-displayed. One solution would be to add the color as a property on the raindrop. Eg, change the constructor:

var rainDrop = function()
{
    this.x = random(canvasWidth+1000);
    this.y = random(-100,-50);
    // Add this:
    this.confettiColor = colors[Math.floor(Math.random() * colors.length)];
};

Then reference that value in the display method:

stroke(this.confettiColor)

Here's a fork of your codePen with the fix.

Upvotes: 1

Related Questions