Les 4 - Objecten gebruiken voor balletjes
LET OP! Deze les begint met veel leeswerk. Zorg dat je dit wel goed leest en begrijpt. Vraag om extra uitleg als dat nodig is.
Waarschijnlijk heb je in je code voor de opdracht met meerdere balletjes iets gebruikt als volgt.
...
gebruiken we om aan te geven dat er op die plek wel code kan staan maar dat we dat niet op hebben geschreven.
...
let xSpeed1 = 2;
let ySpeed1 = 3;
let xBall1 = 21;
let yBall1 = 21;
let xSpeed2 = 5;
let ySpeed2 = 3;
let xBall2 = 50;
let yBall2 = 50;
let xSpeed3 = 1;
let ySpeed3 = 3;
let xBall3 = 70;
let yBall3 = 10;
...
function draw(){
background(255);
if (xBall1 > width - radius || xBall1 < radius){
xSpeed1 = -xSpeed1;
}
if (yBall1 > height - radius || yBall1 < radius){
ySpeed1 = -ySpeed1;
}
xBall1 += xSpeed1;
yBall1 += ySpeed1;
ellipse(xBall1, yBall1, 2*radius, 2*radius);
...
}
...
Voor drie balletjes gaat dit nog wel maar wat als je nou 20 balletjes wil gebruiken? Of 100? Dan wordt je code onleesbaar en een kleine verandering moet je op heel veel plekken je code gaan bijhouden. We willen graag een array of lijst gebruiken om de balletjes in op te slaan. Tot nu toe heb je alleen getallen of Strings opgeslagen in array's maar je kunt ook een heel balletje gaan opslaan en dat gaan met behulp van objecten.
Een object maken
In een object ga je dingen opslaan die bij dat object horen. Bij een balletje zijn dat bijvoorbeeld de x- en y-positie. Kijk in het voorbeeld hoe we dat doen. Om dat te doen maken we eerst een class
wat je kan zien als een template voor een balletje.
class Ball{
constructor(){
this.xPos = 20;
this.yPos = 30;
}
}
We beginnen dus met class
om aan te geven dat we een object gaan maken. In het object maak je altijd een constructor()
-functie. Hierin zet je dingen die je gelijk bij het maken van het object vast wilt leggen. Een soort setupfunctie dus.
Het sleutelwoord this
verwijst naar het object zelf. Zo kun je onderscheid maken tussen wat we noemen de scope van een letiabele. this.xPos
is een letiabele die alleen bestaat in het Ball
-object. Dus als je de volgende code uitvoert zul je op de console een fout krijgen. De letiabele xPos
is niet gedefinïeerd (bestaat niet).
class Ball{
constructor(){
this.xPos = 3;
this.yPos = 4;
this.radius = 6;
}
}
// De regel hieronder leggen we verderop uit
let ball1 = new Ball();
console.log(xPos);
En als je het volgende doet dan zal je de waarde 10 zien.
xPos = 10;
class Ball{
constructor(){
this.xPos = 20;
this.yPos = 30;
this.radius = 10;
}
}
// De regel hieronder leggen we verderop uit
let ball1 = new Ball();
console.log(xPos);
Wat verder belangrijk is dat het object een soort template is. Voordat je echt met het object kunt gaan werken moet je één of meerdere nieuwe objecten maken. Dit wil zeggen dat je meerdere balletjes kunt maken die allemaal een eigen xPos
, yPos
en radius
hebben. Je object legt bepaalde eigenschappen vast.
Het object in jouw programma
We gaan nu het voorbeeld met een balletje veranderen door een object te gebruiken. Een nieuwe instantie maak je in javascript als volgt: let ball1 = new Ball();
. Als je ball1
hebt gemaakt kun je met ball1.xPos
bijvoorbeeld de xPos
opvragen van dit ene balletje.
See the Pen mBPaRJ by Jurjenh (@jurjenh) on CodePen.
Voor nu lijkt het alsof dit ons niet verder heeft gebracht. We hebben veel meer code moeten invoeren! Geduld. De winst komt als we meerdere balletjes gaan gebruiken later.
Bovendien hebben we pas de eerste stap gedaan. Want objecten kunnen niet alleen letiabelen bevatten, maar ook methodes (functies). En dat is superhandig. We gaan nu een methode maken in de Ball-class waarmee we het balletje gaan tekenen en een methode om het balletje te bewegen.
class Ball{
constructor(){
this.xPos = 0;
this.yPos = 0;
this.radius = 1;
this.xSpeed = 0;
this.ySpeed = 0;
}
display(){
ellipse(this.xPos, this.yPos, 2*this.radius, 2*this.radius);
}
move(){
if (this.xPos > width - this.radius || this.xPos < this.radius){
this.xSpeed = -this.xSpeed;
}
if (this.yPos > height - this.radius || this.yPos < this.radius){
this.ySpeed = -this.ySpeed;
}
this.xPos += this.xSpeed;
this.yPos += this.ySpeed;
}
}
En nu komt ons programma er als volgt uit te zien.
let xSize = 600;
let ySize = 200;
let ball1;
function setup(){
createCanvas(xSize, ySize);
// We maken een bal aan
ball1 = new Ball();
ball1.xPos = 21;
ball1.yPos = 21;
ball1.radius = 10;
ball1.xSpeed = 5;
ball1.ySpeed = 3;
}
function draw(){
background(255);
ball1.display();
ball1.move();
}
class Ball{
constructor(){
this.xPos = 0;
this.yPos = 0;
this.radius = 1;
this.xSpeed = 0;
this.ySpeed = 0;
}
display(){
ellipse(this.xPos, this.yPos, 2*this.radius, 2*this.radius);
}
move(){
if (this.xPos > width - this.radius || this.xPos < this.radius){
this.xSpeed = -this.xSpeed;
}
if (this.yPos > height - this.radius || this.yPos < this.radius){
this.ySpeed = -this.ySpeed;
}
this.xPos += this.xSpeed;
this.yPos += this.ySpeed;
}
}
Beginwaarden meegeven bij het maken van een nieuw object
Een laatste verbetering is dat je bij het maken van een object alvast waarden kunt meegeven aan de 'constructor()'.
let xSize = 600;
let ySize = 200;
let ball1;
function setup(){
createCanvas(xSize, ySize);
// We maken een bal aan
ball1 = new Ball(21, 21, 10, 5, 3);
}
function draw(){
background(255);
ball1.display();
ball1.move();
}
class Ball{
constructor(x, y, radius, xspd, yspd){
this.xPos = x;
this.yPos = y;
this.radius = radius;
this.xSpeed = xspd;
this.ySpeed = yspd;
}
...
}
Opdracht
Maak zelf een stuiterend balletje waar je ook de kleur kunt instellen, met behulp van een object.
Opdracht
Herschijf je opdracht voor drie balletjes. Maak nu gebruik van een Ball class.