LESSON 5: INTERACTIE & IMPULSES
INTRODUCTIE
Tot nu toe zijn we er van uit gegaan dat je character alleen is en geen prikkels van buitenaf krijgt. In deze les gaan we kijken hoe we kunnen reageren op prikkels. Zodra je character wordt losgelaten in de buitenwereld zal er een variabele agitation beschikbaar zijn. Deze variabele zal altijd een waarde tussen 0 en 1 hebben. De waarde van agitation wordt bijvoorbeeld beïnvloed door de aanwezigheid van andere characters: als er veel characters in de buurt zijn zal agitation een hogere waarde hebben dan wanneer je character helemaal alleen is. Dit geeft straks ook een heel mooi visueel effect als er steeds meer characters worden losgelaten in de environment.
STAP 1
Om te kunnen reageren op deze externe prikkel moet je 2 dingen toevoegen: de functie setAgitation en de variabele agitation. Deze functie zal aangeroepen worden als er een nieuwe waarde is en deze waarde kun je vervolgens opslaan in de variabele agitation. Omdat je character nog niet in de omgeving is losgelaten zal deze functie niet vanzelf worden aangeroepen. Om de agitation te kunnen testen moeten we deze functie dus zelf aanroepen.
Eén manier om dit te doen is om de variabele mouseX te gebruiken. Voordat je je character uiteindelijk gaat uploaden moet je niet vergeten deze regel weer weg te halen, omdat de agitation dan vanzelf door de omgeving geset zal worden. Deze sketch ziet er hetzelfde uit als de vorige, aangezien we de agitation nog niet gebruiken om je character anders te laten tekenen.
// variable to save the agitation float agitation = 0; void setup() { size(400, 400); } // this function will be called by the environment void setAgitation(float newAgitation) { agitation = newAgitation; } void draw() { background(0); stroke(255); noFill(); // only for testing: use the horizontal mouse position to control the agitation setAgitation(map(mouseX, 0, width, 0, 1)); float phase = frameCount * 0.015; float phaseAddition = map(sin(phase), -1, 1, 0, 0.25); for(int i = 0; i < 10; i++){ float x = sin(phase); float radius = map(x, -1, 1, 40, 300); float lineWidth = map(x, -1, 1, 0, 5); float r = map(x, -1, 1, 0, 255); float g = map(x, -1, 1, 255, 0); float b = map(x, -1, 1, 255, 125); stroke(r, g, b); strokeWeight(lineWidth); ellipse(width / 2, height / 2, radius, radius); phase = phase + phaseAddition; phaseAddition += 0.05; } }
STAP 2
We kunnen nu agitation gebruiken om bijvoorbeeld de dikte van de cirkels te variëren. We gebruiken in dit voorbeeld de random functie om de dikte van de cirkels op een onvoorspelbare manier elk frame aan te passen.
float agitation = 0; void setup() { size(400, 400); } void setAgitation(float newAgitation) { agitation = newAgitation; } void draw() { background(0); stroke(255); noFill(); setAgitation(map(mouseX, 0, width, 0, 1)); float phase = frameCount * 0.025; float phaseAddition = map(sin(phase), -1, 1, 0, 0.75); for(int i = 0; i < 10; i++){ float x = sin(phase); float radius = map(x, -1, 1, 40, 300); float lineWidth = map(x, -1, 1, 0, 5); float r = map(x, -1, 1, 0, 255); float g = map(x, -1, 1, 255, 0); float b = map(x, -1, 1, 255, 125); stroke(r, g, b); // use agitation to change the lineWidth randomly float lineWidthAddition = random(map(agitation, 0, 1, 0, 25)); strokeWeight(lineWidth + lineWidthAddition); ellipse(width / 2, height / 2, radius, radius); phase = phase + phaseAddition; phaseAddition += 0.1; } }
STAP 3
We kunnen agitation voor van alles gebruiken. Als laatste voorbeeld gaan we er voor zorgen dat je character helemaal wit is als agitation 0 is en dat hij kleur krijgt als agitation 1 is. Om dit voor elkaar te krijgen maken we gebruik van de functie lerp, deze functie kun je gebruiken voor zogenaamde lineaire interpolatie. Dit betekent dat we 2 getallen als het ware kunnen mengen. In ons geval willen we alle drie de kleur-componenten (r, g en b) interpoleren tussen 255 (wit) en de kleur-waarde die we eerder bepaald hebben. lerp ziet er zo uit:
float a = 100; float b = 200; float interpolated = lerp(a, b, 0.5)
In dit kleine voorbeeld interpoleren (het schatten van een waarde tussen twee bekende waarden) we tussen de waardes van a en b. Het getal 0.5 geeft aan dat we precies in het midden willen gaan zitten en het resultaat zal dan ook 150 zijn. Stel dat je in plaats van 0.5 de waarde 0 in zou vullen dan is het resultaat 100, en voor de waarde 1 is het resultaat 200. We willen voor deze waarde gebruik maken van de agitation:
float agitation = 0; void setup() { size(400, 400); } void setAgitation(float newAgitation) { agitation = newAgitation; } void draw() { background(0); stroke(255); noFill(); setAgitation(map(mouseX, 0, width, 0, 1)); float phase = frameCount * 0.025; float phaseAddition = map(sin(phase), -1, 1, 0, 0.75); for(int i = 0; i < 10; i++){ float x = sin(phase); float radius = map(x, -1, 1, 40, 300); float lineWidth = map(x, -1, 1, 0, 5); float r = map(x, -1, 1, 0, 255); float g = map(x, -1, 1, 255, 0); float b = map(x, -1, 1, 255, 125); // use the lerp function to interpolate between white and colored depending on agitation r = lerp(255, r, agitation); g = lerp(255, g, agitation); b = lerp(255, b, agitation); stroke(r, g, b); float lineWidthAddition = random(map(agitation, 0, 1, 0, 25)); strokeWeight(lineWidth + lineWidthAddition); ellipse(width / 2, height / 2, radius, radius); phase = phase + phaseAddition; phaseAddition += 0.1; } }