Serwis został przeniesiony pod nową domenę: http://cpp0x.pl/
PowrótPowrótHistoria odwiedzonych stron
AutorWiadomość
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 pobrania

Calosc 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
  • Dokonać kompilacji
1



Statystyki tematuOstatnio przeczytali
Czytało użytkowników:148Phoenix47, 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



PowrótPowrótHistoria odwiedzonych stron
Panel Logowania
Login:
Hasło:

Użytkowników
Obecnie aktywnych:12
Zalogowanych:0
Zarejestrowanych:4367
Ostatnie 24h:538
Non-cookie 24h:2685
Wszystkich:214118
Ostatnia Aktualizacja
2010-09-01 19:27:34 (4 dni temu)
Ostatnio aktywni
wiew24 min
Koni34 min
Mateusz12437 min
fish1364 min
wiewiorka77 min
lenrokskate8 godz
dmx8110 godz
steckel11 godz
pixelmaster14 godz
maciejo14 godz
jurasnumeras15 godz
Imperator_Edi16 godz

Wynajem Sopot - wakacje
Pokój 2 osobowy 130zł/doba;
Lokalizacja: Sopot


O portaluArchiwumHistoriaIndeksRegulaminWyszukiwarkaLinki
Kurs HTML - strona WWW za darmoRestauracja "ATOL" - SopotValid HTML 4.01 TransitionalValid CSS!HTML CSS JavaScript FLASH PHP MySQL