LESSON 4: EIGEN CHARACTER
INTRODUCTIE
In deze les ga je werken aan de ‘ziel’ van je eigen character. We gaan verder waar we in de vorige les gebleven zijn. De stappen in deze les zijn bedoeld als voorbeeld en je bent helemaal vrij om hier van af te wijken om zo echt je eigen character te maken.
STAP 1
In deze stap gaan we niet 1, maar 10 cirkels tekenen. Het zou niet zo handig zijn als we onze code 10 keer zouden kopiëren en plakken. Dat betekent namelijk dat als we iets aan willen passen dat we dat dan 10 keer aan moeten passen. In plaats daarvan kunnen we gebruik maken van een loop. Een loop bij coding is vergelijkbaar met een loop in een video. Het is een constructie waarbij een stukje code dus meerdere keren uitgevoerd kan worden. Laten we daarom een loop gebruiken om de 10 cirkels te gaan tekenen. Je zult in eerste instantie alleen nog geen verschil zien omdat alle 10 de cirkels op precies dezelfde manier getekend zullen worden. Daar gaan we iets aan doen in stap 2.
void setup() { size(400, 400); } void draw() { background(0); stroke(255); noFill(); // this ‘for-loop’ will execute the code within the { and } a number of time (10 in this case) for(int i = 0; i < 10; i++){ float phase = frameCount * 0.015; // every circle determines their own phase float x = sin(phase); // and x value float radius = map(x, -1, 1, 40, 300); // we use them for determining a radius float lineWidth = map(x, -1, 1, 0, 5); // and lineWidth strokeWeight(lineWidth); ellipse(width / 2, height / 2, radius, radius); } }
STAP 2
En nu de verschillen. Om 10 verschillende cirkels te zien kun je de eigenschappen van elke cirkel weer anders instellen. We kunnen bijvoorbeeld de phase voor elke cirkel net anders maken. Een phase (golf) is ook weer een wiskundige term voor een grootheid die de positie van een punt in beweging aangeeft en dus ook beweging brengt in je sketch.
In plaats van dat we de phase voor elke cirkel opnieuw bepalen doen we dit in 1 keer, voordat de loop begint. In de loop kunnen we dan elke keer de waarde van phase een klein beetje ophogen. Dit heeft als resultaat dat elke cirkel anders getekend zal worden. Je kunt in plaats van 10 ook 100 of 1000 cirkels tekenen, probeer maar eens uit. Als je dit doet zul je merken dat de sketch erg langzaam wordt. Probeer er daarom bij alles wat je aanpast goed op te letten dat de sketch er niet te langzaam van wordt.
void setup() { size(400, 400); } void draw() { background(0); stroke(255); noFill(); // by placing this line outside of the for-loop it will only be calculated once per frame // instead of for every circle float phase = frameCount * 0.015; 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); strokeWeight(lineWidth); ellipse(width / 2, height / 2, radius, radius); phase = phase + 0.3; // now we can add a small value to the phase so the next circle will have a slightly different phase } }
STAP 3
In deze stap gaan we kleur toevoegen aan ons character. We zouden 1 keer stroke kunnen aanroepen voordat we gaan tekenen, maar dan zouden alle cirkels dezelfde kleur hebben. Laten we weer gebruik maken van de variabele x en de functie map om elke cirkel een andere kleur te geven afhankelijk van de phase. Probeer zelf eens andere getallen in te vullen in map om te kijken wat er met de kleur van je character gebeurt.
void setup() { size(400, 400); } void draw() { background(0); stroke(255); noFill(); float phase = frameCount * 0.015; 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); // determine r, g and b values for color 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); // set the stroke color strokeWeight(lineWidth); ellipse(width / 2, height / 2, radius, radius); phase = phase + 0.3; } }
STAP 4
Het pulseren van de cirkels is voorspelbaar en misschien een beetje saai. Dit komt omdat we de phase elke keer met een vaste waarde ophogen (in dit geval 0.3). In het kader van creative coding kunnen we dit verhelpen door bijvoorbeeld de sinus-functie weer te gebruiken. Hiervoor introduceren we een nieuwe variabele phaseAddition, die we elk frame opnieuw berekenen aan de hand van de sinus van de phase. Deze phaseAddition gebruiken we vervolgens om de phase op te hogen elke keer dat we een cirkel tekenen.
Om het geheel nog iets onvoorspelbaarder en interessanter te maken hogen we de phaseAddition zelf ook op met een kleine waarde elke keer dat we een cirkel tekenen. Probeer eens te spelen met de getallen in de map functie en de waarde die we bij de phaseAddition optellen. Je zult zien dat kleine veranderingen in de getallen een grote impact kunnen hebben op de beweging van je character.
void setup() { size(400, 400); } void draw() { background(0); stroke(255); noFill(); float phase = frameCount * 0.015; float phaseAddition = map(sin(phase), -1, 1, 0, 0.25); // determine how much the phase should ‘shift’ for every circle 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; // this helps to create an even more unpredictable result } }