[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

29 sie 2010

Bronie w grze Cz.1

W poprzednim poście powierzchownie opisałem 4 rodzaje broni jakimi nasz robocik będzie dysponował. Narazie będzie miał niewyczerpalną amunicję ale z czasem się to zmieni... 
Odrazu napiszę, że kody żródłowe z poprzednich wersji troszeczkę się będą różniły od siebie, ponieważ jak zaznaczyłęm na początku uczę się obiektowości i cały czas przerabiam klasy dodając lub przenosząc pola i metody do innych powstających klas. 
Kody nie różnią się od siebie diametralnie, lecz różnice są zauważalne. Jak ktoś(o ile komuś się zechce :P)  będzie analizował kod i nie będzie czegoś rozumiał lub miał pytania proszę o pytanue w komentarzu pod danym postem to rozwieję wątpliwości :)
Myślałem jak by zrobićklasę odpowiadającą za bronie i wymyśliłem coś takiego:


class Cshots
{
   public:
   int pozpoc_x, pozpoc_y;

   void strzelaniee(int, int);

   Cshots::Cshots ()
   {
      pozpoc_x=0;
      pozpoc_y=0;  
    }  
};



void Cshots::strzelaniee(int pozx, int pozy)
{
     pozpoc_x=pozx+15;
     pozpoc_y=pozy-15;  
}



Klasa sama w sobie nic nie robi ustawia tylko początkową pozycję pocisku (x i y) dopiero w main zabawa się zaczyna :P
Tworzymy sobie 4 obiekty użyję 4 różnych kolorów(każdy kolor odpowada za dany obiekt) bo trochę jest tego kodu w main() 

Cshots strzal_bazooka;
Cshots strzal_machinegun;
Cshots strzal_laser;
Cshots strzal_flamethrower;
 

Teraz pokażę jak się będzie zmieniało w grze bronie. 
Deklarujemy i definiujemy sobie zmienną: int bron=1;
Liczby od 1 do 4 będą odpowiadały za poszczególne bronie: 

1-bazooka
2-karabin maszynowy
3-laser
4-miotacz ognia 


I analogicznie na klawiaturze będziemy zmieniali bronie za pomocą klawiszy 1,2,3,4

if(key[KEY_1])
{
     bron=1;
}

if(key[KEY_2])
{
     bron=2;
}

if(key[KEY_3])  
{
     bron=3;
}

if(key[KEY_4])
{
     bron=4;
}
_________________________________________________________________  


Strzelać będziemy spacją

if( key[KEY_SPACE]) 
{

   if(bron==1)
   {
       if( (strzal_bazooka.pozpoc_y<0) || (strzal_bazooka.pozpoc_y==0) )
      {
          strzal_bazooka.strzelaniee(ludek.pozs_x, ludek.pozs_y ); 
          play_sample(dzwiek, 200,200,1000,0);  
          ammo_bazo--;
      }
   }

   if(bron==2)
   {
       if( (strzal_machinegun.pozpoc_y<0) || (strzal_machinegun.pozpoc_y==0) )
       {
          strzal_machinegun.strzelaniee(ludek.pozs_x, ludek.pozs_y ); 
          play_sample(machingunn, 200,200,1000,0);  
       }   
   } 

   if(bron==3)
   {
       if( (strzal_laser.pozpoc_y<0) || (strzal_laser.pozpoc_y==0) )
       {
          strzal_laser.strzelaniee(ludek.pozs_x, ludek.pozs_y ); 
          play_sample(laserr, 200,200,1000,0);  
       }
   } 

   if(bron==4)
   {
        if( (strzal_flamethrower.pozpoc_y<0) ||(strzal_flamethrower.pozpoc_y==0) )
       {
          strzal_flamethrower.strzelaniee(ludek.pozs_x, ludek.pozs_y ); 
          play_sample(flamethrow, 200,200,1000,0);  
       }
   } 
}


Wytłumaczę tą część kodu. Strzelanie w grze będzie wyglądało w następujący sposób: po wybraniu broni (1,2,3,4) i naciśnięciu spacji z robocika wyleci pocisk z broni, którą mamy aktywowaną. wystrzelenie pocisku będzie możliwe jeżeli jego pozycja y będzie mniejsza od 0 lub równa 0 tzn jeżeli opuści ekran gry, lub jeżeli trafimy w jakiś cel. Na ekranie będzie mógł się znajdować tylko 1 pocisk z poszczególnej broni, aby wystrzelić kolejny pocisk musi wyjść poza ekran lub musimy w coś trafić... 
Widzimy także np:
 play_sample(flamethrow, 200,200,1000,0);  
tutaj odtwarzamy jakis dźwięk akurat dobrałem takie, które przypominają wystrzały z tych broni.

 Omówię jeszcze funkcję z klasy
void Cshots::strzelaniee(int pozx, int pozy)
{
     pozpoc_x=pozx+15;
     pozpoc_y=pozy-15;  
}


Do tej funkcji przesyłamy 2 argumenty pozycję x i y robocika aby pocisk wystrzelony z robocika wyleciał nie ze środka robocika ale z jego "głowy" ładniej to wygląda :P  
Tak więc tą funkcją nadajemy pozycję x i y pocisku troszeczkę zmodyfikowaną z pozycji robocika.
i wywołujemy tak:

strzal_flamethrower.strzelaniee(ludek.pozs_x, ludek.pozs_y ); 
_________________________________________________________________



Dobrze by było gdybyśmy wiedzieli którą broń mamy aktywowaną... Proponuję wrócić do poprzednich 2 postów, tam jest klasa Cmenu i i bitmapy, które teraz wykorzystam.
W prawym dolnym rogu będziemy wyświetlali naszą aktualną broń 

if(bron==1)
{
    masked_blit( menu_bazooka, bufor, 0,0, 674, 515, menu_bazooka->w,    menu_bazooka->h);
}

else if(bron==2)
{
    masked_blit( menu_machinegun, bufor, 0,0, 674, 515, menu_machinegun->w, menu_machinegun->h);
}

else if(bron==3)
{
    masked_blit( menu_laser, bufor, 0,0, 665, 515, menu_laser->w, menu_laser->h);
}

else if(bron==4)
{
    masked_blit( menu_flamethrower, bufor, 0,0, 665, 515, menu_flamethrower->w, menu_flamethrower->h);
}

 


_________________________________________________________________
musimy jeszcze wyświetlić nasze pociski:

if( (frame>=0) && (frame<=80) )
{
   draw_sprite(bufor, mach_gun,
strzal_machinegun.pozpoc_x,    strzal_machinegun.pozpoc_y);
}

if( (frame>=0) && (frame<=80) )
{
   draw_sprite(bufor, pocisk,
strzal_bazooka.pozpoc_x, strzal_bazooka.pozpoc_y);
}

if( (frame>=0) && (frame<=80) )
{
   draw_sprite(bufor, laser,
strzal_laser.pozpoc_x, strzal_laser.pozpoc_y);
}


if( (frame>=0) && (frame<=80) )
{
   draw_sprite(bufor, flame,
strzal_flamethrower.pozpoc_x,    strzal_flamethrower.pozpoc_y);
}

 


_________________________________________________________________ 
i wprawić nasze pociski w ruch tj. po każdym obiegu głównej pętli  while( !key[KEY_ESC]) zmieniamy współrzędną y o pewną wartość. Im większa wartość tym szybciej będzie leciał pocisk. Uważam, że te wartości jak narazie są odpowiedznie, może z biegiem czasu ulegną zmianie :P 

strzal_flamethrower.pozpoc_y=strzal_flamethrower.pozpoc_y-10;
strzal_laser.pozpoc_y=strzal_laser.pozpoc_y-30;
strzal_machinegun.pozpoc_y=strzal_machinegun.pozpoc_y-40;
strzal_bazooka.pozpoc_y=strzal_bazooka.pozpoc_y-5;
 


W następnym poście zrobię kolizję.  Do pobrania kod wraz z plikami potrzebnymi do uruchomienia gry ver.1.02
Jeżeli macie pytania, propozycje to piszcie w komentarzach, napewno odpowiem :)
Gra na tym etapie wygląda następująco:

 

26 sie 2010

wstęp do broni w grze

Napiszę teraz dlaczego w prawie każdej bitmapie występuje kolor różowy.  
Kolor różowy kod RGB(255,0,255) w allegro jest pomijany, tzn jeżeli mamy 2 obrazki: 

1. z białym tłem, jeżeli wyświetlimy tą bitmapę w programie to kolor biały(otaczające tło) także zostanie wyświetlony.

 2. z różowym tłem, jeżeli wyświetlimy tą bitmapę w programie to zostanie wyświetlona tylko bazooka, bez otaczającego ją różowego tła ponieważ kolor różowy kod RGB(255,0,255) jest pomijany.




Na początku bloga napisałem, że będą 4 rodzaje broni: bazooka, karabin maszynowy, laser i miotacz ognia. oto one:


1) bazooka:

Pocisk wystrzelony z tej broni będzie wyglądał tak: 

                                                                             



2) karabin maszynowy:
Pocisk wystrzelony z tej broni będzie wyglądał tak (zwykła kropka w paincie :P): 




3) laser:
  
Pocisk wystrzelony z tej broni będzie wyglądał tak (zwykła kreska w paincie :P): 




4) miotacz ognia:


Pocisk wystrzelony z tej broni będzie wyglądał tak : 



Oczywiście przy wystrzale z każdej broni będzie odtwarzany dźwięk, każda broń będzie inaczej się zachowywała, traciła mniej lub więcej żyć, a także planuję aby miotacz ognia pozwalał na niszczenie wrogich pocisków... Za jakiś czas wrzucę kod wraz z wszystkimi potrzebnymi plikami i jak zawsze napiszę nowego posta  wyjaśniającego wybrane fragmenty kodu.

23 sie 2010

Interfejs w grze

Kolej na obiecany interfejs...
Napewno pamiętacie grę doom, gdzie głowa głównego bohatera po stracie n-% żyć pokrywała sięcoraz bardzierj krwią... Chcę uzyskać podobny efekt, lecz będzie to niestety "kulawe graficznie" ponieważ, nie jestem grafikiem... W grze po stracie kolejnych 10% żyć robocik będzie zamalowywany coraz bardziej kolorem czerwonym....
tak więc na początek deklarujemy sobie 11 bitmap:


BITMAP *Statek_HP100 = NULL;
BITMAP *Statek_HP90 = NULL;
BITMAP *Statek_HP80 = NULL;
BITMAP *Statek_HP70 = NULL;
BITMAP *Statek_HP60 = NULL;
BITMAP *Statek_HP50 = NULL;
BITMAP *Statek_HP40 = NULL;
BITMAP *Statek_HP30 = NULL; 
BITMAP *Statek_HP20 = NULL;
BITMAP *Statek_HP10 = NULL;
BITMAP *Statek_HP0 = NULL;


I dla Statek_HP100 bitmapa będzie wyglądała tak:


 

dla Statek_HP90



*
*

i w końcu dla Statek_HP0 


W tym celu stworzyłem klasę Cmenu, w której będę umieszczał poszczególne elementy interfejsu gry... Oto ona:


class Cmenu
{
 public:
 int pozstathp_x, pozstathp_y;
 int pozmenu_x, pozmenu_y;
 int pos;
 void wyswietl_obrazki();

 Cmenu::Cmenu()
 {
   pozmenu_x=0;
   pozmenu_y=480;
   pozstathp_x=10;
   pozstathp_y=515;
   pos=0;
 }
};



 
void Cmenu::wyswietl_obrazki() 
{
 
masked_blit( menudolne, bufor,0,0,pozmenu_x,pozmenu_y,menudolne->w, menudolne->h);
 
  textprintf_ex(bufor,font,2,488,makecol(0,200,200),-1,"stanzyc: %d%%",zycia);

 
  masked_blit( Statek_HP100, bufor, 0,0, pozstathp_x,pozstathp_y,Statek_HP100->w, Statek_HP100->h);

   if(czas_odt_muz >161)
   {
      czas_odt_muz=0;
   }

   if( frame>=40)
   {  
     masked_blit( Statek_HP100, bufor, 0,0,

     pozstathp_x,pozstathp_y,Statek_HP100->w,Statek_HP100->h);

     if( (zycia > 80) && (zycia<=90) )
     {
        masked_blit( Statek_HP90,bufor,0,0,

        pozstathp_x,pozstathp_y,Statek_HP100->w, Statek_HP100->h); 
     }

     else if( (zycia > 70) && (zycia<=80) )
     {  
         masked_blit( Statek_HP80, bufor, 0,0, 

         pozstathp_x,pozstathp_y,Statek_HP100->w, Statek_HP100->h);  
     }
/*

i tak dalej az do zycia <=0
*/
   
  else if (zycia <= 0)
     {  
        masked_blit( Statek_HP0, bufor, 0,0,

        pozstathp_x,pozstathp_y,Statek_HP100->w, Statek_HP100->h); 
     }
  }  
}

 


W funkcji wyswietl_obrazki() chodzi o to aby od frame=0 do frame=40 wyswietlało nie zamalowanego robocika, a od frame=41 do frame=80 robocika z zamalowana czescia na czerwony kolor. (Niby miał to wyjść efekt popsutej poszczególnej części ale niestety nie mam talentu i wyszło jak wyszło...) Efekt jest taki: jesli mamy mniej niz 91% zyc czerwone czesci robocika zaczynaja nam migac.

w konstruktorze podałem współrzędne elementów interfejsu gry. Żeby było jasne menu_dolne  ma wymiary 800*120 i w konstruktorze jego pozycja Y to pozmenu_y=480, bo Nasza gra ma rozdzielczość 600...  a menu_dolne wygląda tak:


 różowy kolor w bitmapie oznacza, że w grze będzie niewidoczny...

Skoro napisałem o deklarowaniu bitmap to napiszę jak wczytac taka bitmape do programu, a także o tym samym tylko dla dźwięku...

dla Statek_HP100:
podajemy nazwe wczesniej zadlklarowana czyli Statek_HP100 i za pomocą tej instrukcji w cudzyslowie "" podajemy ścieżkę do pliku

Statek_HP100=load_bmp("BMP/Statek_HP/Statek_HP100.bmp",default_palette); 

musimy także pamiętać aby na końcu programu zwolnić używaną pamięć przez bitmapę instrukcją: 

destroy_bitmap(Statek_HP100); 


Warto w programie dodać taką instrukcję, uchroni nas przed jakimś poważnym błędem, a nawet zawieszeniem systemu. Stanie siętak jeśli po uruchomieniu programu zabraknie takiego pliku o tej nazwie we wskazanym przez Nas katalogu :

  if (!Statek_HP100)
{
   set_gfx_mode(GFX_TEXT,0,0,0,0);
   allegro_message("brak pliku .bmp");
   allegro_exit();
   return 0;
}
 



i to by było na tyle. Teraz kolej na dźwięk deklarujemy go w ten sposob:

SAMPLE *dzwiek = NULL;  

definiujemy w podobny sposób jak bitmapy podając ścieżkę:

dzwiek = load_sample("wybuch.wav"); 


I teraz musimy zatrzymać ten dźwięk instrukcją:

 stop_sample(dzwiek); 


i zwolnić z pamięci:

destroy_sample(dzwiek); 

i analogicznie ja kw bitmapach warto dodać instrukcję:

if (!dzwiek)
{
   set_gfx_mode(GFX_TEXT,0,0,0,0);
   allegro_message("brak pliku .wav");
   allegro_exit();
   return 0;
}
 
 
Aha w klasie Cmenu są jeszcze wyświetlane życia za pomocą funkcji:

textprintf_ex(bufor,font,2,490,makecol(0,200,200),-1,"stan zyc: %d%%", zycia); 

1-arg jest to gdzie wyświetlamy ten napis czylu u nas w buforze
2- czcionka
3 i 4 współrzędne
 makecol(0,200,200) ustalamy kolor w systemie RGB
 i nasz tekst: "stan zyc: %d%%", gdzie %d  używamy z C :p i %% aby wyświetlić % (ponieważ % jest znakiem specjalnym i żeby go wyświetlićmusimy go powtórzyć)
-i na koniec zmienna integer u nas zycia



To by było na tyle. W porównaniu do wersji 1.00 zrezygnowałem z nieefektownego elementu wybuchu, w jakiejś wersji dopracuję i dodam ponownie :).  Do pobrania kod wraz z plikami potrzebnymi do uruchomienia gry ver.1.01
Jeżeli macie pytania, propozycje to piszcie w komentarzach, napewno odpowiem :) 
Gra na tym etapie wygląda następująco:



 

17 sie 2010

Klasy robocika i wroga

Jak już na początku wspomiałem praca nad gierką ma mi pomóc zrozumieć obiektowość i przyszedł czas na utworzenie pierwszych klas, a wraz z nimi funkcji, którymi będziemy sterowali naszą postacią. W porównaniu do poprzedniego posta i kodu tutaj uprzątniemy wszystkie zmienne i funkcje "walające się po programie" i zamkniemy je do "pudełka" abyśmy się w przyszłości nie pogubili. (myślę, że gra będzie miała min 1500 linii kodu). Tak więc zaczynamy
Nasza 1 klasa będzie przedstawiała naszego robocika, którym kierujemy:

class Cpostac
 {
 public:
 int pozs_x, pozs_y;
 int pozpoc_x, pozpoc_y;
 void chodzenie();
 void strzelanie();
 void ograniczniki();

 Cpostac::Cpostac()
 {
   pozs_x=250;
   pozs_y=400;
   zycia=100;
 }
};


pozs_x, pozs_y; oznaczają współrzędne robocika a pozpoc_x, pozpoc_y oznaczają współrzędne jego pocisku i w konstruktorze ustalamy współrzędne robocika, jakie będzie miał po uruchomienu gry jak i jego życia. Liczba 100 będzie odpowiednia(ale o tym wspomnę kiedy indziej)
a tutaj mamy definicję metod:

void Cpostac::chodzenie()
{
  if( key[KEY_LEFT]) { pozs_x=pozs_x-2; }
  if( key[KEY_RIGHT]) { pozs_x=pozs_x+2; }
  if( key[KEY_UP]) { pozs_y=pozs_y-1; }
  if( key[KEY_DOWN]) { pozs_y=pozs_y+1; }
}

void Cpostac::ograniczniki()
{
  if(pozs_y>408) { pozs_y=408; }
  if(pozs_y<340) { pozs_y=340; }
  if(pozs_x<0) { pozs_x=0; }
  if(pozs_x>748) { pozs_x=748; }
}

void Cpostac::strzelanie()
{
  pozpoc_x=pozs_x+15;
  pozpoc_y=pozs_y-15;
}

 
 Mała zmiana, teraz gra będzie się nam wyświetlała nie w oknie, lecz na całym ekranie dlatego zmieniłem wartości funkcji void Cpostac::ograniczniki() aby były dostosowane do tej rozdzielczości...

oto funkcja, dzięki której nasza gra jest fullscreen
set_gfx_mode(GFX_AUTODETECT,800,600,0,0); 

 ________________________________________________________________________
Pora na klasę wroga

class Cwrog_easy
{
 public:
 int pozwro_x, pozwro_y;
 int pozpocwro_x, pozpocwro_y;  
 void poruszanie_wroga();
 void strzelanie_wroga();  
 
 Cwrog_easy::Cwrog_easy()
 {
   pozwro_x=rand()%740;
   pozwro_y=0;
 }
};

tutaj omówieniu wymaga  linijka w konstruktorze:
pozwro_x=rand()%550; 
oznacza ona, że pozycja x zostanie wylosowana losowo z przedziału 0-740 (po to aby nasz wróg nie spadał tylko z 1 miejsca)

i funkcje składowe:

void Cwrog_easy::poruszanie_wroga()
{
  pozwro_y++;
  if( (pozwro_y>430) || (pozwro_y==0) )
  {
    pozwro_x=rand()%740;
    pozwro_y=0;
  }
}

void Cwrog_easy::strzelanie_wroga()
{
  if( (pozpocwro_y>460) || (pozpocwro_y==0) )
  {
    pozpocwro_x=pozwro_x+7;
    pozpocwro_y=pozwro_y+25;
  }
  pozpocwro_y=pozpocwro_y+3;
}

 
Omówienie void Cwrog_easy::poruszanie_wroga():
ta funkcja jak inne będzie wywoływana w main() po przebiegu pętli  while( !key[KEY_ESC])  czyli dopóki nie naciśniemy escape i aby nasz wróg się poruszał to po każdym obiegu pętli dodajemy 1 pozwro_y++;.
 Jeżeli nasza postać dojdzie do dołu ekranu to ponownie losujemy jej współrzęną x, a ustawiamy na 0;

if( (pozwro_y>430) || (pozwro_y==0) )
{
  pozwro_x=rand()%740;
  pozwro_y=0;
}  


 Omówienie void Cwrog_easy::strzelanie_wroga();
 Ta funkcja odpowaida za strzelanie naszego wroga. Nasz wróg będzie sprzelał cały czas tzn dopóki pocisk nie opuści ekranu, a jak opuści to przypisujemy pociskowi nowe współrzędne:

if( (pozpocwro_y>460) || (pozpocwro_y==0) )
{
  pozpocwro_x=pozwro_x+7;
  pozpocwro_y=pozwro_y+25; 
}

tak jak w poprzeniej funkcji musimy wprawić nasz pocisk w ruch i po każdym przebiegu pętli dodajemy 3 aby pocisk leciał trochę szybciej od wroga  pozpocwro_y=pozpocwro_y+3;


Wkrótce pokażę klasę odpowiadającą za "menu"(tak ją nazwałem tutaj będą informacje o stanie gry amunicja, życia, pkt itp) i jak wygląda kod gry... Jak ktoś podczas czytania był spostrzegawczy i zauważył pozpocwro_y>460 (czyli jak coś wyjdzie poza ekran) i jest tutaj liczba 460, a nie 600 jak nasza rozdzielczość 800/600 a to dlatego, że w dolnej części będzie wyświetlane menu i musimy zabrać trochę miejsca z całego ekranu na menu czyli  120 pikseli...
Oto screen z wersji (ver.1.01)




15 sie 2010

biblioteka allegro i poczatki gry space destroyer

Na początku powinienem opisać biblioteczkę allegro lecz tego nie zrobię, ponieważ jest już kilka kursów i tutoriali.  Oto 2 z nich: http://kursy.ddt.pl/?TutorialId=7   lub http://www.gamedev.pl/tutorials.php
Opowiem o co w tym chodzi...

Z góry przepraszam za chaos jaki panuje w kodzie, ponieważ dopiero zaczynam uczyć się obiektowości i napiszę to jak umiem czyli strukturalnie. W następnym poście obiecuję zrobić porządek i zrobić jakieś klasy i pliki nagłówkowe...
Na początku tworzymy tak jakby "ćwiartkę układu współrzędnych" czyli taki prostokąt u mnie to
set_gfx_mode(GFX_AUTODETECT,600,480,0,0);
czyli 600:480.
Napisałem ćwiartkę, ponieważ utworzona przez Nas bitmapa w której wszystko będzie się działo dzieli się na 600 /480 pikseli, a lewy górny róg ma współrzędne x=0 y=0


0123
1000   ten punkt ma współrzędne: x=2, y=1
2000


Napiszę teraz o poruszaniu się po takim prostokącie czyli wyświetlaniu bitmap
mamy funkcję z biblioteki allegro:
draw_sprite(bufor, statek, statek_x, statek_y);
służy ona do rysowania na ekranie poszczególnych bitmap.
pierwszym argumentem jest bitmapa, na której będziemy wyświetlali nasze "obrazki", drugim "obrazek" który chcemy wyświetlić, trzeci to współrzędna x, czwarty współrzędna y.


Gra będzie działała w pętli  while( !key[KEY_ESC])  czyli dopóki nie naciśniemy escape.
Naszym głównym bohaterem będzie robocik :) Będziemy nim poruszać za pomocą strzałek:
na boki będzie chodził szybciej
if( key[KEY_LEFT]) {statek_x=statek_x-2;
if( key[KEY_RIGHT]) statek_x=statek_x+2;
 a w górę i w dół wolniej
if( key[KEY_UP]) statek_y--;
if( key[KEY_DOWN]) statek_y++;

potrzebne są jakieś ograniczniki aby postać nie wychodziła za bitmapę 600:480. Oto one:
 p.s. ograniczyłem także postaci zasięg poruszania siędo góry...
if(statek_y>410) { statek_y=410; }
if(statek_y<350) { statek_y=350; }
if(statek_x<0) { statek_x=0; }
if(statek_x>550) { statek_x=550; }


 A teraz o animacji...
Aby gra ładniej wyglądała potrzebna jest jakaś animacja czyli ruch postaci. Głupio jest jeździć robocikiem po ekranie, który nie rusza nogami, rekoma...
Na początek dzielimy nasz timer BPS_TO_TIMER(80) na 80 cyki w ciągu sekundy czyli: 80 frame;
 i sprawdzamy za pomocą: warunku if wartosc frame i wyswietlamy jakies poszczególne obrazki na bitmapie u Nas są 3 :
 statek; statek1, statek2

if( frame<20)
{
   draw_sprite(bufor, statek, statek_x, statek_y);   
}


else if( frame>=20 && frame<40)
{
  draw_sprite(bufor, statek1, statek_x, statek_y);  
}


else if( frame>=40 && frame<60)
{
  draw_sprite(bufor, statek2, statek_x, statek_y);
 }


else if( frame>=60 && frame<80)
{
  draw_sprite(bufor, statek1, statek_x, statek_y); 
}

Teraz jak już mamy Naszego robocika to przydało by się żeby strzelał :)
Nasz pocisk ja każdy obiekt musi posiadaćwspółrzędne x i y
int pocisk_x=0, pocisk_y=0;  
strzelać będziemy spacją:

if( key[KEY_SPACE])
{
   if((pocisk_y<0) || (pocisk_y==0) )
   {
     pocisk_x=statek_x+15, pocisk_y=statek_y-15; play_sample(dzwiek,255,10,1000,0);
   }

 
 ustawiamy pozycję początkową pocisku aby robocik nie strzelał z nóg tylko z głowy czyli  
x pocisk_x=statek_x+15 i y pocisk_y=statek_y-15

 aby nasz pocisk leciał to po każdym obiegu pętli musimy odjąć jakąś wartość
pocisk_y=pocisk_y-8; czyli po każdym obiegu pętli nasz pocisk leci do góry o 8 pikseli

zrobiłem także małe ograniczenie aby można było strzelić ponownie pocisk musi wylecieć za planszę lub miećpozycję y==0;
if((pocisk_y<0) || (pocisk_y==0) )

 Jak możemu już strzelać to przydał by się jakiś cel...
Tworzymy wroga i nadajemy mu współrzędne   int posw_x=200, posw_y=0;  i wprawiamy go w ruch czyli po każdym obiegu pętli leci w dół : posw_y++;

jeżeli nie ustrzelimy wroga i spadnie nam za ekran to musi mieć nowe współrzędne wyjaśnienie niżej...
if (posw_y>420) 
{
   posw_x=rand()%550;
   posw_y=0;
}



jak mamy już cel to musimy zrobić jakąśkolizję aby można było w ten cel trafić. Znalazłem u wujka google taką funkcję:


bool kolizja(int x1,int y1,int s1,int w1,int x2,int y2,int s2,int w2)
{
   if( x2<=x1+s1 && x2>x1 && y2>=y1 && y2<=y1+w1) return true; 
else 
   if( x2<=x1+s1 && x2>x1 && y2+w2>=y1 && y2+w2<=y1+w1) return true; else 
   if( x2+s2<=x1+s1 && x2+s2>x1 && y2>=y1 && y2<=y1+w1) return true; else 
   if( x2+s2<=x1+s1 && x2+s2>x1 && y2+w2>=y1 && y2+w2<=y1+w1) return true; 
else return false; };

i wykorzystujemy ją w taki sposób:
-1argumentem jest pozycja x wroga
 -2argumentem jest pozycja y wroga
-3 argumentem jest "wskażnik do bitmapy" i jej długości pocisk->w
 -4 argumentem jest "wskażnik do bitmapy" i jej wysokości pocisk->h
reszta tak samo tylko mamy wtedy za obiekt pocisk...

 if(kolizja(posw_x, posw_y, pocisk->w, pocisk->h, pocisk_x, pocisk_y, pocisk->w, pocisk->h) == true)
 (jeżeli trafimy we wroga to w jego miejscu zrobiłem animację wybuchu)
 i nadajemy nowe wartości dla wrogra:
posw_x=rand()%550; - aby gra nie była przewidywalna losujemy z przedziału 0-550 liczbę x  współrzędną x
  posw_y=0;

 W grze musi być jeszcze jakaś muzyczka i odtwarzamy ją:
 play_sample(muza, 100,100,1000,1);
 parametry 2 i 3 określają głośność na lewy i prawy głośnik z przedziału 0-255
 4 oznacza prędkość z jaką odgrywany jest plik 1000 to prędkość normalna
i 5 oznacza ile razy ma być odgrywany. Wartość 1 oznacza replay non stop :P, 0 oznacza tylko 1 raz

Jeżeli są jakieś pytania lub jakieś uwagi, sugestie piszcie w komentarzach to wszystko wyjaśnię :)
Do ściągnięcia pełny kod gry(ver. 1.00) wraz z potrzebnymi plikami do uruchomienia gry :)
Oto screen do  (ver. 1.00)