[POBIERZ] kod źródłowy i inne pliki potrzebne do uruchomienia gry  [POBIERZ] 

Zachęcam do komentowania :) Mile widziane sugestie i pytania, na które chętnie odpowiem

31 paź 2010

Menu w grze

Mając chwilę czasu poczytałem o Allegro GUI i uznałem, że jest trochę zagmatwane i nie ma sensu się tego uczyć. Menu zrobiłem(jeszcze nie dokończone) w Allegro w sprytny sposób... Otóż dzięki tej bibliotece możemy używać także myszy. Pozycje myszy to: mouse_x,mouse_y; mouse_b- oznacza stan myszy tzn zmienna ta przechowuje stan poszczególnego klikniętego przycisku np. lewy przycisk myszy: 1, prawy 2, obydwa naraz to 3 itd...
W grze posłużyłem się tylko przyciskiem lewym, którym będziemy wybierali poszczególną część menu. Obrazować je będą bitmapy wyświetlane na bitmapie startu gry menu : nowa gra, powrót do gry, pomoc i wyjście.
Samo kliknięcie nic nam nie da bez poznania współrzędnych myszy i współrzędnych np. nowa gra  
jeżeli mamy już te współrzędne posłużymy się funkcją kolizja. Jeżeli nasz kursor znajduje się w obrębie owej bitmapy i klikniemy lewym przyciskiem myszy to aktywujemy "coś".
Standardowy kursor myszy zastąpiłem innym, ładniejszym :)
Oto funkcja, którą wywołuje się w main()

void gmenu()
{
   unscare_mouse();
   blit(spacedestroyermenu,bufor,0,0,0,0,spacedestroyermenu->w,spacedestroyermenu->h);
   draw_sprite(bufor, nowagra, 200,100);
   draw_sprite(bufor, powrotdogry, 200,200);
   draw_sprite(bufor, pomoc, 200,300);
   draw_sprite(bufor, wyjscie, 200,400);

   if ( kolizja(200,200,powrotdogry->w,powrotdogry->h,mouse_x,mouse_y,kursor->w,kursor->h) )
//powrot do gry
   {
      draw_sprite(bufor, ramka, 191,191);
//brązowa ramka, która jest rysowana jeżeli najedziemy myszką na poszczególne pole menu. Taki bajer ;p (aktywowana jest kolizja)
      if (mouse_b==1) // lewy przycisk myszy
      {
         play_sample(klik, 255,255,1000,0);
//dzwiek oddajacy klikniecie
         
gra=1;
      }
   }

   if ( kolizja(200,100,nowagra->w,nowagra->h,mouse_x,mouse_y,kursor->w,kursor->h) )
// nowa gra
   {
      draw_sprite(bufor, ramka, 191,91);
      if (mouse_b==1)
      {
         play_sample(klik, 255,255,1000,0);
         punktacja=0;
//nadajemy zmiennym poczatkowe wartosci
         zycia=100;
         ammo_bazo=100;
         ammo_machgun=40;
         ammo_laser=0;
         ammo_flame=0;
         
gra=1; //powrot do gry z poczatkowym ustawieniem zmiennych czyli nowa gra :)
      }
   }

   if ( kolizja(200,300,pomoc->w,pomoc->h,mouse_x,mouse_y,kursor->w,kursor->h) )
//pomoc
   {
      draw_sprite(bufor, ramka, 191,291);
      if (mouse_b==1)
      {
         play_sample(klik, 255,255,1000,0);
      }
   }

   if ( kolizja(200,400,powrotdogry->w,powrotdogry->h,mouse_x,mouse_y,kursor->w,kursor->h) )
//wyjscie
   {
      draw_sprite(bufor, ramka, 191,391);
      if (mouse_b==1)

      {
         play_sample(klik, 255,255,1000,0);
          gra=2;
//jeżeli gra=2 to główna pętla gry zostaje zakończona i wychodzimy z gry
      }
   }

show_mouse(bufor);
}


W main wywołujemy ją:
// cos tam
while(gra!=2) 
{
    gmenu();

   while(gra==1)
   {  
        while( ( speed > 0) && ( zycia>0 && punktacja<992) )
        {
           //kod gry
        }
   blit( bufor, screen, 0,0,0,0, 800,600);   //  w grze wszystko rysujemy na buforze, po pełnym obiegu pętli wyświetlamy na screen
   } 
blit( bufor, screen, 0,0,0,0, 800,600);   //wyświetlamy menu gry


oto screen menu: (tło jest tymczasowe dałem tymczasowe aby nie było szarego ekranu)
narazie działa nowa gra, powrót do gry i wyjście. W porownaniu do wersji demo dodane nowe ruchy wgoga v_hard Oczywiście dodaję cały kod i wszystkie pliki potrzebne do uruchomienia gry(ver.1.06) 

29 paź 2010

Menu w grze (prototyp)

Z braku czasu (CCNA i studia) przez ostatnie 13 dni nic nie napisałem i zrobiłem pierwszą, 2-tygodniową przerwę w pracy nad projektem ... W ten weekend postaram się częściowo napisać menu do gry. Zastanawiam się tylko w czym to zrobić.
ALLEGRO: podstawić bitmapy, które będą reprezentowały "button", który będzie wywoływał jakąś czynność po kliknięciu myszą.
ALLEGRO GUI, którego praktycznie nie znam i na pierwszy rzut oka wydaje się torchę zagmatwane. 
Menu będzie wyglądało miej więcej w ten sposób:
 


Oto ciekawy przypadek o szwindlu nigeryjskim :P (nie związane z projektem!!!)
Na allegro sprzedaję iPhona i dostaję masę propozycji kupna, tyle że w j.ang, co mnie zdziwiło bo do tej pory nigdy nie dostałem oferty kupna z innego kraju, a także allegro nie jest popularne za granicą, a szczególnie w Nigerii :P
Oczywiście na początku myślałem, że to ktoś z UK ale potem się okazało, że "dziwnym trafem" wszyscy adresaci mailów są z Nigerii to o mało nie spadłem z krzesła :) 
Oczywiście sprawdziłem IP każdego maila i "odziwo" są identyczne. Spytałem wujka google co wie tym przypadku i naprawdę jest o tym wiele informacji... Chociażby ten artykuł 
Piszę o tym bo może ktoś z Was w przyszłości otrzyma podobne propozycje kupna i nie da się oszukać.

16 paź 2010

ruchy Cwrog_vhard

Miałem zacząć pracować nad menu gry lecz brakuje mi na to czasu... Zaczął się kurs CISCO CCNA1, a do tego studia i niestety zamiast czytać o allegro GUI czytam o sieciach :p 
Ale do rzeczy. W tym poście przedstawię ruchy dla Cwrog_vhard. W poprzednim poście i demo jest klasa tymczasowa dla tego wroga. Nie będę wrzucał kodu bo narazie takowego nie ma :p
Jak przystało na poziom wroga very hard będzie trzelał 3 pociskami na raz, środkowy będzie leciał w dół, a 2 z brzegów na dół po skosie.


Oto rysunek obrazujący (czerwonymi strzałkami)ruchy i (fioletowymi)strzelanie Cwrog_vhard



Kod będzie podobny do Cboss1 czyli 3 tablice na pociski... Wrzucę tylko funkcję odpowiedzialną za strzelanie. Poruszanie jest podobna do pozostałych.

void strzelanie_wroga()
{
   for(int i=0; i<3; i++)
   {
      if ( pozpocwro_y[i]>430)
      {
         if (czest_poc>=ogranicz_czest_poc)
         {
            pozpocwro_x[i]=pozwro_x-10;
            pozpocwro_y[i]=pozwro_y+20; 
            pozpocwro_x[i+1]=pozwro_x+10;
            pozpocwro_y[i+1]=pozwro_y+20; 
            pozpocwro_x[i+2]=pozwro_x+30;
            pozpocwro_y[i+2]=pozwro_y+20;  
            czest_poc=0;  
         }
      }  
      if (pozpocwro_y[i]>430)
      {
         pozpocwro_y[i]=800;
      }
      pozpocwro_y[i]=pozpocwro_y[i]+2;
      pozpocwro_x[0]=pozpocwro_x[0]-1;  // aby pocisk z lewej strony leciał w lewo 
      pozpocwro_x[2]=pozpocwro_x[2]+1; //aby pocisk z prawej strony leciał w prawo 
      czest_poc++;
   }  
}
 

13 paź 2010

Space destroyer -wersja DEMO

Pora na wyczekiwaną wersję DEMO. W tym poście przedstawię tymczasowe bitmapy przedstawiające wrogów , bonusy i amunicję wypadającą z wrogów,  "tymczasowe" bo niestety nie znalazłem bitamp w klimacie gry kosmicznej, które można wprawić w ruch. Może ktoś mi podeśle link :)

Oczywiście każdy z wrogów zależnie od jego poziomu ma coraz większą liczbę żyć, strzela innymi pociskami, które tracą coraz więcej żyć, z każdego wroga wypada inna amunicja. Bronie także mają coraz większą moc. W wersji demo jest 10 etapów i ostatni kończy się bossem.


A oto bitmapy przedtsawiające różne obiekty w grze:

WROGOWIE 

 Cwrog_easy
  

Cwrog_medium 
   

Cwrog_hard
 

Cwrog_vhard - nie pisałem o ruchach dla tego rodzaju wroga, ma ruchy podobne do medium ale rusza się szybciej i strzela szybciej od innych.
 

Cboss1 - tutaj akurat znalazłem na innym blogu(open source tak jak mój blog) 4 bitmapy i jest mini animacja :P 






BONUSY

 apteczka z życiami(wypada rzadko)
 

 szybkie chodzenie(dopalacz :P) 
 
 AMUNICJA

 bazooka:
 
 karabin maszynowy:
 
 laser:
 
 miotacz ognia:
 

 Nie będę przedstawiał posisków wystrzelanych przez wrogów i dźwięków. Jak ściągniecie to zobaczycie. 

Oto elementy, które zrobię w najbliższym czasie. 
- W grze nie ma jeszcze menu(przyjdzie na to czas ;p i zostanie zrobione w Allegro GUI) 
- jakieś ładne fonty
- bitmapy, dzięki którym można uzyskać animację 
- animację wybuchu po zestrzeleniu wroga
- koniec gry (po zniszczeniu [i przekroczeniu 10 etapu w demo] robota przez wrogów gra się wyłącza :P) 

 Kilka osób zagrało w wersję demo i mówią, że jest za trudna, doradzili mi żebym naniósłpewne poprawki co do kodu i samej rozgrywki w grze. 
I mam prośbę do WAS o wypowiedzi czy podoba się Wam gra, co byście zmienili w kodzie i w samej grze. Każda wiadomość od Was będzie dla mnie pomocna :) 


Kod, pliki potrzebne do uruchomienie gry i .dll spakowane i do ściągnięcia pod nazwą space destroyer wersja demo na google.code http://code.google.com/p/spacedestroyer/downloads/list


EDIT: będę konsekwentny i wrzucam screena z gry 

8 paź 2010

Kod w main(), ostatni post przed wersją demo

Oto moje wypociny zawarte w funkcji odpowiadającej za wroga easy. 
W funkcji jest wyswietlenie wroga i jego pocisku, a także wszystkie możliwe kolizje.
Kolizja pociskow z każdej broni z wrogiem, kolizja pocisku wroga z robocikiem, 
kolizja robocika z wrogiem i kolizja pocisku flamethrower z pociskiem wroga czyli możliwość obrony dla robota przed pociskami. 
Przy każdym wywołaniu kolizji "coś się dzieje".  Albo uruchamiamy funkcje odpowiedzialne za LOSOWE wypadanie bonusów, tracimy życia, wypada amunicja, zabijamy wroga
Użyłem Cwrog_easy enemy_e[5]; czyli stowrzyłem 6-elementową tablicę obietków klasy enemy_easy. 6 wrogow tej klasy wystarczy. Liczba wrogich statków uzależniona jest od void etapy() (poprzednie posty).
Napisałem Ostatni post przed wersją demo bo miało być obiektowo, a nie jest do końca. Zastanawiam się aby te kolizje jeszcze upchnąć do klas bo za dużo tu tego ...
Oto kod: 



for(int e=0; e<max_easy; e++) //easy
{
   if( (frame>=0) && (frame<=80) )
   {
   draw_sprite(bufor, wrog, enemy_e[e].pozwro_x, enemy_e [e].pozwro_y);
   draw_sprite(bufor, pociskwroga, enemy_e[e].pozpocwro_x, enemy_e[e].pozpocwro_y);
   }

   if( kolizja(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y,wrog->w,wrog->h,strzal_bazooka.pozpoc_x,strzal_bazooka.pozpoc_y,pocisk->w,pocisk->h) )
   {
      enemy_e[e].odejm_zycia(2);
      strzal_bazooka.pozpoc_y=-40;
      bazooka_dodaj.bazooka(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y);
      zycie_dodaj.aid();
      przyspiesz_dodaj.przyspiesz();
   }

   else if( kolizja(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y,wrog->w,wrog->h,strzal_machinegun.pozpoc_x,strzal_machinegun.pozpoc_y,mach_gun->w,mach_gun->h) )
   {
     enemy_e[e].odejm_zycia(1);
     strzal_machinegun.pozpoc_y=-30;
     bazooka_dodaj.bazooka(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y);
     zycie_dodaj.aid();
     przyspiesz_dodaj.przyspiesz();
   }

   else if( kolizja(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y,wrog->w,wrog->h,strzal_laser.pozpoc_x,strzal_laser.pozpoc_y,laser->w,laser->h) )
   {
     enemy_e[e].odejm_zycia(3);
     bazooka_dodaj.bazooka(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y);
     zycie_dodaj.aid();
     przyspiesz_dodaj.przyspiesz();
   }

   else if( kolizja(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y,wrog->w,wrog->h,strzal_flamethrower.pozpoc_x,strzal_flamethrower.pozpoc_y,flame->w,flame->h) )
   {
     enemy_e[e].odejm_zycia(5);
     enemy_e[e].czest_poc=enemy_e[e].czest_poc-20;
     strzal_flamethrower.pozpoc_y=-30;
     bazooka_dodaj.bazooka(enemy_e[e].pozwro_x,enemy_e[e].pozwro_y);
     zycie_dodaj.aid();
     przyspiesz_dodaj.przyspiesz();
  }
//kolizja pocisku enemy_e z ludkiem
  if( kolizja(ludek.pozs_x,ludek.pozs_y,statek->w,statek->h,enemy_e[e].pozpocwro_x,enemy_e[e].pozpocwro_y,pociskwroga->w,pociskwroga->h) )
  {
    enemy_e[e].pozpocwro_x=0;
    enemy_e[e].pozpocwro_y=700;
    zycia=zycia-2;
  }
//kolizja enemy_e z ludkiem
  if( kolizja(ludek.pozs_x,ludek.pozs_y,statek->w,statek->h,enemy_e[e].pozwro_x,enemy_e[e].pozwro_y,wrog->w,wrog->h) )
  {
    enemy_e[e].pozwro_x=rand()%550;
    enemy_e[e].pozwro_y=0;
    zycia=zycia-4;
  }

//kolizja pocisku enemy_e z pociskiem ludka
  if( kolizja (strzal_flamethrower.pozpoc_x,strzal_flamethrower.pozpoc_y, flame->w, flame->h,enemy_e[e].pozpocwro_x,enemy_e[e].pozpocwro_y,pociskwroga->w,pociskwroga->h) )
  {
    enemy_e[e].pozpocwro_y=700;
  }
  enemy_e[e].strzelanie_wroga();
  enemy_e[e].poruszanie_wroga();
}


Jestem przygotowany na krytykę i otwarty na pomysły co do zmian w kodzie :) 
Pewnie trochę potrwa (w weekend studia)  zanim zrobię kolizje dla innych wrogów ale przy  następnym poście dodam kod w code.google.

5 paź 2010

Ruchome tło w grze

Krótki post na temat mechanizmu poruszania tłem. Jak na początku napisałem ma to być gra, w której akcja obywa się w kosmosie, więc trzeba pomyśleć na tłem do gry. Nie byłoby trudności z dodaniem bitmapy, która by się nie ruszała ale to by było pójście na łatwiznę... Myślałem trochę nad zrobieniem ruchomego tła i wymyśliłem taką funkcję.
Jest to funkcja składowa klasy Cmenu(odpowiedzialna za menu, interfejs gry).
Funkcja działa w taki sposób:
Po każdym obiegu pętli gry wycina "pasek" z góry ekranu, na jego miejsce przesuwa całą bitmapę czyli o 1 piksel do góry, po przesunięciu bitmapy o 1 piksel w górę zostaje nam pusty  pasek u samego dołu i owa funkcja wstawia wycięty pasek na sam dół ekranu.

A oto rysunek pomocniczy, a zarazem skrót mojego kazania :P
S[rzałki obrazują ruch bitmapy. Wycinek o nr 1 wstawiamy na sam dół, i na miejsce 1 wskakuje 2. Po obiegu pętli owa 2 wskakuje na sam dół, a na jej miejsce wskoczy 3 itd.
I króciutka funkcja:

void Cmenu::wyswietl_tlo()
{
   blit(tlo,bufor,0,0,0,-pos,tlo->w,tlo->h);
   blit(tlo,bufor,0,0,0,tlo->h-pos,tlo->w,pos);

   if(pos==tlo->h)
   {
      pos=0;
   }

   pos++;
}


 
Testowałem to i bardzo fajnie wyszło ale niestety nie mam dobrej tekstury (obrazy wziąłem z google) i nie ma dobrego przejścia tzn widać końce bitmapy po podczas przesuwania. Jeżeli chodzi o mnie to ideą pisania gry jest nauka programowania, a nie ładna grafika, choć jeżeli znacie jakieś stronki z teksturami to zapodajcie :)

3 paź 2010

Etapy w grze

Przyszedł czas na rozmyślenia jak zrobić w grze etapy. Myślałem nad tym trochę i wymyśliłem taką funkcję, która przyjmuje globalną zmienną zawierającą liczbę punktów zdobytych przez gracza. Wcześniej w jakimś poście wspomiałem o zmiennej punktacja i teraz o niej pomówimy. Liczba punktów będzie odpowiadała poszczególnym etapom. 
Gra oczywiście zaczyna się z 0-wym dorobkiem punktów. Po zestrzeleniu "odpowiedniego" wroga dostaniemy "odpowiednią" ilość punktów zależnie od poziomu trudności wroga.
np: Cwrog_easy
if(zycia<=0)
{
punktacja++;
}

dostajemy 1 pkt

Cwrog_medium 
if(zycia<=0)
{
punktacja=punktacja+2;

} 
dostajemy 2 pkt 
itd... Jak wyjdzie demo to wtedy zmodyfikuje się odpowiednie wartości co do życ wroga i punktacji za zabicie go.



Teraz opiszę funkcję etapy.
Pierwszej części nie będę opisywał bo wszystko widać...
Do switcha przesyłamy argument etap zawierający liczbę, która jest równa etapowi. i w case przypisujemy do zmiennych wartości np:

 case 1:  
  max_easy=3; - tylu wrogów Cwrog_easy wystąpi w 1 etapie czyli 3
 max_medium=0; - tylu wrogów Cwrog_medium wystąpi w 1 etapie czyli 0
 max_hard=0; 
- tylu wrogów Cwrog_hard wystąpi w 1 etapie
 
max_vhard=0; - tylu wrogów Cwrog_vhard wystąpi w 1 etapie (narazie go nie ma ale trwwaja prace nad wymyśleniem ruchów dla niego)
 max_b1=0; 
- tylu bossów Cboss1 wystąpi w 1 etapie

void etapy(int pkt)
{
   if(pkt<=35) { etap=1; }
   else if( (pkt>36) && (pkt<=60) ) { etap=2; }
   else if( (pkt>61) && (pkt<=120) ) { etap=3; }
   else if( (pkt>121) && (pkt<180) ) { etap=4; }
   else if( (pkt>181) && (pkt<280) ) { etap=5; }
   else if( (pkt>281) && (pkt<400) ) { etap=6; }
   else if( (pkt>441) && (pkt<590) ) { etap=7; }
   else if( (pkt>591) && (pkt<740) ) { etap=8; }
   else if( (pkt>741) && (pkt<890) ) { etap=9; }
   else if( (pkt>891) && (pkt<991) ) { etap=10; }
   else if( (pkt>991) && (pkt<1100) ) { etap=11; }

   switch(etap)
   {

      case 1:
      max_easy=3;
      max_medium=0;
      max_hard=0;
      max_vhard=0;
      max_b1=0;
      break;

      case 2:
      max_easy=1;
      max_medium=2;
      max_hard=0;
      max_vhard=0;
      max_b1=0;
      break;

      case 3:
      max_easy=1;
      max_medium=1;
      max_hard=1;
      max_vhard=0;
      max_b1=0;
      break;

      case 4:
      max_easy=2;
      max_medium=1;
      max_hard=1;
      max_vhard=0;
      max_b1=0;
      break;

     // itd

      case 10:
      max_easy=0;
      max_medium=0;
      max_hard=0;
      max_vhard=0;
      max_b1=1;
      break;

    }
}


Od jakiegoś czasu nie piszę o kodzie w main() bo przyjdzie na to czas, więc pokażę co zrobimy z taką zmienną w głównej pętli gry: 
for(int e=0; e<max_easy; e++) 
{} 
for(int m=0; m<max_medium; m++) 
{}
Taka pętla wykona się tyle razy ilu mamy wrogów w poszczególnym etapie (funkcja etapy i instrukcja case). Zawarte w niej będą funkcje sprawdzające kolizję z różnymi obiektami i inne ciekawe rzeczy ale o tym w następnym poście :) Myślę, że w ciągu 2 tyg powstanie "wczesna" wersja  beta  
P.S. Jeżeli znacie strony z bitmapami o tematyce kosmicznej to dajcie link, bardzo mi pomożecie  :)