01
Po ostatnich ciężkich lekcjach WebGL’a czas na coś prostszego. Dzisiaj zaprowadzimy porządek w kodzie oraz we wszystkich plikach aplikacji. Teoretycznie utrzymywanie porządku nie jest konieczne, ale podczas tworzenia większych programów zaoszczędzimy dzięki temu mnóstwo czasu.
Dla przykładu stworzymy prostą aplikację, której efekt możecie zobaczyć na żywo tutaj, lub na filmiku poniżej.
Zacznijmy od porządku w danych. Wszystkie pliki porozmieszczamy w odpowiednich folderach w zależności od ich zawartości. Tworzymy następujące katalogi:
Oczywiście oprócz wymienionych folderów aplikacja musi zawierać plik, który będzie jej głównym trzonem. Najczęściej będzie to index.html.
Ok, foldery mamy przygotowane, więc zajmijmy się kodem. Do tej pory praktycznie cały zawarty był w pliku index, teraz podzielimy go na części i porozmieszczamy w odpowiednich miejscach. Tworząc aplikacje, można zauważyć pewien powtarzający się schemat. Na wstępie zawsze inicjujemy wszystkie obiekty, zawsze opisujemy ruch na scenie (sceny statyczne nas nie interesują, szczególnie przy tworzeniu gier), oraz oczywiście zawsze rysujemy obiekty na scenie. Aby aplikacja była przejrzysta umieścimy części kodu odpowiedzialne za te operacje w osobnych plikach.
Zacznijmy od inicjalizacji. W folderze scripts tworzymy nowy plik o nazwie init.js. Umieszczamy w nim funkcję g_Init(). W jej ciele znajdą się wszystkie operacje związane z inicjalizacją stworzonych przez nas obiektów. Wywołujemy ją w funkcji webGLStart znajdującej się w pliku głównym. Dzięki temu zostanie ona wywołana tylko raz na starcie programu (dodatkowo będzie można ją wywołać gdy będziemy chcieli zresetować wszystkie ustawienia, np. przy restarcie gry).
Animacje. Wszelkie obliczenia związane z ruchem obiektów na scenie takie jak: symulacje fizyki obiektów, wykrycie kolizji, odpowiedź zderzeń itp będziemy umieszczali w funkcji g_Animate, która znajdzie się w pliku animate.js. Wywołujemy ją w ciele funkcji timeTick zgodnie z założeniami odpowiedniej kolejności działań w pętli programu.
Rysowanie. Wszystkie operacje związane z wyświetlaniem obiektów (np. metoda display klasy Model) wywoływali będziemy w globalnej funkcji g_Draw, którą umieszczamy w pliku draw.js. Rendering obiektów odbywa się na końcu pętli programu, gdy dokonane są już wszystkie obliczenia związane z położeniem (po zakończeniu funkcji g_Animate).
Ok. Wydzieliliśmy najważniejsze części kodu, dzięki czemu główny plik programu – index.html został mocno odciążony i zaczął przypominać źródło strony internetowej (przynajmniej trochę). Pamiętajmy, abyśmy wszystkie nowe klasy tworzyli w osobnych plikach i umieszczali je w folderze scripts. Dzięki temu raczej się nie pogubimy. Możemy również stworzyć bardziej zagłębioną hierarchę folderów i uporządkować w nich swoje skrypty. Na pewno pomoże nam to przy większych aplikacjach. Trzymajmy się również zasady, zgodnie z którą obiekty powinniśmy inicjować w funkcji g_Init, poruszać nimi w funkcji g_Animate, a wyświetlać w funkcji g_Draw.
Dla przykładu stworzymy prostą aplikację uporządkowaną zgodnie z powyższymi zasadami. Efektem będzie obracający się sześcian z nałożoną teksturą naszego loga.
Geometrię sześcianu zapisujemy do pliku Cube_geometry.js, który umieszczamy w folderze objects. Teksturę zapisujemy do folderu textures. Klasę c_Cube, która reprezentuje nasz obiekt tworzymy w pliku cube.js w folderze scripts. Jego zawartość wygląda następująco:
function c_Cube()
{
this.Rot = 0;
this.animate = c_Cube_animate;
}
c_Cube.prototype = new Model();
function c_Cube_animate()
{
this.Rot += 90*elapsed_s;
}
Klasa zawiera jedną zmienną i jedną metodę. Dodatkowo jako jej prototyp ustawiamy klasę Model. Zmienna rot reprezentuje obrót sześcianu, natomiast metoda animate służy do wykonywania operacji na niej.
W pliku index.html tworzymy obiekt klasy c_Cube.
var Cube = new c_Cube;
W globalnej funkcji g_Init inicjujemy obiekt Cube, za pomocą metody, którą klasa c_Cube dziedziczy z klasy Model. Operacja wygląda następująco:
function g_Init()
{
Cube.init("textures/logo.jpg",0,0,Tab1,Tab2,Tab3);
}
W pliku animate.js wywołujemy metodę animate:
function g_Animate()
{
Cube.animate();
}
A w pliku draw.js wyświetlamy nasz obiekt za pomocą metody display:
function g_Draw()
{
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
perspective(45, 1.333, 0.1, 100.0);
loadIdentity();
mvTranslate([0.0, 0.0, -5]);
mvRotate(Cube.Rot,[1,0,0]);
mvRotate(Cube.Rot,[0,1,0]);
mvRotate(Cube.Rot,[0,0,1]);
Cube.display();
}
Wszystkie funkcje globalne: g_Init, g_Draw oraz g_Animate wywoływane są w odpowiednich miejscach w pliku index.html. Uruchamiamy aplikację i widzimy efekt, który chcieliśmy osiągnąć. Program jest przejrzysty i działa poprawnie. Kod aplikacji możecie pobrać tutaj.
Podsumujmy, co dzisiaj zrobiliśmy. Stworzyliśmy konwencję, która pomoże nam utrzymywać porządek w zasobach aplikacji. Ma ona usprawnić pracę nad większymi projektami. Oczywiście możecie utrzymywać dowolny założony przez siebie porządek. Najważniejsze, żebyście się go trzymali i nie tracili czasu na szukanie jakiegoś potrzebnego wam w danej chwili pliku. W naszych tutorialach będziemy się trzymali omówionego dzisiaj układu, więc warto się z nim zapoznać
[...] gry. Możecie je testować, komentować i przede wszystkim cieszyć się grą. Pam… Porządek w kodzie Po ostatnich ciężkich lekcjach WebGL’a czas na coś prostszego. Dzisiaj zaprowadzimy porządek [...]
Z jakiego edytora korzystacie, bardzo przyzwyczajiłem się do autodopełniania, ale nie wiem jak to zrobić żeby widoczne były funkcje obiektów webGL.
WebGL nie jest jeszcze standardem więc z autouzupełnianiem mogą być problemy. Ja piszę obecnie w NetBeansie.
właśnie ja też ale za bardzo łatwo się jebnąć, a kodu widać jest dużo .. później szukaj jednej literki… troche to chore. czy nie ma może gdzieś webGl.js wtedy można było by zmusić (sam to robi) Netbeansa żeby przeszukał plik w poszukiwaniu nazw funkcji i zmiennych.
Znalazłem coś na wzór tego co wspominałem wyżej , napewno się przyda.
link do forum: http://www.khronos.org/message_boards/viewtopic.php?f=46&t=2342
link do pliku: http://www.omam.it/download.php?file=webgl
Super, na pewno się przyda. Może byś wrzucił informację na nasze forum, byłoby dla przyszłych pokoleń