Data: 2008-01-12 14:28:36
dudek | [Allegro, C++] Prosta gra wyścigowa
Mimo, ze C++ ucze sie bardzo krotko postanowilem napisac cos sensownego zeby sprawdzic swoja aktualna wiedze i czy moge juz ja do czegos wykorzystac. W kursie na ddt nie doszedlem do polowy zas podstawy programowania obiektowego poznalem w innym kursie. Dlatego, ze jestem swiezym "programistom" C++ moj kod moze byc zagmatwany, nieciekawy i nieelegancki i nie zdziwie sie jak za jakis czas sam nie wiele bede rozumial z niego :D Sam kod troche mi sie pogmatwal kiedy w trakcie pisania juz zaprojektowanej aplikacji pojawily sie problemy, ktore wynikaly z braku wiedzy o samej C++, skladni itp. Wtedy musialem wszystko pozmieniac, zalozenia, funkcje itd. Wiedze o bibliotece allgro czerpalem z internetu i dokumentacji. Do skompilowania tego programu oczywiscie potrzeba miec zainstalowana biblitoeke allegro. Jesli komus "ze starszych" programistow bedzie chcialo sie wnikac w ten kod moglby ocenic profesjonalniejszym okiem. Gra, ktora postanowilem przeniesc to wyscigi i chyba kazdy mial taka mala badziewiasta konsolke, na ktorej byly tetrisy itp, tam tez byla taka gra wyscigi ktora zawsze lubilem:P Zadanie:Napisac prosta gierke uzywajac biblioteki allegro. Ma jak najbardziej przypominac oryginal. Kod podzielic na moduly. Gierka polega na omijaniu pozostalych samochodow podczas wyscigu. W mojej grze steruje klawiszami : A - lewo, D - prawo , Q - przyspieszaj , E - zwalniaj Do zrobienia:Wprowadzic ilosc zyc, poziom trudnosci i punktacje zalezaca od poziomu trudnosci. I jak beda czas i checi zrobic wieksza aplikacje zawierajaca wiecej gierek przenionych z tych konsolek. [EDIT #1] Dzis 14.01.2008 dodalem punktacje oraz okienkowe powiadamianie gracza. Na poczatku o controlsach a na koncu o ilosci zdobytych punktow. [EDIT #2] Dodalem zycie.Zupelnie inaczej niz w oryginale zamiast ilosc zyc jest wytrzymalosc samochodu ktora sie zmniejsza z kazdym przejechaniem po przeciwniku:) oraz dodalem jeden bajer. Kodu zrodlowego nie zmieniam gdyz to sa zmiany kosmetyczne. Projekt do pobraniaCalosc mozna sciagnac pod tym linkiem i zobaczyc czyms sie rozni od tego co podalem na forum. http://tiny.pl/p2h6 | Data: 2008-01-12 14:30:44
dudek | Plik naglowkowy "game.h"
// Typy wyliczeniowe
enum GAMESTATE { GS_NOTSTARTED, GS_MOVE, GS_LOSE, GS_ERROR, GS_EXIT }; /* zawiera informacje o aktualnym stanie gry */
// extern GAMESTATE GS_GameState; extern BITMAP* bufor;
//stale
const int ENEMY_DISTANCE = 50; // Domyslna odleglosc przeciwnkow od siebie, minimalnie 40 gdyz inaczej zainstniala by sytuacja // w ktorej gracz nie moglby przecisnac sie pomiedzy przeciwnikami const int ENEMY_NUMBER = 3; // liczba przeciwnikow const int LINE_NUMBER = 5; // liczba band po jednej stronie /* Ustawilem stale tych parametrow zeby np w przypadku zwiekszenia obszaru jazdy szybko moc dostosowac liczbe przeciwnikow i band*/ const short R = 0; // Kolor obiektow R const short G = 0 ; // jw. G const short B = 0; // jw. B const short BG_R = 255; // Kolor tla R const short BG_G = 255; // Kolor tla G const short BG_B = 255; // Kolor tla B
/* wszystkie te stale wprowadzilem po to zeby mozna bylo sprawnie operowac programem z poziomu pliku naglowkowego*/
// ** KLASY
class cField // klasa band { public: int x,y, i; // x,y wspolrzedne band, i licznik bool set_up_line_left(); bool set_up_line_right(); void draw_all(); void draw_line(); bool Check_Conflict(); };
class cCar // klasa samochodow { public: int x, y, ex,ey, i; /* x,y wspolrzedne gracza, ex i ey wspolrzedne przeciwnika(pomocnicze), i licznik */ void draw_Player(); void draw_Enemy(); void draw_car(); bool set_up_player(); bool set_up_enemy(); void Take_Side(); bool Check_Conflict(); };
// **PROTOTYPY FUNKCJI**
// inicjalizacja allegro void init(); // funkcja inicjalizujaca biblioteke allegro void deinit(); // funkcja deinicjalizujaca biblioteke allegro int create_bufor(); // utworzenie bufora obrazu
// ******* EDIT 14.01.2008 ******
void square(int, int, int); void square_bg(int, int, int); // prototypy funkcji ktore juz istnialy a zapomnialem ich dodac long point_count(short); // nowa funkcja wyliczajaca wynik gracza na podstawie predkosci jaka jedzie. // ******* /EDIT ****************
| Data: 2008-01-12 14:38:09
dudek | modul inicjalizujacy allegro (dowolna nazwa pliku z rozszerzeniem *.cpp)
#include <allegro.h> #include "game.h"
BITMAP* bufor = NULL; /* utworzenie bufora ekranu. Dla tych ktorzy nie mieli jeszcze z tym doczynienia powiem na czym to polega. Pamiec RAM komputera jest znacznie szybsza od pamieci karty graficznej. Dlatego zamiast rysowac wszystko w pamieci karty graf. lepiej narysowac to w pamieci RAM i przeniesc to do pamieci karty graficznej. Tak jest znacznie szybciej. I bufor bedzie wlasnie takim zapasowym ekranem na ktorym bede wszystko rysowal potem przenosil. Bufor bedzie innego rozmiaru niz ekran widoczny dla gracza ale otym nizej*/
void 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, 200, 200, 0,0); if (res != 0) { allegro_message(allegro_error); exit(-1); } /* rozdzielczosc widoczna ekranu ustawiona zostala 200 na 200. Sama gra toczyc sie bedzie na obszarze 100 na 200. Dodatkowe 100 zarezerwowalem na rzeczy do zrobienia jak punktacje i licznik zyc. */
install_timer(); install_keyboard(); install_mouse();
}
void deinit() { clear_keybuf(); destroy_bitmap(bufor);
}
int create_bufor() { bufor = create_bitmap_ex(32, 200, 400); /* utworzenie bufora wraz z awaryjna wiadomoscia w przypadku niepowodzenia. Czemu bufor jest dluzszy o 200 pikseli? Poniewaz ta gra wymaga zeby samochody wyjezdzaly z poza ekranu. Bufor ustawiam tak zeby 100 pikseli powedrowalo ponad gorna granice i drugie 100 dolna (to wszystko w glownym module gry). Tak rozwiazalem sprawe wchodzacych w ekran i wychodzacych z ekranu samochodzikow i band. */
if (!bufor) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("Nie moge utworzyc bufora"); allegro_exit(); return(0); } };
| Data: 2008-01-12 14:39:51
dudek | modul game.cpp , zawiera wszystkie najwazniejsze funkcje i metody
#include <allegro.h> #include "game.h"
GAMESTATE GS_GameState = GS_NOTSTARTED; // stan gry
// ** Definicje Metod i Funkcji //Funckje void square(int x,int y,int d) // funkcja rysujaca kwadrat { rect(bufor, x, y, x + d, y + d, makecol(R, G, B)); };
void square_bg(int x,int y,int d) // funkcja rysujaca kwadrat { rect(bufor, x, y, x + d, y + d, makecol(BG_R, BG_G, BG_B)); };
// ************** EDIT 14.01.2008 ************ long point_count(short game_speed) { long player_score = 0; if (game_speed >= 100) return ++player_score; else return player_score+=2; if (game_speed <=70) return player_score+=20; }; /* funkcja, ktora wylicza wynik gracza. Za parametr bierze aktualna predkosc. I w zaleznosci od tej predkosci rosnie badz maleje predkosc zwiekszania sie punktacji:) tutaj mozna dowolnie zmienaic wedle uznania. */ // ************** /EDIT **********************
// ** Metody
/////////////////////////////////////////////////////// // cField // ///////////////////////////////////////////////////////
bool cField::set_up_line_left() // ustawia wspolrzedne poczatkowe lewej bandy { if (GS_GameState != GS_NOTSTARTED) return false; x = 0; y = 100 + 50*i ; return true; };
bool cField::set_up_line_right() // ustawia wspolrzedne poczatkowe prawej bandy { if (GS_GameState != GS_NOTSTARTED) return false;
x = 90; y = 100 + 50*i ; return true; };
void cField::draw_line() // metoda, ktora tworzy bande skladajaca siez trzech kwadratow { for(int i = 0 ; i < 3; ++i) { square(x, y + i*10, 10); }; for(int i = 0 ; i < 2 ; ++i) square_bg(x, y + i*10 + 30+1, 10); };
void cField::draw_all() { y+=10; draw_line(); if (y > 300) y = 50; }; /////////////////////////////////////////////////////// // cCar // /////////////////////////////////////////////////////// void cCar::draw_car() // metoda, ktora tworzy samochod skladajacy sie z kwadratow { square(x + 10, y, 10); for(int i = 0; i < 3; ++i) square(x + i*10, y+10, 10); square(x + 10, y + 20, 10); for(int i = 0; i < 2; ++i) square(x + i*20, y + 30, 10); };
bool cCar::Check_Conflict() // funkcja sprawdza czy zaszla kolizja miedzy samochodami. { if ((x == ex) && (y - ey <= 30)) // ex i exy to wspolrzedne przeciwnika { GS_GameState = GS_LOSE; return true; } else return false; }
void cCar::Take_Side() // losuje po ktorej stronie przeciwnik sie pojawi. { int n; srand(time(0)); n = rand()%(2); //if (n > 1) Enemy.x = 50; (n < 1 ? x = 20 : x = 50); }
bool cCar::set_up_player() // funkcja majaca na celu ustawienie poczatkujacych pozycji gracza { if (GS_GameState != GS_NOTSTARTED) return false; // sprawdza czy stan gry faktycznie jest NONSTARTED // Ustawienie obiektu car gracza x = 20; y = 260; return true; };
bool cCar::set_up_enemy() { if (GS_GameState != GS_NOTSTARTED) return false; //Take_Side(Enemy); y = 100 + ENEMY_DISTANCE * 2 * i; return true; };
void cCar::draw_Player() // metoda ktora "steruje" samochodem gracza { if (key[KEY_A]) x = 20; // jesli wcisniety zostal kalwisz A ustaw na danej pozycji if (key[KEY_D]) x = 50; // jesli wcisniety zostal klawisz D ustaw na danej pozycji
draw_car();
}
void cCar::draw_Enemy() // ostateczne umiejscowienie przeciwnika { y+=10; // wylicza nastepna pozycje draw_car(); // rysuje na danej pozycji if (y > 300) // jesli wyszedl poza ekran { // przesuw na gore y = 0; Take_Side(); // wylosuj strone }; };
| Data: 2008-01-12 14:45:02
dudek | main.cpp zawierajacy glowna petle programu
#include <allegro.h> #include "game.h"
//ZMIENNE GLOBALNE short GAME_SPEED = 100; //EDIT 14.01.2008 long l_player_score = 0; // /EDIT
int main() { init(); create_bufor(); clear_to_color(bufor, makecol(BG_R, BG_G, BG_B));
// ***** EDIT 14.01.2008 ***** // ** informacja dla gracza allegro_message(" Lewo A\n Prawo D\n Zwieksz tempo Q\n Zmniejsz tempo E\n"); // ***** /EDIT ***** // ** UTWORZENIE OBIEKTOW
cField LineLeft[5], LineRight[5]; cCar Player_Car; cCar Enemy_Car[3]; //Player_Car.Check_Conflict() = false; // ** ZAINICJOWANIE OBIEKTOW GRACZA, PRZECIWNIKOW I BANDY
Player_Car.set_up_player(); // ustawienie gracza Player_Car.draw_car(); // narysowanie gracza for(int i = 0; i < ENEMY_NUMBER ; ++i) /* petla ktora ustawia i rysuje przeciwnikow*/ { Enemy_Car[i].i = i; // rowna licznik klasy zlicznikiem petli Enemy_Car[i].x = 50; Enemy_Car[i].set_up_enemy(); Enemy_Car[i].draw_car(); }; for(int i = 0; i < LINE_NUMBER ; ++i) // petla ktora ustawia i rysuje bandy { LineLeft[i].i = i ; // rowna licznik obiektu zlicznikiem petli LineLeft[i].set_up_line_left(); LineLeft[i].draw_line(); LineRight[i].i = i ; // rowna licznik obiektu z licznikiem petli LineRight[i].set_up_line_right(); LineRight[i].draw_line();
}; blit(bufor,screen,0,0,0,-100,200,400); /* blit wlasnie kopiuje cala zawartosc bufora na ekran, -100 pikseli w y poza ekranem zeby ukryc samochody ktore po wyjsciu za dolna granice ekranu przeskakuja do gory */ // ** KONIEC INICJACJI POCZATKOWYCH ** \\ GS_GameState = GS_MOVE; // ustawia stan gry na ruch for(;;) // PETLA GLOWNA { if (key[KEY_Q]) GAME_SPEED-=10; // zwieksza tempo gry o 10milisekund if (key[KEY_E]) GAME_SPEED+=10; // zmniejsza tempo gry o 10 milisekund if (GAME_SPEED < 10) GAME_SPEED = 9; Player_Car.draw_Player();
for(int i = 0; i < ENEMY_NUMBER ; ++i) { Enemy_Car[i].draw_Enemy(); Player_Car.ex = Enemy_Car[i].x; /* ustawia pomocnicze wspolrzedne do sprawdzenia kolizji */ /* patrz Check_Conflict(); */ Player_Car.ey = Enemy_Car[i].y; /* ustawia pomocnicze wspolrzedne do sprawdzenia kolizji*/ Player_Car.Check_Conflict(); }; // jw. for(int i = 0; i < LINE_NUMBER ; ++i) { LineLeft[i].draw_all(); //ustawia linie boczna LineRight[i].draw_all(); // ustawia linie boczna }
//***** EDIT 14.01.2008 ****** /**************************************** wyliczanie zdobytych przez gracza punktow i wyswietlanie ich na ekranie ***************************************/ l_player_score += point_count(GAME_SPEED); textout_ex(bufor, font, "Punkty: ", 110, 190, makecol ( R, G, B), -1); textprintf_ex(bufor, font, 110, 200, makecol ( R, G, B), -1, "%d", l_player_score ); // ****** /EDIT ******
blit(bufor,screen,0,0,0,-100,200,400);
if (key[KEY_ESC]) GS_GameState = GS_EXIT; if ((GS_GameState == GS_LOSE) || (GS_GameState == GS_EXIT)) break; clear_to_color(bufor, makecol(BG_R, BG_G, BG_B)); rest(GAME_SPEED); };
// ***** EDIT 14.01.2008 ***** if (GS_GameState == GS_LOSE) allegro_message("przegrales! \nTwoj wynik: %d", l_player_score); // ***** /EDIT *****
deinit(); return 0; } END_OF_MAIN()
| Data: 2008-01-12 19:46:03
Piotr Szawdyński | Kompilacja projektu
Aby skompilować projekt należy: - Ściągnąć bibliotekę allegro (Narzędzia/Sprawdź czy są nowe uaktualnienia/pakiety...)
- utworzyć projekt w Dev-C++
- W opcjach kompilatora C/C++ wpisać:
-DALLEGRO_STATICLINK - W opcjach konsolidatora wpisać:
-lalleg_s -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32 -ldinput -lddraw -ldxguid -ldsound -lwinmm - Dodać wszystkie pliki źródłowe do projektu
| |
| Statystyki tematu | Ostatnio przeczytali |
|---|
| Czytało użytkowników: | 148 | Phoenix47, Mateusz124, maciejo, inny1997, OSA_PL, Loodwin, SteaVe, monkey, osik90, wladcaN, malan, RassTak, Amigen, Patro10, cfaniak, jacek_k, franz, Gronek8624, szorstki83, Quito, odchyl, Bartaz, MAKONDE, Drraven, kamillo121, hide, SideC, dudek, lmario13, sexi | | Przeczytało użytkowników: | 148 | | Czytało osób ogólnie: | 299 | | Przeczytało osób ogólnie: | 299 |
| Ostatnia Aktualizacja| 2010-09-01 19:27:34 (4 dni temu) | |
| Ostatnio aktywni |
|---|
| wiew | 24 min | | Koni | 34 min | | Mateusz124 | 37 min | | fish13 | 64 min | | wiewiorka | 77 min | | lenrokskate | 8 godz | | dmx81 | 10 godz | | steckel | 11 godz | | pixelmaster | 14 godz | | maciejo | 14 godz | | jurasnumeras | 15 godz | | Imperator_Edi | 16 godz |
|