We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Imagine you have a task to display, over a cross, a circle with a color: when you click on it, you have to display another color (from a list) and so on.
Lot of beginners will do code like:
color[] colors = { #FF0000, #00FF00, #0000FF };
int currentColor;
void setup()
{
size(400, 400);
}
void draw()
{
background(255);
stroke(0);
strokeWeight(20);
line(0, 0, width, height);
line(0, height, width, 0);
if (mousePressed && dist(mouseX, mouseY, width / 2, height / 2) < 2 * width / 3)
{
currentColor++;
if (currentColor >= colors.length)
{
currentColor = 0;
}
}
noStroke();
fill(colors[currentColor]);
ellipse(width / 2, height / 2, 2 * width / 3, 2 * height / 3);
}
Then, they come to the forum, asking why the colors aren't displayed in the defined order...
The problem is simple: when the user clicks, the click duration spawns over several frames: by default, the frame rate is of 60 frames per second, so if the user clicks for a 10th of second, the mousePressed
state will be detected on 6 draw()
calls, resulting in displaying six colors in sequence!
Fortunately, the solution is simple too: for such case, it is better to use an event callback, like mousePressed()
. This function is called only once, whatever the duration of the click. So, they move code to this function:
color[] colors = { #FF0000, #00FF00, #0000FF };
int currentColor;
void setup()
{
size(400, 400);
}
void draw()
{
background(255);
stroke(0);
strokeWeight(20);
line(0, 0, width, height);
line(0, height, width, 0);
}
void mousePressed()
{
if (dist(mouseX, mouseY, width / 2, height / 2) < 2 * width / 3)
{
currentColor++;
if (currentColor >= colors.length)
{
currentColor = 0;
}
}
noStroke();
fill(colors[currentColor]);
ellipse(width / 2, height / 2, 2 * width / 3, 2 * height / 3);
}
But now, they complain they see the circle only briefly and only when clicking. That's because it is rarely a good idea to do drawing in these events. It is better to set up state variables, and to handle all drawings in draw()
:
color[] colors = { #FF0000, #00FF00, #0000FF };
int currentColor;
void setup()
{
size(400, 400);
}
void draw()
{
background(255);
stroke(0);
strokeWeight(20);
line(0, 0, width, height);
line(0, height, width, 0);
noStroke();
fill(colors[currentColor]);
ellipse(width / 2, height / 2, 2 * width / 3, 2 * height / 3);
}
void mousePressed()
{
if (dist(mouseX, mouseY, width / 2, height / 2) < 2 * width / 3)
{
currentColor++;
if (currentColor >= colors.length)
{
currentColor = 0;
}
}
}
See How to manage the steps of a game: increasing levels, displaying messages, etc.? for more details on state handling.