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
Obiekt - lista
Czy zwróciłeś uwagę, jak niewygodne jest operować numerami komórek, w których znajdują się konkretne zmienne:
x – TK[i][0] … Ten problem da się rozwiązać za pomocą list, które zapamiętują dane pod konkretną nazwą podczas gdy tablica zapamiętywała zmienną pod konkretnym numerem.
Lista Rk={} również mieści w sobie zestaw zmiennych potrzebnych do animowania jednego kwadratu. Jednak dostęp do tych danych jest dużo wygodniejszy, bo poprzez konkretną nazwę. Rysowanie i sprawdzanie wygląda bardzo podobnie, ale o wiele łatwiej się czyta program.
Losowanie
Losowanie przebiega bardzo podobnie. Za każdym przebiegiem pętli tworzymy nowy
pusty obiekt listy RK i podczas przypisywania konkretnych wartości określamy,
jak ma nazywać się element listy, np. Rk.x=100;.
var ILE = 100; var TK = []; for (var i = 0; i < ILE; i = i + 1){ var Rk={}; Rk.x=losowa(100,300); Rk.y=losowa(100,300); Rk.bok=losowa(1,100); Rk.kat=losowa(0,45); Rk.kolor=LosRGBA(); Rk.vx=losowa(-5,5); Rk.vy=losowa(-5,5); Rk.vk=losowa(-5,5); TK[i]=Rk; |
Rysowanie i odbicia
Rysowanie i sprawdzanie wygląda bardzo podobnie, ale o wiele łatwiej się czyta program.
for (i=0;i<ILE;i=i+1){ //rysowanie kwadratu kwaO(TK[i].x,TK[i].y,TK[i].bok,TK[i].kat,TK[i].kolor); //przesuwanie TK[i].x = TK[i].x + TK[i].vx; TK[i].y = TK[i].y + TK[i].vy; TK[i].kat = TK[i].kat + TK[i].vk; //odbicia if (TK[i].x > w || TK[i].x < TK[i].bok){ TK[i].vx = -TK[i].vx; TK[i].vk = -TK[i].vk; } if (TK[i].y > h || TK[i].y < TK[i].bok){ TK[i].vy = -TK[i].vy; TK[i].vk = -TK[i].vk; } 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 Rk={}; Rk.x=losowa(100,300); Rk.y=losowa(100,300); Rk.bok=losowa(1,100); Rk.kat=losowa(0,45); Rk.kolor=LosRGBA(); Rk.vx=losowa(-5,5); Rk.vy=losowa(-5,5); Rk.vk=losowa(-5,5); TK[i]=Rk; } 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].x,TK[i].y,TK[i].bok,TK[i].kat,TK[i].kolor); TK[i].x = TK[i].x + TK[i].vx; TK[i].y = TK[i].y + TK[i].vy; TK[i].kat = TK[i].kat + TK[i].vk; if (TK[i].x > w || TK[i].x < TK[i].bok){ TK[i].vx = -TK[i].vx; TK[i].vk = -TK[i].vk; } if (TK[i].y > h || TK[i].y < TK[i].bok){ TK[i].vy = -TK[i].vy; TK[i].vk = -TK[i].vk; } if (TK[i][3]>=360){ TK[i][3]=0; } clearTimeout(czas); czas = setTimeout(animacja, skok); } animacja(); </script> |
Odcinkowe łamańce
Z listami już mieliśmy do czynienia podczas rysowania trójkątów
w lekcji 2. Funkcja ODCINEK zwracała dwie współrzędne w postaci listy.
Wykorzystamy funkcję do narysowania animowanego łamańca.
Po ekranie przesuwają się i obracają cztery połączone ze sobą odcinki. Aby obliczyć położenie odcinków na końcach dłuższych ramion wykorzystaliśmy listę, którą zwraca funkcja ODCINEK. Punkt P1 i P2, to listy zawierające współrzędne – one określają początki ramion krótszych. Zwróć uwagę na sposób ich wykorzystania: współrzędna x zawarta jest na liście P1.x1 i P2.x1, a współrzędne y na liście P1.y1 i P2.y1.
function ODCINEK(x,y,bok,kat){ var x1=x+bok*Math.cos(kat*Math.PI/180); var y1=y+bok*Math.sin(kat*Math.PI/180); c.beginPath(); c.moveTo(x,y); c.lineTo(x1,y1); c.stroke(); return {x1,y1}; } var x=100; var y=100; var vx=1; var vy=2; var bok=50; var kat=0; function animacja() { c.clearRect(0, 0, w, h); c.strokeStyle="black"; c.strokeRect(0, 0, w, h); //przesuwanie x=x+vx; y=y+vy; kat=kat+1; //rysowanie odcinków c.lineWidth=5; c.strokeStyle="green"; var P1=ODCINEK(x,y,bok,kat); c.strokeStyle="yellow"; var P2=ODCINEK(x,y,bok,-kat*1.5); c.strokeStyle="blue"; ODCINEK(P1.x1,P1.y1,bok/2,-kat*2+45); c.strokeStyle="red"; ODCINEK(P2.x1,P2.y1,bok/2,kat*3); //odbicia if (x<0 || x>w) vx=-vx; if (y<0 || y>h) vy=-vy; clearTimeout(czas); czas = setTimeout(animacja, skok); } animacja() |
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> |