Opdracht 3 - De avatar besturen
Volgende opdracht - Vorige opdracht - Uitleg
In deze opdracht ga je de avatar laten bewegen met de pijltjestoetsen en, om ervoor te zorgen dat je de beweging goed kan zien, ga je ook wat extra objecten tekenen: bomen!
Bewegen met pijltjestoetsen
Voeg de volgende code toe, helemaal onderaan index.js
:
document.addEventListener('keydown', function(event) {
var code = event.keyCode;
var speed = 15;
if (code == 37) avatar.position.x = avatar.position.x - speed; // pijltje naar links
if (code == 38) avatar.position.z = avatar.position.z - speed; // pijltje omhoog
if (code == 39) avatar.position.x = avatar.position.x + speed; // pijltje naar rechts
if (code == 40) avatar.position.z = avatar.position.z + speed; // pijltje omlaag
});
Met de code document.addEventListener
vertellen we de webbrowser dat we willen reageren als de gebruiker een bepaalde actie uitvoert, in dit geval de actie keydown
, wat betekent: “het indrukken van een knop op het toetsenbord”. Alle code tussen de accolades (“{“ en “}”) wordt dus uitgevoerd iedere keer dat de gebruiker een toets indrukt.
Je kan achterhalen welke toets de gebruiker heeft ingedrukt met de code event.keyCode
. Dit geeft je een numerieke code terug welke overeenkomt met een bepaalde toets. De pijltjestoetsen hebben de codes 37 tot en met 40.
Nu kun je de avatar laten bewegen door de positie in een bepaalde richting te veranderen op basis van welk pijltje ingedrukt wordt. Hoeveel je de positie verandert hangt af van de waarde van speed
: een hogere waarde betekent dat je avatar sneller beweegt.
De animatie(s) starten en stoppen
In opdracht 2 heb je een salto-animatie toegevoegd, maar de enige manier om deze animatie aan of uit te zetten is door de is_cartwheeling
waarde te veranderen van true
naar false
of omgekeerd. Dat ga je nu veranderen.
Pas om te beginnen de animate
functie als volgt aan:
var is_cartwheeling = false;
var is_flipping = false;
function animate() {
requestAnimationFrame(animate);
if (is_cartwheeling) {
avatar.rotation.z = avatar.rotation.z + 0.05;
}
if (is_flipping) {
avatar.rotation.x = avatar.rotation.x + 0.05;
}
renderer.render(scene, camera);
}
animate();
Dit voegt een extra “flip”-animatie toe. Want, waarom niet 😉?
Pas vervolgens de addEventListener
code aan:
document.addEventListener('keydown', function(event) {
var code = event.keyCode;
var speed;
if (code == 37) avatar.position.x = avatar.position.x - speed; // pijltje naar links
if (code == 38) avatar.position.z = avatar.position.z - speed; // pijltje omhoog
if (code == 39) avatar.position.x = avatar.position.x + speed; // pijltje naar rechts
if (code == 40) avatar.position.z = avatar.position.z + speed; // pijltje omlaag
if (code == 67) is_cartwheeling = !is_cartwheeling; // C
if (code == 70) is_flipping = !is_flipping; // F
});
Nu kan de gebruiker de animaties zelf starten met de c
of f
toets.
Het uitroepteken in de code (!
) betekent: Draai de waarde om, dus als de waarde true
was, dan wordt het nu false
en omgekeerd.
Bomen tekenen
Je avatar kan zich nu bewegen, maar wat heb je daaraan in een saaie, lege spelwereld. Om pas echt plezier van het rondrennen te hebben ga je nu wat nieuwe objecten toevoegen, namelijk bomen.
Voeg de volgende code toe, nadat je alle ledematen van de avatar hebt gemaakt, maar voor de animate
functie:
makeTreeAt( 500, 0);
makeTreeAt(-500, 0);
makeTreeAt( 750, -1000);
makeTreeAt(-750, -1000);
function makeTreeAt(x, z) {
var trunk = new THREE.Mesh(
new THREE.CylinderGeometry(50, 50, 200),
new THREE.MeshBasicMaterial({color: 0xA0522D})
);
var top = new THREE.Mesh(
new THREE.SphereGeometry(150),
new THREE.MeshBasicMaterial({color: 0x228B22})
);
top.position.y = 175;
trunk.add(top);
trunk.position.set(x, -75, z);
scene.add(trunk);
}
Omdat alle bomen er hetzelfde uitzien, maak je een functie makeTreeAt
om eenvoudig meerdere bomen te maken. De eerste vier regels roepen deze functie aan om vier bomen te maken op verschillende posities.
In de makeTreeAt
functie maak je een boom die bestaat uit twee onderdelen: de bruine boomstam (de trunk
) en de groene boomtop (de top
). Vervolgens stel je de positie in van de boom aan de hand van de parameters die zijn ingevoerd bij het aanroepen van de functie (x
en z
) en voeg je de boom toe aan de scene
.
De kleuren in de code zien er misschien vreemd uit: 0xA0522D
voor bruin en 0x228B22
voor groen. Dat komt omdat THREE.js
zogenaamde “hexadecimale” codes gebruikt voor kleuren. Gelukkig hoef je die codes niet allemaal uit je hoofd te leren, want op internet zijn er genoeg plekken waar je ze kan achterhalen, zoals hier.
De camera en avatar samen bewegen
Het valt je misschien op dat je de avatar nu wel kunt bewegen, maar voor je het weet loopt hij zo het scherm uit! Om dat te voorkomen kan je de camera vastmaken aan de avatar.
Voeg de volgende regel toe, net voor de 4 makeTreeAt
regels:
avatar.add(camera);
Nu beweegt de camera ook mee als je de avatar beweegt. Helaas werkt dit nog niet vlekkeloos. Probeer namelijk maar eens om de animaties te starten.
Probleem met animaties oplossen
Als je de animatie aanzet, dan blijft je avatar stilstaan terwijl de spelwereld om hem heen beweegt! Dat komt omdat je de camera aan de avatar hebben toegevoegd en dat deze dus mee roteert.
Om dat op te lossen ga je een nieuw object toevoegen waarmee je de camera en avatar aan elkaar kunnen koppelen, maar waarmee je nog steeds de avatar los van de camera kan roteren.
Voeg de volgende code toe, direct onder de regel // ******** SCHRIJF AL JE CODE NA DEZE REGEL ********
:
var marker = new THREE.Object3D();
scene.add(marker);
Zoek nu de volgende twee regels code op (let op: ze staan niet bij elkaar zoals hieronder):
scene.add(avatar);
avatar.add(camera);
en vervang ze door:
marker.add(avatar);
marker.add(camera);
Pas tot slot de addEventListener
code aan:
document.addEventListener('keydown', function(event) {
var code = event.keyCode;
var speed = 15;
if (code == 37) marker.position.x = marker.position.x - speed; // pijltje naar links
if (code == 38) marker.position.z = marker.position.z - speed; // pijltje omhoog
if (code == 39) marker.position.x = marker.position.x + speed; // pijltje naar rechts
if (code == 40) marker.position.z = marker.position.z + speed; // pijltje omlaag
if (code == 67) is_cartwheeling = !is_cartwheeling; // C
if (code == 70) is_flipping = !is_flipping; // F
});
Nu beweeg je het marker
object met de pijltjestoetsen en omdat je zowel de avatar
als de camera
aan dat marker
object hebt gekoppeld bewegen ze samen mee.
Maar omdat je de rotatie in de animate
functie niet hebt aangepast (die roteert nog steeds de avatar
) zal de camera nu stil blijven en lijkt het niet meer of de spelwereld mee draait.