Hubis Opublikowano 26 Grudnia 2009 Zgłoś Opublikowano 26 Grudnia 2009 (edytowane) Ponieważ na zakończenie liceum mam prace całoroczną w C++, zakładam ten topic. Po co ? Aby uporządkować swoje myśli, zmotywować się do pracy i oczywiście spotkać się z liczną krytyką. Na bieżąco będę się starał aktualizować postępy nad pracą. Każdy z naszej grupy mógł wymyślić własny temat. Ja zdecydowałem się na grę typu Mario, większość nesowych gierek tak wyglądała. Proszę się nie spodziewać nie wiadomo czego. Gra będzie czarno biała, i używała do sterowania okna konsolowego. A do wyświetlania drugiego graficznego. Zakładam interakcje z podłożem (wow ludzik będzie stał), ruchy w 3 kierunkach i najważniejsze przesuwanie ekranu w prawo po "mapie" zapisanej w pliku tekstowym. "Mapa" będzie to tablica z 2-ma współrzędnymi które posłużą do rysowania linii. Programy: Dev C++; Biblioteka graficzna allegro; Sterowanie: Esc, Lewo, prawo, góra, dół, F12 = pełny ekran->okno, F12 = okno->pełny ekran To tyle co do wstępu. A teraz etap pierwszy który mam zamiar zrealizować: 1[27.12.2009] cele: -Otwarcie okna graficznego(jeszcze nie wiem jak, potrafiłem to robić kiedyś w borlandzie 3.11), -Wyrysowanie linii na podstawie współrzędnych zapisanych w tablicy(muszę znaleźć funkcję na rysowanie linii). dodatki: -Stworzenie klasy gra, -Rysowanie kolorowych prostych obiektów, -Mapa oparta na trójkątach, -Pobieranie współrzędnych z pliku mapa.txt. edit1:[20:05] Pobieram bibliotekę allegro do trybu graficznego. Rozumiem, że dzięki niej będę mógł zainicjalizować tryb graficzny i rysować linie. edit2:[20:30] Pobrałem, udało mi się użyć funkcji takich jak line rectangle text. Teraz realizuje mój plan = wyrysowanie linii na podstawie współrzędnych zapisanych w tablicy. edit3:[21:39] Ziemie, platformy i inne elementy nie będę rysował za pomocą linii tylko za pomocą trójkątów. To powinno mi pozwolić na uzyskanie większości kształtów. Udało mi się stworzyć tablicę na 3 współrzędne trójkąta i napisać pętlę na jej zerowanie zeruj();. Stworzyłem klasę gra. edit4:[22:04] Pierwszy Error po zamknięciu aplikacji ;/. Dodałem funkcję rysuj(); na rysowanie "mapy" na ekranie. //[22:27]Przerwa na cs'a ;) //[23:20]Wracam do pracy ;) edit5:[23:48] Stworzyłem funkcję czytaj(ifstream& WePl); która pobiera z pliku mapa.txt 6 współrzędnych a następnie zapisuje je do tablicy mapa[j][1,2,3,4,5,6]. Error napriawiony, wynikał z przepełnienia tablicy. Etap pierwszy zakończony ;). ------------------------------------------------------------------------------------------------------------------------------------------------ 2[27.12.2009] cele: -stworzenie współrzędnych aktualnie widocznego ekranu, [04:07]done -przesuwanie obiektów mapy w zależności od współrzędnych ekranu. [04:07]done -rozbudowa współrzędnych ekranu do pola ekranu, [04:07]done -rysowanie tylko tych obiektów które zawierają się w polu ekranu. [04:07]nie będzie dodatki: -stworzenie ludzika, -nałożenie obrazka na ludzika, -ruchy ludzika, -ograniczenie ruchów ludzika, -double buffering wooot!. -drugi etap zakończony. 3[28.12.2009] cele: -uporządkowanie kodu, mam już niezły burdel, [16:36]done -ludzik dochodząc do prawej strony przesuwa mapę. [16:36]done -rozbudować mapę, -dodać tło w formie obrazka, [16:36]done dodatki: -ograniczenie skoku do zużycia zmiennej skok=80; -program działa z taką samą prędkością na każdym pc. edit1:[17:05] Dla oderwania się od nudnego programowania zrobiłem sobie ikonę mario.ico. edit2:[20:05] Zmagałem się z tym, że gra pracowała bardzo wolno. Udało mi się ustalić stałą prędkość dla programu 250. (chyba) Oznacza to, że aplikacja pracuje z prędkością 250 kl/s. Powinno to zaowocować tym, że na większości komputerów będzie działać z taką samą prędkością. Gra działa płynnie. Etap 3 zakończony. 4[28.12.2009] cele: -kolizje, czyli dotykanie elementów mapy przez ludzika. [21:15]done -if(kolizja) nie zmieniaj ludziky. [21:15]done dodatkowe: -ludzik "wchodzi" w górę na pochyłościach, edit1:[21:17] Kolizję sprawdzam za pomocą funkcji getpixel(bufor,roland.ludzikx+15,roland.ludziky+50). Jeżeli pojawi się kolor inny niż biały oznacza to, że obiekt koliduje = ludzik ma przestać spadać. Jeżeli ludzik napotka po swojej prawej obiekt wyżej położony zwiększa swoją wysokość o 1. Przydałby mi się prosty mapmaker który tworzyłby trójkąty i zapisywałby jest do pliku .txt. 5[29.12.2009] edit1:[21:17] -Odkryłem bardzo fajną rzecz w mojej metodzie sprawdzania kolizji. Ponieważ bazuje na kolorach innych od białego, każdy obiekt który ma jakiś kolor jest przeszkodą. Co daje mi bardzo prostą metodę rysowania mapy = paint i biały pędzel. W downloadzie (załącznik) dostępny jest przykładowy obrazek w ten sposób obrobiony. -Ponieważ pliki bmp są stosunkowo duże = obrazek 640x480px zajmuje ~1MB muszę dodać opcję używania plików .JPG. Na teraz pracuje nad dopracowaniem kolizji, żeby nie można było wchodzić w skałę. Postaram się do tego użyć rekurencji. edit2:[0:51] Postanowiłem dodać możliwość chodzenia w lewo i przesuwania mapy w lewo. Kolizje nadal nie poprawione ;/. edit3:[1:30] Ciągle unikam kolizji ;p. edit4:[2:12] -Kolizje bez zmian. Natomiast dodałem prostą animację, poprawiłem trochę kodu z mapy. -Cały czas piszę grę tak aby można było załadować do niej dowolną mapę + dowolne obiekty (kiedyś może złe stwory ; ) Z rana zajmę się kolizjami, i zaplanuje jak będzie wczytywany ciąg obrazków tworzących mapę. Do tego potrzebne będzie dodanie biblioteki umożliwiającej wczytywanie plików .jpg. Czyli mam plan na jutro :). [29.12.2009][00:56] #include <allegro.h>#include <conio.h>#include <fstream>using namespace std;volatile long speed = 0;void increment_speed(){ speed++;} END_OF_FUNCTION(increment_speed); LOCK_VARIABLE(speed);LOCK_FUNCTION(increment_speed); class gra { public: //zmienne int mapa[10][6]; int ekranx, ekrany, ludzikx, ludziky, p1, p2, skok, mapax, mapay, res, a; BITMAP *niebo; BITMAP *niebo2; BITMAP *bufor; BITMAP *ludek; BITMAP *ludekb; //funkcjie void init(); void deinit(); int initbitmap(); void deinitbitmap(); void zeruj(); int ekran(); void czytaj (ifstream& WePl); void kolizje(); void fullscreen(); void przesuniecie(); void przesuniecie2(); void przesuniecie3(); void rysuj(); void ludzik(); void sterowanie(); private: };//inizjalizowanie trybu graficznegovoid gra::init() { int depth, res; allegro_init(); depth = desktop_color_depth(); if (depth == 0) depth = 32; set_color_depth(depth); res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); clear_to_color(screen, makecol(255,255,255)); if (res != 0) { allegro_message(allegro_error); exit(-1); } install_timer(); install_int_ex(increment_speed, BPS_TO_TIMER(250)); install_keyboard(); install_mouse(); /* add other initializations here */}//usuwanie trybu graficznegovoid gra::deinit() { clear_keybuf(); /* add other deinitializations here */}//inicjalizowanie bitmapint gra::initbitmap(){ /*BITMAP *niebo = NULL; BITMAP *niebo2 = NULL; BITMAP *bufor = NULL; BITMAP *ludek = NULL; BITMAP *ludekb = NULL;*/ bufor = create_bitmap(800,600); if (!bufor) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("Nie mogę utworzyć bufora !"); allegro_exit(); return 0; } ludek = load_bmp("ludek.bmp",default_palette); if (!ludek) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("nie mogę załadować obrazka Ludek !"); allegro_exit(); return 0; } ludekb = load_bmp("ludekb.bmp",default_palette); if (!ludek) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("nie mogę załadować obrazka Ludek !"); allegro_exit(); return 0; } niebo = load_bmp("niebo.bmp",default_palette); if (!ludek) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("nie mogę załadować obrazka Ludek !"); allegro_exit(); return 0; } niebo2 = load_bmp("niebo2.bmp",default_palette); if (!ludek) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("nie mogę załadować obrazka Ludek !"); allegro_exit(); return 0; } } //usuwanie bitmapvoid gra::deinitbitmap(){ remove_int(increment_speed); destroy_bitmap(bufor); destroy_bitmap(ludek); destroy_bitmap(niebo); destroy_bitmap(niebo2); } //zerowanie tablicy z 'i' czesciami mapyvoid gra::zeruj(){ for(int i=0;i<=9;i++){ mapa[i][1]=0; mapa[i][2]=0; mapa[i][3]=0; mapa[i][4]=0; mapa[i][5]=0; mapa[i][6]=0; }}//ekranint gra::ekran(){ ekranx=0; ekrany=0; mapax=0; mapay=0; a=0; ludzikx=100; ludziky=20; p1=0; p2=0; skok=0; res=0;} //przesuniecie ludzika void gra::przesuniecie(){ ludzikx+=p1; ludziky+=p2; }//przesuniecie mapy w prawo void gra::przesuniecie2(){ mapax+=ekranx; mapay+=ekrany; /* for(int j=0;j<=10;j++){ mapa[j][1]+=ekranx; mapa[j][3]+=ekranx; mapa[j][5]+=ekranx; mapa[j][2]+=ekrany; mapa[j][4]+=ekrany; mapa[j][6]+=ekrany;}*/ }//przesuniecie mapy w lewo void gra::przesuniecie3(){ mapax+=ekranx; mapay+=ekrany; /* for(int j=0;j<=10;j++){ mapa[j][1]+=ekranx; mapa[j][3]+=ekranx; mapa[j][5]+=ekranx; mapa[j][2]+=ekrany; mapa[j][4]+=ekrany; mapa[j][6]+=ekrany;}*/ } //zczytywanie wspl mapy z pliku i zapisywanie ich do tablicy mapavoid gra::czytaj(ifstream& WePl){ int j=0; while(WePl>>mapa[j][1]>>mapa[j][2]>>mapa[j][3]>>mapa[j][4]>>mapa[j][5]>>mapa[j][6]){j++;} }//Sprawdzanie kolizjiivoid gra::kolizje(){ clear_to_color(bufor, makecol(255,255,255)); blit( niebo2, bufor, 0,0, mapax+800, mapay, niebo->w, niebo->h); blit( niebo2, bufor, 0,0, mapax, mapay, niebo->w, niebo->h); /* for(int j=0;j<=9;j) { triangle(bufor, roland.mapa[j][1],roland.mapa[j][2], roland.mapa[j][3],roland.mapa[j][4], roland.mapa[j][5],roland.mapa[j][6],makecol(100,100,100)); j++;}*/ if(ludziky>429&&ludzikx!=710) {skok=90;} if(getpixel(bufor,ludzikx+15,ludziky+50)!=getpixel(bufor,2,2)) {skok=90;} if(getpixel(bufor,ludzikx+16,ludziky+50)!=getpixel(bufor,2,2)) {ludziky--;} if(ludziky<430&&getpixel(bufor,ludzikx+15,ludziky+50)==getpixel(bufor,2,2)) {ludziky+=1;} blit( niebo, bufor, 0,0, mapax+800, mapay, niebo->w, niebo->h); }//pelny ekranvoid gra::fullscreen(){ if(key[KEY_F12]&&res==0) { set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 800, 600, 0, 0); res=1;} if(key[KEY_F12]&&res==1) { set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); res=0;} }//rysowanie 'i'czesci mapyvoid gra::rysuj(){ //tło aplikacjii/* for(int j=0;j<=1;j){ triangle(screen, mapa[j][1],mapa[j][2], mapa[j][3],mapa[j][4], mapa[j][5],mapa[j][6],makecol(40,40,100)); j++;}*/ rectfill(bufor, 0, 480, 800, 600, makecol(80,80,80)); rectfill(bufor, 0, 510, 250, 600, makecol(128,128,50)); line( bufor,0,480,800,480, makecol(200,200,200)); textout_ex(bufor,font,"Sterowanko:",20,520 ,makecol(255,255,255),-1); textout_ex(bufor,font,"UP DOWN RIGHT LEFT ESC F12",20,530 ,makecol(255,255,255),-1); textout_ex(bufor,font,"WERSJA: 0.005",20,550 ,makecol(255,255,255),-1); blit( bufor, screen, 0,0,0,0, 800,600); }//ludzikvoid gra::ludzik(){ if(ludziky<310&&getpixel(bufor,ludzikx+15,ludziky+51)==getpixel(bufor,2,2)) {a=0;} else {a=1;} if(a==0) {masked_blit( ludekb, bufor, 0,0, ludzikx, ludziky, ludek->w, ludek->h);} else {masked_blit( ludek, bufor, 0,0, ludzikx, ludziky, ludek->w, ludek->h);} //rectfill(screen, ludzikx, ludziky, ludzikx+30, ludziky+50, makecol(128,128,200));}//sterowanievoid gra::sterowanie(){ if(key[KEY_RIGHT]&&ludzikx<710) {p1=1;} if(key[KEY_LEFT]&&ludzikx>50&&mapax<=0) {p1=-1;} if(key[KEY_LEFT]&&ludzikx>0&&mapax==0) {p1=-1;} if(key[KEY_UP]&&skok>0) {skok-=1; p2=-2;} /*if(key[KEY_DOWN]&&ludziky>360) {p2=5;}*/ if(key[KEY_RIGHT]&&ludzikx==710) {ekranx=-1; //ludziky++; if(ludziky>429) {skok=90;}} if(key[KEY_LEFT]&&ludzikx==50&&mapax<0) {ekranx=1; //ludziky++; if(ludziky>429) {skok=90;} //roland.ludzikx+=1; roland.ludzikx+=3; } }int main() {//================================================================================================================ gra roland; roland.init(); roland.initbitmap(); //przygotowanie zmiennych dla gry roland.zeruj(); roland.ekran(); ifstream mapaplik("mapa.txt",ios::in); roland.czytaj(mapaplik); ifstream close; //================================================================================================================ //petla gry while (!key[KEY_ESC]) { while( speed > 0){ roland.kolizje(); roland.sterowanie(); roland.przesuniecie(); roland.przesuniecie2(); roland.ludzik(); roland.rysuj(); //zerowanie roland.p1=0; roland.p2=0; roland.ekranx=0; roland.ekrany=0; speed--;} } //================================================================================================================ roland.deinit(); roland.deinitbitmap(); return 0;}END_OF_MAIN() [29.12.2009][02:23] Działający program wraz z mapa i grafika. 1.5 MB http://www.speedyshare.com/files/20028416/ludek.zip Pobrań: 11 WOOT! :wub: ! Edytowane 29 Grudnia 2009 przez Hubis Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
p3dzi0r Opublikowano 29 Grudnia 2009 Zgłoś Opublikowano 29 Grudnia 2009 Niech ten ludzik sie obraca w ktora strone idzie a nie robi moonwalka ;] , mozesz pomyslec o animowanym czyli niech sobie drepcze. PS co to za szczecinskie liceum ktore widze w miare dobrze tlumaczy c++ ? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Hubis Opublikowano 29 Grudnia 2009 Zgłoś Opublikowano 29 Grudnia 2009 Jeszcze nie wiem jak robić taką grafikę małego ludzika. Dobra, jedną pozę potrafię narysować. Ale jak zrobić proste animacje chodzenia nie mam pojęcia. A liceum to lo9 w szczecinie ;). Informatyka stoi nawet na dużo lepszym poziomie, tylko ja jestem leniwy ;). Parę rzeczy się zapomniało np. przekazywanie zmiennych do funkcji (przez wartość i przez coś tam ;d) . I teraz nie wiem jak z maina przekazać np. bitmapę "bufor" do klasy gra. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
ULLISSES Opublikowano 29 Grudnia 2009 Zgłoś Opublikowano 29 Grudnia 2009 Przy podskoku zmieniasz grafikę na inną. Podobnie robisz z chodzeniem. Jak ludzik się porusza w prawo, to 2-3 zmieniające się cyklicznie (200ms?) grafiki z głową w prawo. Analogicznie dla ruchu w lewo. Przekazywanie przez wskaźniki. Masz jakąś książkę? Symfonia by nie zawadziła. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
p3dzi0r Opublikowano 29 Grudnia 2009 Zgłoś Opublikowano 29 Grudnia 2009 To chyba nie z jacorzynskim ta infa bo on to tylko html'e umie robic :lol: Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Hubis Opublikowano 29 Grudnia 2009 Zgłoś Opublikowano 29 Grudnia 2009 (edytowane) A no tak wskaźniki. Gdzieś mam do tego notatki a4 z lekcji. Na książkę mnie chwilowo nie stać. Rozwiązałem to w prostszy sposób: bitmapy inicjalizuje jako funkcje w klasie gra. Czyli w końcu mogę sobie zrobić porządek w całym kodzie. ;) Kolega się zaoferował zrobić grafikę, zobaczymy jak mu pójdzie ;). edit: To chyba nie z jacorzynskim ta infa bo on to tylko html'e umie robic :lol2: Nie mogę tego ogarnąć: `bufor' undeclared (first use this function) // Czy mogę się jakoś odwołać w funkcji gra::kolizje() : clear_to_color(bufor, makecol(255,255,255)); jako do bufor z funkcji gra::initbitmap() BITMAP *bufor = NULL; bufor = create_bitmap(800,600); Edit2: Ogarnąlem tak że w public: jest napisane: BITMAP *bufor; Nie wiem czy brak = NULL; czegoś nie zepsuje... ;/ Edytowane 29 Grudnia 2009 przez Hubis Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
ULLISSES Opublikowano 29 Grudnia 2009 Zgłoś Opublikowano 29 Grudnia 2009 Z C++ to już niewiele pamiętam. Allegro tym bardziej nie używałem, ale... Chyba można przywalić z grubej rury - zamiast definiować bufor wewnątrz initbitmap, to zrobić z niej zmienną dla całej klasy. Poniższą linijkę wywalasz poza funkcję: bufor = create_bitmap(800,600); Edit: W sumie tak też można. Jednak wtedy musisz pozostawić create_bitmat(800,600) w initbitmap. To co wywaliłeś wyżej określa jedynie, że bufor to bitmapa. Dopiero 'create_bitmat(800,600) nadaje jej jakąś wartość. NULL nie jest potrzebny. Zajrzyj tutaj: http://www.egrafik.pl/kurs-c-plus-plus/6.2.php Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...