[09:00] ¯¯ Modes[#wyklady] ChanServ (+o Gynvael) [09:00] ¯¯ Modes[#wyklady] Gynvael (+m) [09:01] <@Gynvael> witam wszystkich na kolejnym moim wykladzie ;> [09:01] <@Gynvael> tym razem tematem jest Gamedev, czyli tworzenie gier ;> [09:01] <@Gynvael> w sumie chcial bym zeby cos takiego odbywalo sie co tydzien prowadzone przez rozne osoby [09:01] <@Gynvael> w tym tygodniu ja zaczne, a jesli w nastepnych tygodniach ktos by mial ochote opowiedziec troche o stworzeniu jakiejs gierki [09:02] <@Gynvael> badz tez o "tweakowaniu" czy projektowaniu wogole gier [09:02] <@Gynvael> to jak najbardziej zapraszam i zachecam [09:02] ¯¯ Joins[#wyklady] salv (~salv@80.48.232.138) [09:02] <@Gynvael> teraz tak [09:02] ¯¯ Parts[#wyklady] o_O (~o@proxy236.net.pulawy.pl)- [09:02] <@Gynvael> dzisiejszy wyklad bedzie o prostej grze jaka jest sokoban [09:03] <@Gynvael> pierwsza wersja sokobana z jaka sie zetknalem byla gierka Soko-ban firmy sphere inc ;> [09:03] <@Gynvael> http://www.jw-stumpel.nl/sokoban.gif [09:04] <@Gynvael> http://www.mds.mdh.se/~dat95jed/images/logos/sokoban.gif [09:04] <@Gynvael> wygladalo to mniej wiecej tak [09:04] <@Gynvael> sliczna nieprawdaz ? [09:04] <@Gynvael> pozniej powstawaly kolejne klony tej kultowej gry ;> [09:05] <@phoenix> nice [09:05] <@Gynvael> http://www.logicking.com/space_docker_sokoban/images/screen04.jpg [09:05] <@Gynvael> http://www.mozillaquest.com/Linux4Windows/Linux4Windows04/K-Sokoban-01.gif [09:05] <@Gynvael> http://pages.cpsc.ucalgary.ca/~mirtchov/p9/sokoban/sokoban.gif [09:05] <@Gynvael> http://simpler-solutions.net/pmachinefree/images/uploads/sokoban.jpg [09:05] <@Gynvael> etc [09:05] <@Gynvael> teraz conieco "co jest co i czemu" w tej gierce [09:06] <@phoenix> btw http://www.mozillaquest.com/Linux4Windows/Linux4Windows04/K-Sokoban-01.gif ten jest na prawie kazdym linie ;) [09:06] <@Gynvael> anom jest ;> [09:06] <@Gynvael> wiec [09:06] <@Gynvael> mamy bohatera ;> [09:06] <@Gynvael> ktory jest zamkniety w jakims dziwacznym "magazynie" [09:07] <@Gynvael> sa w nim skrzynki (badz diamenty, beczki, zalezy od grafika ;>) [09:07] <@Gynvael> oraz miejsca gdzie te szkrzynki nalezy ustawic (np to czarnozolte pole na ostatnim screenie) [09:08] <@Gynvael> zabawa polega na tym zeby te skrzynki przepchnac na te oznaczone miejsca (obojetnie gdzie ktora skrzynka) [09:08] <@Gynvael> sprawa sie jednak komplikuje [09:08] <@Gynvael> mianowicie skrzynki te mozna jedynie pchac do przodu [09:08] ¯¯ Joins[#wyklady] Galileo (~lol@cdj198.neoplus.adsl.tpnet.pl) [09:08] <@Gynvael> nie mozna ich ciagnac ani nic [09:08] <@Gynvael> wiec jesli za skrzynia jest inna skrzynia badz sciana [09:08] <@Gynvael> to juz nic wiecej nie zrobimy z ta skrzynka i mozemy restartowac level --; [09:09] <@Gynvael> (swoja droga motyw soko-bana byl rowniez w grze Little Big Adventure ;>) [09:09] <@Gynvael> ok [09:09] <@Gynvael> wiec w sumie dzisiaj zajmiemy sie implementacja (a w zasadzie analiza implementacji i czesciowa implementacja) tejze gry [09:10] <@Gynvael> nasza platforma developerska bedzie jezyk C (kompilator polecam MinGW gcc pod windowsa, oraz gcc pod linxa) [09:10] <@Gynvael> OpenGL [09:10] <@Gynvael> oraz SDL [09:10] <@Gynvael> czym jest jezyk C chyba kazdy wie ;> [09:11] <@Gynvael> OpenGL to API do obslugi akceleratora tak w duzym skrocie ;> bardzo proste i wygodne [09:11] <@Gynvael> (btw gre bedziemy robic 2D, ale mimo to wygodnie jest korzystac z OpenGL i jego mozliwosci) [09:11] <@Gynvael> *linuxa ;p [09:11] <@Gynvael> ok [09:12] <@Gynvael> natomiast SDL ( http://www.libsdl.org/index.php ) [09:12] <@Gynvael> jest bardzo przyjaznym libem siedzacym miedzy API systemu operacyjnego a naszym programikiem [09:12] <@Gynvael> sluzy on glownie do obslugi klawiatury, okna gry (w sensie tworzenie etc), dzwieku etc [09:13] <@Gynvael> dzieki czemu to co piszemy jest (prawie) niezalezne od systemu operacyjnego [09:13] <@Gynvael> http://www.libsdl.org/download-1.2.php [09:13] <@Gynvael> proponowal bym zebyscie w wolnej chwili sciagneli to cudo ;> [09:14] <@Gynvael> co do instalacji tego cuda [09:14] <@Gynvael> ogolnie trzeba w sciagnietym archiwum odnalezc pare plikow [09:15] <@Gynvael> pliki z katalogu lib nalezy wrzucic do swojego katalogu lib (np mingw\lib).. zazwyczaj (i powininien byc) jest tam katalog lib/SDL wiec pliki powinny z tym katalogiem byc przerzucone [09:15] <@Gynvael> analogicznie z include [09:15] <@Gynvael> pliki .dll moga trafic do katalogu systemowego naszego [09:16] <@Gynvael> np na windzie 98 jest to windows/system [09:16] <@Gynvael> a na ntkach windows/system32 [09:16] <@Gynvael> linuxsiarze zazwyczaj znaja swoj OS i wiedza gdzie co musi trafic;> [09:17] <@Gynvael> teraz dajcie mi pare sec [09:17] <@Gynvael> to wrzuce pliki na serv [09:17] <@Gynvael> ;> [09:17] <@d0ubl3_j> a ja nie wiem ;o [09:17] <@Gynvael> btw [09:18] <@Gynvael> jak ktos ma linuxa [09:18] <@Gynvael> good by bylo zeby sciagnal zrodla [09:18] <@phoenix> a ja mam to na linie ? [09:18] <@Gynvael> i zapodal standardowa modlitwe [09:18] <@Gynvael> czyli [09:18] <@Gynvael> ./configure --prefix=/usr && make && make install [09:21] ¯¯ Modes[#wyklady] ChanServ (+o G0blin) [09:21] ¯¯ Modes[#wyklady] Gynvael (-m) [09:22] dalej proszê [09:22] <@Gynvael> jakies pytania w miedzyczasie ? [09:22] <@G0blin> wlasnie chcialem sobie pozwolic zdjac m :P [09:22] moge uzyc C++ Buildera ?? [09:22] czy mozna troche szybciej ? :P [09:22] nie ma ;f [09:22] NieWrzucajTegoStrataCzas, w³a¶nie [09:22] <@Gynvael> Galileo sadze ze mozesz, ale nie mam pojecia jak sie tam linkuje [09:22] dalej mow [09:22] <@Gynvael> ok [09:22] <@d0ubl3_j> NieWrzucajTegoStrataCzas: zmien se nick i nie marudz ;p [09:22] ¯¯ Modes[#wyklady] Gynvael (+m) [09:22] <@Gynvael> ok [09:22] <@Gynvael> lecimy dalej [09:23] <@Gynvael> http://gynvael.lunarii.org/temp/soko1.zip [09:23] <@Gynvael> zassajcie i sproobojcie skompilowac [09:23] <@Gynvael> jesli by sie komus udalo to ql ;> [09:23] <@Gynvael> binarke windowsowska dolaczylem [09:23] <@Gynvael> po skompilowaniu i odpaleniu [09:23] <@Gynvael> powinno wygladac to tak [09:23] <@Gynvael> http://gynvael.lunarii.org/temp/soko1.png [09:24] <@Gynvael> ok [09:24] <@Gynvael> teraz mala analiza budowy tego cuda [09:24] <@Gynvael> od strony tego co widac [09:24] <@Gynvael> troche .c troche .h [09:24] <@Gynvael> sokoban.c jest glownym plikiem [09:25] <@Gynvael> i od niego zaraz zaczne [09:25] <@Gynvael> po za tym makefile'e pod winde i linuxa [09:25] <@Gynvael> przypominam ze windowcy z konsoli robia [09:25] <@Gynvael> make -f Makefile.win32 [09:25] <@Gynvael> a linuxowcy [09:25] <@Gynvael> make -f Makefile.linux [09:25] <@Gynvael> po za tym dwa katalogi [09:25] <@Gynvael> gfx i maps [09:25] <@Gynvael> w gfx znajduje sie grafika w formacie TGA [09:25] <@Gynvael> do ktorego to za chwile wroce [09:26] <@Gynvael> a w maps dwa przykladowe levele [09:26] <@Gynvael> mozna je sobie cat'tem/w notepadzie podajzec [09:26] <@Gynvael> jako ze sa to pliczki textowe [09:26] <@Gynvael> ok [09:26] <@Gynvael> teraz tak [09:26] <@Gynvael> wykonanie zaczyna sie w sokoban.c w main (badz WinMain) [09:27] <@Gynvael> if(game_init() != 0) [09:27] <@Gynvael> { [09:27] <@Gynvael> printf("init error\n"); [09:27] <@Gynvael> return 1; [09:27] <@Gynvael> } [09:27] <@Gynvael> while(game_loop() == 0); [09:27] <@Gynvael> game_deinit(); [09:27] <@Gynvael> return 0; [09:27] ¯¯ Parts[#wyklady] Jacek (~jacek@tetra-n46.netp0wer.net)- [09:27] <@Gynvael> nie jest zlym pomyslem dawac tego typu konstrukcje [09:27] <@Gynvael> dziala to tak [09:27] <@Gynvael> na poczatku mamy wszystkie inicjalizacje (game_init()) [09:27] <@Gynvael> czyli: [09:27] <@Gynvael> - inicjowanie SDL [09:27] <@Gynvael> - tworzenie okna z OpenGLem [09:28] <@Gynvael> - ladowanie textur [09:28] <@Gynvael> - wczesniej jeszcze ustawianie parametrow OpenGLa [09:28] <@Gynvael> - ladowanie map [09:29] <@Gynvael> jak to wszystko sie uda [09:29] <@Gynvael> to gra wskakuje do glownej petli -> game_loop() [09:29] <@Gynvael> i trwa w niej dopoki ow funkcja nie zwroci wartosci roznej od 0 [09:29] <@Gynvael> nastepnie po tym jest czyszczenie/deinicjalizacja/zamykanie/niszczenie etc [09:29] <@Gynvael> czyli game_deinit() [09:29] <@Gynvael> tam znajduja sie takie rzeczy jak [09:29] <@Gynvael> - niszczenie textur [09:30] ¯¯ Joins[#wyklady] Szejker_ (~szejker@mixer.biz.tm) [09:30] <@Gynvael> - uwalnianie pamieci po mapach etc [09:30] <@Gynvael> te 3 funkcje znajduja sie w pliku game.c [09:30] <@Gynvael> zacznijmy od analizy game_init [09:31] <@Gynvael> na samym poczatku jest pare stalych/flag/ustawien [09:31] <@Gynvael> int screen_width = 640; [09:31] <@Gynvael> int screen_height = 480; [09:31] <@Gynvael> int screen_flag = SDL_OPENGL; [09:31] <@Gynvael> w sumie dobrym pomyslem zazwyczaj jest kazanie grze odczytanie tego typu ustawien z jakiegos configa [09:31] <@Gynvael> (ale nie chcialem mieszac w kodzie za duzo) [09:32] <@Gynvael> jak sie mozna domyslic sa to ustawienia rozdzielczosci [09:32] ¯¯ Joins[#wyklady] d3a7h (~d3a7h@cqj16.neoplus.adsl.tpnet.pl) [09:32] <@Gynvael> gdyby do flag dodac SDL_FULLSCREEN to gra zamiast w oknie odpalala by sie na fullscreenie (nie polecam tego do celow debugowych ;p zmiana rozdzielczosci chwile trwa ;p) [09:32] <@Gynvael> nastepnie jest inicjalizacja SDL [09:32] <@Gynvael> if( SDL_Init(SDL_INIT_VIDEO) < 0 ) [09:32] <@Gynvael> return 1; [09:33] <@Gynvael> o niej mozna poczytac w dokumentacji SDL wiec sie zbytnio rozwodzil nie bede [09:33] <@Gynvael> info = SDL_GetVideoInfo( ); [09:33] <@Gynvael> if(info == NULL) [09:33] <@Gynvael> goto err; [09:33] <@Gynvael> screen_bpp = info->vfmt->BitsPerPixel; [09:33] <@Gynvael> to pobiera ile bpp mamy ustawione w systemie [09:33] <@Gynvael> potem z ciekawych rzeczy jest [09:33] <@Gynvael> surface = SDL_SetVideoMode( [09:33] <@Gynvael> screen_width, screen_height, [09:33] <@Gynvael> screen_bpp, screen_flag); [09:33] ¯¯ Joins[#wyklady] goadie (goadie@cjb184.neoplus.adsl.tpnet.pl) [09:33] <@Gynvael> jest to w sumie utworzenie okna o danych atrybutach [09:34] <@Gynvael> kolejna ciekawa rzecza jest [09:34] <@Gynvael> SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); [09:34] <@Gynvael> w zaleznosci od rodzaju gry czasem chcemy dostawac jeden event przy nacisnieciu klawisza [09:34] <@Gynvael> i jeden przy puszczeniu [09:35] <@Gynvael> a czasem chcemy uzyskac efekt jak w edytorze textu, czyli raz nacisniemy i przytrzymamy klawisz np "a" [09:35] <@Gynvael> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [09:35] <@Gynvael> to tych "a" pojawi sie wiecej niz jedno, kazde po krotkim odstepie czasowym [09:35] <@Gynvael> ta funkcja ustawia SDLowi wlasnie takie powtorzenia eventa dla klawisza przy przytrzymaniu [09:35] <@Gynvael> dla sokobana to jest wygodne ;> [09:36] <@Gynvael> nastepnie po tym jest ustawienie stuffu OpenGLa [09:36] <@Gynvael> co do samego opengl'a to podam dwa linki [09:36] <@Gynvael> http://opengl.org [09:36] <@Gynvael> http://nehe.gamedev.net [09:36] <@Gynvael> pierwszy jest bodajze oficjalnym sajtem tego standardu [09:36] <@Gynvael> a na drugim znajdziecie genialne tutoriale do OpenGLa [09:37] <@Gynvael> w stuff opengl'owy ktory tam jest za bardzo sie zaglebial rowniez nie bede ;> [09:37] <@Gynvael> z rzeczy na ktore bym zwrocil uwage [09:38] <@Gynvael> jesli korzystamy z OpenGL do gier 2D, to zazwyczaj warto jest wylaczyc DEPTH_TEST (bodajze to jest wykrywanie czy jeden obiekt jest ponizej drugiego) [09:38] <@Gynvael> glDisable(GL_DEPTH_TEST); [09:38] <@Gynvael> po wylaczeniu tego to co "nowsze", bedzie rysowane "na gorze" [09:39] <@Gynvael> nastepnie jest petla wczytujaca texturki [09:39] <@Gynvael> co do samego tworzenia textur [09:40] <@Gynvael> tutaj uzylem nastepujacego manewru [09:40] <@Gynvael> mam tablice globalna (sic!) textures[] w ktorej mam pary { "nazwa.pliku.tga", 0xfffffff } [09:40] <@Gynvael> static my_texture_t textures[] = [09:40] <@Gynvael> { [09:40] <@Gynvael> {"stone.tga", 0xffffffff}, [09:40] <@Gynvael> {"user.tga", 0xffffffff}, [09:40] <@Gynvael> {"stone_hi.tga", 0xffffffff}, [09:40] <@Gynvael> {"wall.tga", 0xffffffff}, [09:40] <@Gynvael> etc... [09:40] ¯¯ Parts[#wyklady] d3a7h[off] (~d3a7h@cqj16.neoplus.adsl.tpnet.pl)- [09:40] <@Gynvael> teraz tak [09:41] <@Gynvael> w tej petli tam pokolei laduje kazda texture w nastepujacy sposob: [09:41] <@Gynvael> snprintf(buffer, sizeof(buffer), "gfx/%s", textures[i].name); [09:41] <@Gynvael> dodaje przedrostek gfx/ przed nazwe pliku [09:41] <@Gynvael> zeby bylo np gfx/stone.tga [09:41] <@Gynvael> akurat z / nie ma problemu w sciezkach, powiewaz / jest supportowany zarowno przez windowsa jak i linuxa [09:42] <@Gynvael> ret = img_load_from_tga(&img, buffer); [09:42] <@Gynvael> if(ret != 0) [09:42] <@Gynvael> goto err; [09:42] <@Gynvael> img_load_from_tga wczytuje bitmape z podanego pliku (buffer) i wypelnia strukturke img_t (img) [09:42] <@Gynvael> textures[i].id = texture_form_img(&img); [09:43] <@Gynvael> nastepnie texture_from_img tworzy z tego texture i wrzuca ID (numer) textury do textures[i].id [09:43] <@Gynvael> czyli zamiast tego 0xffffffff [09:43] <@Gynvael> [09:43] <@Gynvael> img_destroy(&img); [09:43] <@Gynvael> po tym bitmapa jest usuwana z pamieci (textura zostaje) [09:43] <@Gynvael> po tym sa ladowane mapy w analogiczny sposob [09:43] <@Gynvael> snprintf(buffer, sizeof(buffer), "maps/%s", maps[i].name); [09:43] <@Gynvael> [09:43] <@Gynvael> ret = map_from_file(&maps[i].map, buffer);; [09:43] <@Gynvael> if(ret != 0) [09:43] <@Gynvael> goto err; [09:44] <@Gynvael> na koncu jest wybierany pierwszy level czyli [09:44] <@Gynvael> /* select */ [09:44] <@Gynvael> if(map_copy(¤t_map, &maps[0].map) != 0) [09:44] <@Gynvael> goto err; [09:44] <@Gynvael> na to check_move_keys = 1; [09:44] <@Gynvael> mozecie nie patrzec ;> [09:44] <@Gynvael> to pozostalosc po czyms czego nie dokonczylem hehehe [09:44] <@Gynvael> ok [09:44] <@Gynvael> mniej wiecej tak dziala init [09:44] <@Gynvael> teraz co do formatu mapy [09:44] <@Gynvael> otworzcie plik map.h [09:45] <@Gynvael> sa tam dwa structy [09:45] <@Gynvael> typedef struct [09:45] <@Gynvael> { [09:45] <@Gynvael> short x,y; [09:45] <@Gynvael> } map_coord_t; [09:45] <@Gynvael> (tego typu structow pewnie jest full ;p) [09:45] <@Gynvael> czyli wspolzedne (jako liczby calkowite) [09:45] <@Gynvael> oraz dluzszy struct [09:45] <@Gynvael> typedef struct [09:45] <@Gynvael> { [09:45] <@Gynvael> short width; [09:45] <@Gynvael> short height; [09:45] <@Gynvael> map_coord_t player; [09:45] <@Gynvael> [09:45] <@Gynvael> int box_count; [09:45] <@Gynvael> map_coord_t *boxes; [09:45] <@Gynvael> [09:45] <@Gynvael> char *data; [09:45] <@Gynvael> } map_t; [09:45] <@Gynvael> teraz troche o nim [09:46] <@Gynvael> width i height to wielkosc mapy w polach (mapa dzieli sie na rowne pola, kwadratowe btw) [09:46] <@Gynvael> map_coord_t player to koordynaty startowe gracza (z tym ze ja znich potem korzystam do przemieszczania go ;p) [09:46] <@Gynvael> int box_count; to ilosc skrzyni/kamyczkow etc [09:46] <@Gynvael> map_coord_t *boxes; to pointer na tablice z koordynatami skrzynek [09:47] <@Gynvael> char *data to "bitmapa" mapy ;> czyli "rysunek" mapy zlozony ze znakow [09:47] <@Gynvael> wejdzcie do katalogu maps i otworzcie pierwszy pliczek [09:47] <@Gynvael> level1.map [09:47] <@Gynvael> 10 10 2 [09:47] <@Gynvael> .......... [09:47] <@Gynvael> .########. [09:47] <@Gynvael> .#''p'''#. [09:47] <@Gynvael> .##ss##'#. [09:48] <@Gynvael> ..#''##'#. [09:48] <@Gynvael> ..#'''''#. [09:48] <@Gynvael> .##'''###. [09:48] <@Gynvael> .#xx''#... [09:48] <@Gynvael> .######... [09:48] <@Gynvael> .......... [09:48] ¯¯ Joins[#wyklady] Karql (~Karql@where.is.my.host) [09:48] <@Gynvael> i porownajcie ten rysunek z http://gynvael.lunarii.org/temp/soko1.png [09:48] ¯¯ Joins[#wyklady] Karql (~perl@gw4.wiknet.pl) [09:48] <@Gynvael> (ta pomaranczowa kulka to gracz ;> obawiam sie ze nadworny grafik Vexillium, XaoS, ma ostatnio duzo roboty i tylko cos takiego zdolal dla mnie przygotowac ;> ale wystarczy ;>>>) [09:49] <@Gynvael> teraz tak [09:49] <@Gynvael> 10 10 2 <=- to pierwsza linia [09:49] <@Gynvael> jest to: [09:49] <@Gynvael> szerokosc mapy, wysokosc mapy i ilosc skrzynek [09:49] <@Gynvael> mozna by to wyliczyc majac ten rysunek nizej, ale nie ma co sobie zycia utrudniac ;> [09:49] <@Gynvael> teraz tak [09:49] ¯¯ Joins[#wyklady] marcel3miasto (GDYNIA@nadmorska.kraina.snow) [09:49] <@Gynvael> znak . (kropka) to "nic", czyli cos czego sie nie rysuje ;> [09:50] <@Gynvael> znak # (hash) to sciana, mur ;> [09:50] <@Gynvael> znak ' (apostrof) to zwykla podloga [09:50] ¯¯ Joins[#wyklady] Karql (~Karql@where.is.my.host) [09:50] <@Gynvael> znak x (iks ;p) to miejsce na podlodze gdzie trzeba skrzynke dopchac [09:50] <@Gynvael> znak s (es ;p) to skrzynka [09:51] <@Gynvael> znak p (pe ;p) to gracz (player) [09:51] <@Gynvael> jako ze gracz oraz skrzynki sa obiektami "mobilnymi" a nie czescia planszy [09:51] <@Gynvael> to program wczytujac mape zamienia wszystkie p i s na ' (podloge) [09:51] <@Gynvael> natomiast zapamietuje koordynaty w/w (czyli skrzynek i gracza) [09:52] <@Gynvael> jezeli ktos jest zainteresowany jak to dziala dokladnie, to proponuje zajrzec do pliku map.c [09:52] <@Gynvael> raczej nic bardziej skomplikowanego niz for i fscanf tam nie ma [09:52] <@Gynvael> ;> [09:52] <@Gynvael> teraz tak [09:52] <@Gynvael> robimy glosowanie (mi na priva) [09:52] <@Gynvael> czy tlumaczyc jak dziala format TGA [09:52] <@Gynvael> czy znacie go i moge sobie darowac [09:52] <@Gynvael> powiedzmy ze 2 minuty na glosowanie ;> [09:55] ¯¯ Joins[#wyklady] defc0n (~defc0n@80.50.255.74) [09:56] <@d0ubl3_j> to ja powiem ino ze narazie jest 1:1 w meczu w przerwie reklamowej ofc ;> [09:57] <@G0blin> --; [09:57] <@G0blin> 2j: +m jest [09:57] <@d0ubl3_j> ale jest przerwa :p [09:57] <@G0blin> ale +m :P [09:57] ¯¯ Joins[#wyklady] d3a7h[TV] (~d3a7h@cqj16.neoplus.adsl.tpnet.pl) [09:57] <@Gynvael> ok [09:57] <@Gynvael> ;> [09:57] <@d0ubl3_j> ale przerwa [09:57] <@Gynvael> dostalem troche glosowan [09:57] <@Gynvael> wiec mozemy leciec dalej [09:58] <@Gynvael> przewaga dosc znaczna zadecydowaliscie zeby mowic o TGA [09:58] <@Gynvael> wiec ci co go znaja maja 10 minut przerwy ;p [09:58] ¯¯ Parts[#wyklady] Rafal_F (~mega05@195.116.95.162)- [09:58] ¯¯ Parts[#wyklady] goadie (goadie@cjb184.neoplus.adsl.tpnet.pl)- [09:58] ¯¯ Joins[#wyklady] Rafal_F (~mega05@195.116.95.162) [09:59] <@Gynvael> ok [09:59] <@Gynvael> http://gynvael.lunarii.org/temp/tga.txt [09:59] <@Gynvael> (sorx, plik uplowadowalem) [10:00] <@Gynvael> to w sumie najfajniejsza dokumentacja tga jaka znalazlem [10:00] <@Gynvael> wiec tak [10:00] ¯¯ Parts[#wyklady] marcel3miasto (GDYNIA@nadmorska.kraina.snow)- [10:00] <@Gynvael> TGA jest plikiem "obrazkiem" typu bitmapa ;> [10:00] <@Gynvael> sklada sie z naglowka (18 bajtow + ewentualny tzw pole identyfikacyjne, ale nie widzialem tego jeszcze w TGA ;p) + danych [10:01] <@Gynvael> dane moga byc w roznych postaciach: [10:01] <@Gynvael> 1) RGB badz RGBA nieskompresowane, czyli po bajt na kazdy kolor, 3 lub 4 bajty to jeden pixel (to tga type 2) [10:02] <@Gynvael> 2) paleta kolorow + po bajt na kazdy pixel (indexy koloru w palecie) [10:02] <@Gynvael> 3) kompresowane RLE, Huffmanem badz jeszcze jakims innym cholerstwem [10:02] <@Gynvael> etc [10:02] <@Gynvael> ogolnie najciekawszy dla nas jest 1), czyli RGB badz RGBA [10:03] <@Gynvael> ogolnie TGA jest jednym z niewielkiej liczby formatow ktore umieja zapisac w sobie kanal Alpha (przezroczystosc) [10:03] <@Gynvael> z tych co sa wmiare uzyteczne, to GIF umie jednobitowa przezroczystosc zapisac [10:03] <@Gynvael> i PNG (ktory polecam wszystkim, swietny format, kompresja bezstratna) bardzo dobrze sobie radzi z alpha [10:04] <@Gynvael> (nie uzylem tu PNG poniewaz odczyt reczny tego to zaboojstwo, a nie chcialem dolaczac do tak malego projektu kolejnej biblioteki - libpng i libz wymaganego przez w/w) [10:04] <@Gynvael> ok [10:04] <@Gynvael> czyli jak mowilem nas interesuje type 2 [10:04] ¯¯ Joins[#wyklady] DJ_cool_ (andrzej@xdsl-4738.lubin.dialog.net.pl) [10:04] <@Gynvael> (czyli 1) ;> [10:05] <@Gynvael> znajddzie w tym pliczku tga.txt druga tabelke [10:05] <@Gynvael> DATA TYPE 2: Unmapped RGB images. [10:05] <@Gynvael> tak zatytulowana [10:05] <@Gynvael> jest tam pelen opis naglowka [10:05] <@Gynvael> proponuje zajrzec rowniez do img.c [10:05] <@Gynvael> #pragma pack(push, 1) [10:05] <@Gynvael> typedef struct { [10:05] <@Gynvael> unsigned char id_field; [10:05] <@Gynvael> unsigned char c_map; [10:05] <@Gynvael> unsigned char img_type; [10:05] <@Gynvael> unsigned char color_map[5]; [10:05] <@Gynvael> unsigned short x_origin; [10:05] <@Gynvael> unsigned short y_origin; [10:05] <@Gynvael> unsigned short width; [10:05] <@Gynvael> unsigned short height; [10:05] <@Gynvael> unsigned char bpp; [10:05] <@Gynvael> unsigned char flip; [10:05] <@Gynvael> } tga_t; [10:05] <@Gynvael> #pragma pack(pop) [10:06] <@Gynvael> to sa pola tego naglowka zapisane w C ;> [10:06] <@Gynvael> naglowek jak widac (badz nie) ma 18 bajtow ;> [10:06] <@Gynvael> (stac #pragma etc.. bo C bardzo lubi wszystko wyrownywac i by sie spiepszylo) [10:07] <@Gynvael> ogolnie co tam mozna znalezc ciekawego [10:08] <@Gynvael> id_field ( Number of Characters in Identification Field. ) to ilosc bajtow przypadajacych na pole identyfikacycjne [10:08] <@Gynvael> zazwyczaj to jest 0 [10:08] <@Gynvael> jesli nie to znaczy ze po naglowku tyle wlasnie bajtow jest zajete przez costam, i trzeba to przeskoczyc ;> [10:08] <@Gynvael> unsigned char c_map; to dla typu 2 jest 0 zawsze [10:08] <@Gynvael> unsigned char img_type; <=- to dla nas musi == 2 (typ 2gi) [10:09] <@Gynvael> unsigned char color_map[5]; to sa zera [10:09] ¯¯ Joins[#wyklady] djcool|gdzies_tam (dj@xdsl-4738.lubin.dialog.net.pl) [10:09] <@Gynvael> x/y_orgina sa nieciekawe [10:09] <@Gynvael> width i height natomiast sa to wymiary bitmapy [10:09] <@Gynvael> np 640 i 480 ;> [10:09] <@Gynvael> bpp to glebia kolorow, czyli ilosc bitow na pixel [10:10] <@Gynvael> np 24 dla RGB i 32 dla RGBA [10:10] <@Gynvael> potem jest cos co ja oznaczylem sobei jako flip [10:10] <@Gynvael> to tzw Image Specification. [10:10] <@Gynvael> ogolnie jest tam troche rzeczy [10:10] <@Gynvael> z ktorych przydaje sie tlyko bit 5ty [10:10] <@Gynvael> Bit 5 - screen origin bit. [10:10] <@Gynvael> 0 = Origin in lower left-hand corner. [10:10] <@Gynvael> 1 = Origin in upper left-hand corner. [10:11] <@Gynvael> ogolnie chodzi o to ze jesli ten bit jest 0, to mamy bitmapke dogory nogami ;p [10:11] <@Gynvael> i trzeba ja odwrocic [10:11] ¯¯ Joins[#wyklady] Astarot (hjkhhjkhg@aue51.neoplus.adsl.tpnet.pl) [10:11] <@Gynvael> nastepnie po naglowku i ew id-fieldzie sa dane [10:12] <@Gynvael> jesli sie wam chce to rzuccie na to okiem np pod listerem [10:13] <@Gynvael> http://gynvael.lunarii.org/temp/lister.gif [10:14] ¯¯ Parts[#wyklady] mosquito (1000@Bot.Underground)- [10:14] ¯¯ Joins[#wyklady] mosquito (1000@Bot.Underground) [10:14] <@Gynvael> http://gynvael.lunarii.org/temp/floor_mark.png [10:14] <@Gynvael> troche podobne ne [10:14] <@Gynvael> ?;> [10:14] ¯¯ Joins[#wyklady] Dragosino (~Dragon@dl194.internetdsl.tpnet.pl) [10:14] <@Gynvael> z dodatkowych uwag powiem jeszcze ze TGA jest odrobine wredne [10:14] <@Gynvael> bo zamiast zapisywac w pliku RGB [10:14] <@Gynvael> to zapisuje BGR ;p [10:14] <@Gynvael> albo BGRA [10:14] <@Gynvael> i trzeba sobie to R z B zamienic [10:15] <@Gynvael> proponuje zajrzec do img.c oraz do wykladu bodajze #11 albo #10 (albo #9 ;p) z C [10:15] <@Gynvael> na tym wykladzie bylo o odczycie naglowka tga etc [10:16] <@Gynvael> niom [10:16] <@Gynvael> mniej wiecej tak [10:16] <@Gynvael> ogolnie OpenGL robi textury z czystych danych [10:16] <@Gynvael> czyli musi miec w pamieci RGBRGBRGBRGBRGBRGBRGBRGBRGBRGBRGBRGB [10:17] <@Gynvael> bardz RGBARGBARGBARGBARGBARGBA [10:17] <@Gynvael> etc [10:17] <@Gynvael> wiec jesli chodzi o tga wystarczy odczytac naglowek, zaalokowac odpowiednia ilosc pamieci na dane, wczytac dane [10:17] <@Gynvael> poprzestawiac BGR na RGB [10:17] <@phoenix> Gynvael: plz looknij priv mecze sie z tym [10:17] <@Gynvael> bycmoze odwrocic do gooory nogami [10:17] <@Gynvael> i podac GLowi na tacy zeby z tego texture zrobil [10:17] <@Gynvael> taka jedna uwaga [10:18] <@Gynvael> GL lubi textury o wymiarach potegi 2jki [10:18] <@Gynvael> czyli np [10:18] <@d0ubl3_j> e co moje? [10:18] <@Gynvael> 1 2 4 8 16 32 64 128 256 512 etc [10:19] <@Gynvael> czyli np 256x512 jest dobrym wymiarem [10:19] <@Gynvael> ale 512x123 juz nie [10:19] <@Gynvael> ;> [10:19] <@Gynvael> co do samego tworzenia textury [10:19] <@Gynvael> w textures.c jest dosc przejrzysta funkcja [10:19] <@Gynvael> rzuccie na nia okiem i tyle [10:19] <@Gynvael> ogolnie trzeba wygenerowac id texturki, ustawic troche parametrow [10:20] <@Gynvael> a potem podac GLowi dane i on zrobi texturke o id [10:20] <@Gynvael> ;> [10:20] ¯¯ Joins[#wyklady] Phoenix^^ (~good_god@asz121.neoplus.adsl.tpnet.pl) [10:20] <@Gynvael> id jest liczba [10:20] <@Gynvael> np 2, 4 ;> [10:20] <@Gynvael> etc [10:20] <@Gynvael> ok mniej wiecej tyle o tym [10:20] <@Gynvael> pytanka co do tga ? [10:20] ¯¯ Modes[#wyklady] Gynvael (-m) [10:21] <@Gynvael> albo do map [10:21] <@Gynvael> ;> [10:21] chyba nie [10:21] gl.h jest w sdlu? [10:21] <@Gynvael> nie [10:21] Prus: nie [10:21] to oddzielna biblioteka [10:21] <@Gynvael> gl.h POWINNO byc z waszym kompilatorem [10:21] <@Gynvael> jesli go nie ma to bardzo dziwne --; [10:21] tyo [10:21] w devcpp jest [10:21] tya* [10:21] ¯¯ Joins[#wyklady] r00uter (~r00uter@80.51.95.10) [10:21] aha [10:21] ¯¯ Parts[#wyklady] r00uter (~r00uter@80.51.95.10)- [10:22] <@Gynvael> ew na niektorych kompilatorach jest nie tyle gl/gl.h co GL/gl.h albo gl.h [10:22] Gynvael: strasc co jeszcze dzisija bedzie [10:22] <@Gynvael> wiec poproobojcie [10:22] ¯¯ Joins[#wyklady] r00uter (~r00uter@80.51.95.10) [10:22] ¯¯ Parts[#wyklady] r00uter (~r00uter@80.51.95.10)- [10:22] <@Gynvael> salvation: w sumie zaraz powiem o budowie tego ukladu renderujacego w gierce (ale on proooosty jest wiec to chwila) [10:22] <@Gynvael> po czym bede tlumaczyl sam algorytm gry [10:22] jest gl.h ;-) [10:22] i tyle? [10:22] <@Gynvael> i po kolei wrzucal kolejne wersje tej gierki na serva [10:22] ¯¯ Parts[#wyklady] Phoenix (~good_god@asz121.neoplus.adsl.tpnet.pl)- [10:23] <@Gynvael> az wkoncu bedzie dzialac [10:23] acha ;pp [10:23] <@phoenix_> Gynvael: 0 wynikow z tego locata ;/ [10:23] <@Gynvael> potem moze chwile o pomyslach na ulepszenie i tyle [10:23] a ile tyo mniejwiecej zajmie?[min] [10:23] ¯¯ Parts[#wyklady] Rafal_F (~mega05@195.116.95.162)- [10:24] <@Gynvael> sadze ze kolo 40 minut [10:24] <@Gynvael> ok [10:24] ¯¯ Joins[#wyklady] Rafal_F (~mega05@195.116.95.162) [10:24] <@Gynvael> brak pytanek to lecimy dalej [10:24] Gynvael: gardlo cie nie bli od ciaglego gadania? [10:24] ;p [10:24] boli* [10:24] <@Gynvael> ;p [10:25] hardcore ;p [10:25] ¯¯ Modes[#wyklady] Gynvael (+m) [10:25] <@Gynvael> ok [10:25] <@Gynvael> teraz troche o game_loop [10:25] <@phoenix_> spamuje gyna ;D [10:25] <@phoenix_> tzn flooduje ;D [10:25] <@phoenix_> gyn priv [10:25] <@Gynvael> int [10:25] <@Gynvael> game_loop(void) [10:25] <@Gynvael> { [10:25] <@Gynvael> if(events( ) != 0) [10:25] <@Gynvael> return 1; [10:25] <@Gynvael> calcs( ); [10:25] <@Gynvael> scene( ); [10:25] <@Gynvael> return 0; [10:25] <@Gynvael> } [10:26] <@Gynvael> ta mala funkcyjka wywoluje pare innych lokalnych funkcji [10:26] <@Gynvael> w events sa odbierane eventy od SDLa (nacisniecie klawisza, zamkniecie okna, takie tam) [10:27] <@Gynvael> w calcs sa (a raczej beda) liczone ruchy gracza, przesuniecia etc [10:27] <@Gynvael> a w scene() jest rendering [10:28] <@Gynvael> teraz chwile o events [10:28] <@Gynvael> static int [10:28] <@Gynvael> events(void) [10:28] <@Gynvael> { [10:28] <@Gynvael> SDL_Event ev; [10:28] <@Gynvael> memset( &ev, 0, sizeof( SDL_Event ) ); [10:28] <@Gynvael> while( SDL_PollEvent( &ev ) ) [10:28] <@Gynvael> { [10:28] <@Gynvael> switch( ev.type ) [10:28] <@Gynvael> { [10:28] <@Gynvael> case SDL_KEYDOWN: [10:28] <@Gynvael> if(ev.key.keysym.sym == SDLK_ESCAPE) [10:28] <@Gynvael> return 1; [10:28] <@Gynvael> etc [10:28] <@Gynvael> ogolnie jesli ktos kiedys sie bawil np WinAPI albo czyms innym co obsluguje eventy w ten sposob [10:28] <@Gynvael> to nie bedzie mial z tym problemu [10:29] <@Gynvael> ogolnei chodzi o to ze SDL_PollEvent pobiera z listy jakies zdarzenie (lista moze byc pusta, albo moze tam cos byc) [10:29] <@Gynvael> wypelnia strukturke (unie struktur ;p) ev [10:29] <@Gynvael> po czym switch(ev.type) sprawdza czy zdarzyl sie jakis obslugiwany event [10:29] <@Gynvael> np SDL_KEYDOWN == nacisniecie klawisza [10:30] <@Gynvael> ev.key.keysym.sym <=- to symbol/oznaczenie klawisza (w SDL/SDL_keysym.h jest lista pelna symboli) [10:30] <@Gynvael> nmp SDLK_ESCAPE to symbol klawisza escape [10:30] <@Gynvael> przykaldowo jesli nacisniemy escape to funkcja events zroci 1 [10:30] <@Gynvael> -=222641=- if(events( ) != 0) [10:30] <@Gynvael> -=222641=- return 1; [10:30] <@Gynvael> czyli funkcja game_loop zroci jeden [10:31] <@Gynvael> czyli ogolnie wyjdzie z petli (Tej z sokoban.c) [10:31] <@Gynvael> z ciekawych rzeczy [10:31] <@Gynvael> jesli gracz nacisnie jakis klawisz (strzalke) [10:32] <@Gynvael> if(ev.key.keysym.sym == SDLK_DOWN) [10:32] <@Gynvael> my_event = PLAYER_MOVE_DOWN; [10:32] <@Gynvael> if(ev.key.keysym.sym == SDLK_UP) [10:32] <@Gynvael> my_event = PLAYER_MOVE_UP; [10:32] <@Gynvael> etc [10:32] <@Gynvael> to zmienna (int ;p) my_event jest ustawiana na costam [10:32] <@Gynvael> w calcs() to my_event jest analizowane i dopiero tam sa przesuniecia [10:32] <@Gynvael> k [10:32] <@Gynvael> tyle o events [10:32] <@Gynvael> teraz w calcs prawie nic nie ma [10:32] <@Gynvael> static void [10:32] <@Gynvael> calcs(void) [10:32] <@Gynvael> { [10:32] <@Gynvael> switch(my_event) [10:32] <@Gynvael> { [10:33] <@Gynvael> case NO_EVENT: break; [10:33] <@Gynvael> [10:33] <@Gynvael> case PLAYER_MOVE_RIGHT: [10:33] <@Gynvael> player_move(1, 0); [10:33] <@Gynvael> break; [10:33] <@Gynvael> case PLAYER_MOVE_LEFT: [10:33] <@Gynvael> player_move(-1, 0); [10:33] <@Gynvael> break; [10:33] <@Gynvael> etc [10:33] <@Gynvael> czyli jesli jest jakis event do ruchu gracza (PLAYER_MOVE_*) [10:33] <@Gynvael> to wywolana jest funkcja player_move(koordynaty) [10:33] <@Gynvael> te koordynaty tam to x i y PRZESUNIECIA [10:34] <@Gynvael> czyli w prawo np przesuwamy gracza 1 w osi X i 0 w osi Y [10:34] <@Gynvael> w lewo -1 w X i 0 w Y [10:34] <@Gynvael> etc [10:34] <@Gynvael> w player_move narazie nic nie ma [10:34] <@Gynvael> za chwile sie nia zajmiemy [10:34] <@Gynvael> to w sumie najwazniejsza funckja w tej grze hehe [10:34] <@Gynvael> ok [10:34] <@Gynvael> teraz scene() [10:34] <@Gynvael> static void [10:34] <@Gynvael> scene(void) [10:34] <@Gynvael> { [10:34] <@Gynvael> glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); [10:34] <@Gynvael> glMatrixMode( GL_MODELVIEW ); [10:34] <@Gynvael> [10:34] <@Gynvael> scene_render_back( ); [10:34] <@Gynvael> scene_render_map( ); [10:34] <@Gynvael> scene_render_boxes( ); [10:34] <@Gynvael> scene_render_player( ); [10:34] <@Gynvael> [10:34] <@Gynvael> SDL_GL_SwapBuffers( ); [10:34] <@Gynvael> } [10:35] <@Gynvael> glClear czysci ekran ;> (a dokladniej buffor ;p) [10:35] <@Gynvael> a te 4ry funkcje scene_render_* renderuja kolejno tlo (tego splash.tga) [10:35] <@Gynvael> mape [10:35] <@Gynvael> skrzynie [10:35] <@Gynvael> i gracza [10:36] <@Gynvael> GL ogolnie opiera sie na polygonach w przestrzeni [10:36] <@Gynvael> wiec nawet jesli stosujemy GL do 2D, to ucieczki od tego nie ma zbytnio [10:36] <@Gynvael> ale w sumie to moze byc nawet zaleta [10:36] <@Gynvael> przyjrzyjmy sie temu renderowaniu tla [10:36] <@Gynvael> static void [10:36] <@Gynvael> scene_render_back(void) [10:36] <@Gynvael> { [10:36] <@Gynvael> glLoadIdentity( ); [10:36] <@Gynvael> [10:36] <@Gynvael> glTranslatef(0.0f, 0.25f, -1.3); [10:36] <@Gynvael> glEnable(GL_TEXTURE_2D); [10:37] <@Gynvael> glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_SPLASH].id); [10:37] <@Gynvael> my_gl_draw_quad(0,0); [10:37] <@Gynvael> glDisable(GL_TEXTURE_2D); [10:37] <@Gynvael> } [10:37] <@Gynvael> glLoadIdentity( ) resetuje matryce koordynatow [10:37] <@Gynvael> glTranlatef ustawia przesuniecie [10:38] <@Gynvael> (blah, poczytajcie nehe.gamedev.net albo jakis kurs z http://warsztat.pac.pl i pobawcie sie tym, to zrozumiecie to) [10:38] <@Gynvael> glEnable(GL_TEXTURE_2D) wlacza texturowanie [10:38] <@Gynvael> glBindTexture ustawia ktora textura ma byc uzyta [10:38] <@Gynvael> textures[TEXTURE_SPLASH].id) [10:38] <@Gynvael> TEXTURE_SPLASH czyli to co bylo wygenerowane ze splash.tga [10:39] <@Gynvael> my_gl_draw_quad(0,0) [10:39] <@Gynvael> tam mozecie zajrzec [10:39] <@Gynvael> to funkcja ktora rysuje dokladnie jeden czworobok o srodku w podanym punkcie (czyli 0,0) [10:39] <@Gynvael> glDisable(GL_TEXTURE_2D); [10:39] <@Gynvael> } [10:39] <@Gynvael> po tym wylaczam texturowanei i koneic funkcji [10:39] <@Gynvael> z ciekawych scene_.. [10:39] <@Gynvael> zajrzyjcie do renderowania map [10:40] <@Gynvael> max = current_map.height; [10:40] <@Gynvael> if(current_map.width > max) [10:40] <@Gynvael> max = current_map.width; [10:40] <@Gynvael> max *= -2; [10:40] <@Gynvael> [10:40] <@Gynvael> ... [10:40] <@Gynvael> glTranslatef(0.0f, 0.0f, max); [10:40] <@Gynvael> dzieki temu wzorkowi "wielkosc mapy" na ekranie jest ustalana wzgledem wielkosci mapy [10:40] <@Gynvael> czyli np jesli mamy mape 10x10 to ma ona takie wymiary jak teraz na ekranie [10:40] <@Gynvael> http://gynvael.lunarii.org/temp/soko1.png [10:41] <@Gynvael> ale jesli mamy 100x100 to mapa zostanie "odsunieta" wglab ekranu, przez co i tak bedziemy widziec ja cala [10:41] <@Gynvael> tylko ze bedzie zmniejszona [10:41] <@Gynvael> ;> [10:41] <@Gynvael> nastepnie mamy najzwyklejsza w swiecie petle w petli do renderowania kazdego pola osobno [10:41] <@Gynvael> case '#': [10:41] <@Gynvael> glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_WALL].id); [10:41] <@Gynvael> my_gl_draw_quad(-current_map.width + i * 2, [10:41] <@Gynvael> current_map.height - j * 2); [10:41] <@Gynvael> break; [10:42] <@Gynvael> jak widac dla kazdego pola, zaleznie czy to # ' czy x wybieramy inna texture i ja renderujemy [10:42] <@Gynvael> koordynaty kazdego pola wyliczane sa z iteratorow petli glownie [10:42] <@Gynvael> btw w opengl srodek ekranu to 0,0 [10:42] ¯¯ Parts[#wyklady] d3a7h (~d3a7h@cqj16.neoplus.adsl.tpnet.pl)- [10:42] <@Gynvael> ok [10:42] <@Gynvael> co do scene_render_boxes [10:42] <@Gynvael> tam w petli dla kazdego pudelka jest ono rysowane [10:43] <@Gynvael> ale wczesniej jest sprawdzane czy to pudelko/kamyczek nie stoi czasem na 'x' [10:43] <@Gynvael> x = current_map.boxes[i].x; [10:43] <@Gynvael> y = current_map.boxes[i].y; [10:43] <@Gynvael> if(current_map.data[x + y * current_map.width] == 'x') [10:43] <@Gynvael> glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_STONE_HI].id); [10:43] <@Gynvael> else [10:43] <@Gynvael> glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_STONE].id); [10:43] <@Gynvael> [10:43] <@Gynvael> wybieram mu wtedy odpowiednia texturke [10:43] <@Gynvael> albo podswietlona [10:43] <@Gynvael> albo ne [10:43] <@Gynvael> i w ten sam sposob co w reszcie rysuje pole [10:43] <@Gynvael> my_gl_draw_quad(-current_map.width + x * 2, [10:43] <@Gynvael> current_map.height - y * 2); [10:44] <@Gynvael> z ciekawych rzeczy [10:44] <@Gynvael> glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); [10:44] <@Gynvael> glEnable(GL_TEXTURE_2D); [10:44] <@Gynvael> glEnable(GL_BLEND); [10:44] <@Gynvael> tam mamy glBlendFunc( ) i glEnable(GL_BLEND) [10:44] <@Gynvael> to jest wlaczenie przezroczystosci [10:44] <@Gynvael> jesli textura zostala utworzona z kanalem alpha (kanalem przezroczystosci) to moze teraz troche przeswitywac ;> [10:44] <@Gynvael> http://gynvael.lunarii.org/temp/soko1.png [10:45] <@Gynvael> tam kanal alpha (wykorzystany) maja glownie kamyczki i gracz [10:45] <@Gynvael> zauwazcie ze widac pola pod nimi [10:45] <@Gynvael> ok [10:45] <@Gynvael> rendering gracza jest bardzo podobny [10:45] <@Gynvael> tyle ze jeszcze prostszy [10:45] <@Gynvael> x = current_map.player.x; [10:45] <@Gynvael> y = current_map.player.y; [10:45] <@Gynvael> glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_USER].id); [10:45] <@Gynvael> [10:45] <@Gynvael> my_gl_draw_quad(-current_map.width + x * 2, [10:45] <@Gynvael> current_map.height - y * 2); [10:45] <@Gynvael> [10:46] <@Gynvael> jesli ktos w GL nie pisal, to proponuje mu zajrzec na nehe i troche w GLu poexperymentowac [10:46] <@Gynvael> to jest proste, ale trzeba pare rzeczy tam zrozumiec ;> [10:46] <@Gynvael> ok [10:46] <@Gynvael> tyle na temat tego co jest [10:46] <@Gynvael> teraz powiem krotko o samym algorytmie [10:46] <@Gynvael> i powrzucam wersje gry z kolejnymi etapami implementacji algorytmu [10:47] <@Gynvael> ogolnie jest tak [10:47] <@Gynvael> mamy gracza (pomaranczowa kuleczka) [10:47] <@Gynvael> w momencie kiedy player nacisnie na klawiaturze jakas strzalke [10:47] <@Gynvael> to ta kuleczka powinna sie ruszyc na pole wyzej, nizej, po prawej badz po lewej [10:47] <@Gynvael> to jest teraz zrobione [10:47] <@Gynvael> jednak jest pare zasad [10:48] <@Gynvael> mianowicie [10:48] <@Gynvael> jesli gracz chcial by sie ruszyc na sciane [10:48] <@Gynvael> to nie mozna mu na to pozwolic [10:48] <@Gynvael> void [10:48] <@Gynvael> player_move(int x, int y) [10:48] <@Gynvael> { [10:48] <@Gynvael> /* tutaj trzeba pogrzebac */ [10:48] <@Gynvael> current_map.player.x += x; [10:48] <@Gynvael> current_map.player.y += y; [10:48] <@Gynvael> } [10:48] <@Gynvael> to jest obecna postac player_move [10:48] <@Gynvael> narazie uniemozliwmy mu poruszanie sie po murkach [10:49] <@Gynvael> najlepiej jest utworzyc dwie zmienne [10:49] <@Gynvael> new_x i new_y [10:49] <@Gynvael> i zapisac do nich current_map.player.x + x i analogicznie y [10:50] <@Gynvael> majac cos takiego mozemy sprawdzic czy na mapie w miejscu new_x i new_y jest moze murek [10:50] <@Gynvael> if(current_map.data[new_x + new_y * current_map.width] == '#') [10:50] <@Gynvael> jezeli tak jest, wychodzimy z funkcji [10:50] <@Gynvael> w innym wypadku zapisujemy new_x i new_y do current_map.player.... [10:51] <@Gynvael> current_map.player.x = new_x; [10:51] <@Gynvael> current_map.player.y = new_y; [10:52] <@Gynvael> http://gynvael.lunarii.org/temp/soko2.zip [10:52] <@Gynvael> e w8 [10:52] <@Gynvael> current_map.player.x = new_x; [10:52] <@Gynvael> current_map.player.y = new_y; [10:52] <@Gynvael> eh [10:52] <@Gynvael> http://gynvael.lunarii.org/temp/soko2.zip [10:52] <@Gynvael> ok [10:52] <@Gynvael> teraz [10:52] <@Gynvael> teraz gracz juz nie moze wchodzic na murki [10:53] <@Gynvael> teraz troche inna zabaa [10:53] <@Gynvael> *zabawa [10:54] <@Gynvael> ok [10:54] <@Gynvael> kolejna sprawa [10:54] <@Gynvael> jesli gracz bedzie chcial najsc na skrzynke [10:54] <@Gynvael> to: [10:54] <@Gynvael> trzeba sprawdzic za skrzynka w danym kierunku jest sciana badz inna skrzynka [10:54] <@Gynvael> (Tzn kamien w nasyzm wypadku) [10:54] <@Gynvael> jesli tak, to nie nalezy graczowi pozwolic na ruch [10:54] <@Gynvael> w innym wypadku... [10:55] <@Gynvael> nalezy przesunac skrzynke dalej [10:55] <@Gynvael> i gracza [10:55] <@Gynvael> jak sprawdzic czy jest skrzynka tam.. [10:55] <@Gynvael> trzeba po prostu zrobic fora [10:55] <@Gynvael> wprowadzmy sobie jakies int i; [10:56] <@Gynvael> oraz jakas flage z numerem skrzynki [10:56] <@Gynvael> np int numer_skrzyni = -1 [10:56] <@Gynvael> for(i = 0; i < current_map.box_count; i++) [10:56] <@Gynvael> { [10:56] <@Gynvael> if(current_map.boxes[i].x == new_x || [10:56] <@Gynvael> current_map.boxes[i].y == new_y) [10:56] <@Gynvael> { [10:56] <@Gynvael> numer_skrzyni = i; [10:56] <@Gynvael> break; [10:56] <@Gynvael> } [10:56] <@Gynvael> } [10:57] ¯¯ Joins[#wyklady] crgh0st (1000@Bot.Underground) [10:57] <@Gynvael> czyli to sprawdzi po kolei czy kazda skrzynka jest na nowej pozycji gracza [10:57] <@Gynvael> jesli ktoras tak, to break'nie ;> [10:57] <@Gynvael> teraz jezeli znaleziono skrzynie [10:57] <@Gynvael> if(numer_skrzyni != -1) [10:57] <@Gynvael> { [10:57] <@Gynvael> to musimy sprawdzic czy za nia jest sciana czy nie [10:58] <@Gynvael> jezeli jest, to wychodzimy [10:58] <@Gynvael> jak otrzymac koordynaty pola po skrzyni ? [10:58] <@Gynvael> po prostu do new_x dodajmy na chwile x a do new_y y ;> [10:58] <@Gynvael> if(current_map.data[(new_x + x) + (new_y + y) * current_map.width] == '#') [10:58] <@Gynvael> return; [10:58] <@Gynvael> trzeba jeszcze sprawdzic czy nie ma tam innej skrzyni [10:59] <@Gynvael> mozemy uzyc tego fora z gory [10:59] <@Gynvael> ale najlepiej by bylo zebysmy go do funkcji wrzucili [11:01] <@Gynvael> niech to bedzie get_box(int x, int y) [11:01] <@Gynvael> i niech to zwraca numer skrzyni/kamienia/co tam w naszej grze przestawiamy [11:01] <@Gynvael> btw na privie mi mowia [11:01] <@Gynvael> zebym powiedzial ze ludek jest za slaby zeby dwie skrzynie przestawic ;> [11:01] <@Gynvael> ano jest [11:01] <@Gynvael> ;> [11:02] <@Gynvael> w kolejce stal po rozum a nie po miesnie.. [11:02] <@Gynvael> coz.. a skonczyl w dziwnym magazynie --; sorry [11:02] <@d0ubl3_j> cza zakupic stronga?;o [11:02] <@Gynvael> if(box_id(new_x + x, new_y + y) != -1) [11:02] <@Gynvael> return; [11:02] <@Gynvael> tak bedzie wygladac sprawdzenie czy nie ma skrzyni za ta ktora przestawiamy [11:02] <@Gynvael> jesli nie wyjdzie w obu ifach [11:02] <@Gynvael> to trzeba ta skrzynei przesunac [11:02] ¯¯ Parts[#wyklady] Rafal_F (~mega05@195.116.95.162)- [11:03] <@Gynvael> current_map.boxes[box_id].x += x; [11:03] <@Gynvael> current_map.boxes[box_id].y += y; [11:03] <@Gynvael> tam wczesniej ofc if(get_box(new_x + x, new_y + y) != -1) [11:03] <@Gynvael> return; [11:04] ¯¯ Joins[#wyklady] Pabox (~pawelmc@cnp42.neoplus.adsl.tpnet.pl) [11:04] <@Gynvael> eh [11:04] <@Gynvael> i jeszcze jeden blad zrobilem [11:04] <@Gynvael> -=225736=- if(current_map.boxes[i].x == new_x || [11:04] <@Gynvael> -=225736=- current_map.boxes[i].y == new_y) [11:04] <@Gynvael> tam ma byc && oczywiscie [11:04] <@Gynvael> oba koordynaty musza byc rowne [11:06] <@Gynvael> http://gynvael.lunarii.org/temp/soko3.zip [11:06] <@Gynvael> jak widac teraz mozna juz skrzynki przepychac etc [11:07] <@Gynvael> http://gynvael.lunarii.org/temp/soko3.png <=- [11:07] <@Gynvael> -=230747=- przepycha to sie rury od kanalizacji ;p [11:07] <@Gynvael> -=230753=- a skrzynki sie przesoowa :p [11:08] <@Gynvael> wiec oznajmiam ze caly wyklad PRZESOOWALISMY skrzynki [11:08] <@Gynvael> a nie przepychalismy [11:08] <@Gynvael> ;p [11:08] <@Gynvael> ok [11:08] <@Gynvael> teraz do zrobienia zostalo jeszcze pare rzeczy [11:08] <@Gynvael> jako ze sa bardzo proste to nie bede ich dokladnie tlumaczyl [11:08] <@Gynvael> 1) wygranie i zmiana levelu [11:09] <@Gynvael> gracz wygrywa kiedy wszystkie skrzynki sa na niezielono ;> czyli trzeba sprawdzic, np po kazdym przesunieciu SKRZYNKI [11:09] <@Gynvael> czy wszystkei skrzynie sa na 'x' [11:09] <@Gynvael> jesli tak, good work, zmiena planszy [11:09] ¯¯ Parts[#wyklady] Pabox (~pawelmc@cnp42.neoplus.adsl.tpnet.pl)- [11:09] <@Gynvael> 2) w sokobanie zazwyczaj daje sie mozliwosc cofniecia sytuacji na planszy o jeden krok, rowniez wypadalo by to zrobic [11:10] <@Gynvael> 3) warto by rowniez zrobic restartowanie levelu na ktoryms klawiszu, np na enterze ;> [11:11] <@Gynvael> ok [11:11] <@Gynvael> pytanka ? zaraz wrzuce na serv wersje z 1) i 3) [11:11] ¯¯ Modes[#wyklady] Gynvael (-m) [11:12] <^Klocek> osz w morde [11:12] <^Klocek> juz 23 [11:12] juz ? a co spac musisz isc ;p [11:12] <^Klocek> zazwyczaj filmy ogladam [11:12] <^Klocek> o tej godzinie ;p [11:12] :) [11:13] uff [11:13] Gynvael: dosac dokladnie opoisales all ;p [11:13] dosc* [11:14] <@Gynvael> ;> [11:14] <@Gynvael> hmm [11:14] pytanie dot kompilacji, co robi -lGlu? bo nie mo¿e tego u mnie znale¼æ [11:14] <@Gynvael> czyli pytanek brak ? [11:14] -lglu32 [11:14] -lopengl32 [11:14] -lSDL [11:14] <@Gynvael> Prus -lGLU pod linuxem dodaje liba GLU [11:14] tak sie kompilowac powinno ;f [11:14] przynajmnie jmi tak dziala ;p [11:14] <@Gynvael> pod winda powinno sie dac -lglu32 [11:15] ok [11:15] no wlasnie, pod winda ;p [11:15] hmm a ta bliblioteka jest sk±d? :) [11:15] GLU [11:15] <@phoenix_> jutro sie za to wezme dzisiaj nie mam sily [11:15] z katawni ;p [11:15] jutro to bedzie futro ;) [11:16] <@d0ubl3_j> futer juz spi pewnie [11:17] <@phoenix_> albo w niedziele [11:17] <@phoenix_> kurwa [11:17] <@phoenix_> czasu mi brakuje [11:17] <@phoenix_> dzisiaj mam jeszcze sprawozdanie napisac [11:18] <@d0ubl3_j> phoenix_: z czego? [11:18] <@phoenix_> z byle czego [11:18] <@d0ubl3_j> o [11:18] <@Gynvael> Prus twoj kompilator powinien byc w nia wyposarzony [11:18] <@phoenix_> ma byc i tyle ;////////// [11:18] <@d0ubl3_j> to ja ci napisze :p [11:18] ¯¯ Modes[#wyklady] Gynvael (+m) [11:18] <@phoenix_> napisz [11:18] <@d0ubl3_j> ok [11:18] <@Gynvael> http://gynvael.lunarii.org/temp/soko4.zip [11:18] <@d0ubl3_j> na ile? [11:18] <@Gynvael> wersja ze wszystkim [11:18] <@Gynvael> ok [11:18] <@d0ubl3_j> sorx [11:18] <@phoenix_> d0ubl3_j: priv [11:18] <@Gynvael> mniej wiecej tyle na dzisiaj ;> pozno sie zrobilo [11:18] <@Gynvael> komentarze dot wykladu prosze na priva ;> [11:18] <@Gynvael> jesli ktos byl by chetny prowadzic o jakiejs grze za tydzien [11:19] <@Gynvael> to tez na priva do mnie albo do phoenix_'a [11:19] <@Gynvael> ja ze swojej strony powien ze za jakies poltora miesiac planuje wyklad na temat "dobajerowania" gierek ;> [11:19] <@Gynvael> ok [11:19] <@Gynvael> tyle [11:19] <@Gynvael> thx za sluchanie [11:19] <@Gynvael> ;> [11:19] ¯¯ Modes[#wyklady] Gynvael (-m)