var _socialDistanceCount = 0;
createCanvas(_bounds, _bounds + 100);
_normalColor = color(80, 200, 80);
_sickColor = color(210, 200, 0);
_recoveryColor = color(203, 138, 192);
_deadColor = color(200, 70, 70);
_noDistButton = createButton("No social distance");
_noDistButton.position(0, _bounds - 25);
_noDistButton.mousePressed(onNoDistTriggered);
_lowDistButton = createButton("Low social distance");
_lowDistButton.position(130, _bounds - 25);
_lowDistButton.mousePressed(onLowDistTriggered);
_highDistButton = createButton("High social distance");
_highDistButton.position(270, _bounds - 25);
_highDistButton.mousePressed(onHighDistTriggered);
_collisionsButton = createButton("Disable collisions");
_collisionsButton.position(410, _bounds - 25);
_collisionsButton.mousePressed(onCollisionsTriggered);
rect(0, 0, _bounds, _bounds);
for (let i = 0; i < _people.length; i++) {
_normalCount = population;
_socialDistanceCount = 0;
rect(0, _bounds, _bounds, _bounds - 100);
for (let i = 0; i < population; i++) {
let person = new Person(random(_bounds), random(_bounds));
if (i / population * 100 < socialDistance) {
person.practiceSocialDistance();
for (let i = 0; i < _people.length; i++) {
if (!_people[i].socialDistance) {
_people[i].setState(SICK);
function displayStats() {
text("Total: " + _people.length, 10, 20);
text("Social distance: " + _socialDistanceCount + " (" + percentage(_socialDistanceCount, _people.length) + "%)", 10, 40);
text("Healthy: " + _normalCount + " (" + percentage(_normalCount, _people.length) + "%)", 10, 60);
text("Sick: " + _sickCount + " (" + percentage(_sickCount, _people.length) + "%)", 10, 80);
text("Recovered: " + _recoveryCount + " (" + percentage(_recoveryCount, _people.length) + "%)", 10, 100);
text("Passed: " + _deathCount + " (" + percentage(_deathCount, _people.length) + "%)", 10, 120);
function displayGraph() {
let sickHeight = map(_sickCount, 0, _people.length, height - 100, height) - _bounds;
let normalHeight = map(_normalCount, 0, _people.length, height - 100, height) - _bounds;
let recoveryHeight = map(_recoveryCount, 0, _people.length, height - 100, height) - _bounds;
let deadHeight = map(_deathCount, 0, _people.length, height - 100, height) - _bounds;
let speed = frameCount * 0.25;
line(speed, y, speed, y - deadHeight);
stroke(red(_deadColor) + brighter, green(_deadColor) + brighter, blue(_deadColor) + brighter);
point(speed - 1, y - deadHeight);
line(speed, y, speed, y - sickHeight);
stroke(red(_sickColor) + brighter, green(_sickColor) + brighter, blue(_sickColor) + brighter);
point(speed - 1, y - sickHeight);
line(speed, y, speed, y - normalHeight);
line(speed, y, speed, y - recoveryHeight);
stroke(red(_recoveryColor) + brighter, green(_recoveryColor) + brighter, blue(_recoveryColor) + brighter);
text("OUTBREAK DONE", width / 2, height / 2);
function percentage(value, maxValue) {
return (value / maxValue * 100.0).toFixed(1);
function onNoDistTriggered() {
function onLowDistTriggered() {
function onHighDistTriggered() {
function onCollisionsTriggered() {
_collisions = !_collisions;
_collisionsButton.html("Disable collisions");
_collisionsButton.html("Enable collisions");