Yhdistetään hahmon ohjailu nuolinäppäimillä ja taulukkoidea ja luodaan peli, jossa avaruusalus väistelee putoavia meteoriittejä (ympyröitä). Ympyröillä on paikka (x,y) joiden arvot sijoitamme taulukkoon. Ympyrä sijoitetaan ikkunan yläreunassa taulukkoon ja poistetaan taulukosta ikkunan alareunassa. Ympyrän vaakasuuntainen paikka x arvotaan satunnaisesti ikkunan leveyden mukaan. Ympyrän pystysuuntainen paikka on alussa y = 0, mutta se kasvaa laskurin avulla. Käytänössä jokaisen ympyrän y arvoa taulukossa kasvatetaan laskurin pallot[a].y = pallot[a].y+nopeus avulla, missä a on for-silmukan muuttuja, joka käy läpi taulukon kaikki solut. Kokonainen ohjelma on seuraava.
var paikkax = 200; // Aluksen vaakasuuntainen paikka alussa var paikkay = 550; // Aluksen pystysuuntainen paikka alussa var koko = 20; // Aluksen koko var muutos = 0.2; // Aluksen nopeus var pisteet = 0; // Pisteet alussa var pallot = []; // Luodaan pallot taulukko var r = 10; // Meteoriitin (ympyrän) säde var nopeus = 2; // Meteoriitin nopeus function setup() { createCanvas(600, 600); // Ikkunan koko pallot[0] = { x:random(width), y:0 }; // Sijoitetaan ensimmäinen ympyrä taulukkoon textSize(20); // Tekstin koko 20 button = createButton('Uusi peli'); // Luo painonappi button button.position(500, 20); // Painonapin paikka oikean yläreuna eli piste (500,20) button.mousePressed(UusiPeli); // Kun painonappia painetaan, niin kutsu UusiPeli funktiota } function draw() { background(200,200,0); // Tyhjennä tausta fill(255,0,0); // Aseta punainen täyttöväri ympyrää varten for (var a=0; a< pallot.length; a++) { // Käy taulukon solut läpi ellipse(pallot[a].x,pallot[a].y,2*r,2*r); // Piirrä ympyrät, jossa paikka luetaan taulukosta pallot[a].y=pallot[a].y+nopeus; // Kasvata y:n arvoa nopeuden verran (= ympyrä liikkuu alaspäin) if (pallot[a].y == 50) { // 50 px välein pallot.push ({ // Luo uusi ympyrä taulukkoon x: random(width), // Arvotaan vaakasuuntainen paikka y: 0 // Sijoitetaan ikkunan yläreunaan }) } if (pallot[a].y > (height+r)) { // Jos ympyrä saavuttaa alareunan pallot.shift(); // Poista ympyrä taulukosta pisteet++; // Anna yksi piste, koska väistely on onnistunut } if (keyIsPressed) { // Jos painiketta painettu if ((keyCode == LEFT_ARROW) && (paikkax > koko)) { // Jos vasen pohjassa ja ei vielä ikkunan vasemmassa reunassa paikkax=paikkax-muutos; // Liiku vasemmalle pienentämällä paikkax:n arvoa muutoksen verran } // Lopeta jos if ((keyCode == RIGHT_ARROW) && (paikkax < (width-koko))) { // Jos oikea pohjassa ja ei vielä ikkunan oikeassa reunassa paikkax=paikkax+muutos; // Liiku oikealle kasvattamalla paikkax:n arvoa muutoksen verran } // Lopeta jos } // Lopeta ulompi jos (KeyIsPressed) hahmo(paikkax,paikkay,koko/100,0); // Jos ympyrä on avaruusaluksen sisällä if ( ((pallot[a].x+r) > paikkax) && ((pallot[a].x-r) < (paikkax+koko)) && ((pallot[a].y+r) > paikkay) && ((pallot[a].y-r) < (paikkay+koko)) ) { noLoop(); // Niin lopeta peli lopettamalla toisto draw-lohkosta } } fill(0); // Tekstin väri musta text("Pisteet: "+pisteet,10,50); // Näytä pisteet } function hahmo(x, y, koko,kulma) { var w = 150; // Pyöritys pisteen korjaus var h = 150; push(); // Koordinaatisto muistiin translate(x,y); // Liikuta hahmoa rotate(radians(kulma)); // Pyöritä hahmoa scale(koko); // Skaalaa hahmoa // Tästä alkaa oman hahmon piirtokomennot strokeWeight(3); fill(200,50,0); rect(70-w,130-h,20,100); rect(210-w,130-h,20,100); rect(110-w,200-h,80,40); fill(250,100,0); triangle(150-w,100-h,50-w,200-h,250-w,200-h); fill(180,80,0); beginShape(); vertex(150-w,50-h); vertex(170-w,100-h); vertex(200-w,220-h); vertex(100-w,220-h); vertex(130-w,100-h); endShape(CLOSE); fill(255,255,0); ellipse(150-w,125-h,40,50); // Tähän loppuu oman hahmon piirtokomennot pop(); } function UusiPeli() { pallot = []; pallot[0] = { x:random(width), y:0 }; paikkax = 200; paikkay = 550; pisteet = 0; loop(); } |
Voit testa peliä tässä. Avaruusalus liikkuu vasemmalle ja oikealle nuolinäppäimillä. Jos peli ei tottele nuolinäppäimiä, niin voit aluksi napsauttaa pelin päällä hiiren vasemmalla painikkeella, jotta ikkuna on valittu. Huomaa, että tätä peliä ei voi ohjata tabletilla.
Paranneltu peli
Parannetaan peliä vielä siten, että alus voi ampua (neliöitä). Ammuksia varten tarvitsemme toisen taulukon, johon ammukset sijoitetaan ja josta ne poistetaan. Lisäksi tarvitsemme ehdon, että onko ympyrä (= meteoriitti) neliön (=ammus) sisäpuolella. Jos on niin siinä tapauksessa poistamme ympyrän taulukosta eli taulukon keskeltä. Poisto taulukon keskeltä onnistuu splice-komennolla. Katsotaan koodia tarkemmin.
var paikkax = 200; // Aluksen aloituspaikka vaakasuunnassa var paikkay = 550; // Aluksen aloituspaikka pystysuunnassa var koko = 20; // Aluksen koko var muutos = 0.2; // Aluksen nopeus var pisteet = 0; // Pisteet alussa var ammuttu = false; // Ei vielä ammuttu, muuttuja estää sarjatulen var laskuri = 0; // Laskuri-muuttuja meteoriitteja varten, jotka luodaan laskurin avulla var pallot = []; // Luodaan pallot-taulukko (=meteoriitit) var ammukset = []; // Luodaan ammukset-taulukko (=ammukset) var r = 10; // Ympyrän säde var r2 = 20; // Neliön koko var nopeus = 2; // Meteoriitin (Ympyrän) nopeus var nopeus2 = 5; // Ammuksen (Neliön) nopeus function setup() { createCanvas(600, 600); // Ikkunan koko 600x600 pallot[0] = { x:random(width), y:0 }; // Sijoitetaan ensimmäinen ympyrä taulukkoo textSize(20); // Tekstin koko 20 button = createButton('Uusi peli'); // Luodaan painonappi button.position(500, 20); // painonapin paikka button.mousePressed(UusiPeli); // Kun painonappia painetaan, niin kutsutaan funktiota UusiPeli } function draw() { laskuri++; // Kasvata laskuria if (laskuri%50 == 0) { // Kun laskuri saa arvoja 50,100,150,200,250,... jne pallot.push ({ // niin luodaan uusi ympyrä x: random(width), // Arvotaan vaakasuuntainen paikka y: 0 // Sijoitetaan ikkunan yläreunaan }); } background(200,200,0); // Tyhjennä ikkuna fill(255,0,0); // Punainen täyttöväri for (var a = (pallot.length-1); a >= 0; a--) { // Käydään pallo-taulukko läpi lopusta alkuun ellipse(pallot[a].x, pallot[a].y ,2*r,2*r); // Piirrä ympyrät pallot[a].y=pallot[a].y+nopeus; // Liikuta ympyröitä alaspäin kasvattamalla y:n arvoa taulukossa if (pallot[a].y > (height+r)) { // Jos ympyrä on ikkunan alareunassa pallot.shift(); // niin poista ympyrä taulukosta pisteet++; // Anna piste lisää koska olet väistellyt onnistuneesti } // Avaruusaluksen ohjaus rakenne if (keyIsPressed) { // Jos näppäintä painettu if ((keyCode == LEFT_ARROW) && (paikkax > koko)) { // Jos vasemmalle painettu ja ei olla vielä reunassa paikkax=paikkax-muutos; // Liikuta avaruusalusta vasemmalle laskurin avulla } // Lopeta jos if ((keyCode == RIGHT_ARROW) && (paikkax < (width-koko))) { // Jos oikealle painettu ja ei olla vielä reunassa paikkax=paikkax+muutos; // Liikuta avaruusalusta oikealle laskurin avulla } // Lopeta jos if (key == char(32)) { // Jos painettu välilyönti painiketta if (ammuttu == false) { // Eikä vielä ammuttu ammukset.push ({ // Niin silloin luo neliö ammukset-taulukkoon x2: paikkax-10, // Ammuksen aloituspaikka avaruusaluksen mukaan y2: paikkay-30 // Ammuksen aloituspaikka avaruusaluksen mukaan }); ammuttu = true; // Muuta arvo ammuttu eli voi ampua uudestaan } // ennen kuin on vapauttanut painalluksen } } else { // Jos ei painike ole pohjassa ammuttu = false; // niin anna lupa ampua uudestaan } hahmo(paikkax,paikkay,koko/100,0); // Piirrä avaruusalus paikkaan (paikkax, piakkay) // Tarkistetaab onko meteoriitti osunut avaruusalukseen if ( ((pallot[a].x+r) > paikkax) && ((pallot[a].x-r) < (paikkax+koko)) && ((pallot[a].y+r) > paikkay) && ((pallot[a].y-r) < (paikkay+koko)) ) { noLoop(); // Lopeta toisto textSize(100); // Tekstin koko fill(255,0,255); // Tekstin väri text("Game Over",50,height/2); // Tulosta teksti: Game Over } // Tarkistetaan onko meteoriitti osunut ammukseen for (var b = (ammukset.length-1); b >= 0; b--) { if ( ((pallot[a].x+r) > ammukset[b].x2) && ((pallot[a].x-r) < (ammukset[b].x2+r2)) && ((pallot[a].y+r) > ammukset[b].y2) && ((pallot[a].y-r) < (ammukset[b].y2+r2)) ) { pallot.splice(a,1); // Poista meteoriitti eli ympyrä ammukset.splice(b,1); // Poista ammus eli neliö pisteet = pisteet+10; // Anna 10 pistettä hyvästä osumasta background(255); // Välähdys osumisen merkiksi } // Lopeta jos } // Lopeta for-silmukka } // Lopeta ulompi for-silmukka // Ammusten liikkuminen for-silmukan avulla for (var c=0; c< ammukset.length; c++) { // Käydään läpi ammustaulukko läpi fill(0,0,255); // Ammuksen väri sininen rect(ammukset[c].x2, ammukset[c].y2, r2, r2); // Piirrä ammukset eli neliöt ammukset[c].y2 = ammukset[c].y2 - nopeus2; // Liikuta ammuksia ylöspäin vähentämällä laskuria if (ammukset[c].y2 < 0) { // Jos ammus yläreunassa ammukset.shift(); // niin silloin poista ammus } // Lopeta jos } // Lopeta for-silmukka fill(0); // Musta tekstin väri textSize(20); // Tekstin koko text("Pisteet: "+pisteet,10,50); // Tulosta pisteet } function hahmo(x, y, koko,kulma) { var w = 150; // Pyöritys pisteen korjaus var h = 150; push(); // Koordinaatisto muistiin translate(x,y); // Liikuta hahmoa rotate(radians(kulma)); // Pyöritä hahmoa scale(koko); // Skaalaa hahmoa // Tästä alkaa oman hahmon piirtokomennot strokeWeight(3); fill(200,50,0); rect(70-w,130-h,20,100); rect(210-w,130-h,20,100); rect(110-w,200-h,80,40); fill(250,100,0); triangle(150-w,100-h,50-w,200-h,250-w,200-h); fill(180,80,0); beginShape(); vertex(150-w,50-h); vertex(170-w,100-h); vertex(200-w,220-h); vertex(100-w,220-h); vertex(130-w,100-h); endShape(CLOSE); fill(255,255,0); ellipse(150-w,125-h,40,50); // Tähän loppuu oman hahmon piirtokomennot pop(); } function UusiPeli() { pallot = []; ammukset = []; pallot[0] = { x:random(width), y:0 }; paikkax = 200; paikkay = 550; pisteet = 0; loop(); } |
Valmis peli näyttää tältä. Myös tässä napsauta kerran hiirellä ikkunan päällä, ennen kuin ohjata alusta nuolinäppäimillä. Avaruusalus ampuu neliöitä, kun painat nuolinäppäintä.
P5.JS YouTube-kurssi
Haluatko oppia p5.js ohjelmointia lisää? Coding Train on tehnyt YouTube-soittolistan, jossa on kokonainen kurssi P5.js-ohjelmoinnista.
https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA
Kirjastojen käyttö
Mikäli sinua kiinnostaa peliohjelmointi, niin siinä tapauksessa kanttaa tutustua seuraaviin JavaScript-kirjastoihin.
Kirjastoissa on valmiit toiminnot hahmojen liikkumiseen ja animointiin. Lisätietoja kirjastojen käytöstä ja niillä luoduista peleistä on löydettävissä myös YouTubesta. Kokosin tähän muutamia linkkejä. YouTubesta löytyy paljon ohjeita myös p5.js ohjelmointiin.