Created
December 9, 2012 15:32
-
-
Save erikdubbelboer/4245619 to your computer and use it in GitHub Desktop.
Dutch javascript space invaders tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Regels die met // starten zijn commentaar en horen niet bij de code van het programma. | |
// Dit soort regels zijn handig om dingen in uit te leggen zodat als je later | |
// de code nog eens door leest je nog weet wat er ook alweer precies gebeurd. | |
// Deze regels zijn in een browser nodig om 2d tekeningen te kunnen maken. | |
// ctx is het object wat wij straks kunnen gebruiken om alles mee te tekenen. | |
var canvas = document.getElementById('canvas'); | |
var ctx = canvas.getContext('2d'); | |
// We willen bijhouden welke toetsen de speler heeft ingedrukt. | |
// We gebruiken hier voor een object dat voor elke toets een variabele heeft. | |
var keys = { | |
up : false, // Als het spel start zijn alle toetsen nog niet ingedrukt. | |
down : false, | |
left : false, | |
right: false | |
}; | |
// Dit is een lijst (array) van de kogels. | |
var bullets = []; | |
// We slaan hier op hoe groot de kogels zijn. | |
var bulletSize = 10; | |
// Dit is het object van de speler. | |
// De speler heeft een x en y coördinaat. | |
// De speler heeft ook een breedte (sx) en hoogte (sy). | |
var player = { | |
x : 100, | |
y : 300, | |
sx: 20, | |
sy: 20 | |
}; | |
// Dit is een lijst van alle tegenstanders. | |
var enemies = []; | |
// We voegen hier met een loop een paar tegenstanders toe. | |
// We beginnen bij -10 zodat de eerste tegenstander net buiten de | |
// linker kant van het beeld is. | |
// We gaan elke keer 35 pixels naar rechts en voegen een nieuwe | |
// tegenstander toe. Dit doen we net zo lang tot dat we aan de rechter | |
// kant van het speelveld (wat 400 pixels breed is) zijn aangekomen. | |
for (var x = -10; x < 400; x += 35) { | |
// enemies is een lijst (array). Deze heeft een functie push waar | |
// mee we elementen aan de lijst kunnen toevoegen. | |
enemies.push({ | |
x: x, | |
y: 50 // Zet de tegenstander op hoogte 50. | |
}); | |
} | |
// We doen hier precies het zelfde als net alleen nu beginnen we bij 10 | |
// en stoppen we bij 410 waar door deze rij tegenstanders precies | |
// tussen de andere tegenstanders in zitten. Ook plaatsen we deze | |
// tegenstanders op hoogte 80 wat dus net onder de andere is. | |
for (var x = 10; x < 410; x += 35) { | |
enemies.push({ | |
x: x, | |
y: 80 | |
}); | |
} | |
// Met deze ingebouwde functie vragen we de browser om onze functie elke | |
// keer uit te voegen als de speler een toets indrukt. | |
window.addEventListener('keydown', function(e) { | |
if (e.keyCode == 38) { // 38 is de code voor het pijltje omhoog. | |
keys.up = true; | |
} else if (e.keyCode == 40) { // Omlaag. | |
keys.down = true; | |
} else if (e.keyCode == 37) { // Links. | |
keys.left = true; | |
} else if (e.keyCode == 39) { // Rechts. | |
keys.right = true; | |
} | |
// 107 is de code voor de + toets. | |
// Hier mee kunnen we de speler groter maken. | |
else if (e.keyCode == 107) { | |
player.sx += 5; | |
player.sy += 5; | |
} else if (e.keyCode == 109) { // - om de speler kleiner te maken. | |
player.sx -= 5; | |
player.sy -= 5; | |
} | |
// 32 is de code voor de spatie. Hier mee schiet je een kogel af. | |
else if (e.keyCode == 32) { | |
bullets.push({ | |
// Plaats de nieuwe kogel in het midden van de speler. | |
// De rechter kant van de speler zit op positie player.x. | |
// De kogel moet dus op die positie + de helft van de breedte | |
// van de de speler beginnen. Maar de kogel zelf heeft ook een | |
// breedte dus daar moet weer de helft er van af. | |
// | |
// Op deze manier komt de kogel altijd in het midden van de speler uit. | |
// Probeer de speler maar eens groter te maken met de + toets en dan | |
// een kogel af te schieten. | |
x: player.x + (player.sx / 2) - (bulletSize / 2), | |
// De kogel begint op dezelfde hoogte als de speler. | |
y: player.y | |
}); | |
} | |
}); | |
// Het zelfde als boven doen we voor als de speler de toets los laat. | |
window.addEventListener('keyup', function(e) { | |
if (e.keyCode == 38) { // Omhoog. | |
keys.up = false; | |
} else if (e.keyCode == 40) { // Omlaag. | |
keys.down = false; | |
} else if (e.keyCode == 37) { // Links. | |
keys.left = false; | |
} else if (e.keyCode == 39) { // Rechts. | |
keys.right = false; | |
} | |
}); | |
// Deze functie verwijdert de kogel op positie i uit de kogels lijst. | |
// We doen dit door een nieuwe lijst te maken waar de kogel die in de | |
// oude lijst op positie i zat er niet in te stoppen. | |
function removeBullet(i) { | |
var newBullets = []; | |
// We kunnen hier niet i als naam gebruiken omdat we die | |
// al als naam van een van de parameters van de functie hebben gebruikt. | |
// | |
// Loop door alle kogels heen. | |
for (var j = 0; j < bullets.length; j += 1) { | |
// Als de kogen niet op die positie zit van de kogel die we niet willen | |
// hebben voegen we hem aan de nieuwe lijst toe. | |
if (i != j) { | |
newBullets.push(bullets[j]); | |
} | |
} | |
// Vervang de huidige kogels lijst met de nieuwe die we net gemaakt hebben. | |
bullets = newBullets; | |
} | |
// Deze functie doet precies het zelfde als de functie hier boven (removeBullet) | |
// alleen deze functie verwijdert een tegenstander uit de tegenstanders lijst. | |
function removeEnemy(i) { | |
var newEnemies = []; | |
for (var j = 0; j < enemies.length; j += 1) { | |
if (i != j) { | |
newEnemies.push(enemies[j]); | |
} | |
} | |
enemies = newEnemies; | |
} | |
// Deze functie beweegt de speler. Waar de speler heen beweegt hangt af | |
// van welke toetsen de speler op dit moment ingedrukt heeft. | |
function movePlayer() { | |
if (keys.up) { | |
player.y -= 10; | |
} | |
if (keys.down) { | |
player.y += 10; | |
} | |
if (keys.left) { | |
player.x -= 10; | |
} | |
if (keys.right) { | |
player.x += 10; | |
} | |
// Als de speler buiten het speel veld beweegt plaatsen we hem gewoon | |
// weer terug naar de rand van het speel veld. | |
if (player.x < 0) { | |
player.x = 0; | |
} | |
// player.x is de linker kant van de speler dus player.x + player.sx is de | |
// rechter kant welke niet buiten de rechter kant van het speelveld mag komen. | |
else if ((player.x + player.sx) > 400) { | |
player.x = 400 - player.sx; | |
} | |
// Doe het zelfde voor de boven en onderkant van het speelveld. | |
if (player.y < 0) { | |
player.y = 0; | |
} else if ((player.y + player.sy) > 400) { | |
player.y = 400 - player.sy; | |
} | |
} | |
// Deze functie verplaatst de kogels. | |
function moveBullets() { | |
// loop door de lijst van kogels heen. | |
// bullets.length is een variabele die aan geeft hoe lang de | |
// kogels (bullets) lijst is. | |
for (var i = 0; i < bullets.length; i += 1) { | |
bullets[i].y -= 15; | |
// Als de kogel aan de bovenkant van het scherm aankomt verwijderen we hem. | |
// | |
// Met computer coördinaten tellen we in tegenstelling tot met grafieken | |
// altijd van boven naar beneden. De bovenkant van het speelveld is dus op | |
// y = 0 en de onderkant is y = 400. | |
// De x coördinaat gaat wel van links naar rechts zoals met grafieken. | |
if (bullets[i].y < 0) { | |
removeBullet(i); | |
} else { | |
// Als we de kogel niet verwijdert hebben kunnen we kijken of de kogel een | |
// tegenstander heeft geraakt. | |
// | |
// We lopen eerst door de lijst van alle tegenstanders heen. | |
// We kunnen hier niet weer i gebruiken omdat we nog in de | |
// loop hier boven zitten waar we i al gebruiken. | |
for (var j = 0; j < enemies.length; j += 1) { | |
// We gaan hier niet kijken of de kogel de tegenstander raakt | |
// maar of de kogel de tegenstander niet raakt. Ik heb dit zo | |
// gedaan omdat het controleren of de tegenstander niet geraakt is | |
// veel makkelijker is. | |
// | |
// We hoeven alleen maar te kijken of de kogel links, rechts, boven | |
// of onder te tegenstander zit. | |
// | |
// We kijken eerst of de kogel rechts zit. Dit is zo als de rechter | |
// kant van de kogel (x was links, dus x + de breedte van de kogel) | |
// minder is dan de linker kant van de tegenstander (x). | |
// | |
// de || betekend OF. Dus we willen dat een van deze dingen waar is. | |
if ((bullets[i].x + bulletSize < enemies[j].x ) || | |
// Daarna kijken we of de linker kant van de kogel (x) hoger is dan | |
// de rechter kant van de tegenstander. | |
(bullets[i].x > enemies[j].x + 20) || | |
// En we doen precies het zelfde met de hoogtes. | |
(bullets[i].y + bulletSize < enemies[j].y ) || | |
(bullets[i].y > enemies[j].y + 20)) { | |
// Als een van de vorige dingen waar was raakt de kogel deze | |
// tegenstander dus niet. | |
} else { | |
// Als al de vorige dingen niet waar was raakt de kogel de | |
// tegenstander dus wel. Verwijder in dat geval de kogel en | |
// de tegenstander. | |
removeEnemy(j); | |
removeBullet(i); | |
// Het break; commando kan gebruikt worden binnen in een for () | |
// loop om deze af te breken voordat de conditie in de loop | |
// (in dit geval j < enemies.length) onwaar is. | |
// Omdat deze kogel al een tegenstander geraakt heeft en dus zelf | |
// ook vernietigt is hoeven we niet verder te gaan met de loop. | |
break; | |
} | |
} | |
} | |
} | |
} | |
// Deze functie beweegt te tegenstanders naar rechts. | |
function moveEnemies() { | |
for (var i = 0; i < enemies.length; i += 1) { | |
enemies[i].x += 3; | |
// Als de tegenstander aan de rechterkant uit het beeld beweegt | |
// plaatsen we hem aan de linker kant net buiten het beeld. | |
// Op deze manier komt bij links weer tevoorschijn. | |
if (enemies[i].x > 400) { | |
enemies[i].x = -20 | |
} | |
} | |
} | |
// Deze functie tekend de speler. | |
function drawPlayer() { | |
// Kleuren worden aangegeven met rood,groen,blauw. | |
// Elke van deze heeft een waarde van 0 tot 255. | |
// Maak de speler groen. | |
// | |
// Je kan hier eens proberen met de kleuren te spelen. | |
ctx.fillStyle = 'rgb(0, 255, 0)'; | |
ctx.fillRect(player.x, player.y, player.sx, player.sy); | |
} | |
// Deze functie tekend de kogels. | |
function drawBullets() { | |
// De ctx.fillRect() functie gebruikt de ctx.fillStyle variabele voor de kleur. | |
// Omdat alle kogels dezelfde kleur hebben hoeven we deze variabele dus maar | |
// een keer te zetten en niet voor elke aanroep van ctx.fillRect(). | |
ctx.fillStyle = 'rgb(0, 0, 255)'; | |
for (var i = 0; i < bullets.length; i += 1) { | |
ctx.fillRect(bullets[i].x, bullets[i].y, bulletSize, bulletSize); | |
} | |
} | |
// Deze functie tekend de tegenstanders. | |
function drawEnemies() { | |
ctx.fillStyle = 'rgb(255, 0, 0)'; | |
for (var i = 0; i < enemies.length; i += 1) { | |
// De tegenstanders bestaan uit een vierkantje en 2 driehoekjes | |
// aan de zijkant. | |
// | |
// ctx.fillRect() wil als eerste argument een x coördinaat. | |
// Als 2e argument een y coördinaat. Als 3e argument een | |
// breedte en als 4e argument een hoogte. | |
// | |
// Probeer hier maar eens mee te spelen om de tegenstanders anders te tekenen. | |
ctx.fillRect(enemies[i].x + 5 , enemies[i].y , 10, 10); | |
ctx.fillRect(enemies[i].x , enemies[i].y + 5, 5 , 10); | |
ctx.fillRect(enemies[i].x + 15, enemies[i].y + 5, 5 , 10); | |
} | |
} | |
// De main functie is onze functie die meerdere keren per seconde aangeroepen zal worden. | |
// Deze functie zorgt er eerst voor dat alle objecten op het speelveld bewegen. | |
// Daarna maakt het het heel speelveld zwart en zorgt het er voor dat alles getekend | |
// wordt. | |
function main() { | |
// Beweeg alles. | |
movePlayer(); | |
moveBullets(); | |
moveEnemies(); | |
// Maak het speel veld zwart. | |
ctx.fillStyle = "rgb(0, 0, 0)"; | |
ctx.fillRect(0, 0, 400, 400); | |
// Teken alles. | |
drawPlayer(); | |
drawBullets(); | |
drawEnemies(); | |
} | |
// De ingebouwde setInterval() roept de functie die je als eerste argument mee | |
// geeft elke N milliseconde aan. Waar bij N het 2e argument is. | |
// In dit geval willen we dus dat onze main functie elke 100 milliseconde, | |
// dat is 10 keer per seconde, word aangeroepen. | |
setInterval(main, 100); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment