mgr inż. Wacław Libront * Bobowa 2017-2019

ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu

Lekcja 6

Tablice w JS

  1. tablice
  2. losowanie
  3. zmienne
  4. rysowanie

Tablice
Jak sprawić, aby po ekranie „fruwało” 100 kwadratów? Definiować tyle zestawów zmiennych? Z pomocą przychodzą tablice, które są zestawem komórek, w których można zapamiętać wiele zmiennych. Definicja pustej tablicy i przypisywanie do niej jest niezwykle proste. Pamiętać należy, że pierwszy element tablicy ma numer „zero”. Do każdego elementu tablicy można przypisać liczbę, tekst albo obiekty złożone, np. inną tablicę – w tym przypadku mamy do czynienia z tablicami wielowymiarowymi.

 

Typową tablicę jednowymiarową definiujemy i przypisujemy do niej wartości, jak pokazano w poniższej ramce. W naszym animowanym przykładzie będziemy chcieli, aby w tablicy były zapisane wszystkie współrzędne, skoki, kolory kwadratów, dlatego wygodniej będzie posłużyć się tablicą dwuwymiarową (pokratkowana kartka papieru).

//tablica jednowymiarowa
var TK = [];
//do elementu zerowego wstawiamy liczbę 100
TK[0] = 100;
//zmienna x przyjmuje wartość 100
x = TK[0];

W tablicy TK, w elemencie o numerze [0] zapamiętano 8 danych koniecznych do animowania jednego kwadratu, w kolejności: x, y, bok, kąt, kolor, vx, vy, vk. W ramce przykłąd definiowania takiej tablicy i sposób obsługi numerów komórek.

//tablica jednowymiarowa
var TK = [];
//element zerowy tablicy jest tablicą o 8 komórkach
TK[0] = [100, 100, 50, 0, „red”, 1, 2, 1];
//zmienna kolor jest równa "red" - piąty element tablicy o numerze 4
var kolor = TK[0][4];

Losowanie
Aby zapamiętać dane dla 100 kwadratów, należy zdefiniować 100 różnych zestawów. Najłatwiej oczywiście zrobić to za pomocą losowania. Funkcja Math.random losuje liczby rzeczywiste z przedziału 0..1. Funkcja Math.round zaokrągla liczbę rzeczywistą do całkowitej. Przygotowana funkcja losowa(p,k) losuje liczby całkowite z przedziału p..k.

function losowa(p,k) {
  return Math.round(Math.random()*(k-p)+p);
}

Za pomocą funkcji losowa  można wylosować kolory dla funkcji RGB lub RGBA.

function LosRGBA(){
  var r = losowa(0,255);
  var g = losowa(0,255);
  var b = losowa(0,255);
  var a = Math.random();
  return "rgb("+r+","+g+","+b+","+a+")";
}

Losowanie zmiennych początkowych
Wykorzystujemy funkcje losowa i LosRGBA do przygotowania zestawy zmiennych, które wstawiamy do kolejnych komórek tablicy TK. W ten sposób każdy kwadrat będzie rozpoczynał swoją podróż w innym miejscu, z różnymi kolorami i szybkościami.

var ILE = 100;
for (var i = 0; i < ILE; i = i + 1){
  var x = losowa(100,300);
  var y = losowa(100,300);
  var bok = losowa(1,100);
  var kat = losowa(0,45);
  var kolor = LosRGBA();
  var vx = losowa(-5,5);
  var vy = losowa(-5,5);
  var vk = losowa(-5,5);
  TK[i] = [x,y,bok,kat,kolor,vx,vy,vk];
}

Rysowanie i odbicia
Za pomocą pętli FOR będziemy rysować wszystkie kwadraty, przesuwać, obracać i sprawdzać odbicia. Wszystkie dotychczasowe zmienne dla pojedynczego kwadratu zamieniamy na odpowiadające im pozycje w tablicy: zamiast x wykorzystamy element zerowy tablicy TK[i][0], zamiast y – element pierwszy TK[i][1], itd.

for (i=0; i<ILE; i=i+1){
  //rysowanie
  kwaO(TK[i][0],TK[i][1],TK[i][2],TK[i][3],TK[i][4]);

  //przesuwanie i obrót
  TK[i][0]=TK[i][0]+TK[i][5];
  TK[i][1]=TK[i][1]+TK[i][6];
  TK[i][3]=TK[i][3]+TK[i][7];
  //odbicia
  if (TK[i][0] > w || TK[i][0] < TK[i][2]){
    TK[i][5]=-TK[i][5]; 
    TK[i][7]=-TK[i][7];
  }
  if (TK[i][1] > h || TK[i][1] < TK[i][2]){
    TK[i][6]=-TK[i][6]; 
    TK[i][7]=-TK[i][7];
  }
  //zerowanie kąta
  if (TK[i][3]>=360){
    TK[i][3]=0;
  }

Cały program animacji 100 kolorowych kwadratów

<canvas width="400" height="400" id="can"></canvas>
<script>
  var c = can.getContext("2d");

  var w = c.canvas.width;
  var h = c.canvas.height;
  var skok = 10;
  var czas;

function kwaO(xs,ys,bok,kat,kolor){
  c.save();
  c.translate(xs-bok/2,ys-bok/2);
  c.rotate(Math.PI*kat/180);
  c.fillStyle=kolor;
  c.fillRect(-bok/2,-bok/2,bok,bok);
  c.restore();
} 

function losowa(p,k) {
  return Math.round(Math.random()*(k-p)+p);
}

function LosRGBA(){
  var r = losowa(0,255);
  var g = losowa(0,255);
  var b = losowa(0,255);
  var a = Math.random();
  return "rgb("+r+","+g+","+b+","+a+")";
}
//losowanie danych początkowych
var ILE = 100;
var TK = [ILE];

for (var i = 0; i < ILE; i = i + 1){
  var x = losowa(100,300);
  var y = losowa(100,300);
  var bok = losowa(1,100);
  var kat = losowa(0,45);
  var kolor = LosRGBA();
  var vx = losowa(-5,5);
  var vy = losowa(-5,5);
  var vk = losowa(-5,5);
  TK[i] = [x,y,bok,kat,kolor,vx,vy,vk];
}

function animacja() {
  c.clearRect(0, 0, w, h);
  c.strokeRect(0, 0, w, h);

  for (i=0;i<ILE;i=i+1)
  {
    kwaO(TK[i][0],TK[i][1],TK[i][2],TK[i][3],TK[i][4]);

    TK[i][0]=TK[i][0]+TK[i][5];
    TK[i][1]=TK[i][1]+TK[i][6];
    TK[i][3]=TK[i][3]+TK[i][7];
    if (TK[i][0] > w || TK[i][0] < TK[i][2])
    {
      TK[i][5]=-TK[i][5]; 
      TK[i][7]=-TK[i][7];
    }
    if (TK[i][1] > h || TK[i][1] < TK[i][2])
    {
      TK[i][6]=-TK[i][6]; 
      TK[i][7]=-TK[i][7];
    }
    if (TK[i][3]>=360)
    {
      TK[i][3]=0;
    }
  }

  clearTimeout(czas);
  czas = setTimeout(animacja, skok); 
}

animacja();
  
</script>

Szablon

<canvas width="400" height="400" id="can"></canvas>
<script>
  var c = can.getContext("2d");

  var w = c.canvas.width;
  var h = c.canvas.height;
  var skok = 10;
  var czas;
  
function animacja() {
  c.clearRect(0, 0, w, h);
  //rysowanie i przesuwanie obiektu




  clearTimeout(czas);
  czas = setTimeout(animacja, skok); 
}

animacja();
</script>