Blog (9)
Komentarze (25)
Recenzje (2)

HTML5 w tworzeniu gier (cz. 3)

@lukasz.developerHTML5 w tworzeniu gier (cz. 3)13.04.2011 01:39

Hej,

inne zajęcia trochę odciągnęły mnie od blogowania, jednak po dłuższym czasie napisałem trzecią, jak na razie ostatnią część (mini)cyklu o HTML5 i wykorzystywaniu jego możliwości w połączeniu z Java Scriptem do tworzenia prostych gier. Czas więc odnaleźć na dysku nieco przykurzony programik z opadającymi płatkami śniegu i brać się do jego rozbudowy :).

Poprzednie części minikursu możecie znaleźć wśród wcześniejszych postów: część l., pokazująca jak stworzyć szkielet strony z elementem canvas (płótnem) i wykonywać na nim proste operacje za pomocą języka Java Script część ll., prezentującą jak zmienić opadające kółka w płatki śniegu i dodać odrobinę interaktywności ;)

Dziś zmodyfikujemy nieznacznie zaimplementowaną wcześniej obsługę klawiatury, dodamy do gry zasady oraz umożliwimy odgrywanie dźwięków.

Obsługa klawiatury

Ten temat został już poruszony w poprzedniej części kursu. Ze stworzonego przez nas kodu usuniemy liczby o znaczeniu, które na pierwszy rzut oka może nie być jasne jeśli włączmy aplikację po dłuższej przerwie ;). Mowa o kodach klawiszy.

Dodajmy na początku naszego pliku z kodem JS pomocniczą "strukturę", zbierającą kody klawiszy, które mogą się nam przydać :).


var kodyKlawiszy = {
					lewo : 37,  /* strzałka w lewo */
					prawo : 39, /* strzałka w prawo */
					gora : 38, /* strzałka w dół */
					dol : 40, /* strzałka w górę */
					akcja: 32 /* spacja */
			   };

Następnie zmieńmy kod funkcji ruchGracza tak, aby używał naszej struktury:


function ruchGracza()
{
if ((wcisnietyKlawisz == kodyKlawiszy.lewo) && (gracz.x > gracz.szybkosc))
	{
		gracz.x -= gracz.szybkosc;
	}
	else if ((wcisnietyKlawisz == kodyKlawiszy.prawo) && (gracz.x < (szerokoscCanvas - gracz.szybkosc)))
	{
		gracz.x += gracz.szybkosc;
	}
}

Dzięki temu rozwiązaniu patrząc na kod od razu widać, którego klawisza on dotyczy. Ma to jeszcze jedną zaletę: jeśli nagle stwierdzimy, że zamiast akcji dla Ctrl lepiej używać spacji, nie musimy przeglądać całego kodu. Wystarczy, że zmienimy go w strukturze kodyKlawiszy i sprawa załatwiona :).

Nasza śniegowa kula przesuwa się już z lewo i prawo. Czas dać jej więcej swobody i umożliwić jej ruch również w pionie :).


function ruchGracza()
{
	if ((wcisnietyKlawisz == kodyKlawiszy.lewo) && (gracz.x > gracz.szybkosc))
	{
		gracz.x -= gracz.szybkosc;
	}
	else if ((wcisnietyKlawisz == kodyKlawiszy.prawo) && (gracz.x < (szerokoscCanvas - gracz.szybkosc)))
	{
		gracz.x += gracz.szybkosc;
	}
	else if ((wcisnietyKlawisz == kodyKlawiszy.gora) && (gracz.y > gracz.szybkosc))
	{
		gracz.y -= gracz.szybkosc;
	}
	else if ((wcisnietyKlawisz == kodyKlawiszy.dol) && (gracz.y < (wysokoscCanvas - gracz.szybkosc)))
	{
		gracz.y += gracz.szybkosc;
	}
}

Cel gry

Jeśli chcemy nasze dzieło można było nazywać grą, powinniśmy dać jej pewien określony cel. Proponuję, aby w przypadku tego demka zadaniem gracza było unikanie przez jak najdłuższy czas wszystkich płatków śniegu. Potrzebujemy więc licznika, który będzie ów czas odmierzał.

Dodajmy dla niego element div do kodu w pliku strony html:

[code] W śniegu

W śniegu

0
Element canvas nie jest obsługiwany przez twoją przeglądarkę [/code]

Notka Stronę początkowo przygotowałem po angielsku i zauważyłem, że niektóre teksty nie zostały przetłumaczone. Korzystając z okazji postanowiłem więc naprawić to niedopatrzenie ;).

Uwaga Jeśli polskie znaki nie będą się poprawnie wyświetlać pomimo ustawienia lang="pl" i charset="UTF-8", pamiętajmy, aby upewnić się czy kodowanie pliku z kodem źródłowym to UTF-8.

W pliku ze stworzonym przez nas skryptem w JS dodajmy natomiast ustawienie początkowej wartości dla wyświetlanego licznika, który wystartuje przy inicjalizacji gry i zostanie zatrzymany w chwili pierwszego zetknięcia z płatkiem śniegu.

Zmodyfikujmy w tym celu funkcję inicjalizujGre w przedstawiony sposób:


...
function inicjalizujGre(glownyCanvas)
{
canvasElement = glownyCanvas;
canvasElement.width = szerokoscCanvas;
canvasElement.height = wysokoscCanvas;

licznikElement = document.getElementById("licznik");
licznikElement.innerHTML = "0";
...
}
...

dodajmy pola dla przechowywania wartości licznika


/* licznik czasu gry w milisekundach */
var licznik = 0;
/* liczba klatek po ostatnim odswiezeniu licznika na stronie */
var klatkaPoOdswiezeniu = 0;
/* informacja co ile klatek licznik na stronie ma zostac odswiezony*/
var odswiezajCoLiczbeKlatek = 10;

pierwsze z nich będzie przechowywało faktyczną wartość, a drugie informację o liczbie klatek od ostatniego odświeżenia licznika. Trzecie pole określa co ile klatek licznik ma być odświeżany.

W głównej pętli aktualizujmy nasz licznik o odpowiednią wartość:


function glownaPetla()
{
/* aktualizuj licznik czasu */
licznik += dlugoscKlatki/1000.0;
klatkaPoOdswiezeniu = (klatkaPoOdswiezeniu + 1) % odswiezajCoLiczbeKlatek;
if (klatkaPoOdswiezeniu == 0)
{
	/* aktualizuj wyswietlana wartosc licznika */
	if (licznikElement)
	{
		/* wyswietl liczbe zaokraglona do jednego miejsca po przecinku */
		licznikElement.innerHTML = licznik.toFixed(1);
	}
}
...
}

Na koniec dodajmy funkcję weryfikującą czy nasza śniegowa kulka koliduje z przynajmniej jednym z opadających płatków:


function sprawdzKolizje()
{
	for(var j = 0; j < platki.length; j++)
	{
		if (Math.abs(platki[j].x - gracz.x) < gracz.r + platki[j].aktualneR/2)
		{
			if (Math.abs(platki[j].y - platki[j].r/2 - gracz.y) < gracz.r + platki[j].r/2)
			{
				return true;
			}
		}
	}
	return false;
}

jeśli tak jest, wyświetlimy odpowiednią informację i zatrzymamy grę:


function glownaPetla()
{
...
if (klatkaPoOdswiezeniu == 0)
{
	...
}

/* sprawdz kolizje z platkami  */
if (sprawdzKolizje())
{
	clearInterval(glownaPetlaUchwyt);
	var gameEndText = "KONIEC GRY";
	var counterText = "Punkty: " + licznik.toFixed(1);
	/* napisz wysrodkowany tekst z wynikiem punktowym gracza */
	context.shadowColor = "white";
	context.fillStyle = "#FFD800";
	context.font = "bold 20px sans-serif";
	context.fillText(gameEndText, szerokoscCanvas/2 - context.measureText(gameEndText).width/2, wysokoscCanvas/2 - 30);
	context.fillText(counterText, szerokoscCanvas/2 - context.measureText(counterText).width/2, wysokoscCanvas/2);
	return;
}
...
}

W powyższym fragmencie używamy metody fillText do narysowania wskazanego tekstu oraz measureText do uzyskania informacji o jego graficznej długości. Zgodnie ze znalezionymi informacjami tekst może zajmować więcej miejsca niż to określa użyty przez nas sposób, jednak na nasze potrzeby dokładność powinna być wystarczająca. Zainteresowanych tematem odsyłam do specyfikacji. Jak pewnie zauważyliście użyliśmy tu również nowej zmiennej o nazwie glownaPetlaUchwyt. Wskazuje ona niejako, o które okresowe wywołanie metody nam chodzi. Wartość tą uzyskać możemy zapisując wartość zwracaną przez odpowiednie wywołanie funkcji setInterval. Dodajmy zatem nową zmienną:


var glownaPetlaUchwyt;

i zmodyfikujmy odpowiednią linię w metodzie inicjalizujGre:


function inicjalizujGre(glownyCanvas)
{
...
/* jeśli element canvas jest obsługiwany */
if (canvasElement.getContext)
{
...			
/* uruchom glowna petle gry */
glownaPetlaUchwyt = setInterval(glownaPetla, dlugoscKlatki);
}
...
}

Dźwięki

Gra bez dźwięków jest jak...w każdym razie powinna jakieś dźwięki mieć :P. Dlatego na zakończenie dodamy do naszej zimowej gry chociaż odgłosy towarzyszące zmianie kierunku kulki.

Do katalogu ze skryptem dodajmy krótki plik z dźwiękiem, którego chcemy użyć. Ważne, aby plik był w formacie *.ogg (jeśli demo ma działać w firefox 3.5 lub 4). Nazwijmy plik sound.ogg. Dodajmy nową zmienną:


var audioElement;

a następnie w metodzie inicjalizującej inicjalizujGre dopiszmy kilka linii wczytujących dane z pliku:


function inicjalizujGre(glownyCanvas)
{
canvasElement = glownyCanvas;
canvasElement.width = szerokoscCanvas;
canvasElement.height = wysokoscCanvas;

audioElement = document.createElement('audio');
audioElement.setAttribute('src', 'sound.ogg');
audioElement.load();
...
}

funkcję obsługującą wciśnięcie klawisza (zdefiniowaną wewnątrz funkcji inicjalizującej grę) zmodyfikujmy tak, aby miała postać:


function inicjalizujGre(glownyCanvas)
{
...
/* jeśli element canvas jest obsługiwany */
if (canvasElement.getContext)
{
...
document.onkeydown = function(e)
								{
									var e = window.event || e;
									
									if (wcisnietyKlawisz != e.keyCode)
									{
										wcisnietyKlawisz = e.keyCode;
										audioElement.pause();
										audioElement.currentTime = 0;
										audioElement.play();
									}
								};
...
}
...
}

zatrzymujemy odtwarzanie włączone wcześniej (jeśli nie zostało ono zakończone), resetujemy pozycję odtwarzania do początku pliku i ponownie pozwalamy odtworzyć nasz dźwięk. Teraz przy każdej zmianie kierunku ruchu kulki towarzyszyć nam będzie efekt dźwiękowy :).

Przedstawiona tu obsługa dźwięków jest bardzo podstawowa i nieco uproszczona. W celu uzyskania dokładniejszych informacji można zajrzeć na wybraną stronę z podanych w sekcji Przydatne linki.

Dalsza rozbudowa gry

Dodanie możliwości wielokrotnej rozgrywki, menu itd. nie wnosi specjalnie wiele nowego i może bazować na przedstawionych tu informacjach. Dlatego też, aby nie rozdmuchiwać niepotrzebnie naszego tutoriala, pozostawiam dodanie tej funkcjonalności, a także dalszą rozbudowę gry jako ćwiczenie dla chętnych :).

Na zachętę zamieszczam obrazek z canvasa podczas gry :).

Podsumowanie

Ten krótki kurs to w zamierzeniu pewna prosta prezentacja ilustrująca jak przy użyciu HTML5 i odrobiny Java Script można dodać do naszej strony trochę więcej interaktywności lub wzbogacić ją o prostą grę. Nie miał być to megatutorial jak opanować tajniki HTML5 i Java Script, lecz raczej kilka artykułów opisujących w jaki sposób rozpocząć swoją przygodę z każdym z nich i zachęcić do ich dalszego poznawania. Jeśli chcecie pogłębić swoją wiedzę na poruszane tematy, możecie np.: zajrzeć do linków umieszczonych sekcji Przydatne linki w wybranej części cyklu :).

Mam nadzieję, że wszystkim, którzy nie mieli wcześniej okazji do zabawy z HTML5 i JS poprzez ten kurs przybliżyłem trochę tematykę tworzenia interaktywnych treści i prostych gier na stronach www.

Starałem się, aby przedstawione w każdej z części opisy i fragmenty kodu nie zawierały błędów uniemożliwiających kompilację. Jeśli jednak będziecie mieli jakiekolwiek problemy lub dodatkowe pytania związane z tematem, piszcie.

Pozdrawiam,

Łukasz

Przydatne linki

http://www.whatwg.org/specs/web-apps/current-work/multipage/index.html... specyfikacja HTML5 w przystępnej formie, istnieje też możliwość pobrania jej w postaci pliku PDF

http://diveintohtml5.org znacznie bardziej obszerny opis możliwości HTML5, z uwzględnieniem elementu Canvas, obsługi plików wideo, geolokacji, tworzeniu stron działających offline i innych.

http://www.html5rocks.com/tutorials/audio/quick przystępny opis krok po kroku jak umieścić na stronie i obsługiwać tagi audio

http://www.position-absolute.com/articles/introduction-to-the-html5-au... kolejny artykuł o obsłudze tagów audio

http://www.elated.com/articles/javascript-timers-with-settimeout-and-s... artykuł opisujący metody czasowego wywoływania funkcji setTimeout i setInterval

Szanowna Użytkowniczko! Szanowny Użytkowniku!
×
Aby dalej móc dostarczać coraz lepsze materiały redakcyjne i udostępniać coraz lepsze usługi, potrzebujemy zgody na dopasowanie treści marketingowych do Twojego zachowania. Twoje dane są u nas bezpieczne, a zgodę możesz wycofać w każdej chwili na podstronie polityka prywatności.

Kliknij "PRZECHODZĘ DO SERWISU" lub na symbol "X" w górnym rogu tej planszy, jeżeli zgadzasz się na przetwarzanie przez Wirtualną Polskę i naszych Zaufanych Partnerów Twoich danych osobowych, zbieranych w ramach korzystania przez Ciebie z usług, portali i serwisów internetowych Wirtualnej Polski (w tym danych zapisywanych w plikach cookies) w celach marketingowych realizowanych na zlecenie naszych Zaufanych Partnerów. Jeśli nie zgadzasz się na przetwarzanie Twoich danych osobowych skorzystaj z ustawień w polityce prywatności. Zgoda jest dobrowolna i możesz ją w dowolnym momencie wycofać zmieniając ustawienia w polityce prywatności (w której znajdziesz odpowiedzi na wszystkie pytania związane z przetwarzaniem Twoich danych osobowych).

Od 25 maja 2018 roku obowiązuje Rozporządzenie Parlamentu Europejskiego i Rady (UE) 2016/679 (określane jako "RODO"). W związku z tym chcielibyśmy poinformować o przetwarzaniu Twoich danych oraz zasadach, na jakich odbywa się to po dniu 25 maja 2018 roku.

Kto będzie administratorem Twoich danych?

Administratorami Twoich danych będzie Wirtualna Polska Media Spółka Akcyjna z siedzibą w Warszawie, oraz pozostałe spółki z grupy Wirtualna Polska, jak również nasi Zaufani Partnerzy, z którymi stale współpracujemy. Szczegółowe informacje dotyczące administratorów znajdują się w polityce prywatności.

O jakich danych mówimy?

Chodzi o dane osobowe, które są zbierane w ramach korzystania przez Ciebie z naszych usług, portali i serwisów internetowych udostępnianych przez Wirtualną Polskę, w tym zapisywanych w plikach cookies, które są instalowane na naszych stronach przez Wirtualną Polskę oraz naszych Zaufanych Partnerów.

Dlaczego chcemy przetwarzać Twoje dane?

Przetwarzamy je dostarczać coraz lepsze materiały redakcyjne, dopasować ich tematykę do Twoich zainteresowań, tworzyć portale i serwisy internetowe, z których będziesz korzystać z przyjemnością, zapewniać większe bezpieczeństwo usług, udoskonalać nasze usługi i maksymalnie dopasować je do Twoich zainteresowań, pokazywać reklamy dopasowane do Twoich potrzeb. Szczegółowe informacje dotyczące celów przetwarzania Twoich danych znajdują się w polityce prywatności.

Komu możemy przekazać dane?

Twoje dane możemy przekazywać podmiotom przetwarzającym je na nasze zlecenie oraz podmiotom uprawnionym do uzyskania danych na podstawie obowiązującego prawa – oczywiście tylko, gdy wystąpią z żądaniem w oparciu o stosowną podstawę prawną.

Jakie masz prawa w stosunku do Twoich danych?

Masz prawo żądania dostępu, sprostowania, usunięcia lub ograniczenia przetwarzania danych. Możesz wycofać zgodę na przetwarzanie, zgłosić sprzeciw oraz skorzystać z innych praw wymienionych szczegółowo w polityce prywatności.

Jakie są podstawy prawne przetwarzania Twoich danych?

Podstawą prawną przetwarzania Twoich danych w celu świadczenia usług jest niezbędność do wykonania umów o ich świadczenie (tymi umowami są zazwyczaj regulaminy). Podstawą prawną przetwarzania danych w celu pomiarów statystycznych i marketingu własnego administratorów jest tzw. uzasadniony interes administratora. Przetwarzanie Twoich danych w celach marketingowych realizowanych przez Wirtualną Polskę na zlecenie Zaufanych Partnerów i bezpośrednio przez Zaufanych Partnerów będzie odbywać się na podstawie Twojej dobrowolnej zgody.