<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>luq techblog</title>
	<atom:link href="http://luq10.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://luq10.wordpress.com</link>
	<description>o tworzeniu słów kilka...</description>
	<lastBuildDate>Tue, 03 Jan 2012 21:12:43 +0000</lastBuildDate>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='luq10.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>luq techblog</title>
		<link>http://luq10.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://luq10.wordpress.com/osd.xml" title="luq techblog" />
	<atom:link rel='hub' href='http://luq10.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Cheaty na Google+</title>
		<link>http://luq10.wordpress.com/2011/08/21/cheaty-na-google/</link>
		<comments>http://luq10.wordpress.com/2011/08/21/cheaty-na-google/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 14:59:39 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[GameDev]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[cheat]]></category>
		<category><![CDATA[Flood-It]]></category>
		<category><![CDATA[google+]]></category>
		<category><![CDATA[konami]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1287</guid>
		<description><![CDATA[Chodź dawno nic nie pisałem dziś króciutko o możliwości cheatowania w jednej z Google plusowych gier. &#160; Dokładniej rzecz biorąc w grze Flood-It!. Przeglądając kod (zresztą dość miernej jakości) można natknąć się na funkcje korzystającą z plugina Kanomi tworzącą sekwencje znaków dzięki którym można wygrać z dość niezłym wynikiem (20971520 pkt :]) &#160; Ładnie opisane [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1287&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img alt="Flood-It!" src="http://www.otworzumysl.pl/wp-content/uploads/2011/08/flood1.png" title="Flood-It!" class="alignright" width="300" /> Chodź dawno nic nie pisałem dziś króciutko o możliwości cheatowania w jednej z Google plusowych gier.</p>
<p>&nbsp;</p>
<p>Dokładniej rzecz biorąc w grze <a href="https://plus.google.com/games/479261262298">Flood-It!</a>. Przeglądając kod (zresztą dość miernej jakości) można natknąć się na funkcje korzystającą z plugina <a href="http://plugins.jquery.com/project/konami-code" title="Kanoni plugin for jQuery" target="_blank">Kanomi</a> tworzącą sekwencje znaków dzięki którym można wygrać z dość niezłym wynikiem (<strong>20971520 pkt</strong> :])</p>
<p>&nbsp;</p>
<p>Ładnie opisane komentarzami w kodzie:</p>
<p>&nbsp;</p>
<p><em>// set the keys for Konami code: up, up, down, down, left, right, left, right, b, a</em></p>
<p>&nbsp;</p>
<p><em>// win the game with cheat for at least 5 steps</em></p>
<p>&nbsp;</p>
<p>A więc wystarczy załadować grę <strong>zrobić min. 5 ruchów</strong> i kliknąć z klawiatury sekwencje znaków<br />
<strong>up, up, down, down, left, right, left, right, b, a</strong> i cieszyć się z wyniku :)</p>
<p>&nbsp;</p>
<p>Wycinek kodu:</p>
<p>&nbsp;</p>
<p><pre class="brush: jscript;">
// Check Konami cheat code - if the code is inserted - win the board with 25 steps.
function checkKonamiCode() {
  if (window.addEventListener) {
    // set the keys for Konami code: up, up, down, down, left, right, left, right, b, a
    var konami = [38,38,40,40,37,39,37,39,66,65];
    var keyIndex = 0;
    var MIN_CHEAT_STEPS = 5;
 
    // listen to key strokes
    window.addEventListener(&quot;keydown&quot;, function(e) {
      if (e.keyCode == konami[keyIndex++]) {
        // and check to see if the user has entered the Konami code
        if (keyIndex == konami.length) {
          // win the game with cheat for at least 5 steps
          var winSteps = parseInt($lp('#cur_round').text(),10);
          if (winSteps &gt;= MIN_CHEAT_STEPS) {
            startNewGame(true);
            updateGameStart();
            $lp('#cur_round').text(winSteps);
            floodItGame.endGame(true);
            keyIndex = 0;
          }
        }
      // wrong sequence - start over
      } else {
        keyIndex = 0;
      }
    }, true);
  }
}
</pre></p>
<p>&nbsp;</p>
<p>Myślę, że powyższy kod został pozostawiony specjalnie bo jeśli miałby służyć debugowaniu to po co taka duża sekwencja znaków? Po co w ogóle Konami? Dlaczego trzeba zrobić min. 5 ruchów? Jeśli miało by to służyć debugowaniu to raczej zrobiono by sobie buttona do tego w htmlu :) A więc myślę, że developerzy <a href="http://www.labpixies.com/" title="http://www.labpixies.com/" target="_blank">Labpixies</a> specjalnie zostawili możliwość cheatowania ;)</p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/category/programowanie/js/'>JS</a> Tagged: <a href='http://luq10.wordpress.com/tag/cheat/'>cheat</a>, <a href='http://luq10.wordpress.com/tag/flood-it/'>Flood-It</a>, <a href='http://luq10.wordpress.com/tag/google/'>google+</a>, <a href='http://luq10.wordpress.com/tag/konami/'>konami</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1287/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1287/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1287/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1287/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1287/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1287/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1287/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1287/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1287&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2011/08/21/cheaty-na-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://www.otworzumysl.pl/wp-content/uploads/2011/08/flood1.png" medium="image">
			<media:title type="html">Flood-It!</media:title>
		</media:content>
	</item>
		<item>
		<title>PHP i define()</title>
		<link>http://luq10.wordpress.com/2011/01/05/php-i-define/</link>
		<comments>http://luq10.wordpress.com/2011/01/05/php-i-define/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 22:46:23 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[const]]></category>
		<category><![CDATA[vat]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1255</guid>
		<description><![CDATA[To będzie bardzo krótki wpis, do których raczej nie przyzwyczaiłem ;) Na początek zagadka, co spowoduje podany kod: &#160; &#160; Wywali błąd? Nadpisze wartość liczby? Otóż nie. Jeśli nastąpiłoby nadpisanie wartości integera były to spory idiotyzm ze strony języka. Jednak co ciekawe nie wywali też błędu i stała o nazwie &#8217;100&#8242; powstanie, czego dowodem jest: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1255&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>To będzie bardzo krótki wpis, do których raczej nie przyzwyczaiłem ;)<br />
Na początek zagadka, co spowoduje podany kod:</p>
<p>&nbsp;</p>
<p><pre class="brush: php;"> 
  echo 100;
  define('100', 'stala 100');
  echo 100;
</pre></p>
<p>&nbsp;</p>
<p>Wywali błąd? Nadpisze wartość liczby?<br />
Otóż nie. Jeśli nastąpiłoby nadpisanie wartości integera były to spory idiotyzm ze strony języka. Jednak co ciekawe nie wywali też błędu i stała o nazwie &#8217;100&#8242; powstanie, czego dowodem jest:</p>
<p>&nbsp;</p>
<p><pre class="brush: php;">
  print_r(get_defined_constants());
  /*
    zwróci:

    (...)
    [100] =&gt; stala 100
  */
</pre></p>
<p>&nbsp;</p>
<p>Jednak nijak nie dostaniemy się do podanej stałej poprzez samą jej nazwę, jedynym sposobem jest użycie funkcji:</p>
<p>&nbsp;</p>
<p><pre class="brush: php;"> 
  echo constant('100');
</pre></p>
<p>&nbsp;</p>
<p>Dla porównania Javascript nie pozwala na takie rzeczy:</p>
<p>&nbsp;</p>
<p><pre class="brush: jscript;"> 
const 100 = 'stala 100'; // SyntaxError: missing variable name
</pre></p>
<p>&nbsp;</p>
<p>Na koniec dodam tylko, że pomysł na wpis zrodził się, jak już niejednokrotnie było, przez <a href="http://forum.php.pl">forum.php.pl</a>. Niestety w ten sposób zmiany VAT-u w swojej aplikacji nie dokonamy :D</p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/programowanie/php/'>PHP</a> Tagged: <a href='http://luq10.wordpress.com/tag/const/'>const</a>, <a href='http://luq10.wordpress.com/tag/vat/'>vat</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1255/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1255/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1255/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1255&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2011/01/05/php-i-define/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>
	</item>
		<item>
		<title>Inne spojrzenie na style CSS</title>
		<link>http://luq10.wordpress.com/2011/01/04/inne-spojrzenie-na-style-css/</link>
		<comments>http://luq10.wordpress.com/2011/01/04/inne-spojrzenie-na-style-css/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 18:07:46 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1222</guid>
		<description><![CDATA[Wstęp Ostatnio coraz częściej zdarza mi się pracować na frontend-zie. W sumie zawsze myślałem, że to nie może być ciekawe, ale przyznaje &#8211; myliłem się&#8230; W dobie, cały czas tworzonego jeszcze, HTML5 oraz wdrażanego CSS3 można naprawdę fajnie się pobawić tymi nowymi mechanizmami. Oczywiście największym problemem w tej warstwie aplikacji webowej jest integracja ze wszystkimi [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1222&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3 style="margin-left:20px;">Wstęp</h3>
<p><img src="http://luq10.files.wordpress.com/2011/01/723955_colors.jpg" alt="" title="723955_colors" width="300" height="188" class="alignright size-full wp-image-1252" /><br />
Ostatnio coraz częściej zdarza mi się pracować na frontend-zie. W sumie zawsze myślałem, że to nie może być ciekawe, ale przyznaje &#8211; myliłem się&#8230; W dobie, cały czas tworzonego jeszcze, HTML5 oraz wdrażanego CSS3 można naprawdę fajnie się pobawić tymi nowymi mechanizmami. Oczywiście największym problemem w tej warstwie aplikacji webowej jest integracja ze wszystkimi popularnymi przeglądarkami które nie zawsze interpretują nasz kod tak jak trzeba, natomiast można też przyczepić się do ograniczeń płynących z samego CSS-a.</p>
<p>&nbsp;</p>
<p>Jeśli się zastanowić nad tym to dojdziemy do wniosku, że jedyne zmiany dokonywane są przez dodawanie nowych właściwości (rzadziej selektorów czy pseudoklas) Oczywiście, to bardzo duże zmiany &#8211; opacity, border-radius, box-shadow etc. otwierają nam drogę ku naprawdę fajnym rozwiązaniom. Natomiast brak zmian w tzw. warstwie core. W sumie to logiczne, bo z tym co mamy możemy zrobić wszystko, tyle, że nie zawsze jest to takie łatwe, proste i czytelne.</p>
<p>&nbsp;</p>
<h3 style="margin-left:20px;">Czego brakuje</h3>
<p>Zapewne zastanawiasz się teraz o czym mowa. Chodzi np. o przekazywanie zmiennych do arkusza styli, dzięki czemu możemy uzyskać efekt personalizacji strony. Obojętnie czy to będzie kolor tła na podstawie pogody/pory roku/pory dnia czy inny styl zależny od miejsca aktualnie zalogowanego użytkownika w rankingu. Z tym co dziś mamy da się to zrobić w całkiem prosty, lecz nie do końca elegancki sposób.</p>
<p>&nbsp;<br />
<span id="more-1222"></span></p>
<p>Wystarczy skrypt PHP generujący i zwracający plik CSS (z odpowiednim nagłówkiem).</p>
<p>&nbsp;</p>
<p><pre class="brush: xml;">
   &lt;link href=&quot;/css/generator.php?season=&lt;?=$season?&gt;&quot; rel=&quot;stylesheet&quot;/&gt;
</pre></p>
<p>&nbsp;</p>
<p>Dzięki czemu w <em>generator.php</em> mamy dostęp do zmiennej GET o nazwie <strong>season</strong> i na jej podstawie używamy konkretnych kolorów, obrazków etc.</p>
<p>&nbsp;</p>
<p>Tak btw. można by nadpisywać style:</p>
<p>&nbsp;</p>
<p><pre class="brush: xml;">
   &lt;link href=&quot;/css/general.css&quot; rel=&quot;stylesheet&quot;/&gt;
   &lt;link href=&quot;/css/&lt;?=$season?&gt;.css&quot; rel=&quot;stylesheet&quot;/&gt;
</pre></p>
<p>&nbsp;</p>
<p>ale dla większej ilości zmiennych chyba tego nie ogarniemy&#8230;</p>
<p>&nbsp;</p>
<p>Rozwiązanie generatorem styli jest jak najbardziej dobre tyle, że zawsze trzeba by kopiować ten sam początek z pliku <em>generator.php</em>, należało by zadbać o jakiegoś cache-a tak aby dla każdego użytkownika nie generować na nowo tego samego szablonu. Poza tym, taki frontend-owiec tworzący arkusz styli nie powinien być zmuszony znać chociaż w minimalnym stopniu PHP. Warto by stworzyć odrębny mini-język, z pętlami, warunkami, możliwością deklarowania zmiennych, oraz garstką funkcji. Jeśli chodzi o HTML-a, popularne są systemy szablonów jak np. bardzo krytykowane <a href="http://www.smarty.net/">Smarty</a> czy, raczej chwalone polskie, <a href="http://www.invenzzia.org/en/projects/open-power-libraries/open-power-template">OPT</a>. Dlaczego nie stworzyć czegoś takiego dla CSS-a? A najlepiej jak ten parsowany język byłby taki sam jak w systemach szablonów HTML-owych. Tak aby popularne systemy szablonów miały dwie części: szablony HTML-owe oraz CSS-owe.</p>
<p>&nbsp;</p>
<p>Kolejnym powodem dla którego warto stworzyć takie cudo są właśnie nowe właściwości rodem z CSS3. Jak wiadomo, aktualnie przeglądarki wykorzystują swoje odmiany nowych właściwości, najczęściej poprzedzone prefixem, np: aby uzyskać efekt przezroczystości działający cross-browser musimy napisać:</p>
<p>&nbsp;</p>
<p><pre class="brush: plain;">
#foo {
  opacity:0.5;
  -moz-opacity:0.5;
  -khtml-opacity:0.5;
  -ms-filter:&quot;progid:DXImageTransform.Microsoft.Alpha(Opacity=50)&quot;;
  filter:alpha(opacity=50);
}
</pre></p>
<p>&nbsp;</p>
<p>Jeśli chcemy nadać przezroczystość większej ilość elementów, musimy albo kopiować te 5 linijek i wklejać je za każdym razem, albo stworzyć klasę .opacity01, .opacity02&#8230; .opacity1 i nadawać je w atrybucie class dla wszystkich tych elementów. Oba te rozwiązania nie są zbyt elegancje. Jakże ładniej byłoby gdybyśmy mogli napisać w ten sposób: </p>
<p>&nbsp;</p>
<p><pre class="brush: css;">
function opacity($val){
  opacity:$val;
  -moz-opacity:$val;
  -khtml-opacity:$val;
  -ms-filter:&quot;progid:DXImageTransform.Microsoft.Alpha(Opacity=$val*100)&quot;;
  filter:alpha(opacity=$val*100);
}

#foo {
  opacity(0.5);
}
#bar div a {
  opacity(0.7);
}
</pre></p>
<p>&nbsp;</p>
<p>Tworzenie funkcji przydałoby się także w &#8222;zwykłych&#8221; przypadkach, np:</p>
<p>&nbsp;</p>
<p><pre class="brush: css;">
function absolute($top, $left, $zIndex = auto){
  position: absolute;
  top: $top;
  left: $left;
  if(false!==$zIndex){
    z-index: $zIndex;
  }
}

#foo { absolute(50, 100, 9999); }
#bar{ absolute(10, 200, false); }
</pre></p>
<p>&nbsp;</p>
<p>Zawszę jest też problem z kolorami. Nie oszukujmy się, zapis <em>#45B27F</em> czy <em>rgb(127, 46, 78)</em> nie jest łatwy do zapamiętania. Poza tym głównych kolorów których używamy na stronie jest kilka, warto by tworzyć sobie tablice definicji kolorów i wtedy jest to po prostu dla nas czytelniejsze:</p>
<p>&nbsp;</p>
<p><pre class="brush: css;">
$colors = {
  blueLight:&quot;#0080e0&quot;,
  blueDark:&quot;#00599c&quot;
};

#foo { border: 1px solid $colors.blueLight; color: $colors.blueDark; }
#bar{ background-color: $colors.blueDark; }
</pre></p>
<p>&nbsp;</p>
<p>Już nie mówię o przypadku kiedy w stylach CSS mielibyśmy rozpoznaną wersje i rodzaj przeglądarki:</p>
<p>&nbsp;</p>
<p><pre class="brush: css;">
if(CORE_BROWSER_TYPE == FIREFOX &amp;&amp; CORE_BROWSER_VERSION &lt; 2.1){
  //
}
else{
  //
}
</pre></p>
<p>Naprawdę fajnie było by gdyby powstał taki framework do CSS-a.<br />
W jednym z kolejnych wpisów spróbuje zaprezentuje pokrótce <a href="https://github.com/anthonyshort/Scaffold/wiki">Scaffold CSS Framework</a>.</p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/programowanie/css/'>CSS</a>, <a href='http://luq10.wordpress.com/category/web/'>Web</a>, <a href='http://luq10.wordpress.com/category/webmastering/'>Webmastering</a> Tagged: <a href='http://luq10.wordpress.com/tag/css-2/'>css</a>, <a href='http://luq10.wordpress.com/tag/framework/'>framework</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1222/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1222&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2011/01/04/inne-spojrzenie-na-style-css/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2011/01/723955_colors.jpg" medium="image">
			<media:title type="html">723955_colors</media:title>
		</media:content>
	</item>
		<item>
		<title>Kup to. Proszę!</title>
		<link>http://luq10.wordpress.com/2010/10/24/kup-to-prosze/</link>
		<comments>http://luq10.wordpress.com/2010/10/24/kup-to-prosze/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 15:51:15 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[biznes]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[partyzancki]]></category>
		<category><![CDATA[projetowanie]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1193</guid>
		<description><![CDATA[Dziś zgoła odmienny wpis. Nie będzie o nudnym klepaniu kodu, rozwiązywaniu błędów i wąskich gardeł, optymalizacji czy bezpieczeństwie. Dziś zajmiemy się projektowaniem i marketingiem, który szczególnie ważny jest właśnie w web aplikacjach. W erze start-up`ów, licznych zakupów internetowych, youtube`a i facebook`a, marketing internetowy jest nieodłącznym elementem pracy web developera. Nie ważne, że kod jest idealny [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1193&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://mainhg.demotywatory.pl/uploads/201010/1287506446_by_ReVolted_500.jpg"><img alt="przeslanie" src="http://mainhg.demotywatory.pl/uploads/201010/1287506446_by_ReVolted_500.jpg" title="przeslanie" class="alignright" width="250" height="600" /></a></p>
<p>Dziś zgoła odmienny wpis. Nie będzie o nudnym klepaniu kodu, rozwiązywaniu błędów i wąskich gardeł, optymalizacji czy bezpieczeństwie. Dziś zajmiemy się projektowaniem i marketingiem, który szczególnie ważny jest właśnie w web aplikacjach. W erze start-up`ów, licznych zakupów internetowych, youtube`a i facebook`a, marketing internetowy jest nieodłącznym elementem pracy web developera. Nie ważne, że kod jest idealny i działa świetnie jak nie umiesz go sprzedać. Po co komu świetna gra przy której Ty męczyłeś się z całym zespołem przez 2 lata wyrywając sobie resztki włosów z głowy, kląc przy niej raz po raz a kiedy już udało się ją skończyć i poprawić wszystkie błędy okazało się, że owszem, grafika super, wykorzystaliście masę nowości technicznych i technologicznych ale grywalność leży&#8230;?  </p>
<p>&nbsp;</p>
<p>Tak naprawdę zawszę najważniejszy jest pomysł. Najlepiej taki który jest niebanalny, ciekawy, taki który budzi podziw ale może być także zdziwienie, ogólnie chodzi o silną emocję (może to też być np. obrzydzenie czy strach). Bardzo ciekawym sposobem dotarcia do potencjalnych klientów jest <a href="http://pl.wikipedia.org/wiki/Marketing_partyzancki">Marketing partyzancki</a>. Cytując wiki, jest to:</p>
<p>&nbsp;</p>
<blockquote><p>forma marketingu zbliżona do marketingu wirusowego, polegająca na promowaniu dóbr i usług za pomocą niekonwencjonalnych technik, w zależności od grupy docelowej, jak np. napisy sprayem na murach prezentujące daną markę czy vlepki.</p>
<p>W tej technice stosuje się zarówno niekonwencjonalne, mające przykuć uwagę środki, jak również niekonwencjonalne treści, np. widok krwi, drastycznych scen itp. Przede wszystkim jednak technika ta bazuje na tanich środkach. Dodatkowo daje ona taki efekt, że odbiorca infekowany jest memami nawet unikając kontaktu z tradycyjnymi nośnikami reklam. Informacja o produkcie czy usłudze, podobnie jak w marketingu wirusowym, może dalej rozchodzić się w postaci plotki oraz dalszych przekazów informacji drogami niekonwencjonalnymi.</p></blockquote>
<p>&nbsp;</p>
<p>Jednym z najciekawszych przykładów tej formy reklamy, na który natrafiłem jakiś czas temu, jest akcja marketingowa dla firmy Absolut. Koszt całkowity to praktycznie 0 zł. Wystarczył jeden karton z magazynu, butelka promowanego alkoholu (którą oczywiście wróciła z powrotem) oraz jedno lotnisko. Tak, tak, lotnisko ;)</p>
<p>&nbsp;</p>
<p>Butelkę zapakowano do otwartego kartonu, tak aby trunek był widoczny, i puszczono razem z bagażami na tej lotniskowej karuzeli (nie mam pojęcia jak to się fachowo nazywa :&gt;). Zresztą oto filmik:</p>
<p>&nbsp;</p>
<span style="text-align:center; display: block;"><a href="http://luq10.wordpress.com/2010/10/24/kup-to-prosze/"><img src="http://img.youtube.com/vi/5pqhhAIDKos/2.jpg" alt="" /></a></span>
<p>&nbsp;</p>
<p>Tak naprawdę ludzie mają dość monotonii, lubią rzeczy ciekawe, lubią się bawić. I tutaj wkracza inicjatywa <a href="http://www.thefuntheory.com/">The Fun Theory</a>. Owa teoria zabawy opiera się na przekonaniu, że zabawa jest najłatwiejszym sposobem na zmianę zachowań ludzi na lepsze. Najbardziej popularnym produktem wywodzącym się z owej inicjatywy są fortepianowe schody. Dzięki nim procent ludzi, korzystający z tradycyjnych schodów w stosunku do schodów ruchomych wzrósł o 66%! (tak przynajmniej twierdzą autorzy). Chociaż mnie osobiście o wiele bardziej podoba się Bottle Bank Arcade:</p>
<p>&nbsp;</p>
<span style="text-align:center; display: block;"><a href="http://luq10.wordpress.com/2010/10/24/kup-to-prosze/"><img src="http://img.youtube.com/vi/zSiHjMU-MUo/2.jpg" alt="" /></a></span>
<p>&nbsp;</p>
<p>Jak to ma się do internetu i programistów? Działa dokładnie tak samo! Najważniejszy jest pomysł. Spójrzmy na taki np. serwis <a href="http://www.podbij.pl/">podbij.pl</a>. Jeśli prześledzić zasadzę działania wychodzi na to, że serwis zarabia bardzo dużo. Kupuje telewizor za 1000zł, sprzedaje go za 300zł ale za same podbicia dostaje 30 000zł, bo podbicie o 0,01 zł jest tożsamy z jedną realną zlotówką. Fajnie nie? ;)</p>
<p>&nbsp;</p>
<p>Kolejnym przykładem który mogę podać jest sytuacja z mojego życia. Podczas promocji mojej szkoły na targach edukacyjnych powstały 2 gry, jedną było moje <a href="http://luq10.wordpress.com/2010/04/22/catch-the-block/">Catch the block</a> a drugą była banalnie prosta lecz o wiele lepsza marketingowa gra, której autorem jest <a href="http://tiwo.org.pl/">wolf</a>. Grafika rysowana gdzieś w paincie z wykorzystaniem narzędzia pędzel :) Stojące na przeciwko siebie postacie z bronią w ręku, odliczenie w dół od 3, po zejściu licznika do 0, user musiał nacisnąć grzybek (drewniane pudełko, kolorowe grzybki i mechanizm z normalnej myszki &#8211; jeden user miał lewy przycisk, drugi &#8211; prawy, wszytko złożone i podpięte pod USB), kto nacisnął pierwszy ten wygrywał, natomiast falstart był nagradzany śmiercią. Gra cieszyła się mega popularnością :]</p>
<p>&nbsp;</p>
<p>Jeśli masz własną firmę, kub, pub, restauracje to koniecznie stwórz fanpage na facebook`u. Jak przyciągnąć userów? Najskuteczniej jest stworzyć aplikację (lub jeśli nie umiesz, zleć to komuś) dzięki której można wygrać nagrody (darmowe piwo, karta rabatowa na tydzień, koszulka, tu pomysłów jest naprawdę mnóstwo) dzięki temu jest masa ludzi którzy klikną na &#8222;Lubię to&#8221;, ich znajomi to widzą, poza tym każda wygrana jest rzucana na ich wall`a, a tym znajomym którzy nie mają jeszcze konta na FB opowiadają jak to wczoraj wygrali darmowe piwo, dzięki czemu nasza firma jest rozpoznawana :)</p>
<p>&nbsp;</p>
<p>Ostatecznie należy dążyć do tego aby swoje tytułowe &#8222;Kup to. Proszę!&#8221; zamienić na czyjeś &#8222;Sprzedaj mi to. Proszę!&#8221;</p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/marketing/'>Marketing</a> Tagged: <a href='http://luq10.wordpress.com/tag/biznes/'>biznes</a>, <a href='http://luq10.wordpress.com/tag/e-commerce/'>e-commerce</a>, <a href='http://luq10.wordpress.com/tag/marketing-2/'>marketing</a>, <a href='http://luq10.wordpress.com/tag/partyzancki/'>partyzancki</a>, <a href='http://luq10.wordpress.com/tag/projetowanie/'>projetowanie</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1193/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1193&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/10/24/kup-to-prosze/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://mainhg.demotywatory.pl/uploads/201010/1287506446_by_ReVolted_500.jpg" medium="image">
			<media:title type="html">przeslanie</media:title>
		</media:content>
	</item>
		<item>
		<title>Paczka game_map</title>
		<link>http://luq10.wordpress.com/2010/10/05/paczka-game_map/</link>
		<comments>http://luq10.wordpress.com/2010/10/05/paczka-game_map/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 19:21:40 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[GameDev]]></category>
		<category><![CDATA[GameMap]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1187</guid>
		<description><![CDATA[Witam po znów długiej przerwie. Dziś bardzo krótko z racji braku czasu na cokolwiek&#8230; &#160; Kilka osób prosiło mnie aby udostępnić paczkę z game_map (trzeba by wymyślić jakąś nazwę&#8230;) który gościł przez kilka poprzednich wpisów a teraz z racji właśnie owego braku czasu na razie jest zawieszony w działaniach. Naprawdę bardzo cieszy mnie duże zainteresowanie [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1187&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Witam po znów długiej przerwie. Dziś bardzo krótko z racji braku czasu na cokolwiek&#8230;</p>
<p>&nbsp;</p>
<p>Kilka osób prosiło mnie aby udostępnić paczkę z game_map (trzeba by wymyślić jakąś nazwę&#8230;) który gościł przez kilka poprzednich wpisów a teraz z racji właśnie owego braku czasu na razie jest zawieszony w działaniach. Naprawdę bardzo cieszy mnie duże zainteresowanie tym projektem (jeśli można to tak nazwać). Zamieszczona poniżej paczka jest wersją nowszą niż serwerowa i jest to totalnie wersja developerska (zacząłem pisać pobieranie kolejnych części mapy po przejściu do krawędzi aktualnie pobranej ale to nie jest skończone). Mam nadzieję, że niczego nie zapomniałem spakować.</p>
<p>&nbsp;</p>
<p><a href="http://wls-team.ovh.org/projects/game_map.rar">Pobierz game_map</a></p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/category/gamedev/gamemap/'>GameMap</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1187/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1187&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/10/05/paczka-game_map/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>
	</item>
		<item>
		<title>Apcelerator Titanium dla Android`a</title>
		<link>http://luq10.wordpress.com/2010/08/24/apcelerator-titanium-dla-androida/</link>
		<comments>http://luq10.wordpress.com/2010/08/24/apcelerator-titanium-dla-androida/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 13:05:33 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[android skd]]></category>
		<category><![CDATA[appcelerator]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[titanium]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1151</guid>
		<description><![CDATA[Jakieś dwa tygodnie temu pokazano mi takie narzędzie jak Appcelerator Titanium. Titanium to platforma która umożliwia tworzyć aplikację deskoptowe jak i mobilne (iPhone, Android, iPad, BlackBerry) w językach czysto webowych (HTML, CSS, JavaScript, PHP, Python i Ruby). Jest to konkurencja dla Adobowego środowiska AIR z tą różnicą, że Titanium jest w pełni otwarte. &#160; Przez [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1151&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Jakieś dwa tygodnie temu pokazano mi takie narzędzie jak <a href="http://www.appcelerator.com/">Appcelerator Titanium</a>. Titanium to platforma która umożliwia tworzyć aplikację deskoptowe jak i mobilne (iPhone, Android, iPad, BlackBerry) w językach czysto webowych (HTML, CSS, JavaScript, PHP, Python i Ruby). Jest to konkurencja dla Adobowego środowiska AIR z tą różnicą, że Titanium jest w pełni otwarte. </p>
<p>&nbsp;</p>
<p>Przez te dwa tygodnie pracowałem (i dalej pracuję) nad pewną małą aplikacją dla Google Android, dlatego jedynie nad wersją mobilną API będę się rozwodzić.</p>
<p>&nbsp;<br />
<span id="more-1151"></span></p>
<p>Na początek rzuca się w oczy bardzo kiepska <a href="http://developer.appcelerator.com/apidoc/mobile/">dokumentacja</a>. Już wyjaśniam dlaczego kiepska&#8230; Po pierwsze, bardzo, ale to bardzo rzadko można spotkać jakiś przykład, co naprawdę, przynajmniej na początku, jest kłopotliwe. Po drugie, brakuje danych pewnych elementach API, które można wyczytać z cudzych kodów. Pierwszą z nich jest brak w ogóle wspomnienia w dokumentacji o aliasie do głównego obiektu API. Dokumentacja wspomina jedynie o <strong>Titanium</strong> natomiast wygodniej jest stosować o wiele krótszą nazwę <strong>Ti</strong></p>
<p><pre class="brush: jscript;">
// to samo
Titanium.userAgent;
Ti.userAgent;
</pre></p>
<p>Kolejnym takim elementem którego nie znalazłem w dokumentacji są setery do obiektów, np:</p>
<p><pre class="brush: jscript;">
var bnt = Ti.UI.createButton({ title: 'foo' });
bnt.setTitle( 'bar' ); // o tym nie ma ani słowa 
</pre></p>
<p>Po trzecie, uważam, że fajnie by było dodać obrazki jak wygląda przykładowy obiekt z kontenera Ti.UI bo nie zawsze nazwa mówi sama za siebie, zresztą nawet jeśli mówi to wolałbym, żeby była możliwość podglądu obiektu, bo przecież nie mam zielonego pojęcia jak będzie wyglądał Ti.UI.Toolbar. Oczywiście każdy wie czym jest Toolbar ale jak ten konkretny obiekt wygląda z różnymi konfiguracjami parametrów już raczej nie bardzo.     </p>
<p>&nbsp;</p>
<p>W razie problemów i niejasności pomocy możemy szukać w <a href="http://developer.appcelerator.com/questions/created">Questions &amp; Answers</a> ale o wiele więcej informacji jest zawartych w <a href="https://appcelerator.tenderapp.com/discussions">panelu dyskusyjnym</a>. Jeśli natomiast chcemy zobaczyć jakieś przykładowe kody to polecam pobrać i zaimportować do Titanium <a href="http://github.com/appcelerator/KitchenSink">Kitchen Sink</a></p>
<p>&nbsp;</p>
<p>Jadnak patrząc obiektywnie całe API jest bardzo proste, mamy łatwy dostęp do bazy danych urządzenia (jest to SQLite oczywiście), możemy korzystać z obiektu XHR, który obsługuje się dokładnie jak ten klasyczny znany z przeglądarek, tworzenie obiektów User Interface i dodawanie ich na ekran jest prościutkie. Przyszło mi bawić się także funkcjami dotyczącymi Facebooka i muszę powiedzieć, że umieszczenie czegoś na naszym Facebook`owym wall`u jest dziecinnie proste.</p>
<p>&nbsp;</p>
<p>Najlepiej pokaże to na przykładnie. Nasza aplikacja będzie sprawdzała czy posiada dane w bazie urządzenia i tworzyła z tego tabele (obiekt TableView), natomiast jeśli nie będzie w bazie tych danych to nasza aplikacja spróbuje je pobrać w formacie JSON z <a href="http://wls-team.ovh.org/projects/data.txt">przykładowej strony</a>, zapisze je do bazy a następnie będzie postępować analogicznie jak wyżej. Efektem będzie wyświetlenie czegoś takiego:</p>
<p><a href="http://luq10.files.wordpress.com/2010/08/example_android.jpg"><img src="http://luq10.files.wordpress.com/2010/08/example_android.jpg?w=100&#038;h=150" alt="" title="example_android" width="100" height="150" class="aligncenter size-thumbnail wp-image-1152" /></a></p>
<p>Na początek tworzymy elementy GUI:</p>
<p><pre class="brush: jscript;">
var loader = Ti.UI.createActivityIndicator({
    height :50,
    width :10,
	message : 'Loading data...'
});
var window = Ti.UI.createWindow({
	backgroundColor	:'#ddd',
	fullscreen : true
});
var table = Ti.UI.createTableView({
	backgroundColor : '#fff',
	width : 300,
	height : 360,
	top : 20,
	left : 10,
	borderRadius : 5,
	borderWidth : 1,
	borderColor : '#444',
	separatorColor : '#444',
	scrollable : true,
	rowHeight : 41
});
window.add( table );
window.open();
</pre></p>
<p>Tworzymy obiekt Window oraz TableView, którego dodajemy do okienka, następnie je otwieramy. Obiekt ActivityIndicator natomiast to okienko blokujące cały ekran jednocześnie informujące o wykonywaniu jakichś operacji. Będziemy je wyświetlać podczas pobieranie i zapisywania danych do bazy, po tych operacjach zostanie ukryte. Będzie to wyglądać tak:</p>
<p><a href="http://luq10.files.wordpress.com/2010/08/loader2.jpg"><img src="http://luq10.files.wordpress.com/2010/08/loader2.jpg?w=100&#038;h=150" alt="" title="loader" width="100" height="150" class="aligncenter size-thumbnail wp-image-1155" /></a></p>
<p>Stworzymy sobie bazę danych:<br />
<pre class="brush: jscript;">
Ti.Database.install( 'mybase.db', 'mybase' );
var db = Ti.Database.open( 'mybase' );
db.execute( 'CREATE TABLE IF NOT EXISTS user ( id INTEGER PRIMARY KEY, name VARCHAR, age INTEGER )' );
</pre><br />
Z tego powodu, że nie wiemy czy user odpalił pierwszy raz aplikację czy po raz kolejny, tworzymy tabelkę najpierw sprawdzając czy aby na pewno takiej tabeli jeszcze nie ma. Następnie tworzymy dwie funkcję. Pierwsza pobiera nasze przykładowe dane:</p>
<p><pre class="brush: jscript;">
function loadData(){
	loader.show(); // pokaż loader
	var data = null;
	
	var xhr = Ti.Network.createHTTPClient();
	xhr.onreadystatechange = function(){
		try{
			if( this.readyState == 4 &amp;&amp; this.status == 200  ){
				data = eval( '(' + this.responseText + ')' );
				saveData( data ); // wywołanie kolejnej funckji
			}
		}
		catch( e ){
			Ti.API.info( e.name + ':' + e.message );
		}
	};
				
	xhr.open( 'GET', 'http://wls-team.ovh.org/projects/data.txt' );
	xhr.setTimeout( 5000 );
	xhr.send();
}
</pre><br />
Po pobraniu danych z serwera uruchamiana jest kolejna zdefiniowana przez nas funkcja:<br />
<pre class="brush: jscript;">
function saveData( dataArr ){
	var dataTable = [];
	
	for( var i = 0, len = dataArr.length; i &lt; len; i++ ){
		db.execute( 
			'INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )', 
			null,
			dataArr[i].name,
			dataArr[i].age
		);
		
		dataTable[i] = Ti.UI.createTableViewRow({ 
			title : dataArr[i].name + ' : ' + dataArr[i].age 
		});
	}
	
	table.setData( dataTable );
	loader.hide(); // ukryj loader
}
</pre><br />
Zapisujemy dane do bazy i tworzymy obiekty wierszy dla tabeli, następnie dodajemy te dane do naszego obiektu TableView.</p>
<p>Pozostał nam jeszcze kod główny:<br />
<pre class="brush: jscript;">
var q = db.execute( 'SELECT name, age FROM user' );

if( q.rowCount == 0 ){
	loadData();	
}
else{
	var dataTable = [];
	var i = 0;
	
	while( q.isValidRow() ){	
		dataTable[i] = Ti.UI.createTableViewRow({ 
			title : q.fieldByName( 'name' ) + ':' + q.fieldByName( 'age' ) 
		});
		
		i++;
		q.next();
	}
	q.close();
	
	table.setData( dataTable );
}
</pre></p>
<p>To wszystko. Prawda, że proste? Na koniec dodam tylko cały kod w jednej części:</p>
<p><pre class="brush: jscript;">
ffunction loadData(){
	loader.show(); // pokaż loader
	var data = null;
	
	var xhr = Ti.Network.createHTTPClient();
	xhr.onreadystatechange = function(){
		try{
			Ti.API.info( 'state: ' + this.readyState ); //@log
			
			if( this.readyState == 4 &amp;&amp; this.status == 200  ){
				data = eval( '(' + this.responseText + ')' );
				saveData( data );
			}
		}
		catch( e ){
			Ti.API.info( e.name + ':' + e.message );
		}
	};
				
	xhr.open( 'GET', 'http://wls-team.ovh.org/projects/data.txt' );
	xhr.setTimeout( 5000 );
	xhr.send();
}

function saveData( dataArr ){
	var dataTable = [];
	
	for( var i = 0, len = dataArr.length; i &lt; len; i++ ){
		db.execute( 
			'INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )', 
			null,
			dataArr[i].name,
			dataArr[i].age
		);
		
		dataTable[i] = Ti.UI.createTableViewRow({ 
			title : dataArr[i].name + ' : ' + dataArr[i].age 
		});
	}
	
	table.setData( dataTable );
	loader.hide(); // ukryj loader
}

// gui
var loader = Ti.UI.createActivityIndicator({
    height :50,
    width :10,
	message : 'Loading data...'
});
var window = Ti.UI.createWindow({
	backgroundColor	:'#ddd',
	fullscreen : true
});
var table = Ti.UI.createTableView({
	backgroundColor : '#fff',
	width : 300,
	height : 360,
	top : 20,
	left : 10,
	borderRadius : 5,
	borderWidth : 1,
	borderColor : '#444',
	separatorColor : '#444',
	scrollable : true,
	rowHeight : 41
});
window.add( table );
window.open();

// database
Ti.Database.install( 'mybase.db', 'mybase' );
	var db = Ti.Database.open( 'mybase' );
	db.execute( 'CREATE TABLE IF NOT EXISTS user ( id INTEGER PRIMARY KEY, name VARCHAR, age INTEGER )' );
	
// main
var q = db.execute( 'SELECT name, age FROM user' );

if( q.rowCount == 0 ){
	loadData();	
}
else{
	var dataTable = [];
	var i = 0;
	
	while( q.isValidRow() ){	
		dataTable[i] = Ti.UI.createTableViewRow({ 
			title : q.fieldByName( 'name' ) + ':' + q.fieldByName( 'age' ) 
		});
		
		i++;
		q.next();
	}
	q.close();
	
	table.setData( dataTable );
}
</pre></p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/programowanie/js/'>JS</a> Tagged: <a href='http://luq10.wordpress.com/tag/android/'>android</a>, <a href='http://luq10.wordpress.com/tag/android-skd/'>android skd</a>, <a href='http://luq10.wordpress.com/tag/appcelerator/'>appcelerator</a>, <a href='http://luq10.wordpress.com/tag/mobile/'>mobile</a>, <a href='http://luq10.wordpress.com/tag/titanium/'>titanium</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1151/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1151&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/08/24/apcelerator-titanium-dla-androida/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/08/example_android.jpg?w=100" medium="image">
			<media:title type="html">example_android</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/08/loader2.jpg?w=100" medium="image">
			<media:title type="html">loader</media:title>
		</media:content>
	</item>
		<item>
		<title>SQL, JSON i Ajax… czyli część 3. tworzenia mapy pod grę</title>
		<link>http://luq10.wordpress.com/2010/07/07/sql-json-i-ajax%e2%80%a6-czyli-czesc-3-tworzenia-mapy-pod-gre/</link>
		<comments>http://luq10.wordpress.com/2010/07/07/sql-json-i-ajax%e2%80%a6-czyli-czesc-3-tworzenia-mapy-pod-gre/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 16:55:27 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[GameDev]]></category>
		<category><![CDATA[GameMap]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1104</guid>
		<description><![CDATA[Dość długo zwlekałem z tym wpisem&#8230; szczerze mówiąc, bardzo dużo czasu i sił kosztuje mnie opisywanie mojego, hm&#8230; projektu, bo tak to można nazwać. Tak naprawdę więcej czasu spędziłem nad pisaniem poprzednich dwóch wpisów niż nad pisaniem kodu do nich. Sam nie jestem fanem tutoriali programistycznych i od dziś nie będę pisał na ten temat [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1104&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Dość długo zwlekałem z tym wpisem&#8230; szczerze mówiąc, bardzo dużo czasu i sił kosztuje mnie opisywanie mojego, hm&#8230; projektu, bo tak to można nazwać. Tak naprawdę więcej czasu spędziłem nad pisaniem poprzednich dwóch wpisów niż nad pisaniem kodu do nich. Sam nie jestem fanem tutoriali programistycznych i od dziś nie będę pisał na ten temat rozwodząc się nad moją każdą decyzją podjętą w czas projektowania tego wszystkiego. Będę zwracał uwagę na elementy ciekawe pomijając te błahe.  </p>
<p>&nbsp;</p>
<p>Okej, <a href="http://luq10.wordpress.com/2010/07/03/aplikacja-webowa-edytor-map/">ostatnio</a> zakończyliśmy na GUI pod edytor map, dziś dopiszemy trochę kodu aby nasz edytor zapisywać dane dt. mapy do bazy a także odczytywał stworzoną mapę po przeładowaniu strony tak, aby można było kontynuować prace nad całym naszym światem. Dodatkowo stworzymy kod który umożliwi nam w grze przesuwanie mapy. Szkoda czasu czas zaczynać.</p>
<p>&nbsp;<br />
<span id="more-1104"></span></p>
<h3 style="margin-left:20px;">Baza</h3>
<p>Oczywiście potrzebna nam jest baza danych i informacjami nt. mapy. Stworzyłem 2 tabelki:</p>
<p>&nbsp;</p>
<p><strong>game_map_sprite</strong><br />
<span style="border-bottom:1px solid #000;">spriteId</span> | posX | posY | isWalkable | memo</p>
<p><strong>game_map_field</strong><br />
<span style="border-bottom:1px solid #000;">fieldId</span> | <span style="border-bottom:1px dashed #000;">spriteId</span> | mapPosX | mapPosY</p>
<p>&nbsp;</p>
<p>Pierwsza zawiera informacje o kafelkach. <strong>posX </strong>i <strong>posY </strong>to dane w którym miejscu leży dana kafelka na obrazku wszystkich spritów, czyli zgodnie z obrazkiem:</p>
<p><img src="http://luq10.files.wordpress.com/2010/07/map_sprite_memo.jpg" alt="All map sprites" /></p>
<p><strong>isWalkable</strong> mówi czy wolno chodzić po tym polu, memo w sumie nie jest używane ale zawiera opis obrazka. Wszystkie moje wpisy w tej tabelce prezentują się w ten sposób (dodałem 2 nowe sprity: wolf i mashroom):<br />
<pre class="brush: sql;">
(1, 0, 0, 0, 'tree_top_left'),
(2, 1, 0, 0, 'tree_top_right'),
(3, 0, 1, 0, 'tree_bottom_left'),
(4, 1, 1, 0, 'tree_bottom_right'),
(5, 2, 0, 1, 'extra_grass'),
(6, 2, 1, 0, 'bush'),
(7, 3, 0, 1, 'grass'),
(10, 4, 0, 0, 'mashroom'),
(9, 3, 1, 0, 'wolf');
</pre></p>
<p>W drugiej tabelce, której zawartość będzie generowana przez edytor map, są informacje jaki sprit leży na jakiej pozycji x,y na mapie. No i to by było na temat struktury bazy.</p>
<h3 style="margin-left:20px;">Ajax action</h3>
<p>Teraz przyszła pora na napisanie akcji jaka będzie odbywać się po wypełnieniu komórki mapy w edytorze map. Oczywiście ta akcja będzie wywoływana przez asynchroniczne zapytanie co będzie sprawiało że nasz edytor będzie aplikacją typu RIA (Rich Internet Aplication). Wrące tylko, że bardzo dobrą praktyką jest tworzenie w jednym pliku wszystkich akcji ajaxowych, dzięki temu łatwiej to zabezpieczyć i zarządzać, np. osobny kontroler i poszczególne akcje w modelu MVC.</p>
<p><pre class="brush: plain;">
/ajax/setFoo/foo
/ajax/getFoo  
</pre></p>
<p>ja nie będę w taki sposób pisać bo mnie chodzi o przedstawienie problemu i jego rozwiązania a stosując tutaj jakiś framework pracujący zgodnie z wzorcem MVC kodu byłoby więcej, poza tym nie każdy znałby danego framerowka&#8230; Stworzyłem plik <strong>ajaxAction.php</strong>:</p>
<p><pre class="brush: php;">
require_once './class/DataBase.class.php';
	
	$action = $_GET['act']; 
	
	switch( $action ){
		case 'set_field':
			$sId	= intval( $_GET['sid'] );
			$x 		= intval( $_GET['x'] );
			$y 		= intval( $_GET['y'] );
			
			$db = new DataBase();
			
			$select = $db-&amp;gt;select(
				array( 'fieldId' ),
				'game_map_field',
				&amp;quot;WHERE mapPosX = $x AND mapPosY = $y&amp;quot;
			);
			$fieldId = $select[0]['fieldId'];
			
			if( !$fieldId ){
				$db-&amp;gt;insert(
					'game_map_field',
					array(
						'spriteId'	=&amp;gt; $sId,
						'mapPosX'	=&amp;gt; $x,
						'mapPosY'	=&amp;gt; $y
					)
				);
			}
			else{
				$db-&amp;gt;update(
					'game_map_field',
					array(
						'spriteId'	=&amp;gt; $sId,
						'mapPosX'	=&amp;gt; $x,
						'mapPosY'	=&amp;gt; $y
					),
					&amp;quot;fieldId = $fieldId&amp;quot;
				);
			}
		break;
}
</pre></p>
<p>Dołączona plik <strong>DataBase.class.php</strong> to nic innego jak klasa zarządzająca bazą, prosty DataBaseHandler umożliwiający w prosty sposób wykonywać zapytania SQL`owe. Nie będę tego opisywać. Skrypt jest prościutki. Wpisując w pasek adresu:<br />
<pre class="brush: plain;">
.../ajaxAction.php?act=set_field&amp;amp;x=0&amp;amp;y=0&amp;amp;sId=6
</pre><br />
Dodajemy (lub edytujemy jeśli już istnieje wpis o takim x,y) do tabelki <strong>game_map_field</strong> rekord:<br />
<pre class="brush: sql;">
NULL, 6, 0, 0
</pre><br />
Co mówi, że na pozycji (x;y) = (0;0) będzie znajdował się obrazek krzaczka (sprit o spriteId == 6).</p>
<h3 style="margin-left:20px;">Ajax request</h3>
<p>Teraz wystarczy w odpowiednim miejscu wstawić asynchroniczne wysłanie zapytania HTTP w naszym edytorze map. Dokładniej rzecz biorąc wstawimy to w miejsce komentarza:<br />
<pre class="brush: plain;">
// ajax query
// not jet...
</pre><br />
<a href="http://luq10.wordpress.com/2010/07/03/aplikacja-webowa-edytor-map/">z ostatniego listeningu ostatniego wpsiu</a>. Cała funkcja wywołana zdarzeniem click na komórce mapy prezentuje się następująco:<br />
<pre class="brush: jscript;">
$('td').click(function(){
	if( actualField ){
		// set image in HTML table 
		var xSprite, ySprite;
		
		xSprite = actualFieldX * -CORE_SIZE_FIELD;
		ySprite = actualFieldY * -CORE_SIZE_FIELD;

		$(this).css( 'background-image', 'url(../gfx/my_map.png)' );
		$(this).css( 'background-position', xSprite+'px '+ySprite+'px' );
		$(this).text('');
			

// new code
		// ajax query
		$.get( 
			'../ajaxAction.php', 
			{
				act		: 'set_field',
				sid		: actualField, // id wybranego sprita
				x		: $(this).attr( 'x' ), // pozycja X na mapie
				y		: $(this).attr( 'y' ) // pozycja Y na mapie
			}
		);
	}
// ~new code end
});
</pre></p>
<p>Jedna funkcja w jQuery i już, gotowe ;) </p>
<h3 style="margin-left:20px;">Tworzenia JSON`a z całej mapy</h3>
<p>Teraz jeszcze potrzebne nam jest aby po załadowaniu edytora, komórki przedstawiające pola mapy zostały wypełnione. Powinno być to rozwiązane po stronie PHP ale tymczasowo jest to zrobione tak samo w technologii Ajax, zresztą i tak potrzebne na głównej stronie jest pobieranie JSON`a z mapy (ostatecznie będą to kawałki z mapy a nie cała mapa). W <strong>ajaxAction.php</strong> mam jeszcze jedną akcję:<br />
<pre class="brush: php;">
(...)
	case 'get_all_map':
		$db = new DataBase();
			
		$fields = $db-&amp;gt;select(
			array( 'm.spriteId', 'm.mapPosX', 'm.mapPosY', 's.posX', 's.posY' ),
			'game_map_field AS m LEFT JOIN game_map_sprite AS s ON m.spriteId = s.spriteId',
			'ORDER BY mapPosX, mapPosY'
		);
			
		$map = array();
		foreach( $fields as $k =&amp;gt; $v ){
			$map[ $v['mapPosY'] ][ $v['mapPosX'] ] = new JsonField( $v['posX'], $v['posY'] ); 
		}
		echo json_encode( $map );
	break;
}
	
class JsonField
{
	public $x;
	public $y;
		
	public function __construct( $x, $y ){
		$this-&amp;gt;x = $x;
		$this-&amp;gt;y = $y;
	}
}
</pre><br />
Pobieramy wszystkie rekordy dotyczące pól mapy (wiążemy obie tabelki relacją), następnie tworzymy na tej podstawie JSON`a o strukturze:<br />
<pre class="brush: plain;">
[y_mapy][x_mapy] = { 
    x: x_sprita_na_obrazku, 
    y: y_sprita_na_obrazku 
}
</pre><br />
Oczywiście aby funkcja <a href="http://php.net/manual/en/function.json-encode.php">json_encode()</a> stworzyła nam w 2-wymiarowej tablicy obiekt z właściwościamy x oraz y, musimy posiadać klasę o takich właściwościach z dostępem publicznym, do tego właśnie służy klasa <strong>JsonField</strong>. Teraz wpisując w pasek adresu:<br />
<pre class="brush: plain;">
ajaxAction.php?act=get_all_map
</pre><br />
Odbieramy coś takiego:<br />
<pre class="brush: plain;">
[
	[
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;2&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		{&amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;1&amp;quot;}
	],
	[
		{&amp;quot;x&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;},
		(...)
	]
	(...)
]
</pre></p>
<p>Teraz to załadujemy zaraz po utworzeniu drzewka DOM edytora:<br />
<pre class="brush: jscript;">
$.get( 
	'../ajaxAction.php', 
	{ act: 'get_all_map' },
	function( data ){
		var JSONmap = JSON.parse( data );
		var x, y;
		var xSprite, ySprite;
			
		$('td').each(function( index ){
			y = $(this).parent().find('th').html();
			x = index - ( y * 15 /* 15 is cnt columns */ ) - y;
			$(this).html(
				x+','+y
			);
		
			$(this).attr( 'x', x );
			$(this).attr( 'y', y );
				
			if( JSONmap[y][x] ){
				xSprite = JSONmap[y][x].x * -CORE_SIZE_FIELD;
				ySprite = JSONmap[y][x].y * -CORE_SIZE_FIELD;
		
				$(this).css( 'background-image', 'url(../gfx/my_map.png)' );
				$(this).css( 'background-position', xSprite+'px '+ySprite+'px' );
					
				$(this).html( '');
			}
		});
	}
);
</pre><br />
kod ten zastąpił ten oto wycinek:<br />
<pre class="brush: jscript;">
var x, y;
$('td').each(function( index ){
	y = $(this).parent().find('th').html();
	x = index - ( y * 10 ) - y;
	$(this).html(
		x+','+y
	);
});
</pre><br />
Dzięki temu:</p>
<ul>
<li>1 wykonujemy asynchroniczne zapytanie o JSON`a z mapą</li>
<li>2 jeśli odbierzemy odpowiedź to:
<ul>
<li>2.1 parsujemy wynik do JSON`a</li>
<li>2.2  liczymy x i y każdego pola mapy i wpisujemy te dane do komórki (to już mieliśmy), przypisujemy te dane do atrybutów x i y</li>
<li>2.3 jeśli istnieje w naszym JSON`ie wpis mówiący o spricie w danym polu to:</li>
<ul>
<li>2.3.1 wypełnij go odpowiednim spritem i skasuj z niego tekst.</li>
</ul>
</ul>
</li>
</ul>
<p>Na dziś to tyle. Cały edytor został zbudowany na szybko i wiele rzeczy trzeba podrasować, idea będzie niezmieniona ale wiele należałoby zmienić, szablon generowany przez PHP, pobieranie zakresu mapy a nie jej całej, możliwość przesuwania osi x i y (wtedy zostanie pobrany nowy zakres), pobieranie spritów z bazy&#8230; Jednak nie będzie to już tutaj opisywane, chodziło mi o przedstawienie właśnie idei a nie gotowego sposobu.</p>
<p>&nbsp;</p>
<p>Chciałem jeszcze dziś opisać system przesuwania mapy, który jest już stworzony ale wpis rozrósł by się do ogromnych rozmiarów a więc zrobię to innym razem. <span style="color:#f00;font-weight:bold;font-size:14px;">Tymczasem można się bawić <a href="http://wls-team.ovh.org/projects/game_map/map_editor/">edytorem</a> i <a href="http://wls-team.ovh.org/projects/game_map/">mapą</a></span></p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/programowanie/ajax/'>Ajax</a>, <a href='http://luq10.wordpress.com/category/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/category/gamedev/gamemap/'>GameMap</a>, <a href='http://luq10.wordpress.com/category/programowanie/js/'>JS</a>, <a href='http://luq10.wordpress.com/category/programowanie/'>Programowanie</a>, <a href='http://luq10.wordpress.com/category/programowanie/sql-programowanie/'>SQL</a> Tagged: <a href='http://luq10.wordpress.com/tag/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/tag/jquery/'>jQuery</a>, <a href='http://luq10.wordpress.com/tag/json/'>JSON</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1104/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1104&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/07/07/sql-json-i-ajax%e2%80%a6-czyli-czesc-3-tworzenia-mapy-pod-gre/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/map_sprite_memo.jpg" medium="image">
			<media:title type="html">All map sprites</media:title>
		</media:content>
	</item>
		<item>
		<title>Aplikacja webowa &#8211; edytor map</title>
		<link>http://luq10.wordpress.com/2010/07/03/aplikacja-webowa-edytor-map/</link>
		<comments>http://luq10.wordpress.com/2010/07/03/aplikacja-webowa-edytor-map/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 16:53:01 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[GameDev]]></category>
		<category><![CDATA[GameMap]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[web aplication]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1066</guid>
		<description><![CDATA[Kontynuując mój poprzedni wątek nt. mapy gry webowej, dziś stworzyłem GUI (Graphical User Interface) pod edytor map, który jest niezbędny do dalszej pracy. Nie wyobrażam sobie jakbym miał &#8222;z ręki&#8221;, w bazie, dodawać kolejne pola do mapy lub nawet skryptowo przez PHP, po prostu do generowania mapy trzeba mieć podgląd na całość, innego wyjścia nie [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1066&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img src="http://luq10.files.wordpress.com/2010/07/map_editor.jpg" alt="Map editor" style="float:right;margin-left:10px;width:350px;" /></p>
<p>Kontynuując mój <a href="http://luq10.wordpress.com/2010/07/02/canvas-sprites/#comments">poprzedni wątek nt. mapy gry webowej</a>, dziś stworzyłem GUI (Graphical User Interface) pod edytor map, który jest niezbędny do dalszej pracy. Nie wyobrażam sobie jakbym miał &#8222;z ręki&#8221;, w bazie, dodawać kolejne pola do mapy lub nawet skryptowo przez PHP, po prostu do generowania mapy trzeba mieć podgląd na całość, innego wyjścia nie ma.</p>
<p>&nbsp;</p>
<p>Wyszło mi to, myślę, nieźle. Zresztą screen widać obok. </p>
<p>&nbsp;</p>
<p>W sumie jest to wersja dość uboga i powinno to wyglądać coś jak Photoshop. Powinno być okienko Navigator przez które możemy się przesuwać po całości, wybierać x,y od którego chcemy mieć podgląd etc. oraz okienko Sprites, oba oczywiście drag&amp;drop. Ale, w końcu &#8222;nie od razu Rzym zbudowano&#8221;, na razie to co jest wystarczy mi spokojnie :)</p>
<p>&nbsp;</p>
<p>Już na początek podam linka do edytora, oto on:<br />
<a style="font-size:22px;" href="http://wls-team.ovh.org/projects/game_map/map_editor/">Map Editor</a></p>
<p>Wystarczy kliknąć na jakimś spricie a następnie na polu na mapie gdzie go chcemy wstawić.</p>
<p>&nbsp;<br />
<span id="more-1066"></span></p>
<h3 style="margin-left:20px;">Jak to jest zrobione?</h3>
<p>To od początku, <strong>index.html</strong><br />
&nbsp;<br />
&nbsp;<br />
<pre class="brush: xml;">
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Map Editor for Game by `luq`&lt;/title&gt;
    &lt;meta http-equiv=&quot;Content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;./style/style.css&quot; /&gt;
	
	&lt;script type=&quot;text/javascript&quot; src=&quot;../js/game.cfg.js&quot;&gt;&lt;/script&gt;
	
	&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;./js/map_editor.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
&lt;body&gt;
	
	&lt;table&gt;
		&lt;tr id=&quot;scaleX&quot;&gt;
			&lt;th&gt;.&lt;/th&gt;
			&lt;th&gt;0&lt;/th&gt;
			&lt;th&gt;1&lt;/th&gt;
			&lt;th&gt;2&lt;/th&gt;
			&lt;th&gt;3&lt;/th&gt;
			&lt;th&gt;4&lt;/th&gt;
			&lt;th&gt;5&lt;/th&gt;
			&lt;th&gt;6&lt;/th&gt;
			&lt;th&gt;7&lt;/th&gt;
			&lt;th&gt;8&lt;/th&gt;
			&lt;th&gt;9&lt;/th&gt;
			&lt;th&gt;10&lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;th class=&quot;scaleY&quot;&gt;0&lt;/th&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
			&lt;td&gt;&lt;/td&gt;
		&lt;/tr&gt;
                (...)
	&lt;/table&gt;
	
	&lt;div id=&quot;fields&quot;&gt;
		Sprites&lt;br/&gt;
		
		&lt;div style=&quot;background-position: 0px 0px;&quot; x=&quot;0&quot; y=&quot;0&quot; rel=&quot;1&quot;&gt;&lt;/div&gt;
		&lt;div style=&quot;background-position: -40px 0px;&quot; x=&quot;1&quot; y=&quot;0&quot; rel=&quot;2&quot;&gt;&lt;/div&gt;
		&lt;div style=&quot;background-position: -80px 0px;&quot; x=&quot;2&quot; y=&quot;0&quot; rel=&quot;5&quot;&gt;&lt;/div&gt;
		&lt;div style=&quot;background-position: -120px 0px;&quot; x=&quot;3&quot; y=&quot;0&quot; rel=&quot;7&quot;&gt;&lt;/div&gt;
		&lt;div style=&quot;background-position: 0px -40px;&quot; x=&quot;0&quot; y=&quot;1&quot; rel=&quot;3&quot;&gt;&lt;/div&gt;
		&lt;div style=&quot;background-position: -40px -40px;&quot; x=&quot;1&quot; y=&quot;1&quot; rel=&quot;4&quot;&gt;&lt;/div&gt;
		&lt;div style=&quot;background-position: -80px -40px;&quot; x=&quot;2&quot; y=&quot;1&quot; rel=&quot;6&quot;&gt;&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><br />
Dołączone zostało oczywiście jQuery, <strong>game.cfg.js</strong> to jest plik do którego przerzucono stałą <strong>CORE_SIZE_FIELD</strong> i tylko tyle zawiera (patrz <strong>index.html</strong> z <a href="http://luq10.wordpress.com/2010/07/02/canvas-sprites/#more-1009">Canvas &amp; Sprites</a> a dokładniej skrypt dodany inline), <strong>map_editor.js</strong> to serce mechanizmu i o tym będzie dalej. </p>
<p>&nbsp;</p>
<p>W tabelce &lt;th /&gt; to liniuszek/miarka czy jak tam kto woli, &lt;td /&gt; natomiast to pola w które możemy &#8222;wklejać&#8221; sprity, w div[id=fields] zawarte są wszystkie kafelki, oczywiście z wykorzystaniem CSS Sprites. Dodatkowo, dodałem argumenty x i y, które są przyjaźniejszą alternatywą dla mnogości liczby 40 jaki pozycji sprita na głównym obrazku. Odzwierciedla to rysunek już znany z poprzedniego wpisu.</p>
<p><img src="http://luq10.files.wordpress.com/2010/07/map_sprite_memo.jpg" alt="All map sprites" /></p>
<p>W sumie chyba nie będzie mi to potrzebne ale zawsze warto pewne informacje mieć. Argument rel, natomiast przechowuje mi id tego sprita zgodnie z bazą, ale o niej nie będziemy dziś mówić. Jest mi on niezbędny do wykonania Ajax`owego zapytania generującego SQLowe zapytanie dodające/edytujące kafelkę w podanej pozycji na mapie.</p>
<p>&nbsp;</p>
<p>Należałoby jeszcze podać plik ze stylami, <strong>style.css<br />
</strong><pre class="brush: css;">
body { margin: 0; padding: 0; font-family: verdana; font-size: 10px; font-weight: bold; }
table { border-spacing: 0; }

#scaleX { background-color: #000; color: #fff; height: 15px;  }
#scaleX th{ border-right: 1px dashed #fff; text-align: center;  }

th.scaleY { background-color: #000; color: #fff; width: 15px; border-top: 1px dashed #fff; }

td { cursor: pointer; text-align: center; color: #bbb; font-size: 9px; padding: 0; margin: 0; }

#fields { margin-top: 20px; }
#fields div { float: left; margin-right: 5px; background-image: url(../../gfx/my_map.png); border: 2px solid #fff; cursor: pointer; }
</pre></p>
<p>Tutaj jedynie<br />
<pre class="brush: css;">
#fields div { border: 2px solid #fff; }
</pre><br />
wymaga szybkiego wytłumaczenia. Po co dawać obramowanie o kolorze takim samym jak tło? Przecież wtedy go nie widać. No właśnie, w wym celu jest taki border zrobiony. Gdy klikamy na jakąś kafelkę dostaje ona czerwonego obramowania, ale gdyby nie było wcześniej żadnego obramowania to szerokość całego box model by się zmieniła, co dawałoby, niezbyt fajny efekt.</p>
<p>&nbsp;</p>
<p>Teraz przyszła pora na <strong>map_editor.js</strong><br />
<pre class="brush: jscript;">
$(document).ready(function(){
        // liniuszek X
	$('#scaleX th').css( 'width', CORE_SIZE_FIELD + 'px' );
	$('#scaleX th:first').css( 'width', 15 + 'px' );
	
        // liniuszek Y
	$('th.scaleY').css( 'height', CORE_SIZE_FIELD + 'px' );

	   // szachownica
	$('tr td:odd').css( 'background-color', '#EFEFFF' );
	
        // komórka
	$('#fields div').css({
		'width': CORE_SIZE_FIELD + 'px',
		'height': CORE_SIZE_FIELD + 'px',
	});
</pre></p>
<p>Czyli ustawiamy szerokości i wysokości w tabelce korzystając ze stałej CORE_SIZE_FIELD. Następnie:</p>
<p><pre class="brush: jscript;">
var x, y;
$('td').each(function( index ){
	y = $(this).parent().find('th').html();
	x = index - ( y * 10 ) - y;
	$(this).html(
		x+','+y
	);
});
</pre><br />
Wpisujemy w każdą komórkę jej x i y. Ogólnie to ostatecznie będzie generowanie dynamicznie przez PHP bo musi być wczytana już istniejąca siatka mapy, więc to przy okazji zrobi PHP&#8230; Napisanie tego w jQuery w końcu nie było trudne, więc to zamieściłem w aktualnej wersji.<br />
Kolejne są 2 zdarzenia, pierwsze z nich:</p>
<p><pre class="brush: jscript;">
// event`s
var actualField 	= null;
var actualFieldX 	= null;
var actualFieldY 	= null;
$('#fields div').click(function(){
    // kasuj ramke
    if( actualField ){
        $('#fields div[rel='+actualField+']').css( 'border-color', '#fff' );
    }
		
    actualField  = $(this).attr( 'rel' );
    actualFieldX = $(this).attr( 'x' );
    actualFieldY = $(this).attr( 'y' );
		
    $(this).css( 'border-color', '#f00' );
		
});
</pre><br />
Czyli &#8211; po kliknięciu na któryś z obrazków spritów, zostaje dodane mu obramowanie, równocześnie z poprzedniego (jeśli było) zostaje &#8222;ściągnięte&#8221; oraz do zmiennych zostają wczytane argumenty x, y oraz rel tego sprita.<br />
Ostatni wycinek:<br />
<pre class="brush: jscript;">
$('td').click(function(){
	if( actualField ){
		// set image in HTML table 
		var xSprite, ySprite;
		
		xSprite = actualFieldX * -CORE_SIZE_FIELD;
		ySprite = actualFieldY * -CORE_SIZE_FIELD;

		$(this).css( 'background-image', 'url(../gfx/my_map.png)' );
		$(this).css( 'background-position', xSprite+'px '+ySprite+'px' );
		//$(this).css( 'color', '#444' );
		$(this).text('');
			
		// ajax query
		// not jet...
	}
});
</pre><br />
Czyli &#8211; po kliknięciu na którąś komórkę siatki mapy, jeśli wybraliśmy jakiś sprit, dodaj go jako obrazek tła tej komórki i wyczyść jej zawartość (bo przysłania to obrazek).<br />
Jak widać komentarz, wskazuje gdzie będzie odbywać się komunikacja asynchroniczna z serwerem, ale o tym już następnym razem. Będzie też o tym jak wyglądać będzie baza danych, zaprojektujemy zapytanie i będzie też trochę PHP.</p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/category/gamedev/gamemap/'>GameMap</a>, <a href='http://luq10.wordpress.com/category/programowanie/js/'>JS</a> Tagged: <a href='http://luq10.wordpress.com/tag/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/tag/web-aplication/'>web aplication</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1066/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1066/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1066/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1066/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1066/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1066/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1066/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1066/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1066&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/07/03/aplikacja-webowa-edytor-map/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/map_editor.jpg" medium="image">
			<media:title type="html">Map editor</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/map_sprite_memo.jpg" medium="image">
			<media:title type="html">All map sprites</media:title>
		</media:content>
	</item>
		<item>
		<title>Canvas &amp; Sprites</title>
		<link>http://luq10.wordpress.com/2010/07/02/canvas-sprites/</link>
		<comments>http://luq10.wordpress.com/2010/07/02/canvas-sprites/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 18:19:31 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[GameDev]]></category>
		<category><![CDATA[GameMap]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[sprite]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=1009</guid>
		<description><![CDATA[Tak jakoś wyszło, że postanowiłem napisać własny system poruszania się po mapie w widoku od góry. Mam teraz trochę czasu więc co mi tam&#8230; a skrobnę se&#8230; a co?! Całość ma działać tak jak dużo gier na GameBoy`a tzn. mamy bohatera który pozostaje zawsze na środku ekranu, oraz ma ograniczony widok ma mapę (widzi tylko [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1009&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img src="http://luq10.files.wordpress.com/2010/07/map2.jpg" alt="Mapa" style="float:left;margin-right:5px;" /></p>
<p>Tak jakoś wyszło, że postanowiłem napisać własny system poruszania się po mapie w widoku od góry. Mam teraz trochę czasu więc co mi tam&#8230; a skrobnę se&#8230; a co?! Całość ma działać tak jak dużo gier na GameBoy`a tzn. mamy bohatera który pozostaje zawsze na środku ekranu, oraz ma ograniczony widok ma mapę (widzi tylko to co jest najbliżej niego). Idąc przesuwa się mapa tj. widzi to czego wcześniej nie widział&#8230; </p>
<p>&nbsp;</p>
<p>Zresztą chyba każdy wie o co chodzi :)</p>
<p>&nbsp;</p>
<p>Całość będzie oparte o canvas (HTML5), JS + jQuery + Ajax + JSON, MySQL i PHP. </p>
<p>&nbsp;</p>
<p><strong>Grafika została pobrane z jakiegoś ogromnego obrazka-mapy i nie należy do mnie, jest użyta jedynie w celu pokazowym. Jeśli jesteś autorem i nie podoba Ci się to, że prezentuję kod wraz z Twoją grafiką, proszę o kontakt via email</strong></p>
<p>&nbsp;</p>
<p>W tym wpisie chcę opisać jak generować mapę.</p>
<p>&nbsp; </p>
<p><span id="more-1009"></span></p>
<p>&nbsp;<br />
&nbsp;<br />
&nbsp;</p>
<h3 style="margin-left:20px;">Mapa &#8211; przemyślenia</h3>
<p><strong>a)</strong><br />
Najprymitywniejszym sposobem generowania mapy jest stworzenie sobie kafelków w każdy z oddzielnym pliku i wczytywanie ustawianie ich jako tło w siatce div`ów.</p>
<p>1.png<br />
<img src="http://luq10.files.wordpress.com/2010/07/1.png" alt="1" /></p>
<p>2.png<br />
<img src="http://luq10.files.wordpress.com/2010/07/2.png" alt="2" /></p>
<p><pre class="brush: xml;">
&lt;style type=&quot;text/css&quot;&gt;
#map div.row { width: 40px; height: 40px; float: left; }
#map div.clear { clear: both; }
&lt;/style&gt;

(...)

&lt;div id=&quot;map&quot;&gt;
    &lt;div class=&quot;row&quot;&gt;
        &lt;div style=&quot;background: url(1.png) no-repeat;&quot;&gt;&lt;/div&gt;
        &lt;div style=&quot;background: url(2.png) no-repeat;&quot;&gt;&lt;/div&gt;
        &lt;div style=&quot;background: url(1.png) no-repeat;&quot;&gt;&lt;/div&gt;
        &lt;div style=&quot;background: url(1.png) no-repeat;&quot;&gt;&lt;/div&gt;
        (...)
    &lt;/div&gt;
    &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;
    (...)
&lt;/div&gt;
</pre></p>
<p>Rozwiązanie niedobre z kilku powodów. Po pierwsze, obrazki w osobnych plikach to więcej wysłanych zapytań do serwera (w celu ich uzyskania) co daje większy czas wczytywania strony i większe obciążenie serwera. Po drugie, siatka div`ów nie umożliwia nam operowaniu na poszczególnych pikselach (co nam oferuje canvas), jest to niefajne i trudno się w to integruje. Może to było dobre rozwiązanie jakieś 2 lata temu, kiedy nikt o canvas nie słyszał (a może i nawet dawniej?), ale dziś należy skorzystać z canvas`a, w końcu po to go wymyślono. W końcu ułatwi nam to pracę :)</p>
<p><strong>b) </strong></p>
<p>Już o wiele lepszym sposobem byłaby taka sama siatka div`ów ale z wykorzystaniem CSS Sprites.</p>
<p>map.png<br />
<img src="http://luq10.files.wordpress.com/2010/07/sprites_map.png" alt="CSS Sprites map" /></p>
<p><pre class="brush: xml;">
&lt;style type=&quot;text/css&quot;&gt;
#map div.row { width: 40px; height: 40px; float: left; }
#map div.clear { clear: both; }
&lt;/style&gt;

(...)

&lt;div id=&quot;map&quot;&gt;
    &lt;div class=&quot;row&quot;&gt;
        &lt;div style=&quot;background: url(map.png) 0px 0px no-repeat;&quot;&gt;&lt;/div&gt;
        &lt;div style=&quot;background: url(map.png) -40px 0px no-repeat;&quot;&gt;&lt;/div&gt;
        &lt;div style=&quot;background: url(map.png) 0px 0px no-repeat;&quot;&gt;&lt;/div&gt;
        &lt;div style=&quot;background: url(map.png) 0px 0px no-repeat;&quot;&gt;&lt;/div&gt;
        (...)
    &lt;/div&gt;
    &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;
    (...)
&lt;/div&gt;
</pre></p>
<p>W tym wypadku pobieramy tylko jeden obrazek i wyświetlamy go częściami. A więc jest to jedynie jedno zapytanie do serwera. Zresztą taki wielki szum wokół tego całego CSS Sprites się zrobił, wszyscy reklamują jaki to jest szczyt technologi, takie fajne, zajebiste, a rozwiązanie te w świecie programowania deskoptowego (głównie gier, no w sumie tylko tutaj się z tym spotkałem) jest znane od bardzo dawna. Oczywiście żeby mnie ktoś źle nie zrozumiał, fajnie, że takie coś przeniesiono do web`a, ale czy to jest aż takie wielkie cudo, żeby każdy webdeveloper musiał na swoim blogu opisywać i rozwodzić się nad tą, no&#8230; nie odkrywczą &#8222;techniką&#8221;?</p>
<p><strong>c)</strong> </p>
<p>Stosujemy element canvas + kafelki w oddzielnych plikach.</p>
<p><strong>d)</strong></p>
<p>Stosujemy canvas + 1 plik z kafelkami pod mapę. To właśnie to rozwiązanie jest najlepsze (przynajmniej w tym przypadku) i zostanie tutaj zaprezentowane.</p>
<h3 style="margin-left:20px;">Do roboty</h3>
<p>No to pierwszy na odstrzał idzie <strong>index.html</strong><br />
<pre class="brush: xml;">
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Game by `luq`&lt;/title&gt;
    &lt;meta http-equiv=&quot;Content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;./style/style.css&quot; /&gt;
	
	&lt;script type=&quot;text/javascript&quot;&gt;
		var CORE_SIZE_FIELD = 40; // wielkosc kafleki
	&lt;/script&gt;
	
	&lt;script type=&quot;text/javascript&quot; src=&quot;./js/jquery.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;./js/Map.class.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;./js/start.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;weather&quot;&gt;&lt;/div&gt;
	&lt;canvas id=&quot;game_map&quot; width=&quot;400&quot; height=&quot;400&quot;&gt;
		Upss.. canvas nie działa na tej przeglądarce.
	&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre></p>
<p>Tutaj za dużo nie ma do tłumaczenia. Chyba z oczywistych powodów została stworzona zmienna CORE_SIZE_FIELD, natomiast div[id=weather] na razie pominę w opisie, o nim będzie na końcu.<br />
<strong><br />
style/style.css</strong></p>
<p><pre class="brush: css;">
body { margin: 0; padding: 0; }

#weather { width: 400px; height: 400px; position: absolute; top: 2px; left: 2px; display: none; }
#game_map { border: 2px solid #777; }
</pre></p>
<p>No i teraz to o co głównie mi chodziło w tym wpisie, <strong>Map.class.js</strong> ale po kawałku:</p>
<p><pre class="brush: jscript;">
function Map( mapId ){
	this.mapId = mapId;										// Map id
	this.canvasMap = document.getElementById( this.mapId ); // DOM canvas object
	this.ctx; 												// Canvas context
	this.img;												// Map image (all sprites of map)
	this.sizeFild = CORE_SIZE_FIELD;						// Size of field
	
	if( this.canvasMap.getContext ){
		this.ctx = this.canvasMap.getContext( '2d' );
		
		if( this.ctx ){
			this.img = new Image();
			this.img.src = './gfx/my_map.png';
		}
	}
}
</pre></p>
<p>Konstruktor nie robi nic ciekawego. Podajemy mu id elementu canvas, przypisuje do właściwości niezbędne nam dane, tworzy kontekst canvas`a i tworzy obiekt obrazka z wszystkimi naszymi spritami, zresztą oto on:</p>
<p><strong>gfx/my_map.png</strong> (pozostawiłem &#8222;nieco&#8221; miejsca na kolejne sprity)<br />
<img src="http://luq10.files.wordpress.com/2010/07/my_map.png" alt="My sprites map" /></p>
<p>Teraz czas na metody:<br />
<pre class="brush: jscript;">
Map.prototype._drawField = function( xCanvas, yCanvas, xImage, yImage ){
	this.ctx.drawImage( 
		this.img, 
		xImage * this.sizeFild, 
		yImage * this.sizeFild, 
		this.sizeFild, 
		this.sizeFild, 
		xCanvas * this.sizeFild, 
		yCanvas * this.sizeFild, 
		this.sizeFild, 
		this.sizeFild
	);
}
</pre><br />
Za pomocą niej rysujemy poszczególne kafelki na canvas`ie. Nie posługujemy się w niej pikselami a liczbami określającymi wiersz oraz kolumnę, zarówno w canvas`ie jak i naszym zbiorze spritów. Jest to wygodniejsze i prostsze w obsłudze. Co do samej funkcji drawImage() a konkretniej jej argumentów, to całkiem fajnie prezentuje poszczególne z nich, obrazek pod prototypem tejże funkcji w <a href="https://developer.mozilla.org/en/Canvas_tutorial/Using_images#Slicing">MDC</a>. Ogólnie rzecz biorąc jest to metoda prywatna, właściwie prywatna tylko z tego względu bo ja tam mówię ;) &#8211; JS niestety nie ma modyfikatorów dostępu (bo tak to się chyba zwie), mają być dodane w kolejnej wersji ECMAScript`u.</p>
<p>Kolejną metodą jest:<br />
<pre class="brush: jscript;">
Map.prototype.drawMap = function( JSONmap ){
	for( var i = 0; i &lt; 10; i++ ){
		for( var j = 0; j &lt; 10; j++ ){
			this._drawField( j, i, JSONmap[i][j].x, JSONmap[i][j].y );
		}
	}
}
</pre></p>
<p>Po prostu wypełnia całą mapę zgodnie z danymi podanym w 2-wymiarowej tablicy obiektów &#8211; czyli jest to JSON. Ostatecznie oczywiście te dane będą odbierane z bazy danych, następnie budowany z nich będzie JSON po stronie PHP a my odbierzemy to przez asynchroniczne zapytanie AJAX`owe. JSON taki będzie musiał wyglądać w ten sposób:<br />
<pre class="brush: jscript;">
var JSONmap = [
    // 1. wiersz canvasa
    [
        { 'x' : 0, 'y' : 1 }, // 1. kolumna canvasa
		{ 'x' : 1, 'y' : 1 }, // 2. kolumna canvasa
		{ 'x' : 3, 'y' : 0 }, (...)
		{ 'x' : 3, 'y' : 0 },
		{ 'x' : 2, 'y' : 0 },
		{ 'x' : 3, 'y' : 0 },
		{ 'x' : 0, 'y' : 1 },
		{ 'x' : 1, 'y' : 1 },
		{ 'x' : 0, 'y' : 1 },
		{ 'x' : 1, 'y' : 1 }
	],
	// 2. wiersz 
	(...)
]
</pre></p>
<p>We właściwościach x i y oczywiście są &#8211; odpowiednio &#8211; wiersz oraz kolumna spritów, liczone od zera:</p>
<p><img src="http://luq10.files.wordpress.com/2010/07/map_sprite_memo.jpg" alt="Map sprite memo" /></p>
<p>No i to w sumie wszystko. <strong>js/start.js</strong> zawiera:<br />
<pre class="brush: jscript;">
$(document).ready(function(){
    var oMap = new Map( 'game_map' );
    var JSONmap = (...) // nie bedę tego tu wklejał...
    oMap.drawMap( JSONmap );
});
</pre></p>
<p>Jeszcze dopisałem mały bajer. Stworzyłem sobie możliwość efektów pogodowych, świetlnych (dzień/noc) na mapie. Po to jest właśnie ten div[id=weather]. W <strong>js/Map.class.js</strong> mamy jeszcze:</p>
<p><pre class="brush: jscript;">
/**
 * Set night mode
 */
Map.prototype.night = function(){
    $('#weather').css( 'background-color', '#000' );
    $('#weather').fadeTo( 2000, 0.3 );
}

/**
 * Set day mode
 */
Map.prototype.day = function(){
    $('#weather').fadeOut( 2000 );
}
</pre></p>
<p>natomiast w <strong>js/start.js</strong><br />
<pre class="brush: jscript;">
$('#game_map').click(function(){
    oMap.night();
});
	
$('#weather').click(function(){
    oMap.day();
});
</pre></p>
<p>Co umożliwia po kliknięciu zmienić porę dnia (oczywiście ostatecznie nie będzie to tak działać). Zresztą zobacz sam jak to działa, oraz podejrzyj kod jeśli chcesz. </p>
<p><a href="http://wls-team.ovh.org/projects/game_map/" style="font-size:22px;">LINK</a></p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/category/gamedev/gamemap/'>GameMap</a>, <a href='http://luq10.wordpress.com/category/programowanie/js/'>JS</a>, <a href='http://luq10.wordpress.com/category/web/'>Web</a> Tagged: <a href='http://luq10.wordpress.com/tag/canvas/'>canvas</a>, <a href='http://luq10.wordpress.com/tag/gamedev/'>GameDev</a>, <a href='http://luq10.wordpress.com/tag/sprite/'>sprite</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/1009/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/1009/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/1009/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/1009/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/1009/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/1009/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/1009/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/1009/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=1009&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/07/02/canvas-sprites/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/map2.jpg" medium="image">
			<media:title type="html">Mapa</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/1.png" medium="image">
			<media:title type="html">1</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/2.png" medium="image">
			<media:title type="html">2</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/sprites_map.png" medium="image">
			<media:title type="html">CSS Sprites map</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/my_map.png" medium="image">
			<media:title type="html">My sprites map</media:title>
		</media:content>

		<media:content url="http://luq10.files.wordpress.com/2010/07/map_sprite_memo.jpg" medium="image">
			<media:title type="html">Map sprite memo</media:title>
		</media:content>
	</item>
		<item>
		<title>similar_text in MySQL</title>
		<link>http://luq10.wordpress.com/2010/07/01/similar_text-in-mysql/</link>
		<comments>http://luq10.wordpress.com/2010/07/01/similar_text-in-mysql/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 11:02:48 +0000</pubDate>
		<dc:creator>luq</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[levenshtein]]></category>
		<category><![CDATA[similar_text]]></category>

		<guid isPermaLink="false">http://luq10.wordpress.com/?p=981</guid>
		<description><![CDATA[Już dawno miałem napisać ten wpis ale jakoś nie wyszło. Ostatnio spotkałem się z problemem jak na poziomie bazy danych wyciągnąć podobne stringi (podobieństwo procentowe). Chodziło o sprawdzanie literówek. W PHP istnieje funkcja similar_text() i robi dokładnie to o co mi chodziło. Wonderfully! Tylko, że mnie potrzeba było pobrać wszystkie podobne dane (powiedzmy 80%) z [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=981&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Już dawno miałem napisać ten wpis ale jakoś nie wyszło. Ostatnio spotkałem się z problemem jak na poziomie bazy danych wyciągnąć podobne stringi (podobieństwo procentowe). Chodziło o sprawdzanie literówek. W PHP istnieje funkcja <a href="http://php.net/manual/en/function.similar-text.php">similar_text()</a> i robi dokładnie to o co mi chodziło.</p>
<p><pre class="brush: php;">
    similar_text( 'abrakadabra', 'kadabra', $p );
    echo $p; // 77.7777777778
</pre></p>
<p>Wonderfully! Tylko, że mnie potrzeba było pobrać wszystkie podobne dane (powiedzmy 80%) z bazy wobec wpisanego ciągu, więc skrajnym idiotyzmem byłoby pobieranie wszystkich rekordów i mielenie tego przez PHP. Chodzi o zapytanie w stylu: </p>
<p><pre class="brush: sql;">
      SELECT foo.id FROM foo WHERE SIMILAR( foo.name, 'jakis string' ) &gt; 0.8
</pre></p>
<p>Oczywiście funkcja SIMILAR nie występuje w MySQL`u a więc trzeba napisać własną. Nigdy nie pisałem własnej funkcji/procedury składowej w MySQL`u więc była to dla mnie ciekawa lekcja. No dobra&#8230; nawet nie napisałem tej funkcji, zainstalowałem tylko to co podał mi <strong>wookieb</strong> na forum <a href="http://forum.php.pl">php.pl</a>. Ogólnie similar_text korzysta z algorytmu Olivera, natomiast istnieje też coś takiego jak <a href="http://pl.wikipedia.org/wiki/Odleg%C5%82o%C5%9B%C4%87_Levenshteina">Odległość Levenshteina</a>, którą zresztą ma odzwierciedlenie w PHP <a href="http://www.php.net/manual/en/function.levenshtein.php">levenshtein()</a>. Odległość Levenshteina oczywiście jak można przeczytać na wiki do której podałem linka, zwraca liczbę całkowitą &#8211; najmniejsza ilość zmian jakie należy wykonać na ciągu A, aby go zamienić w ciąg B. Ofc. można liczyć z tego procent:</p>
<p><pre class="brush: php;">
    $word  	= 'kadabra';
    $word2 	= 'abrakadabra';
	$len1 = strlen( $word );
	$len2 = strlen( $word2 );
    $len = $len1 &gt; $len2 ? $len1 : $len2; 
	
    $p = round(( 1 -levenshtein( $word, $word2 ) / $len ) * 100);
    echo $p; // 64
</pre> </p>
<p>No i właśnie takie rozwiązanie zastosowałem tyle, że na bazie danych. Wykonanie jest w sumie banalne, wystarczy zainstalować (? nie wiem czy to dobre słowo) dwie funkcje i gotowe. Tworzymy plik <strong>1.sql</strong>:</p>
<p><pre class="brush: sql;">
DELIMITER //

CREATE FUNCTION LEVENSHTEIN (s1 VARCHAR(255), s2 VARCHAR(255))
  RETURNS INT
    DETERMINISTIC
      BEGIN
        DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
        DECLARE s1_char CHAR;
        DECLARE cv0, cv1 VARBINARY(256);
        SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
        IF s1 = s2 THEN
          RETURN 0;
        ELSEIF s1_len = 0 THEN
          RETURN s2_len;
        ELSEIF s2_len = 0 THEN
          RETURN s1_len;
        ELSE
          WHILE j &lt;= s2_len DO
            SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
          END WHILE;
          WHILE i &lt;= s1_len DO
            SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
            WHILE j &lt;= s2_len DO
                SET c = c + 1;
                IF s1_char = SUBSTRING(s2, j, 1) THEN SET cost = 0; ELSE SET cost = 1; END IF;
                SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
                IF c &gt; c_temp THEN SET c = c_temp; END IF;
                SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
                IF c &gt; c_temp THEN SET c = c_temp; END IF;
                SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
            END WHILE;
            SET cv1 = cv0, i = i + 1;
          END WHILE;
        END IF;
        RETURN c;
      END
//

DELIMITER ;
</pre></p>
<p>oraz <strong>2.sql</strong><br />
<pre class="brush: sql;">
DELIMITER //

CREATE FUNCTION LEVENSHTEIN_RATIO (s1 VARCHAR(255), s2 VARCHAR(255))
  RETURNS INT
    DETERMINISTIC
      BEGIN
        DECLARE s1_len, s2_len, max_len INT;
        SET s1_len = LENGTH(s1), s2_len = LENGTH(s2);
        IF s1_len &gt; s2_len THEN SET max_len = s1_len; ELSE SET max_len = s2_len; END IF;
        RETURN ROUND((1 - LEVENSHTEIN(s1, s2) / max_len) * 100);
      END
//

DELIMITER ;
</pre></p>
<p>Odpalamy konsole, logujemy się, nastepnie:<br />
<pre class="brush: plain;">
mysql&gt; use foo;
mysql&gt; source c:/1.sql;
mysql&gt; source c:/2.sql;
mysql&gt; SELECT LEVENSHTEIN_RATIO( 'abrakadabra', kadabra ); // 64 :)
</pre></p>
<p>to wszystko co musimy zrobić. Jeśli chodzi o optymalizację (przy tabelce z ~1000 rekordów działa to ~7 sek.) to można by okrajać mielony obszar z tych ~1000 rekordów. Jednym pomysłem jest ucinanie go do rekordów o tej samej literze (ludzie raczej nie popełniają literówki w pierwszym znaku).</p>
<p><pre class="brush: sql;">
SELECT 
    id, name, LEVENSHTEIN_RATIO( name, 'luq' ) AS similar
FROM (
    SELECT id, name
    FROM table
    WHERE SUBSTRING( name, 1, 1 ) = 'l'
) AS foo
HAVING similar &gt; 80
</pre></p>
<p>Drugim pomysłem (który wysnuł <strong>wookieb</strong>) jest stworzenie w tabelce pole zawierającego długość stringa (żeby tego nie liczyć, bo wtedy to byłoby wolniejsze) i okrajać sobie zakres szukania do rekordów mających długość +/- np. 2 znaki.</p>
<p>To by było na tyle. Z tego miejsca, serdeczne dzięki <strong>wookieb</strong>!</p>
<br />Filed under: <a href='http://luq10.wordpress.com/category/programowanie/sql-programowanie/'>SQL</a> Tagged: <a href='http://luq10.wordpress.com/tag/levenshtein/'>levenshtein</a>, <a href='http://luq10.wordpress.com/tag/similar_text/'>similar_text</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/luq10.wordpress.com/981/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/luq10.wordpress.com/981/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/luq10.wordpress.com/981/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/luq10.wordpress.com/981/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/luq10.wordpress.com/981/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/luq10.wordpress.com/981/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/luq10.wordpress.com/981/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/luq10.wordpress.com/981/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=luq10.wordpress.com&amp;blog=6772148&amp;post=981&amp;subd=luq10&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://luq10.wordpress.com/2010/07/01/similar_text-in-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d5aa2da2d739b6fabf36a277514d36f3?s=96&#38;d=&#38;r=G" medium="image">
			<media:title type="html">luq</media:title>
		</media:content>
	</item>
	</channel>
</rss>
