kubawal Temat założony przez niniejszego użytkownika |
[C++] [Allegro] Problem z kolizją (znowu... :) ) » 2012-11-20 16:04:07 Witam! Ostatnio napisałem sobie gierkę typu "ludzik ruszany strzałkami" Wszystko działało, do momentu, gdy dodałem kolizję z obiektem i zamiast skomplikowanego kodu dodałem klasy. Oto mój kod: classes.h #include <allegro.h> #include <string>
using namespace std;
inline int randint( int max ) { return rand() % max; }
inline int randint( int min, int max ) { return randint( max - min ) + min; }
#define K_1_2 1 #define K_2_3 2 #define K_3_4 3 #define K_4_1 4 #define K_NOT 0
bool kolizja( int x1, int y1, int s1, int w1, int x2, int y2, int s2, int w2 );
class Object { public: int X, Y; int W, H; BITMAP * bmp; struct Invalid { Invalid() { } }; Object( string name, int xX = 0, int yY = 0 ) : X( xX ) , Y( yY ) { bmp = load_bmp( name.c_str(), default_palette ); if( !bmp ) throw Invalid(); W = bmp->w; H = bmp->h; } virtual ~Object() { destroy_bitmap( bmp ); } virtual bool collision( Object & o ); };
class Enemy;
class Player : public Object { struct Pos { int x, y; Pos( int xx, int yy ) : x( xx ) , y( yy ) { } }; int edges( Object & o ); public: int HP; int edge; Player( string name = "C:\\grafika\\ludek.bmp", int xX = 300, int yY = 300 ) : Object( name, xX, yY ) , HP( 100 ) , edge( K_NOT ) { } bool collision( Object & o ); };
class Enemy : public Object { public: Enemy( string name = "C:\\grafika\\przeszkoda.bmp", int xX = - 1, int yY = - 1 ) : Object( name ) { if( xX = - 1 ) X = randint( 0, 600 - W ); else X = xX; if( yY = - 1 ) Y = randint( 0, 600 - H ); else Y = yY; } };
class Buffer { BITMAP * buf; int color; public: Buffer( int w, int h, int ccolor = makecol( 0, 0, 0 ) ) : buf( create_bitmap( w, h ) ) , color( ccolor ) { clear(); } ~Buffer() { destroy_bitmap( buf ); } void clear() { clear_to_color( buf, color ); } enum Copy_type { Normal, Masked }; void copy( BITMAP * src, int x, int y, Copy_type bt ); void draw(); };
classes.cpp #include "classes.h"
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; };
bool Object::collision( Object & o ) { if( kolizja( X, Y, W, H, o.X, o.Y, o.W, o.H ) || kolizja( o.X, o.Y, o.W, o.H, X, Y, W, H ) ) return true; else return false; }
bool Player::collision( Object & o ) { if( Object::collision( o ) ) { edge = edges( o ); return true; } else return false; }
int Player::edges( Object & o ) { Pos o1( o.X, o.Y ), o2( o.X + o.W, o.Y ), o3( o.X + o.W, o.Y + o.H ), o4( o.X, o.Y + o.W ); Pos p1( X, Y ), p2( X + W, Y ), p3( X + W, Y + H ), p4( X, Y + W ); if( o1.y == p3.y &&(( p3.x >= o1.x && p3.x <= o2.x ) ||( p4.x >= o1.x && p4.x <= o2.x ) ) ) return K_1_2; if( o2.x == p2.x &&(( p1.y >= o2.y && p1.y <= o3.y ) ||( p4.y >= o2.y && p4.y <= o3.y ) ) ) return K_2_3; if( o3.y == p1.y &&(( p1.x >= o3.x && p1.x <= o4.x ) ||( p2.x >= o3.x && p2.x <= o4.x ) ) ) return K_3_4; if( o4.x == p2.x &&(( p2.y >= o4.y && p2.y <= o1.y ) ||( p3.y >= o4.y && p3.y <= o1.y ) ) ) return K_4_1; return K_NOT; }
void Buffer::copy( BITMAP * src, int x, int y, Copy_type bt ) { switch( bt ) { case Normal: blit( src, buf, 0, 0, x, y, src->w, src->h ); break; case Masked: masked_blit( src, buf, 0, 0, x, y, src->w, src->h ); break; } } void Buffer::draw() { blit( screen, buf, 0, 0, 0, 0, buf->w, buf->h ); clear(); }
main.cpp #include "classes.h" #define SILA_ODBICIA 5
Buffer buf( 800, 800, makecol( 255, 255, 255 ) );
void Game(); void Repaint( Player & p, Enemy & e );
int main( void ) { allegro_init(); install_keyboard(); set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 800, 0, 0 ); set_color_depth( 8 ); set_palette( default_palette ); clear_to_color( screen, makecol( 0, 255, 255 ) ); Game(); allegro_exit(); return 0; } END_OF_MAIN();
void Game() try { Player player( "C:\\grafika\\ludek.bmp" ); Enemy enemy( "C:\\grafika\\przeszkoda.bmp" ); clear_to_color( screen, makecol( 0, 255, 255 ) ); while( !key[ KEY_ESC ] ) { if( !player.collision( enemy ) ) { if( key[ KEY_UP ] ) player.Y--; if( key[ KEY_DOWN ] ) player.Y++; if( key[ KEY_LEFT ] ) player.X--; if( key[ KEY_RIGHT ] ) player.X++; } else { switch( player.edge ) { case K_1_2: player.Y -= SILA_ODBICIA; break; case K_2_3: player.X += SILA_ODBICIA; break; case K_3_4: player.Y += SILA_ODBICIA; break; case K_4_1: player.X -= SILA_ODBICIA; default: allegro_message( "Niespodziawany błąd w funkcji Player::colission(): niezdefiniowana krawędź uderzenia" ); } player.HP -= 10; } Repaint( player, enemy ); } } catch( Object::Invalid oi ) { allegro_message( "Wystąpił błąd ładowania bitmap \"ludek.bmp\" i \"przeszkoda.bmp\"" ); return; }
void Repaint( Player & p, Enemy & e ) { buf.copy( p.bmp, p.X, p.Y, Buffer::Masked ); buf.copy( e.bmp, e.X, e.Y, Buffer::Masked ); buf.draw(); buf.clear(); }
Gdy próbuje ją uruchomić, występuje błąd czasu wykonania ("Wystąpił problem z aplikacją allegro.exe..." itd.) Wiecie, co się dzieje? Pozdrawiam kubawal |