Sieciowe Technologie Mobilne Laboratorium 2 Tworzenie wieloplatformowych aplikacji mobilnych przy użyciu biblioteki PhoneGap. Łukasz Kamiński
Laboratorium 2 Na dzisiejszym laboratorium skupimy się na implementacji klas Sprite oraz AnimatedSprite. 1.1. Implementacja klasy Sprite. Na poprzednich zajęciach stworzyliśmy pierwszy samodzielny, ruszający się obiekt gry. Wraz ze wzrostem złożoności aplikacji pojawiać się będą kolejne zachowania obiektów gry. Warto zatem zdefiniować klasę, która przejmie odpowiedzialność za właściwości i metody obiektów gry. W wielu silnikach do tworzenia gier 2D klasy tego typu zwykło się nazywać Sprite'ami. Wykorzystaj poniższy kod, jako szkielet klasy Sprite, którą będziesz implementował jako element biblioteki, w pliku lab.js. /**Sprite ruszający się obiekt z obrazkową, graficzną reprezentacją.*/ kamyk.sprite = Class.$extend({ /**Konstruktor*/ init : function(x, y) { //Współrzędne rogu sprite'a this.x = x; this.y = y; //Rozmiary sprite'a this.sizex = 1; this.sizey = 1; //odległości od rogu do środka sprite'a na razie błędne wartości this.midxoffset = 1; this.midyoffset = 1; //prędkość this.speed = 1; //czy się rusza
this.ismoving = false; //obrazek this.image = undefined; /**Tę metodę wywoła ImageLoader z laboratorium 1.*/ setimage: function(img) { this.image = img; this.resize(this.image.width,this.image.height); /**Zmiana rozmiaru*/ resize: function(newwidth,newheight) { this.sizex = newwidth; this.sizey = newheight; this.midxoffset = Math.floor(this.sizeX / 2); this.midyoffset = Math.floor(this.sizeY / 2); this. middlecoordsinit(); /**Zmiana współrzędnych środka*/ middlecoordsinit: function() { this.midx = this.x + this.midxoffset; this.midy = this.y + this.midyoffset; /**Rysowanie*/ render: function(ctx) { if (this.image!== undefined) { ctx.drawimage(this.image, Math.floor(this.x), Math.floor(this.y), this.sizex, this.sizey); update: function(dt) { //limit darmowego kodu do wklejenia został przekroczony... ;) ); Przekształć kod klasy MonsterShooter z poprzedniego laboratorium, aby używał klasy Sprite. Zmień sposób tworzenia obiektów gry: this.hero = new kamyk.sprite(40, 40); ładowania obrazków (wykorzystaj właściwość imagereceiver klasy ImageLoader): this.imageloader.addurl("img/mage.jpg", this.hero); oraz rysowania i aktualizacji obiektów: this.hero.render(this.context); this.hero.update(dt); Spraw, aby obiekt poruszał się kolejno wzdłuż wszystkich czterech krawędzi ekranu. Wzbogać go o odpowiednie metody, odpowiedzialne za obliczanie odległości do celu, zmianę współrzędnych,
ustalanie kolejnego celu do osiągnięcia. Wykorzystaj te metody, by odpowiednio zaimplementować metodę update(). 1.2. Implementacja klasy AnimatedSprite. Kolejnym zadaniem do realizacji jest zapewnienie animacji obiektów gry. Klasycznym sposobem na realizację tego zadania jest dostarczenie obrazka, który zawiera niezbędne klatki animacji, ułożone w formie regularnej tablicy. Animacja polega na regularnym podmienianiu wybranych klatek animacji w trakcie rysowania obiektu. Poniżej zamieszczono przykładowy obrazek z 12 klatkami animacji, ułożonymi w 4 wierszach i 3 kolumnach. Dygresja Używanie osobnych obrazków dla każdego z obiektów gry nie jest optymalne podejście to zostało przedstawione, aby nieco uprościć proces tworzenia gry na laboratorium. Bardziej właściwym podejściem jest przygotowanie pojedynczego pliku graficznego, zawierającego wszystkie niezbędne zasoby graficzne. Plik taki bywa często nazywany atlasem. http://www.altdevblogaday.com/2012/09/17/building-an-html5-game-dont-shrug-off-atlases/ Wykorzystaj poniższy kod, jako szkielet klasy AnimatedSprite, którą będziesz implementował jako element biblioteki, w pliku lab.js. Zauważ, że nowa klasa dziedziczy po Sprite. /**Animowany obiekt gry*/ kamyk.animatedsprite = kamyk.sprite.$extend({ /**Konstruktor z dodatkowymi parametrami - ilością kolumn i rzędów w obrazku z animacjami*/ init : function(x, y, numcol, numrow) { this.$super(x, y); //liczba kolumn obrazka this.cols = numcol; //liczba wierszy obrazka this.rows = numrow; //co ile ms podmieniać obrazek(klatkę) animacji this. framechangedt = 50; //ile czasu jest już wyświetlany aktualny obrazek(klatka) animacji this. curframetime = 0; //indeks aktualnej klatki animacji this. curframeind = 0; // ramki /klatki animacji domyślnie pierwsza ramka obrazka this.frames = [0]; //czy zapętlać animację this.loopanim = true; //czy wstrzymać animację this.stopanim = false; /**Zmodyfikowana wersja metody setimage() -> rozmiar nie może już być rozmiarem obrazka*/
setimage: function(img) { this.image = img; this.sizex = Math.floor(this.image.width / this.cols); this.sizey = Math.floor(this.image.height / this.rows); this.midxoffset = this.sizex / 2; this.midyoffset = this.sizey / 2; this. middlecoordsinit(); /**Ustala, które części obrazka mają brać udział w animacji*/ setanimationframesseq: function(framenumbers) { this.frames = framenumbers; this. curframetime = 0; this. curframeind = 0; this.curframe = this.frames[this. curframeind]; /**Rysuje w odpowiednim miejscu (x,y) odpowiedni fragment obrazka*/ render: function(ctx) { if (this.image!== undefined) { var xframe = (this.curframe % this.cols) * this.sizex; var yframe = Math.floor(this.curFrame / this.cols) * this.sizey; ctx.drawimage(this.image, xframe, yframe, this.sizex, this.sizey, Math.floor(this.x), Math.floor(this.y), this.sizex, this.sizey ); update: function(dt) { //limit darmowego kodu do wklejenia znowu został przekroczony... ;) ); Niech poruszający się po ekranie obiekt będzie od tej pory obiektem klasy AnimatedSprite. Spraw, aby w trakcie poruszania obiekt ten był animowany. ZADANIE Zadanie do wykonania polega na wyświetleniu z wykorzystaniem obiektu <canvas> prostej sceny, zawierającej obrazek tła oraz animowany obiekt poruszający się wzdłuż kolejnych krawędzi ekran. Animacja ma być realizowana w oparciu o plik graficzny zawierający klatki animacji. Punktacja: 1 pkt. - modyfikacja kodu z poprzedniego laboratorium, aby funkcjonował w oparciu o klasę Sprite; poruszanie się wzdłuż krawędzi ekranu 2 pkt. - modyfikacja ruszającego się obiektu gry, aby wykorzystywał klasę AnimatedSprite do zapewnienia animacji opartej na podmianie klatek 2 pkt. - implementacja kodu zgodnie z wymaganiami z instrukcji: podział na bibliotekę i grę właściwą, symulowanie klas w JavaScript