Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Allegro, C++] Błąd po kolizji

Ostatnio zmodyfikowano 2009-03-29 16:18
Autor Wiadomość
paczaja
Temat założony przez niniejszego użytkownika
[Allegro, C++] Błąd po kolizji
» 2009-03-27 17:17:35
Witam!
Mam problem z moją grą w Allegro...jest to banalna gra, w którym jedna postać goni drugą i musi ją złapać...gdy złapie jest kolizja...i tu jest problem...funkcje kolizjii już mam, ale daje if'a, że jeżeli wystąpi kolizja ma pokazać jakiś obrazeczek a potem wrzucić ludki do rogów...wszystko by było dobrze, ale jeżeli złapiemy drugiego ludka i przytrzymamy np: strzałkę w górę to nasza postać zacznie w połowie ekranu...jak temu zaradzić?? Oto kod:

C/C++
class Cpostac
{
public:
    short int x, y;
    short int s, w;
};

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;
   
};

Cpostac ludek1, ludek2;
#include <allegro.h>
#include <winalleg.h>
#include <winable.h>
volatile long speed = 0;

void increment_speed()
{
    speed++;
}
END_OF_FUNCTION( increment_speed );

LOCK_VARIABLE( speed );
LOCK_FUNCTION( increment_speed );

int main()
{
    allegro_init();
    install_keyboard();
    set_color_depth( 16 );
    set_gfx_mode( GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0 );
    clear_to_color( screen, makecol( 150, 150, 150 ) );
    install_timer();
    install_int_ex( increment_speed, BPS_TO_TIMER( 300 ) );
    BITMAP * zacz = NULL;
    BITMAP * zlap = NULL;
    BITMAP * bufor = NULL;
    BITMAP * ludekb1 = NULL;
    BITMAP * ludekb2 = NULL;
   
    bufor = create_bitmap( 640, 480 );
    ludekb1 = load_bmp( "ludekb1.bmp", default_palette );
    ludekb2 = load_bmp( "ludekb2.bmp", default_palette );
    zlap = load_bmp( "zlap.bmp", default_palette );
    zacz = load_bmp( "zacz.bmp", default_palette );
   
    ludek1.x = 610; ludek1.y = 440; ludek1.s = 40; ludek1.w = 40;
    ludek2.x = 0; ludek2.y = 0; ludek2.s = 40; ludek2.w = 40;
    while( !key[ KEY_SPACE ] )
    {
        masked_blit( zacz, screen, 0, 0, 0, 0, zacz->w, zacz->h );
        if( key[ KEY_ESC ] ) {
            destroy_bitmap( bufor );
            destroy_bitmap( ludekb1 );
            destroy_bitmap( ludekb2 );
           
            allegro_exit();
            return 0; }
        readkey();
    }
    while( !key[ KEY_ESC ] )
    {
       
        while( speed > 0 )
        {
           
            if( ludek1.y == 440 ) ludek1.y--;
           
            if( ludek1.x == 610 ) ludek1.x--;
           
            if( ludek1.y == 0 ) ludek1.y++;
           
            if( ludek1.x == 0 ) ludek1.x++;
           
            if( key[ KEY_LEFT ] ) ludek1.x--;
           
            if( key[ KEY_RIGHT ] ) ludek1.x++;
           
            if( key[ KEY_UP ] ) ludek1.y--;
           
            if( key[ KEY_DOWN ] ) ludek1.y++;
           
            if( ludek2.y == 440 ) ludek2.y--;
           
            if( ludek2.x == 610 ) ludek2.x--;
           
            if( ludek2.y == 0 ) ludek2.y++;
           
            if( ludek2.x == 0 ) ludek2.x++;
           
            if( key[ KEY_A ] ) ludek2.x--;
           
            if( key[ KEY_D ] ) ludek2.x++;
           
            if( key[ KEY_W ] ) ludek2.y--;
           
            if( key[ KEY_S ] ) ludek2.y++;
           
            speed--;
        }
        clear_to_color( bufor, makecol( 150, 150, 150 ) );
       
        masked_blit( ludekb1, bufor, 0, 0, ludek1.x, ludek1.y, ludek1.s, ludek1.w );
        masked_blit( ludekb2, bufor, 0, 0, ludek2.x, ludek2.y, ludek2.s, ludek2.w );
       
       
        if( kolizja( ludek1.x, ludek1.y, ludek1.s, ludek1.w, ludek2.x, ludek2.y, ludek2.s, ludek2.w ) == true )
        { masked_blit( zlap, screen, 0, 0, 200, 200, zlap->w, zlap->h );
           
            ludek1.x = 610; ludek1.y = 440; ludek1.s = 40; ludek1.w = 40;
            ludek2.x = 0; ludek2.y = 0; ludek2.s = 40; ludek2.w = 40;
        }
        blit( bufor, screen, 0, 0, 0, 0, 640, 480 );
       
    }
   
    destroy_bitmap( bufor );
    destroy_bitmap( ludekb1 );
    destroy_bitmap( ludekb2 );
   
    allegro_exit();
    return 0;
}
END_OF_MAIN();
P-5056
DejaVu
» 2009-03-27 17:33:17
Proponuję zacząć od zmiany funkcji kolizji: http://archiwum.ddt.pl/?TextId=1660

Ta z tematu jest przetestowana, natomiast z tego co forum pokazało, to z tą funkcją Easykodera są jakieś problemy.

Po drugie polecam opisać problem lepiej/jaśniej, ponieważ czytając to 3 razy nie za bardzo wiem o co chodzi... przypuszczam, że może chodzić o to, iż ludek zostaje na środku, a nie w rogu (tak zrozumiałem).
P-5057
paczaja
Temat założony przez niniejszego użytkownika
» 2009-03-27 19:48:07
Z tą funkcją kolizji to narazie nie mam problemu...a co do tego błędu...

C/C++
if( kolizja( ludek1.x, ludek1.y, ludek1.s, ludek1.w, ludek2.x, ludek2.y, ludek2.s, ludek2.w ) == true )
{ masked_blit( zlap, screen, 0, 0, 200, 200, zlap->w, zlap->h );
    rest( 1000 );
    ludek1.x = 610; ludek1.y = 440; ludek1.s = 40; ludek1.w = 40;
    ludek2.x = 0; ludek2.y = 0; ludek2.s = 40; ludek2.w = 40;
}

Teoretycznie gdy program wykryje błąd powinien pokazać obrazek ("zlap.bmp"), później odczekać 1s i wrzucić oba ludziki do rogów...i tak się dzieje, jeżeli odrazu po pokazaniu się w/w obrazka puścimy klawisze sterowania. W przeciwnym wypadku(jeżeli przytrzymamy klawisze sterowania) ludzik nie zaczyna już od rogu tylko w innym położeniu. Przesunie się zgodnie z użytym klawiszem(jeżeli użyjemy klawisza odpowiedzialnego za ruch w lewo to zacznie troche bardziej z lewej strony). To wygląda, jakby przez daną sekundę zbierał informacje o wciśniętym klawiszu, a następnie wyzwalał to, dzięki czemu nie zaczyna już w swoim oryginalnym położeniu.
P-5058
DejaVu
» 2009-03-27 20:17:59
Jeśli nastąpi kolizja ustaw jeszcze speed = 0;.
P-5059
paczaja
Temat założony przez niniejszego użytkownika
» 2009-03-27 20:35:51
Super, działa. Dzięki. Mam jeszcze jedno pytanie: jak zrobić aby na początku nad player'em 1 pisało coś w stylu "gonisz!" a gdy już złapie to nad playerem nr2 by się takie coś pojawiało. Chodzi o to aby było tak na zmianę. Myślałem nad podwojeniem tej głównej pętli. Najpierw gra pracowałaby na 1 pętli, a jeżeli nastąpi kolizja to zmienia obrazek(na jakiś specyficzny - "goniący") i przechodzi na drugą pętlę...Ale może jest jakiś lepszy sposób?
P-5061
DejaVu
» 2009-03-27 20:59:16
Jest... wstawiasz zmienną:
int goniGracz = 0;
Zmiana goniącego:
C/C++
switch( goniGracz )
{
case 0:
    goniGracz = 1;
    break;
case 1:
    goniGracz = 0;
    break;
} //switch
Sposobów jest dużo więcej i są też dużo krótsze, jednak to chyba będzie najprostsze do zrozumienia :).
P-5063
pekfos
» 2009-03-28 09:01:31
po co sie trucdzić z tyloma argumentami?
bool kolizja( int, int, int, int, int, int, int, int );
można to zrobić tak:
bool kolizja( Cpostac, Cpostac );
bo w klasie Cpostac są zmienne x, y, h, w, więc zamiast
podawać je osobno można podać je razem i oszczędzić sobie trudu
P-5071
DeBugger
» 2009-03-29 16:18:40
bool kolizja( CPostac & postac, CPostac & postac1 )
P-5112
« 1 »
  Strona 1 z 1