Close menu
Close menu

Tunnistaudu

Kirjaudu

Etkö ole vielä jäsen?

Liity jäseneksi

Putoavat pallot

Tehdään ohjelma, jossa arvotaan 100 ympyrää satunnaiseen paikkaan (x,y), jotka putoavat alaspäin. Tällöin ympyrän pystysuuntainen paikka y kasvaa laskurin avulla nopeuden verran. Kun ympyrä putoaa ulos ikkunasta (= ikkunan korkeus + ympyrän säde), niin muuttujan y-arvo nollataan eli tällöin ympyrä palautuu takaisin ylös.

var x = [ ];  // Luodaan taulukko x
var y = [ ];  // Luodaan taulukko y
var R = [ ];  // Luodaan taulukko R
var G = [ ];  // Luodaan taulukko G
var B = [ ];  // Luodaan taulukko B
var A = [ ];  // Luodaan taulukko A
var r = 50;      // Määritellään muuttuja r ja annetaan sille alkuarvo 50 (ympyrän säde)
var nopeus = 5;  // Määritellään muuttuja nopeus ja annetaan sille alkuarvo 5
function setup() {
  createCanvas(600, 600);          // Ikkunan koko 600 x 600
  for (var a = 0; a < 100; a++) {  // For-silmukka, jossa a saa arvoja 0,1,2,...,99
    x[a] = random(width);          // Arvo taulukkoon x satunnainen luku väliltä 0...600 (=witdth)
    y[a] = random(height);         // Arvo taulukkoon y satunnainen luku väliltä 0...600 (=height)
    R[a] = random(255);            // Arvo taulukkoon R satunnainen luku väliltä 0...255
    G[a] = random(255);            // Arvo taulukkoon G satunnainen luku väliltä 0...255
    B[a] = random(255);            // Arvo taulukkoon B satunnainen luku väliltä 0...255
    A[a] = random(255);            // Arvo taulukkoon A satunnainen luku väliltä 0...255
  }
}
function draw() {
   background(200,200,0);            // Tyhjennä tausta ja väritä se keltaiseksi
   noStroke();                       // Ei reunaviivaa
   for (var b=0; b< y.length; b++) { // Käy läpi taulukon y kaikki solut (0,1,2,3,...,length)
    fill(R[b], G[b], B[b], A[b]);    // Aseta täyttöväri. Lue värin arvot tulukoista R, G, B ja A
    ellipse(x[b],y[b],2*r,2*r);      // Piirrä ympyrä, jonka halkasija on 2r paikkaan (x,y)
    y[b]=y[b]+nopeus;                // Kasvata pallon pystysuuntaista paikkaa y-taulukossa nopeuden verran
    if (y[b] > (height+r)) {         // Jos y:n arvo on suurempi kuin ikkunan korkeus+ympyrän säde, niin 
        y[b] = 0;                    // nollaa y:n arvo eli palauta se takaisin ylös
    } 
  }
}

 

Kuten havaitaan pallot vain siirtyvät alhaalta ylös samoihin paikkoihin kuin alussa arvotut paikat.

Kehitetään edellistä esimerkkiä eteenpäin. Kuinka taulukkoon voidaan lisätä uusia soluja taulukon loppuun? Entä kuinka voitaisiin poistaa taulukon ensimmäinen solu? Nämä onnistuvat JavaScript:n push(); ja shift(); komenoilla.

Komento Merkitys
taulukko.push(Solun arvo) Komento lisää uuden solun taulukon loppuun.
taulukko.shift() Komento poistaa solun taulukon alusta.

Katsotaan asiaa esimerkin avulla. Luodaan esimerkiksi taulukko, jossa on kirjaimet A,B,C,D,E. Komennolla push voimme lisätä taulukon loppuun uuden solun ja sijoittaa siihen uuden kirjaimen. Vastaavasti komennolla shift voimme poistaa taulukon alusta yhden solun. Samalla poistuu taulukon solun sisältö eli tässä tapauksessa ”A”-kirjain.


Tehdään edellinen harjoitus uudestaan käyttäen push ja shift-komentoja. Setup-lohkossa arvotaan vain yhdelle ympyrälle arvot, joka lähtee putoamaan. Tehdään ohjelmaan ehto, kun taulukon y-arvo on 20, niin luodaan uusi ympyrä eli taulukon koko kasvaa yhdellä. Vastaavasti jos taulukon y:n arvo on suurempi kuin ikkunan korkeus summattuna ympyrän säteellä, niin poistetaan taulukon viimeinen solu. Koska ympyrät luodaan järjestyksessä, niin taulukon ensimmäinen ympyrä on aina alimmainen, joka poistetaan ensimmäisenä.

var x = [ ];  // Tyhjien taulukoiden luonti
var y = [ ];
var R = [ ];
var G = [ ];
var B = [ ];
var A = [ ];
var r = 50;                // Ympyrän säde
var nopeus = 5;            // Ympyrän nopeus
function setup() {
  createCanvas(600, 600);  // Ikkunan koko 600 x 600
  x[0] = random(width);    // Sijoitetaan ensimmäiseen soluun arvot
  y[0] = 0; 
  R[0] = random(255);
  G[0] = random(255);
  B[0] = random(255);
  A[0] = random(255);
}
function draw() {
   background(200,200,0);              // Tyhjennä tausta
   noStroke();                         // Ei reunaviivaa

   for (var a=0; a< y.length; a++) {   // Käydään läpi taulukon solut
    fill(R[a], G[a], B[a], A[a]);      // Asetetaan täyttöväri taulukoista
    ellipse(x[a],y[a],2*r,2*r);        // Piirretään ympyrä
    y[a]=y[a]+nopeus;                  // Ympyrä liikkuu alaspäin laskurin avulla
    if (y[a] == 20) {                  // Kun viimeksi luotu (edellinen) ympyrä saa arvon 20
            x.push(random(width));     // Niin luodaan uusi ympyrä uuteen soluun
            y.push(0);
            R.push(random(255));
            G.push(random(255));
            B.push(random(255));
            A.push(random(255));
    }
    if (y[a] > (height+r)) {           // Jos  ympyrä ikkunan alareunassa, niin poista taulukon ensimmäinen solu
          x.shift();
          y.shift();
          R.shift();
          G.shift();
          B.shift();
          A.shift();
    } 
  }
}

Yllä olevassa ohjelmassa on vielä sellainen puute, että siinä on satunnaiselle värille (R G B A) ja ympyrän paikalle (x,y) kullekin oma taulukkonsa. Voisimmeko käyttää vain yhtä taulukkoa? Kyllä se onnistuu, kun käytämme taulukon olio-ominaisuutta hyväksi. Luodaan yksi taulukko jonka nimi on pallot ja sijoitetaan siihen kaikki muuttujat arvoineen. Käytämme tässä rakennetta:

var taulukko = { muuttuja1 : arvo1, muuttuja2 : arvo2, … ,muuttujan : arvon };

Huomaa, että jokaisen taulukon sisällä olevan muuttujan nimen perässä on kaksoispiste, jonka jälkeen sijoitetaan muuttujalle arvo. Kun haluamme taulukkoon sijoittaa toisen muuttujan arvo, niin käytämme välissä pilkkua.

Kun haluamme saada taulukon ensimmäisen solun ensimmäisen muuttujan arvon, niin viittaamme siihen rakenteella:

taulukko[0].muuttuja1

Alla oleva kuva havainnollistaa asiaa.

Muutetaan edellinen esimerkki yhteen taulukkoon eli luodaan yksi taulukko jonka nimi on pallot ja sijoitetaan siihen kaikki muuttujat arvoineen.

var pallot = [];  // Luo tyhjä taulukko
var r = 50;       // Pallon säde
var nopeus = 5;   // pallon nopeus
function setup() {
  createCanvas(600, 600);           // Ikkunan koko
  pallot[0] = { x:random(width),    
                y:0, 
                R : random(255),
                G : random(255),
                B : random(255),
                A : random(255)
              };
}
function draw() {
   background(200,200,0);
   noStroke();

   for (var a=0; a< pallot.length; a++) {
    fill(pallot[a].R, pallot[a].G, pallot[a].B, pallot[a].A);
    ellipse(pallot[a].x,pallot[a].y,2*r,2*r); 
    pallot[a].y=pallot[a].y+nopeus;
    if (pallot[a].y == 20) {       // Jos pallo on paikassa y = 20, niin 
          pallot.push ({           // lisää uusi pallo
            x: random(width),
            y: 0,
            R : random(255),
            G : random(255),
            B : random(255),
            A : random(255)
          })
    }
    if (pallot[a].y > (height+r)) {  // Jos pallo on alareunassa
          pallot.shift();            // niin poista pallo
    } 
  }
}

Ohjelma toimii halutunlaisesti ja lopputulos näyttää tältä.

Ideoiden yhdistäminen

Haluamme tehdä ohjelman, jossa hahmo eli avaruusalus liikkuu alhaalta ylös ja taustalla pallot putoavat ylhäältä alas edellisen esimerkin mukaisesti. Yhdistämme nyt kaikki aikaisemmin käydyt ideat samaan ohjelmaan. Katsotaan ensin ohjelman koodi läpi.

var pysty = 650; // Hahmon aloitus paikka pystysuunnassa
var vaaka = 300; // Hahmon aloitus paikka vaakasuunnassa
var koko = 1;    // Kerroin, joka ilmaisee avaruusaluksen koon
var muutos = 2;  // Avaruusaluksen nopeus vaakasuunnassa

var pallot = []; // Taulukko palloja varten
var r = 50;      // Pallon säde
var nopeus = 5;  // pallon putoamisnopeus (Huomio: 20 pitää olla jaollinen nopeudella)

var tausta;      // Luodaan muuttuja taustatasoa varten
function setup() {
  createCanvas(600, 600);             // Ikkunan koko on 600 x 600
  tausta = createGraphics(600, 600);  // Luodaan taustataso, jonka koko on 600 x 600
  tausta.clear();                     // Tyhjennä taustataso
 
  pallot[0] = { x:random(width),      // Luodaan ensimmäinen pallo
                y:0, 
                R : random(255),
                G : random(255),
                B : random(255),
                A : random(255)
              };
}

function draw() {
   background(200,200,0);              // Tyhjennä tausta ja väritä se keltaiseksi
  
   // Alempi-taso
   tausta.clear();                     // Tyjennä pallo-taso
   tausta.noStroke();                  // Ei reunaviivaa palloissa
   for (var a=0; a< pallot.length; a++) {
    tausta.fill(pallot[a].R, pallot[a].G, pallot[a].B, pallot[a].A);   // Aseta väri
    tausta.ellipse(pallot[a].x,pallot[a].y,2*r,2*r);                   // Piirrä pallot
    pallot[a].y=pallot[a].y+nopeus;                                    // Liikuta palloja alas
    if (pallot[a].y == 20) {                                           // jos y = 20 (Katso huomio ylempää)
          pallot.push ({                                               // niin luo uusi pallo
            x: random(width),
            y: 0,
            R : random(255),
            G : random(255),
            B : random(255),
            A : random(255)
          })
    }
    if (pallot[a].y > (height+r)) {                   // Jos alareunassa
          pallot.shift();                             // Poista pallo
    } 
  }
  image(tausta, 0, 0);                                // Piirrä pallo taustatasolle                                 
  
  // Ylempi taso 
  pysty--;                                // Liikesuunta ylös
  vaaka = vaaka+muutos;                   // Sivuttaisliike vaakasuunnassa
  hahmo(vaaka,pysty,koko,pysty);          // Kutsutaan aliohjelmaa
  if (pysty < -250) {                     // Jos hahmo ylhäällä
    pysty = 650;                          // silloin nollaa laskuri (= palauta alas)
  }
  if (vaaka > 500) {                     // Jos oikeassa reunassa
    muutos = -muutos;                    // liiku vasemalle
  }
  if (vaaka < 100) {                     // Jos vasemmassa reunassa
    muutos = -muutos;                    // liiku oikealle
  }
}

function hahmo(x, y, koko,kulma) {
  var w = 150;  // Pyöritys keskipisteen 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();
}

Lopullinen animaatio näyttää nyt tältä.