Rughailon Temat założony przez niniejszego użytkownika |
[c++, allegro5] Złe poruszanie przy obrocie obiektu » 2013-07-01 20:31:36 Witam. Mam pewien problem, którego nijak rozwiązać nie potrafię. Mam klase czołgu, w której są wszystkie potrzebne zmienne i funkcje na obracanie. Tanks.hpp #ifndef TANKS_HPP_INCLUDED #define TANKS_HPP_INCLUDED
#include "main.h" #include "input.h"
class cTank { public: int x, y; int w, h; float v, max_v; int strength; float angle_tank; float v_gun, angle_gun; ALLEGRO_BITMAP * tank; ALLEGRO_BITMAP * gun; cTank( int, int, int, int, float, int, ALLEGRO_BITMAP *, ALLEGRO_BITMAP * ); bool gun_angle(); bool go(); };
#endif
Tanks.cpp #include "Tanks.hpp"
extern CKeyboard key; extern CMouse mouse;
cTank::cTank( int X, int Y, int W, int H, float MAX_V, int STRENGHT, ALLEGRO_BITMAP * TANK, ALLEGRO_BITMAP * GUN ) : x( X ) , y( Y ) , w( W ) , h( H ) , max_v( MAX_V ) , strength( STRENGHT ) , tank( TANK ) , gun( GUN ) { v = 0; angle_tank = 0; v_gun = 0; angle_gun = 0; }
bool cTank::gun_angle() { angle_gun = atan2( mouse.getY() - y, mouse.getX() - x ); }
bool cTank::go() { if( key.Press( ALLEGRO_KEY_W ) ) v += 0.1; if( key.Press( ALLEGRO_KEY_A ) ) angle_tank -= 0.01; if( key.Press( ALLEGRO_KEY_D ) ) angle_tank += 0.01; if( key.Press( ALLEGRO_KEY_S ) ) v -= 0.1; x += v * cos( angle_tank ); y += v * sin( angle_tank ); cout << x << " , " << y << endl; } I teraz jest problem, bo gdy obrócę czołgiem o pewną wartość, to czołg zaczyna sam jechać, a jeśli stoi, to po poruszeniu, za bardzo zmniejsza swoją pozycje na osi x(jedzie nienaturalnie w góre ekranu). Przeglądałem tematy na tym forum i siedziałem nad kartką, ale nic nie przychodzi mi do głowy. Szereg poprawek także nie pomógł. I tu jeszcze kod na wyświetlanie grafiki czołgu.
al_draw_rotated_bitmap( one.tank, getBmpW( one.tank ) / 2, getBmpH( one.tank ) / 2, one.x, one.y, one.angle_tank, 0 );
|
|
DejaVu |
» 2013-07-02 00:29:31 angle_gun = atan2( mouse.getY() - y, mouse.getX() - x );
To jest niepoprawne. Jeżeli Allegro przyjmuje kąty w stopniach to musisz pozamieniać radiany na stopnie. atan2 |
|
SeaMonster131 |
» 2013-07-02 10:47:23 @up: Allegro5 przyjmuje kąt w radianach, wiec nie trzeba niczego zamieniać ;) |
|
DejaVu |
» 2013-07-02 10:49:04 No to może bitmapa ma puste miejsce z jakiegoś boku i wówczas środek czołgu nie jest po środku tekstury, tylko w innym miejscu przez co uzyskuje się dziwne efekty. |
|
Gabes |
» 2013-07-02 13:34:15 Napisałem mały testowy program, który chyba lepiej pokaże wszystko, niż kilka linijek które nic ci nie pomogą. #include <allegro5/allegro.h> #include <allegro5/allegro_font.h> #include<allegro5/allegro_image.h> #include <cmath> int main() { al_init(); al_install_keyboard(); al_install_mouse(); al_init_font_addon(); al_init_image_addon(); ALLEGRO_KEYBOARD_STATE key_state; ALLEGRO_MOUSE_STATE mouse_state; al_set_new_display_flags( ALLEGRO_FULLSCREEN ); ALLEGRO_DISPLAY * okno = al_create_display( 800, 600 ); al_set_window_title( okno, "Tank" ); ALLEGRO_BITMAP * tank = al_create_bitmap( 40, 80 ); ALLEGRO_BITMAP * lufa = al_create_bitmap( 10, 60 ); ALLEGRO_FONT * font8 = al_create_builtin_font(); al_set_target_bitmap( tank ); al_clear_to_color( al_map_rgb( 150, 50, 50 ) ); al_set_target_bitmap( lufa ); al_clear_to_color( al_map_rgb( 255, 250, 250 ) ); al_set_target_bitmap( al_get_backbuffer( okno ) ); float TankX = 400, TankY = 560; float SpeedT = 0.04; float AngleT = 0.0; float AngleL = 0.0; while( !al_key_down( & key_state, ALLEGRO_KEY_ESCAPE ) ) { al_clear_to_color( al_map_rgb_f( 0.5, 0.5, 0.5 ) ); al_get_keyboard_state( & key_state ); al_get_mouse_state( & mouse_state ); if( al_key_down( & key_state, ALLEGRO_KEY_D ) ) AngleT += 0.001; if( al_key_down( & key_state, ALLEGRO_KEY_A ) ) AngleT -= 0.001; if( al_key_down( & key_state, ALLEGRO_KEY_W ) ) SpeedT += 0.0001; if( al_key_down( & key_state, ALLEGRO_KEY_S ) ) SpeedT -= 0.0001; if( al_key_down( & key_state, ALLEGRO_KEY_SPACE ) ) SpeedT = 0.04, TankX = 400, TankY = 300; TankX += SpeedT * cos( AngleT - ALLEGRO_PI / 2 ); TankY += SpeedT * sin( AngleT - ALLEGRO_PI / 2 ); AngleL = atan2( TankY - mouse_state.y, TankX - mouse_state.x ) - ALLEGRO_PI / 2, 0; al_draw_rotated_bitmap( tank, al_get_bitmap_width( tank ) / 2, al_get_bitmap_height( tank ) / 2, TankX, TankY, AngleT, 0 ); al_draw_rotated_bitmap( lufa, al_get_bitmap_width( lufa ) / 2, al_get_bitmap_height( lufa ), TankX, TankY, AngleL, 0 ); al_draw_textf( font8, al_map_rgb( 255, 255, 0 ), 5, 5, 0, "TankX=%3.0f , TankY=%3.0f , AngleL%4.0f , AngleT%4.0f", TankX, TankY, AngleL, AngleT ); al_flip_display(); } al_destroy_bitmap( tank ); al_destroy_bitmap( lufa ); al_destroy_display( okno ); return 0; } Edycja: Poprawiłem kod, niepotrzebnie zamieniałem wcześniej na stopnie, a w funkcji wyświetlającej z powrotem na radiany. Było tak: TankX += speedT * cos(( angleT * ALLEGRO_PI ) / 180.0 ); TankY += speedT * sin(( angleT * ALLEGRO_PI ) / 180.0 ); al_draw_rotated_bitmap( tank, 40 / 2, 80 / 2, TankX, TankY,( angleT - 90 ) *( ALLEGRO_PI / 180 ), 0 ); |
|
Rughailon Temat założony przez niniejszego użytkownika |
» 2013-07-04 14:28:18 No niestety nadal nie działa tak, jak powinno. O dziwo przykładowy kod działa, więc podejrzewam, że spieprzyłem coś małego.
No nic. Dziękuje wam bardzo za pomoc. :)
//edit Już wszystko działa. Seamonster131 rozwiązał problem. :) Okazało się zmienne x i y w klasie czołgu powinny być we float, a nie w int. Na dodatek trzeba było usunąć "-ALLEGRO_PI/2" w cos() i sin(). |
|
« 1 » |