<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michał Środek &#187; Gry</title>
	<atom:link href="http://srodek.info/category/gry/feed" rel="self" type="application/rss+xml" />
	<link>http://srodek.info</link>
	<description>Po prostu devBlog</description>
	<lastBuildDate>Thu, 02 Sep 2010 08:24:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Poruszanie się po mapie</title>
		<link>http://srodek.info/blog/387/poruszanie-sie-po-mapie</link>
		<comments>http://srodek.info/blog/387/poruszanie-sie-po-mapie#comments</comments>
		<pubDate>Fri, 09 Jul 2010 22:17:32 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Moje projekty]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=387</guid>
		<description><![CDATA[Mimo, że czołg w mojej grze jeździ, porusza się przez ściany. Dzisiaj zwalczę ten problem dodając kilka linijek kodu odpowiedzialnych za wykrywanie kolizji obiektów, tak aby czołg nie mógł znajdować się w tej samej pozycji co mur lub woda. Przede wszystkim przebudujmy kilka linijek odpowiedzialnych za wykrywanie zdarzeń klawiatury. O ile kod ten wciąż nie [...]]]></description>
			<content:encoded><![CDATA[<p>Mimo, że czołg w mojej grze jeździ, porusza się przez ściany. Dzisiaj zwalczę ten problem dodając kilka linijek kodu odpowiedzialnych za wykrywanie kolizji obiektów, tak aby czołg nie mógł znajdować się w tej samej pozycji co mur lub woda.</p>
<p><span id="more-387"></span></p>
<p>Przede wszystkim przebudujmy kilka linijek odpowiedzialnych za wykrywanie zdarzeń klawiatury. O ile kod ten wciąż nie jest doskonały i wymaga dalszego doszlifowania, o tyle aktualnie musi nam wystarczać.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">37</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// LEFT</span>
<span style="color: #009900;">&#123;</span>
	GameTank.<span style="color: #660066;">changeDirection</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameTank.<span style="color: #660066;">x</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
		GameTank.<span style="color: #660066;">changePosition</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">38</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// UP</span>
<span style="color: #009900;">&#123;</span>
	GameTank.<span style="color: #660066;">changeDirection</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameTank.<span style="color: #660066;">y</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span>
		GameTank.<span style="color: #660066;">changePosition</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">39</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// RIGHT</span>
<span style="color: #009900;">&#123;</span>
	GameTank.<span style="color: #660066;">changeDirection</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameTank.<span style="color: #660066;">x</span><span style="color: #339933;">&lt;</span><span style="color: #CC0000;">480</span><span style="color: #009900;">&#41;</span>
		GameTank.<span style="color: #660066;">changePosition</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">40</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// DOWN</span>
<span style="color: #009900;">&#123;</span>
	GameTank.<span style="color: #660066;">changeDirection</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameTank.<span style="color: #660066;">y</span><span style="color: #339933;">&lt;</span><span style="color: #CC0000;">480</span><span style="color: #009900;">&#41;</span>
		GameTank.<span style="color: #660066;">changePosition</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Co się zmieniło? Wszelkie polecenia zmiany położenia czołgu są teraz przekazywane do metody <em>GameTank.changePosition()</em>. To ona zabezpiecza grę przed przecinaniem się obiektów.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">changePosition<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span>y<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> newPosition <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span><span style="color: #339933;">+</span>x<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">y</span><span style="color: #339933;">+</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> newField <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>Math.<span style="color: #660066;">ceil</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>newPosition<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> Math.<span style="color: #660066;">ceil</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>newPosition<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">/</span><span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> offset <span style="color: #339933;">=</span> newPosition<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">%</span>32<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
			<span style="color: #003366; font-weight: bold;">var</span> fields <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">else</span>
			<span style="color: #003366; font-weight: bold;">var</span> fields <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> offset <span style="color: #339933;">=</span> newPosition<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">%</span>32<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>y<span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
			<span style="color: #003366; font-weight: bold;">var</span> fields <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">else</span>
			<span style="color: #003366; font-weight: bold;">var</span> fields <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> checkField <span style="color: #339933;">=</span> GameBoard.<span style="color: #660066;">board</span><span style="color: #009900;">&#91;</span>newField<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>fields<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>newField<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>fields<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>checkField<span style="color: #339933;">==</span><span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> checkField<span style="color: #339933;">==</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">||</span> offset<span style="color: #339933;">==</span><span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> offset<span style="color: #339933;">&gt;</span><span style="color: #CC0000;">29</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>offset<span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span> <span style="color: #339933;">&amp;&amp;</span> offset<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">6</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span><span style="color: #339933;">+=</span>x<span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">y</span><span style="color: #339933;">+=</span>y<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000066; font-weight: bold;">else</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> checkField <span style="color: #339933;">=</span> GameBoard.<span style="color: #660066;">board</span><span style="color: #009900;">&#91;</span>newField<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>fields<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>newField<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>fields<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>checkField<span style="color: #339933;">==</span><span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> checkField<span style="color: #339933;">==</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span><span style="color: #339933;">+=</span>x<span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">y</span><span style="color: #339933;">+=</span>y<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>

<p>Najpierw określam współrzędne nowego położenia czołgu(jego górnego lewego narożnika) oraz współrzędne pola na krórym się znajduje. Następnie wyznaczam odstęp(offset) jaki dzieli czołg od krawędzi kratki(Pamiętajmy, że czołg nie jest szeroki na 32px tak jak pole na mapie). Dzięki określeniu pewnej granicy błędu nie będziemy musieli ustawiać się idealnie aby przejechać między dwoma obszarami blokującymi. Znacznie ułatwi to sterowanie.</p>
<p>Kolejnym krokiem jest określenie 2 pól(fields), na podstawie których badane będą kolizje. To jakie pola wybierze skrypt zależy od kierunku w jakim się poruszamy. A są to:</p>
<p><img src="http://srodek.info/wp-content/uploads/2010/07/tanksMap.png" alt="" title="tanksMap" width="390" height="272" class="aligncenter size-full wp-image-391" /></p>
<p>Następnie jest sprawdzany rodzaj tych pól oraz odległość czołgu o nich. Jeżeli wszystko się zgadza, pozycja czołgu zostaje zmieniona.</p>
<p>Całość działa całkiem sprawnie. Efekt końcowy możesz zobaczyć <a href="/examples/game-0.0.5/">tutaj</a></p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/387/poruszanie-sie-po-mapie/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Obsługa klawiatury oraz licznik FPS</title>
		<link>http://srodek.info/blog/328/obsluga-klawiatury-oraz-licznik-fps</link>
		<comments>http://srodek.info/blog/328/obsluga-klawiatury-oraz-licznik-fps#comments</comments>
		<pubDate>Sat, 22 May 2010 21:58:18 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Moje projekty]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=328</guid>
		<description><![CDATA[W dzisiejszym artykule pokażę prosty sposób na wychwycenie zdarzenia przytrzymania klawiszy klawiatury oraz rozpoczniemy mierzenie prędkości naszej gry tj. współczynnika FPS. Umieścimy na naszej mapie czołg oraz umożliwimy sterowanie nim za pomocą klawiszy strzałek. UWAGA: Artykuł jest kontynuacją poprzedniego: Canvas — Rysujemy mapę Przede wszystkim potrzebujemy czołgu. Na potrzeby artykułu oraz mojej gry stworzyłem prosty [...]]]></description>
			<content:encoded><![CDATA[<p>W dzisiejszym artykule pokażę prosty sposób na wychwycenie zdarzenia przytrzymania klawiszy klawiatury oraz rozpoczniemy mierzenie prędkości naszej gry tj. współczynnika <abbr title="Frame Per Second - klatki na sekundę">FPS</abbr>. Umieścimy na naszej mapie czołg oraz umożliwimy sterowanie nim za pomocą klawiszy strzałek.</p>
<p><span id="more-328"></span></p>
<p class="warning">UWAGA: Artykuł jest kontynuacją poprzedniego: <a href="http://srodek.info/blog/270/rysujemy-mape">Canvas — Rysujemy mapę</a></p>
<p>Przede wszystkim potrzebujemy czołgu. Na potrzeby artykułu oraz mojej gry stworzyłem prosty szkic w <abbr title="GNU Image Manipulation Program">GIMP-ie</abbr>:</p>
<p><img src="http://srodek.info/wp-content/uploads/2010/05/btank.png" alt="Czołg" title="Czołg" width="32" height="32"/></a></p>
<p>Zanim umieścimy go na planszy, przeanalizujmy kilka innych ważnych aspektów.</p>
<h3>Obsługa klawiatury</h3>
<p>Aby sterować naszym czołgiem musimy stworzyć obiekt przechwytujący zdarzenia klawiatury. Najbardziej problematyczny jest jednak sposób ich działania w JavaScript. Dla przeciętnego klawisza są wywoływane 4 zdarzenia:</p>
<ol>
<li>keydown</li>
<li>keypress</li>
<li>textInput</li>
<li>keyup</li>
</ol>
<p>Zdarzenie textInput  zdefiniowane niedawno przez <abbr title="World Wide Web Consorcium">W3C</abbr> obsługują, bodajże, tylko przeglądarki w oparciu o silnik WebKit. Z pozostałymi zdarzeniami jest różnie. Keypress jest pomijane w przypadku klawiszy specjalnych takich jak shift, alt i ctrl. Niestety nie ma jasno zdefiniowanej listy klawiszy specjalnych. Przeglądarki w oparciu o WebKit zaliczają do nich np. klawisze strzałek, FireFox już nie. Co więcej identyfikacja klawiszy w różnych przeglądarkach jest realizowana w oparciu o inne pola(event.keyCode, event.which oraz event.charCode). Na szczęście wszystkie całkiem sprawnie obsługują pole <em>keyCode</em>, więc nie jest to aż tak ogromny problem(pomijając fakt, że czasami keyCode dla tego samego klawisza jest inny w różnych przeglądarkach). Podsumowując. <strong>Obsługa klawiatury w JavaScript to istny koszmar</strong> i moim zdaniem powinna zostać przebudowana. Wystarczy pozostawić keydown, textInput oraz keyup oraz ujednolicić kody klawiszy. Jest jednak lista klawiszy bezpiecznych(działających identycznie lub bardzo podobnie w różnych środowiskach). Znalazłem w sieci ciekawe <a href="http://unixpapa.com/js/key.html">zestawienie</a> na ten temat.</p>
<p>Warto wiedzieć w jaki sposób działa zdarzenie przytrzymania klawisza. Przeglądarki realizują to bardzo dziwnie. W przypadku wciśnięcia klawisza jest wywoływana akcja keydown, keypress oraz keyup. Następnie wywoływane jest ponownie zdarzenie keydown, po nim keypress oraz znów keyup. I tak, aż do momentu puszczenia klawisza. W naszym przypadku zdarzenie keypress pominiemy(tym bardziej, że w przypadku strzałek nie zawsze jest ono wywoływane) więc zaobserwujemy:<br />
<strong><br />
keydown<br />
keyup<br />
keydown<br />
keyup<br />
(…)<br />
keydown<br />
keyup<br />
</strong></p>
<p>Oczywiście w przypadku naszej gry akcja utrzymywania klawisza musi być ciągła dlatego musimy opóźnić zwolnienie klawisza. Napiszmy prostą klasę.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> keyHandler <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    keyLastEvent<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">//true = keyDown, false = keyUp</span>
    keyStatus<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
    keyDown<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ustawienie statusu na jeden(klawisz wcisniety po raz pierwszy)</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">keyStatus</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">===</span>undefined<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            keyHandler.<span style="color: #660066;">keyStatus</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
            keyHandler.<span style="color: #660066;">keyLastEvent</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>keyHandler.<span style="color: #660066;">keyLastEvent</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// ostatnia akcja byl keyUp =&gt; powtarzane down, up; down, up</span>
                keyHandler.<span style="color: #660066;">keyStatus</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">++;</span>
&nbsp;
            keyHandler.<span style="color: #660066;">keyLastEvent</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    keyUp<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        keyHandler.<span style="color: #660066;">keyLastEvent</span><span style="color: #009900;">&#91;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// odcisniecie klawisza z 10ms opóźnieniem</span>
        window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">decreaseKeyStatus</span><span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">keyCode</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    decreaseKeyStatus<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>keyCode<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">keyStatus</span><span style="color: #009900;">&#91;</span>keyCode<span style="color: #009900;">&#93;</span><span style="color: #339933;">--;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    isHolded<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">keyStatus</span><span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Klasa zawiera tablicę klawiszy. W przypadku wciśnięcia np. strzałki w lewo(keyCode = 37) następuje zwiększenie o jeden wartości keyStatus[37]. Jeżeli ta wartość jest większa od zera metoda isHolded() zwraca true co informuje nas, że klawisz jest przytrzymywany. W przypadku systemów z rodziny Windows zdarzenie keyUp nie jest powtarzane. Zatem zwiększenie wartości naszego licznika powinno nastąpić tylko raz w przypadku pierwszego pojawienia się zdarzenia keyDown. Aby wiedzieć jakiego rodzaju zdarzenie zostało ostatnio wywołane(up czy down) stworzyłem zmienną keyLastEvent i modyfikuję ją wg. potrzeb. Dzięki takiej budowie naszej klasy(tj. bez warunkowych lini kodu zależnych od systemu operacyjnego lub przeglądarki) akcja przytrzymania klawisza zostanie poprawnie rozpoznana nawet w przypadku poprawienia błędów w jednej z przeglądarek.</p>
<p>Aby kod ten zadziałał potrzebujemy dodatkowo określić, które z naszych funkcji nasłuchują. Zrobimy to w metodzie init() obiektu GameBoard tuż pod kodem ładującym tekstury.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">preloadTextures</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        document.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'keydown'</span><span style="color: #339933;">,</span> keyHandler.<span style="color: #660066;">keyDown</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        document.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'keyup'</span><span style="color: #339933;">,</span> keyHandler.<span style="color: #660066;">keyUp</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Pętla główna</h3>
<p>W przypadku gier ważne jest utworzenie pętli głównej programu. Będzie ona za każdym razem sprawdzała stan zdarzeń pochodzących z klawiatury, sieci oraz sztucznej inteligencji. W przypadku małych gier(np. kółko i krzyżyk, sudoku, saper) jest to nieistotne, u nas — w grze pełnej animacji — po prostu konieczne.</p>
<p>Stwórzmy dodatkowy obiekt będący centralną sterownią naszej gry.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> GameMain <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    img<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    x<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
    y<span style="color: #339933;">:</span><span style="color: #CC0000;">480</span><span style="color: #339933;">,</span>
    direction<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>  <span style="color: #006600; font-style: italic;">// 0= LEFT 1 =UP, 2 = RIGHT, 3=DOWN</span>
    mainLoop<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
            GameBoard.<span style="color: #660066;">drawBoard</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">37</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// LEFT</span>
            <span style="color: #009900;">&#123;</span>
                GameMain.<span style="color: #660066;">direction</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">x</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
                    GameMain.<span style="color: #660066;">x</span><span style="color: #339933;">-=</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">38</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// UP</span>
            <span style="color: #009900;">&#123;</span>
                GameMain.<span style="color: #660066;">direction</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">y</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
                    GameMain.<span style="color: #660066;">y</span><span style="color: #339933;">-=</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">39</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// RIGHT</span>
            <span style="color: #009900;">&#123;</span>
                GameMain.<span style="color: #660066;">direction</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">x</span><span style="color: #339933;">&lt;</span><span style="color: #CC0000;">480</span><span style="color: #009900;">&#41;</span>
                    GameMain.<span style="color: #660066;">x</span><span style="color: #339933;">+=</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">40</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// DOWN</span>
            <span style="color: #009900;">&#123;</span>
                GameMain.<span style="color: #660066;">direction</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">y</span><span style="color: #339933;">&lt;</span><span style="color: #CC0000;">480</span><span style="color: #009900;">&#41;</span>
                    GameMain.<span style="color: #660066;">y</span><span style="color: #339933;">+=</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
            <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">37</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">41</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>keyHandler.<span style="color: #660066;">isHolded</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                    document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'key-'</span><span style="color: #339933;">+</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">background</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'red'</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">else</span>
                    document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'key-'</span><span style="color: #339933;">+</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">background</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'white'</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">translate</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">x</span><span style="color: #339933;">,</span>GameMain.<span style="color: #660066;">y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">direction</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">:</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">rotate</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">90</span> <span style="color: #339933;">*</span> Math.<span style="color: #660066;">PI</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">180</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">drawImage</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,-</span><span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">:</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">rotate</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">180</span> <span style="color: #339933;">*</span> Math.<span style="color: #660066;">PI</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">180</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">drawImage</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span><span style="color: #339933;">,-</span><span style="color: #CC0000;">32</span><span style="color: #339933;">,-</span><span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">:</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">rotate</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">270</span> <span style="color: #339933;">*</span> Math.<span style="color: #660066;">PI</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">180</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">drawImage</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span><span style="color: #339933;">,-</span><span style="color: #CC0000;">32</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
                    GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">drawImage</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #009900;">&#125;</span>
            GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">restore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
             FrameCounter.<span style="color: #660066;">updateFPS</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Image<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'images/btank.png'</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">img</span>.<span style="color: #660066;">tank</span>.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            GameBoard.<span style="color: #660066;">init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Metoda mainLoop() będzie wywoływana co określony, bardzo krótki czas. Dzięki temu będziemy w stanie na bierząco wychwytywać nadchodzące zdarzenia.</p>
<p>Podzielona jest ona na kilka akcji. Pierwszą z nich jest rysowanie mapy. Następnie sprawdzamy poszczególne klawisze strzałek. W przypadku przytrzymania jedngo z nich, zmieniamy współrzędne naszego czołgu — pola x oraz y klasy GameMain. Kolejnym krokiem jest zapisanie stanu obiektu canvas. Translacja o wektor, obrót w odpowiednim kierunku oraz rysowanie czołgu. Następnie przywracamy stan obszaru canvas i wywołujemy licznik <abbr title="Frame Per Second - klatki na sekundę">FPS</abbr></p>
<p>Odczyt grafiki czołgu umieściłem w metodzie init(). Jest to nasza nowa metoda inicjalizująca, którą musimy wywołać aby uruchomić grę.</p>
<h3>Licznik FPS</h3>
<p>Ważnym elementem podczas testowania gry jest licznik FPS. Dzięki niemu będziemy mogli określić, które elementy gry są napisane nieoptymalnie oraz, który kod należy wymienić. Oko ludzkie jest w stanie zaobserwować jedynie 25 klatek filmu w każdej sekundzie. Dla mnie jest to jednak mało. Spróbujmy sprawdzić aby gra posiadała przynajmniej 40fps. Moja klasa licząca ilość klatek wygląda następująco:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> FrameCounter <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    lastFrameTime<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    updateFPS<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> currentTime <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fps'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1000</span><span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span>currentTime<span style="color: #339933;">-</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">lastFrameTime</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'fps'</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">lastFrameTime</span> <span style="color: #339933;">=</span> currentTime<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Jak ten kod działa? W każdej klatce obliczana jest różnica pomiędzy aktualnym czasem oraz czasem wyświetlania poprzedniej klatki. W ten sposób możemy obliczyć czas(w milisekundach) wykonywania się jednej klatki. Dzieląc przez tą wartość 1000 otrzymujemy ilość klatek na sekundę. </p>
<h3>Uruchomienie</h3>
<p>Zmieniona została klasa inicjująca naszą grę więc w metodzie GameBoard.preloadTextures() musi zajść lekka zmiana:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    preloadTextures<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> img <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Image<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        img.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        img.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            GameBoard.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">createPattern</span><span style="color: #009900;">&#40;</span>img<span style="color: #339933;">,</span> <span style="color: #3366CC;">'repeat'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameBoard.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
                GameBoard.<span style="color: #660066;">preloadTextures</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span>
                window.<span style="color: #660066;">setInterval</span><span style="color: #009900;">&#40;</span>GameMain.<span style="color: #660066;">mainLoop</span><span style="color: #339933;">,</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>

<p>Gotowe! Pełny kod źródłowy z dzisiejszego artykułu jest dostępny również <a href="/examples/game-0.0.3/index.html">online</a>,  jako działająca całość. Zapraszam do testów.</p>
<h3>Optymalizacja</h3>
<p>Po uruchomieniu gry zapewne zauważyłeś, że działa ona bardzo wolno. Jedynie przeglądarki działające w oparciu o WebKit potrafią osiągnąć oczekiwane 40 klatek. Poniżej dołączam małe zestawienie przeglądarek(aktualne ustawienia — odświeżanie klatki co 10ms —  powoduje, że maksymalna ilość klatek na sekundę to 100).</p>
<table>
<tr>
<th>Przeglądarka</th>
<th><abbr title="Frame Per Second - klatki na sekundę">fps</abbr></th>
</tr>
<tr>
<td>Safari (OS X)</td>
<td>50–60</td>
</tr>
<tr>
<td>Google Chrome(5.0.375.38 beta, GNU/Linux)</td>
<td>58–60</td>
</tr>
<tr>
<td>Mozilla Firefox(3.5.9, GNU/Linux)</td>
<td>31–33</td>
</tr>
<tr>
<td>Konqueror(4.3.5–0.1.1, GNU/Linux)</td>
<td>15–17</td>
</tr>
<tr>
<td>Opera(10.10, GNU/Linux)</td>
<td>12–16</td>
</tr>
</table>
<p>Oczywiście jest to zbyt mało aby gra była w pełni grywalna, ponieważ na mapie poruszać będzie się kilka czołgów otoczonych szeregiem animacji. Pamiętajmy jednak, że kod, który umieściłem na serwerze jest niezoptymalizowany. W kolejnych artykułach przedstawię sztuczki jak przyspieszyć rysowanie elementów w obiekcie canvas oraz jak skrócić czas wykonywania się zwykłego kodu JavaScript.</p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/328/obsluga-klawiatury-oraz-licznik-fps/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Canvas — Rysujemy mapę</title>
		<link>http://srodek.info/blog/270/rysujemy-mape</link>
		<comments>http://srodek.info/blog/270/rysujemy-mape#comments</comments>
		<pubDate>Sat, 15 May 2010 23:40:17 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Moje projekty]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=270</guid>
		<description><![CDATA[Dzisiaj stworzę pierwszą wersję planszy do mojej gry. Spróbujmy wykreować obszar 16x16, generowany na podstawie tablicy z informacjami o poszczególnych polach. Po wygenerowaniu mapy pozostanie ona całkowicie statyczna więc liczenie fps pozostawię do kolejnego artykułu. Dzisiaj zajmijmy się stworzeniem głównej klasy oraz kilku metod inicjalizujących naszą planszę. Przede wszystkim potrzebujemy obiektu canvas o rozmiarach 512x512px(16x16 [...]]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj stworzę pierwszą wersję planszy do mojej gry. Spróbujmy wykreować obszar 16x16, generowany na  podstawie tablicy z informacjami o poszczególnych polach. Po wygenerowaniu mapy pozostanie ona całkowicie statyczna więc liczenie <abbr title="Frame per second - Ilość klatek na sekundę">fps</abbr> pozostawię do kolejnego artykułu. Dzisiaj zajmijmy się stworzeniem głównej klasy oraz kilku metod inicjalizujących naszą planszę.</p>
<p><span id="more-270"></span></p>
<p>Przede wszystkim potrzebujemy obiektu canvas o rozmiarach 512x512px(16x16 pól o rozmiarach 32x32px).</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;canvas id=&quot;gameBoard&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/canvas&gt;</pre></div></div>

<p>Do wygenerowania mapy potrzebujemy również kilku tekstur. Tymczasowo posiadam jedynie trawę, wodę, cegłę oraz lód.</p>
<ol>
<li><img src="http://srodek.info/wp-content/uploads/2010/05/brick.png" alt="" width="32" height="32" /></li>
<li><img src="http://srodek.info/wp-content/uploads/2010/05/gameback.png" alt="" width="32" height="32" /></li>
<li><img src="http://srodek.info/wp-content/uploads/2010/05/ice.png" alt="" width="32" height="32" /></li>
<li><img src="http://srodek.info/wp-content/uploads/2010/05/water.png" alt="" width="32" height="32" /></li>
</ol>
<p>Trawę ustawiłem jako tło elementu canvas bezpośrednio w pliku CSS. Spróbujmy stworzyć główną klasę o nazwie GameBoard.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> GameBoard <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    ctx<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span>
    TEXTURE_ID<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>ICE<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> BRICK<span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> WATER<span style="color: #339933;">:</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 
    textures<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'images/ice.png'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'images/brick.png'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'images/water.png'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
    board<span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
    drawBoard<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> y<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> y<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">16</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> x<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> x<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">16</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">board</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">fillStyle</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">board</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">fillRect</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">*</span><span style="color: #CC0000;">32</span><span style="color: #339933;">,</span>y<span style="color: #339933;">*</span><span style="color: #CC0000;">32</span><span style="color: #339933;">,</span><span style="color: #CC0000;">32</span><span style="color: #339933;">,</span><span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">restore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    preloadTextures<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> img <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Image<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        img.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        img.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            GameBoard.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> GameBoard.<span style="color: #660066;">ctx</span>.<span style="color: #660066;">createPattern</span><span style="color: #009900;">&#40;</span>img<span style="color: #339933;">,</span> <span style="color: #3366CC;">'repeat'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>GameBoard.<span style="color: #660066;">textures</span><span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
                GameBoard.<span style="color: #660066;">preloadTextures</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">else</span>
                GameBoard.<span style="color: #660066;">drawBoard</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">canvas</span> <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gameBoard'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">canvas</span>.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">ctx</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">canvas</span>.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2d&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">preloadTextures</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Pierwsze pole naszego obiektu — ctx(context) to kontekst obiektu canvas. Po przez niego odwołujemy do wszystkich metod rysujących. Następny obiekt — TEXTURE_ID — jest niczym innym jak zbiorem stałych(troszkę to przypomina enum znane z c++). W tym przykładzie nie jest on w ogóle używany jednak w przyszłości wygodniejsze będzie odwoływanie się za pomocą nazw. Kolejne pole — textures — to tablica adresów do naszych tekstur. Zauważ, że indeksy w tej tablicy odpowiadają wartościom stałych w TEXTURE_ID( TEXTURE_ID.ICE = 1 oraz textures[1] = ‚images/ice.png’). Przyjąłem, że tekstura zerowa to po prostu tekstura pusta(pełna przezroczystość). Na końcu widnieje tablica <em>board</em> zawierająca informacje o każdym polu. Liczba od 0 do 3 określa rodzaj tekstury.</p>
<h3>init()</h3>
<p>Metoda ta wyłapuje kontekst naszego pola canvas zapisuje go do pola <em>ctx</em> oraz wywołuje metodę preloadTextures(1). Rozpoczniemy ładowanie tekstur rozpoczynając od tej o identyfikatorze jedynki(zero jest zarezerwowane dla tekstury pustej).</p>
<h3>preloadTextures()</h3>
<p>Jako parametr metoda ta przyjmuje identyfikator tekstury(jej indeks w tablicy textures). Najpierw tworzymy pusty obraz, a następnie ustalamy jego adres. Po załadowaniu pliku z grafiką generujemy nowy wzór za pomocą ctx.createPattern() oraz nadpisujemy nim adres przechowywany w tablicy textures. Następnie sprawdzamy czy tekstura o identyfikatorze o jeden większym istnieje. Jeśli tak ładujemy ją. Jeśli nie wyświetlamy mapę</p>
<h3>drawBoard()</h3>
<p>Ta metoda rysuje pole po polu przechodząc przez wszystkie elementy z tablicy board. Sądzę, że kod jest oczywisty.</p>
<p>Efekt działania skryptu:</p>
<p><a href="http://srodek.info/wp-content/uploads/2010/05/board.png"><img src="http://srodek.info/wp-content/uploads/2010/05/board.png" alt="" title="board" width="512" height="512" class="aligncenter size-full wp-image-292" /></a></p>
<h3>Co następnym razem?</h3>
<p>Umieścimy na planszy naszą postać oraz zaprogramujemy metody odpowiedzialne za wyłapywanie zdarzeń klawiatury. Możliwe stanie się płynne poruszanie po mapie.</p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/270/rysujemy-mape/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Serwer gry. Część druga</title>
		<link>http://srodek.info/blog/256/serwer-gry-czesc-druga</link>
		<comments>http://srodek.info/blog/256/serwer-gry-czesc-druga#comments</comments>
		<pubDate>Fri, 14 May 2010 19:40:47 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[Moje projekty]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=256</guid>
		<description><![CDATA[Spróbujmy udoskonalić nasz serwer tak aby posiadał możliwości prostego chatu — wysyłanie wiadomości ogólnych do wszystkich użytkowników oraz prywatnych tylko do jednej osoby. Mój kod urósł prawie do 150 linijek przy czym nie uwzględnia on kilku rzeczy, o których wspomnę podczas pisania protokołu lub tworzenia klientów.(w końcu nie piszę MUD-a i telnet muszę zastąpić czymś [...]]]></description>
			<content:encoded><![CDATA[<p>Spróbujmy udoskonalić nasz serwer tak aby posiadał możliwości prostego chatu — wysyłanie wiadomości ogólnych do wszystkich użytkowników oraz prywatnych tylko do jednej osoby. Mój kod urósł prawie do 150 linijek przy czym nie uwzględnia on kilku rzeczy, o których wspomnę podczas pisania protokołu lub tworzenia klientów.(w końcu nie piszę <a href="http://pl.wikipedia.org/wiki/MUD_(RPG)">MUD-a</a> i telnet muszę zastąpić czymś innym).</p>
<p><span id="more-256"></span></p>
<p>Poprawiony kod wygląda tak:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
<span style="color: #990000;">set_time_limit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> GameClient
<span style="color: #009900;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$socket</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">socket</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$socket</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> sendMessage<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #990000;">socket_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$message</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Wysylam wiadomosc do '</span><span style="color: #339933;">.</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #339933;">.</span><span style="color: #0000ff;">': '</span><span style="color: #339933;">.</span><span style="color: #000088;">$message</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> GameServer
<span style="color: #009900;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$master</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$address</span><span style="color: #339933;">;</span> 
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$port</span><span style="color: #339933;">;</span> 
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$maxClients</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$sockets</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$clients</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'127.0.0.123'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$port</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">14117</span><span style="color: #339933;">,</span> <span style="color: #000088;">$maxClients</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">address</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$address</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">port</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$port</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">maxClients</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$maxClients</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_create</span><span style="color: #009900;">&#40;</span>AF_INET<span style="color: #339933;">,</span> SOCK_STREAM<span style="color: #339933;">,</span> SOL_TCP<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">socket_bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">port</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">socket_listen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span> <span style="color: #339933;">-&gt;</span> <span style="color: #004000;">master</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$changedSockets</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #339933;">;</span>
         <span style="color: #990000;">socket_select</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$changedSockets</span><span style="color: #339933;">,</span><span style="color: #000088;">$write</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #000088;">$exceptions</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$changedSockets</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$socket</span><span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// zmiana gniazda głównego =&gt; nowe polaczenie</span>
            <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
               <span style="color: #000088;">$socket</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_accept</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
               <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$socket</span><span style="color: #339933;">;</span>
               <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clients</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GameClient<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #009900;">&#125;</span>
            <span style="color: #666666; font-style: italic;">// zmiana gniazda jednego z klientów</span>
            <span style="color: #b1b100;">else</span>
            <span style="color: #009900;">&#123;</span>
               <span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_read</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
               <span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot; <span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
               <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$input</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'exit'</span><span style="color: #009900;">&#41;</span>
               <span style="color: #009900;">&#123;</span>
                  <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Bye bye!'</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
                  <span style="color: #666666; font-style: italic;">// send data to socket </span>
                  <span style="color: #990000;">socket_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$output</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                  <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                  <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                  <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clients</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$id</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                  <span style="color: #990000;">socket_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #009900;">&#125;</span>
               <span style="color: #b1b100;">else</span>
               <span style="color: #009900;">&#123;</span>
                  <span style="color: #000088;">$command</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">!==</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
                      ? <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                      <span style="color: #339933;">:</span> <span style="color: #000088;">$input</span><span style="color: #339933;">;</span>
&nbsp;
                  <span style="color: #b1b100;">switch</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$command</span><span style="color: #009900;">&#41;</span>
                  <span style="color: #009900;">&#123;</span>
                     <span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'hello'</span><span style="color: #339933;">:</span>
                        <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Hello!'</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
                     <span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'list'</span><span style="color: #339933;">:</span>
                        <span style="color: #666666; font-style: italic;">// identyfikatory wszystkich gniazd</span>
                        <span style="color: #000088;">$all</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                         <span style="color: #666666; font-style: italic;">// identyfikator uzytkownika</span>
                        <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #666666; font-style: italic;">// usuniecie ID glownego gniazda oraz gniazda uzytkownika</span>
                        <span style="color: #000088;">$all</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_diff</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$all</span><span style="color: #339933;">,</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$all</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                           <span style="color: #000088;">$output</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'Nie ma innych osob'</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">else</span>
                           <span style="color: #000088;">$output</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'ID innych osob to: '</span><span style="color: #339933;">.</span><span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">', '</span><span style="color: #339933;">,</span><span style="color: #000088;">$all</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
                     <span style="color: #b1b100;">default</span><span style="color: #339933;">:</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$command</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                        <span style="color: #009900;">&#123;</span>
                           <span style="color: #666666; font-style: italic;">// identyfikator uzytkownika</span>
                           <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                           <span style="color: #666666; font-style: italic;">// wyslanie wiadomosci do wszystkich</span>
                           <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$command</span><span style="color: #339933;">==</span><span style="color: #0000ff;">'0'</span><span style="color: #009900;">&#41;</span>
                           <span style="color: #009900;">&#123;</span>
                              <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clients</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$client</span><span style="color: #009900;">&#41;</span>
                              <span style="color: #009900;">&#123;</span>
                                 <span style="color: #666666; font-style: italic;">// nie wysylamy do siebie</span>
                                 <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #339933;">!=</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
                                    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendMessage</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                              <span style="color: #009900;">&#125;</span>
                              <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Do wszystkich'</span><span style="color: #339933;">;</span>
                           <span style="color: #009900;">&#125;</span>
                           <span style="color: #666666; font-style: italic;">// nie wysylamy do siebie, uzytkownik istnieje</span>
                           <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$command</span><span style="color: #339933;">!=</span><span style="color: #000088;">$id</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$command</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                           <span style="color: #009900;">&#123;</span>
                              <span style="color: #666666; font-style: italic;">// jeden mniejszy ponieważ $this-&gt;master znajduje sie</span>
                              <span style="color: #666666; font-style: italic;">// w tablicy gniazd a nie jest klientem</span>
                              <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clients</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$command</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendMessage</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                              <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'OK'</span><span style="color: #339933;">;</span>
                           <span style="color: #009900;">&#125;</span>
                           <span style="color: #b1b100;">else</span>
                              <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span><span style="color: #0000ff;">'Bledny ID'</span><span style="color: #339933;">;</span> 
                        <span style="color: #009900;">&#125;</span>
                        <span style="color: #b1b100;">else</span>
                           <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Niezrozumiale polecenie: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$input</span><span style="color: #339933;">.</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span> 
                  <span style="color: #009900;">&#125;</span>
                  <span style="color: #990000;">socket_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$output</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
         <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __desctruct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #990000;">socket_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$gameServer</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GameServer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Czas na krótką analizę. Pierwsze co rzuca się w oczy to nowa klasa <em>GameClient</em>. Jest to klasa, z którą wiążę pewne plany. Obiekty tej klasy przechowują dwie rzeczy — gniazdo oraz jego identyfikator. Metoda sendMessage() służy do wysyłania wiadomości do użytkownika, który jest podpięty do tego gniazda.</p>
<p>W klasie <em>GameServer</em> pojawiły się dwa nowe pola prywatne, tablica <em>sockets</em> przechowująca wszystkie gniazda dostępne dla serwera oraz tablicę <em>clients</em> przechowującą obiekty klasy <em>GameClient</em>.</p>
<p>Ogólne założenia się nie zmieniły — wciąż istnieje pętla nieskończona jednak jej zawartość została zmodyfikowana.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$changedSockets</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sockets</span><span style="color: #339933;">;</span>
<span style="color: #990000;">socket_select</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$changedSockets</span><span style="color: #339933;">,</span><span style="color: #000088;">$write</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #000088;">$exceptions</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Użyliśmy tutaj funkcji socket_select(). W parametrach podajemy referencje(dlatego pierwsza linijka jest konieczna) do tablic gniazd, a funkcja pozostawia w nich jedynie te elementy, w których zaszły pewne zdarzenia. Pierwszy parametr odpowiada czy czytanie, czyli wybrane zostaną jedynie te gniazda, które coś przesyłają do serwera. Drugi i trzeci parametr odpowiadają za pisanie oraz wyjątki lecz nas one nie interesują. Ostatni parametr dotyczy limitu czasu oczekiwania na wybranie poszczególnych gniazd. Null oznacza brat limitu czasowego.</p>
<p>Następnie sprawdzamy każde z gniazd z tablicy <em>$changedSockets</em>. Jeśli gniazdo jest tym samym co gniazdo główne serwera oznacza to, że nowy użytkownik chce ustanowić połączenie. Robimy to tworząc nowe gniazdo i dopisując informacje o nim do tablic <em>$this-&gt;sockets</em> oraz <em>$this-&gt;clients</em>. W przypadku innych gniazd odczytywane są dane przesyłane do serwera.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_read</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot; <span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Używam funkcji trim() aby wyczyścić dane przychodzące do serwera z różnych niepotrzebnych białych znaków.</p>
<p>Pozostały kod to pseudo-protokół chatu. W przypadku przesłania komunikatu pustego lub wiadomości <em>exit</em> połączenie z użytkownikiem jest zrywane. Polecenie <em>hello</em> jest czysto demonstracyjne. W przypadku wpisania <em>list</em> pojawia się lista identyfikatorów innych użytkowników dostępnych aktualnie lub komunikat o ich braku. Wysyłanie komunikatów do innych użytkowników odbywa się w następujący sposób:</p>
<p>ID komunikat</p>
<p>Jeżeli ID wynosi zero wiadomość jest przesyłana do wszystkich uczestników chatu.</p>
<p>Serwer ten wciąż nie jest idealny. Nie zabezpiecza on przed połączeniem się zbyt dużej ilości użytkowników. Protokół również jest dosyć dziwny. W zasadzie stworzyłem go jedynie w celach edukacyjnych. Proponowałbym jego wymianę na coś przyjaźniejszego. Co warto dopisać do takiego serwera? Można spróbować uporać się z problemem pokojów dla różnych grup użytkowników. Zapewne te rzeczy opiszę niebawem na blogu lecz tymczasowo zrobię przerwę z php. Już niebawem sporo informacji na temat rysowania w obiekcie Canvas. Może zrobić jakąś fajną planszę w rzucie izometrycznym?</p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/256/serwer-gry-czesc-druga/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Serwer gry. Część pierwsza.</title>
		<link>http://srodek.info/blog/227/serwer-gry-czesc-pierwsza</link>
		<comments>http://srodek.info/blog/227/serwer-gry-czesc-pierwsza#comments</comments>
		<pubDate>Thu, 13 May 2010 22:47:15 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[Moje projekty]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=227</guid>
		<description><![CDATA[Pisząc grę internetową trzeba zastanowić się nad sposobem komunikacji między graczami oraz bazą danych. W przypadku aplikacji przeglądarkowych dużego wyboru nie ma. Praktycznie wszystkie gry wykorzystują technologię AJAX. Jak to działa w praktyce? Nie za dobrze. Spróbujmy stworzyć coś dużo bardziej wydajniejszego. Sposób działania technologi AJAX AJAX to rozwiązanie jednostronne. Klient prosi serwer o pewne [...]]]></description>
			<content:encoded><![CDATA[<p>Pisząc grę internetową trzeba zastanowić się nad sposobem komunikacji między graczami oraz bazą danych. W przypadku aplikacji przeglądarkowych dużego wyboru nie ma. Praktycznie wszystkie gry wykorzystują technologię AJAX. Jak to działa w praktyce? Nie za dobrze. Spróbujmy stworzyć coś dużo bardziej wydajniejszego.</p>
<p><span id="more-227"></span></p>
<h3>Sposób działania technologi AJAX</h3>
<p>AJAX to rozwiązanie jednostronne. Klient prosi serwer o pewne informacje, a ten je wysyła użytkownikowi. Serwer nie posiada dokładnych informacji na temat ilości aktualnie połączonych użytkowników oraz nie może wysłać do żadnego z nich samodzielnie żadnej informacji(tj. może jedynie odpowiadać na ich zapytania).</p>
<p style="text-align:center;"><a href="http://srodek.info/wp-content/uploads/2010/05/ajax.png"><img src="http://srodek.info/wp-content/uploads/2010/05/ajax.png" alt="" title="Schemat działania technologi AJAX" width="540" height="200" class="aligncenter size-full wp-image-231" /></a><br />
<em>Kocham robić te fajne obrazki i choć nie mają one niczego wspólnego z UML-em mam nadzieję, że jesteś w stanie je odczytywać</em></p>
<p>Przeanalizujmy przykład czatu internetowego w którym mamy trzech użytkowników(Client1, Client2, Client3). Pierwszy z nich chce wysłać informację do trzeciego. Wygląda to następująco:</p>
<ul>
<li>(1) Client1 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(2) Client2 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(3) Client3 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(4) Client1 wysyła do serwera wiadomość przeznaczoną dla użytkownika Client3. Serwer zwraca informację o przyjęciu danych.</li>
<li>(4,5) Serwer zapisuje wiadomość do swojego bufora(w tym przykładzie bazy danych)</li>
<li>(5) Client2 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(6) Client3 pyta serwer czy są jakieś wiadomości do niego.</li>
<li>(6,5) Serwer odczytuje z bazy danych wiadomość oraz zwraca ją użytkownikowi.</li>
<li>(7) Client1 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(8) Client2 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(9) Client3 pyta serwer czy są jakieś wiadomości do niego. Serwer zwraca informację o ich braku.</li>
<li>(…)</li>
</ul>
<p>Jak widać wykonywanych jest wiele niepotrzebnych zapytań. Każdy z klientów musi stale wysłać zapytanie do serwera co w przypadku małego czasu może powodować spore zużycie procesora serwera. W sytuacji, gdy czas będzie większy w grze pojawią się lagi. Jak ten problem rozwiązuje się w „normalnych“ grach internetowych? Używane są gniazda.</p>
<h3>Jak działają gniazda</h3>
<p style="text-align:center"><a href="http://srodek.info/wp-content/uploads/2010/05/socket.png"><img src="http://srodek.info/wp-content/uploads/2010/05/socket.png" alt="" title="socket" width="540" height="200" class="aligncenter size-full wp-image-239" /></a><br />
<em>Szerokie linie oznaczają nasłuchiwanie serwera oraz klientów</em></p>
<p>Każdy z klientów musi ustanowić połączenie z serwerem. Serwer dla każdego z nich tworzy gniazdo za pomocą którego w dowolnym momencie może wysłać informację do jednego z użytkowników.</p>
<p>Wygląda to tak:</p>
<ul>
<li>(0) Client1, Client2, Client3 nawiązują połączenie z serwerem(tworzone są gniazda)</li>
<li>(1) Client1 wysyła wiadomość do serwera (serwer zwraca komunikat o sukcesie)</li>
<li>(2) Serwer odnajduje gniazdo trzeciego użytkownika</li>
<li>(3) Serwer wysyła wiadomość do Client3</li>
</ul>
<p>W odróżnieniu do technologi AJAX w tym przypadku nasz serwer napisany w php musi ciąglę nasłuchiwać, a więc proces tego skryptu musi być cały czas uruchomiony. W tym celu tworzy się pętlę nieskończoną, którą cięgle sprawdza stan gniazda serwera.</p>
<h3>Pierwsza implementacja</h3>
<p>Spróbujmy stworzyć pierwszy działający serwer. Nie będzie on pozwalał na przekazywanie danych innym użytkownikom, a połączenia nie będą utrzymywane.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
<span style="color: #990000;">set_time_limit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> GameServer
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$master</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$address</span><span style="color: #339933;">;</span> 
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$port</span><span style="color: #339933;">;</span> 
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$maxClients</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'127.0.0.1'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$port</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">14117</span><span style="color: #339933;">,</span> <span style="color: #000088;">$maxClients</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">address</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$address</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">port</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$port</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">maxClients</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$maxClients</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_create</span><span style="color: #009900;">&#40;</span>AF_INET<span style="color: #339933;">,</span> SOCK_STREAM<span style="color: #339933;">,</span> SOL_TCP<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
		<span style="color: #990000;">socket_bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">port</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">socket_listen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
		<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
                        <span style="color: #666666; font-style: italic;">// akceptujemy połączenie, tworzymy gniazdo </span>
			<span style="color: #000088;">$socket</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_accept</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
			<span style="color: #666666; font-style: italic;">// odczytujemy informacje z gniazda</span>
			<span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #990000;">socket_read</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
			<span style="color: #666666; font-style: italic;">// przygotowujemy dane do wysyłki</span>
			<span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Wyslales do serwera: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$input</span><span style="color: #339933;">.</span><span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
			<span style="color: #666666; font-style: italic;">// Wysyłamy dane użytkownikowi</span>
			<span style="color: #990000;">socket_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$output</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                        <span style="color: #666666; font-style: italic;">// zamykamy połączenie z użytkownikiem</span>
			<span style="color: #990000;">socket_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$socket</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __desctruct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// zamknięcie głównego gniazda</span>
		<span style="color: #990000;">socket_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">master</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$gameServer</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GameServer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Tworzymy obiekt $gameServer. W konstruktorze możemy podać kilka parametrów: adres i port pod jakim serwer będzie nasłuchiwał oraz maksymalną ilość użytkowników(ta zmienna nie jest używana w tym przykładzie lecz przyda się później).  </p>
<h4>Kilka słów o numeracji portów</h4>
<p class="quicknote">W przypadku IP w wersji czwartej do dyspozycji mamy 2<sup>16</sup> portów. Te o numerach poniżej 1024 wymagają uprawnień administracyjnych. W większości przypadków są one już zarezerwowane dla innych usług(np. 80 dla http, 23 dla ftp, 21 dla telnet itd.). Najwygodniej jest po prostu ich nie ruszać.</p>
<p>Do zmiennej $this-&gt;master zapisywane jest główne gniazdo serwera tworzone za pomocą socket_create(). To ono będzie odbierało wszystkie informacje przychodzące od innych użytkowników. Co oznaczają parametry wewnątrz?</p>
<ul>
<li>Pierwszy informuje jaka rodzina protokołów będzie używana w przypadku naszego gniazda. <em>AF_INET</em> określa, że będą to protokoły(TCP oraz UDP) w oparciu o IPv4. Możemy również poinformować o użyciu IPv6 zamieniając ten parametr na <em>AF_INET6</em>.</li>
<li>Drugi parametr określa rodzaj transmisji. Do wyboru mamy:
<ul>
<li><strong>SOCK_STREAM</strong> —  informacje przesyłane są w obu kierunkach jednocześnie, bez spadku transferu, sekwencyjnie oraz niezawodnie za pomocą strumieni bajtów. Bazowym protokołem jest TCP.</li>
<li><strong>SOCK_DGRAM</strong> — datagramowy protokół bezpołączeniowy z brakiem kontroli przepływu i retransmisji. Bazowym protokołem jest UDP(To jest dobry wybór w przypadku pisania gry internetowej!).</li>
<li><strong>SOCK_SEQPACKET</strong> — informacje przesyłane są w obu kierunkach jednocześnie, bez spadku transferu, sekwencyjnie. Od klienta wymagane jest aby odczytywane były całe pakiety przy każdym zapytaniu.</li>
<li><strong>SOCK_RAW</strong> — gniazdo RAW czyli bezpośredni do niego dostęp. Umożliwia to stworzenie własnego protokołu komunikacji. Opcja raczej dla zaawansowanych użytkowników.</li>
<li><strong>SOCK_RDM</strong> — niezawodna transmisja pakietów nie gwarantująca porządkowania pakietów. Ta opcja nie zadziała w wielu systemach operacyjnych. Raczej dla zaawansowanych użytkowników.</li>
</ul>
</li>
<li>Ostatni parametr to po prostu ID protokołu. W przypadku TCP oraz UDP możemy skorzystać ze stałych SOL_TCP(6) oraz SOL_UDP(17). Pełną listę identyfikatorów znajdziesz w <em>/etc/protocols</em></li>
</ul>
<p>W naszym przykładzie stworzyliśmy gniazdo wykorzystujące protokół TCP. W kolejnej lini informujemy nasze gniazdo pod jakim adresem i jaki port ma nasłuchiwać. Gdy to określimy uruchamiamy nasłuchiwanie.</p>
<p>Ten proces jest bardzo prosty. Stworzona została pętla nieskończona, która przy każdym obrocie akceptuje gniazdo przychodzące. następnie odczytuje z niego dane, odsyła je do użytkownika oraz zamyka połączenie. Serwer uruchomiony raz będzie działał w nieskończoność(prawie w nieskończoność <img src='http://srodek.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) więc ważne jest aby wyłączyć sprawdzanie czasu wykonywania się skryptu. W tym celu w pierwszej linijce kodu widnieje wywołanie funkcji set_time_limit()</p>
<h3>Testujemy serwer</h3>
<p>Uruchom konsolę z dwoma zakładkami. Aby uruchomić nasz serwer w pierwszej wpisz:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php server.php</pre></div></div>

<p>W drugiej spróbujmy aktywował połączenie</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hellson<span style="color: #000000; font-weight: bold;">@</span>hellson:~<span style="color: #000000; font-weight: bold;">&gt;</span> telnet 127.0.0.1 <span style="color: #000000;">14117</span>
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is <span style="color: #ff0000;">'^]'</span>.
Hello
Wyslales <span style="color: #000000; font-weight: bold;">do</span> serwera: Hello
Connection closed by foreign host.
hellson<span style="color: #000000; font-weight: bold;">@</span>hellson:~<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<p>W przypadku zamknięcia skryptu wykonany zostanie destruktor zamykający gniazdo główne.</p>
<p>Mam nadzieję, że ten artykuł ułatwił ci zrozumienie idei gniazd. Już jutro kontynuacja tematu. Ulepszę kod serwera tak aby odbierał informacje od różnych użytkowników jednocześnie. Połączenie będzie utrzymywane aż do momentu wpisania „exit“ przez użytkownika.</p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/227/serwer-gry-czesc-pierwsza/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Mark Morgan — „Vault Archives“</title>
		<link>http://srodek.info/blog/219/mark-morgan-vault-archives-za-darmo</link>
		<comments>http://srodek.info/blog/219/mark-morgan-vault-archives-za-darmo#comments</comments>
		<pubDate>Thu, 13 May 2010 11:10:37 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[Muzyka]]></category>
		<category><![CDATA[Fallout]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=219</guid>
		<description><![CDATA[Fallout 2 to zdecydowanie w dalszym ciągu jedno z moich głównych źródeł inspiracji. Dlaczego teraz nikt nie robi takich gier? Muzyka z tej legendarnej produkcji została udostępniona w całości za darmo przez Aural Network — Firmę, w której aktualnie pracuje Mark Morgan. Oczywiście licencja obejmuje jedynie użycie niekomercjalne. http://auralnetwork.com/releases UWAGA: Tymczasowo(zapewne pod wpływem Wykop.pl) możliwość pobierania [...]]]></description>
			<content:encoded><![CDATA[<p style="width:300px; padding:20px; float:right"><a href="http://srodek.info/wp-content/uploads/2010/05/aural001.png"><img class="size-medium wp-image-221" title="aural001" src="http://srodek.info/wp-content/uploads/2010/05/aural001-300x300.png" alt="" width="300" height="300" /></a></p>
<p>Fallout 2 to zdecydowanie w dalszym ciągu jedno z moich głównych źródeł inspiracji. Dlaczego teraz nikt nie robi takich gier? Muzyka z tej legendarnej produkcji została udostępniona w całości za darmo przez Aural Network — Firmę, w której aktualnie pracuje Mark Morgan. Oczywiście licencja obejmuje jedynie użycie niekomercjalne.</p>
<p><a href="http://auralnetwork.com/releases">http://auralnetwork.com/releases</a></p>
<p><em>UWAGA: Tymczasowo(zapewne pod wpływem Wykop.pl) możliwość pobierania została wstrzymana. Utwory dostępne do przesłuchania za pomocą odtwarzaczy flashowych można pobrać z <a href="http://auralnetwork.com/wp-content/uploads/2010/02/">http://auralnetwork.com/wp-content/uploads/2010/02/</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/219/mark-morgan-vault-archives-za-darmo/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nowy projekt na biurku</title>
		<link>http://srodek.info/blog/215/nowy-projekt-na-biurku</link>
		<comments>http://srodek.info/blog/215/nowy-projekt-na-biurku#comments</comments>
		<pubDate>Wed, 12 May 2010 17:52:53 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>
		<category><![CDATA[Moje projekty]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=215</guid>
		<description><![CDATA[Troszkę byłem ostatnio nieobecny lecz w tym czasie wytworzyłem kilka ciekawych pomysłów. Pod wpływem fascynacji Gwiezdnymi Wrotami rozpocząłem pracę nad grą internetową! Całość chcę oprzeć na technologiach dostępnych w HTML5. Użyję dodatkowo troszkę xHTML-a (głównie chodzi mi o SVG). Przygotujcie się na serię artykułów na temat obiektu Canvas, obsługi połączeń w php, pamięci podręcznej, pamięci [...]]]></description>
			<content:encoded><![CDATA[<p>Troszkę byłem ostatnio nieobecny lecz w tym czasie wytworzyłem kilka ciekawych pomysłów. Pod wpływem fascynacji Gwiezdnymi Wrotami rozpocząłem pracę nad grą internetową! Całość chcę oprzeć na technologiach dostępnych w HTML5. Użyję dodatkowo troszkę xHTML-a (głównie chodzi mi o SVG). Przygotujcie się na serię artykułów na temat obiektu Canvas, obsługi połączeń w php, pamięci podręcznej, pamięci współdzielonej itp. ponieważ planuję każdy etap produkcji opisać na blogu.<br />
<span id="more-215"></span></p>
<h3>Dlaczego nie Flash?</h3>
<p>Po pierwsze, jest to zamknięta technologia, która moim zdaniem prędzej czy później umrze śmiercią naturalną. Podobno Microsoft już zadeklarował, że nie będzie jej więcej wspierał. Po drugie, wydajność pozostawia wiele do życzenia. Po trzecie, problemem jest przechwytywanie zdarzeń myszki, która opuściła obszar obiektu flash. Tworzenie całej strony za pomocą jednego obiektu flash mija się z celem. Po czwarte, nie stać mnie aby sobie zakupić flasha. Co więcej, nie jestem pewien, czy Wine pozwoliłby mi go uruchomić pod moim linuksem.</p>
<h3>Więcej o grze</h3>
<p>Założenia są kosmiczne tj. gra odbywała się będzie w kosmosie, będzie możliwość podróżowania na mapie i walki z innymi graczami w czasie rzeczywistym. Chcę również wprowadzić rozwój technologiczny oraz jednostki komputera. Wymagane będzie całkiem niezłe łącze, nowoczesna przeglądarka oraz w miarę szybki procesor. Sam nie wiem, o czym będzie ta gra. Nie znam się na pisaniu scenariuszy, fabuły itp. Chcę po prostu posprawdzać i poćwiczyć użycie kilku fajnych technologii. Reszta myślę, że przyjdzie sama(tj. ktoś do pomocy).</p>
<p>Aby to nie brzmiało jak rzucanie słów na wiatr, podrzucam kilka moich planet zrobionych w GIMP-ie oraz pierwszą wersję mapy:</p>
<ul>
<li><a href="/uni/gfx/planeta_a.png">Planeta A</a></li>
<li><a href="/uni/gfx/planeta_b.png">Planeta B</a></li>
<li><a href="/uni/map.html">Mapa</a></li>
</ul>
<p>Jeśli masz ciekawe pomysły pisz do mnie(michal.srodek na gmailu). Już jutro artykuł na temat dalszych postępów zawierający trochę informacji technicznych.</p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/215/nowy-projekt-na-biurku/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Command &amp; Conquer za darmo</title>
		<link>http://srodek.info/blog/164/command-conquer-za-darmo</link>
		<comments>http://srodek.info/blog/164/command-conquer-za-darmo#comments</comments>
		<pubDate>Mon, 15 Feb 2010 11:30:11 +0000</pubDate>
		<dc:creator>Michał Środek</dc:creator>
				<category><![CDATA[Gry]]></category>

		<guid isPermaLink="false">http://srodek.info/?p=164</guid>
		<description><![CDATA[Planowałem kontynuować dzisiaj temat związany z bezpieczeństwem stron internetowych — a dokładniej „podglądaniu“ historii użytkownika odwiedzającego naszą stronę, jednak dowiedziałem się, że Westwood Studio udostępniło kilka swoich gier całkowicie za darmo. Co więcej, nie ma ograniczeń dotyczących lokalizacji(kilka gier było dostępnych tylko dla ludzi z USA). Do pobrania są trzy gry: C&#38;C: Timberian Sun + [...]]]></description>
			<content:encoded><![CDATA[<p>Planowałem kontynuować dzisiaj temat związany z bezpieczeństwem stron internetowych — a dokładniej „podglądaniu“ historii użytkownika odwiedzającego naszą stronę, jednak dowiedziałem się, że Westwood Studio udostępniło kilka swoich gier całkowicie za darmo. Co więcej, nie ma ograniczeń dotyczących lokalizacji(kilka gier było dostępnych tylko dla ludzi z USA). Do pobrania są trzy gry:</p>
<ul>
<li>C&amp;C: Timberian Sun + Firestorm</li>
<li>C&amp;C: Red Alert</li>
<li>C&amp;C: Timberian Dawn</li>
</ul>
<p>Sądząc po testach na winehq.org powinny działać całkiem sprawnie pod Linuksem. Wszystkie są dostępne pod adresem: <a href="http://www.commandandconquer.com/classic">http://www.commandandconquer.com/classic</a><br />
<span id="more-164"></span><br />
Gry te przypominają mi moje dzieciństwo — czasy gdy za grę(C&amp;C: Red Alert) u pirata(jedyna osoba w mieście posiadająca przegrywarkę) płaciło się 30zł, a wypożyczenie gry na jeden dzień do Pegasusa 5-10zł(w zależności od jakości gry).</p>
<p>Zakupiłem ostatnio Commandos Ultimate Anthology. Jedyne 30zł, a gry ją naprawdę świetne. Szkoda, że te współczesne nie podobają mi się tak, jak te stare. Czy twórcy dążą do ulepszeń graficznych kosztem grywalności, czy to może efekt działania Commodore 64 na mój mózg gdy byłem mniejszy?</p>
]]></content:encoded>
			<wfw:commentRss>http://srodek.info/blog/164/command-conquer-za-darmo/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
