|
Rotating sprite in allegro |
Neomex
Member #11,618
January 2010
|
Hello, [code] --- I found similar thread on this forum, and was trying to make like there, but I still got problem, because it rotates well, but mouse is behind player. const double rad_to_deg = 180.0/M_PI; player.angle = -atan2( mouse_x - player.x, mouse_y-player.y); |
type568
Member #8,381
March 2007
|
You should really read your post at least once after posted, at least unless you learn how to use the forum's formatting. Neomex said: I found similar thread on this forum, and was trying to make like there, but I still got problem, because it rotates well, but mouse is behind player.
So put it above the "player"? o0
|
Neomex
Member #11,618
January 2010
|
That's not what I mean, but I just rotated texture at 180 degrees and now works perfectly, but I don't know how to move player to mouse direction. 1const double rad_to_deg = 180.0/M_PI;// 360.0/(2.0*M_PI);
2const double deg_to_adeg = 32.0/45.0;// 256.0/360.0;
3const double rad_to_adeg = 128.0/M_PI;
4
5double tab_sin[360];
6double tab_cos[360];
7
8void laduj_sin_cos()
9{
10 for(int i=0; i < 360; i ++)
11 {
12 tab_sin[i] = sin((M_PI*(i))/180);
13 tab_cos[i] = cos((M_PI*(i))/180);
14 }
15}
16
17
18...
19
20
21if( key[KEY_W] )
22 {
23 //player.x += cos(player.angle) * 5;
24 //player.y += sin(player.angle) * 5;
25 player.angle = player.angle * rad_to_adeg;
26 player.x -= 2*tab_cos[ int( player.angle ) ];
27 player.y -= 2*tab_sin[ int( player.angle ) ];
28
29 }
It moves in strange ways |
GullRaDriel
Member #3,861
September 2003
|
What do you want to do exactly ? According to my crystal ball (which is not really working fine ya know): 1) You have a point that represent the player with x and y "Code is like shit - it only smells if it is not yours" |
Neomex
Member #11,618
January 2010
|
Main.cpp 1#include "main.h"
2#include "bmp.h"
3#include "timer.h"
4
5#include "player.h"
6
7int main()
8{
9allegro_init();
10depth = desktop_color_depth();
11if (depth == 0) depth = 32;
12 set_color_depth(depth);
13
14res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, WINDOW_X, WINDOW_Y, 0, 0);
15 if (res != 0) {
16 allegro_message(allegro_error);
17 exit(-1);
18 }
19
20install_timer();
21install_keyboard();
22install_mouse();
23install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,"");
24set_volume(255,255);
25
26//select_mouse_cursor(1);
27show_mouse(screen);
28LOCK_VARIABLE(speed_counter); //Used to set the timer - which regulates the game's
29LOCK_FUNCTION(increment_speed_counter);//speed.
30
31install_int_ex(increment_speed_counter, BPS_TO_TIMER(60));//Set our BPS
32
33//inits
34Cplayer player;
35
36buf = create_bitmap(WINDOW_X, WINDOW_Y);
37grass = load_bitmap("grass.bmp", 0);
38
39hud = load_bitmap("hud.bmp", 0);
40ppistol = load_bitmap("ppistol.bmp", 0);
41
42laduj_sin_cos();
43
44while (!key[KEY_ESC])
45{
46 /* put your code here */
47 clear(buf);
48 masked_blit(grass, buf, 0, 0, 0, 0, grass->w, grass->h);
49 masked_blit(hud, buf, 0, 0, 800, 0, hud->w, hud->h);
50
51 while(speed_counter > 0)
52 {
53 if( key[KEY_W] )
54 {
55 player.x += cos(player.angle) * 5;
56 player.y += sin(player.angle) * 5;
57 //player.angle = player.angle * rad_to_adeg;
58 //player.x -= 2*tab_cos[ int( player.angle ) ];
59 //player.y -= 2*tab_sin[ int( player.angle ) ];
60
61 }
62
63 //player.angle = atan2(player.x-player.y, mouse_x-mouse_y);
64 player.angle = -atan2( mouse_x - ( player.x + 25 ), mouse_y - ( player.y + 25 ) );
65 //player.angle = atan2( mouse_y - player.y, mouse_x-player.x);
66
67 player.hlong+=0.02;
68
69 speed_counter --;
70 }
71
72 //textprintf(buf, font, 0, 0, makecol(255, 0, 0), "Red Text");
73
74 //SCORES ON HUD
75 textprintf_ex(buf, font, 880, 125, makecol(0, 0, 255), -1, "%i" , player.life);
76 textprintf_ex(buf, font, 880, 185, makecol(0, 0, 255), -1, "%i" , player.score);
77 textprintf_ex(buf, font, 880, 250, makecol(0, 0, 255), -1, "%i" , player.wastedammo);
78 textprintf_ex(buf, font, 880, 320, makecol(0, 0, 255), -1, "%i" , player.ammo);
79 textprintf_ex(buf, font, 880, 380, makecol(0, 0, 255), -1, "%i" , player.score);
80 textprintf_ex(buf, font, 820, 510, makecol(0, 0, 255), -1, "%f" , player.hlong);
81 //TILDE VARIABLES
82 if( key[KEY_TILDE] && console == false )
83 {
84 console = true;
85 }else
86 if( key[KEY_TILDE] && console == true )
87 {
88 console = false;
89 }
90 if( console == true )
91 {
92 textprintf_ex(buf, font, 10, 10, makecol(255, 0, 0), -1, "Player Angle: %f" , player.angle*rad_to_adeg);
93 textprintf_ex(buf, font, 10, 20, makecol(255, 0, 0), -1, "Player X: %f" , player.x);
94 textprintf_ex(buf, font, 10, 30, makecol(255, 0, 0), -1, "Player Y: %f" , player.y);
95 }
96
97 rotate_sprite( buf , ppistol , player.x, player.y , ftofix( player.angle*rad_to_adeg ) ); //(player.angle*256)/360.0) );
98 //masked_blit(ppistol, buf, 0, 0, player.x, player.y, ppistol->w, ppistol->h);
99
100 masked_blit(buf, screen, 0, 0, 0, 0, buf->w, buf->h);
101}
102
103destroy_bitmap(buf);
104destroy_bitmap(grass);
105destroy_bitmap(ppistol);
106destroy_bitmap(hud);
107
108clear_keybuf();
109return 0;
110}
111END_OF_MAIN()
main.h 1#include <allegro.h>
2#include <math.h>
3
4#define WINDOW_X 1000
5#define WINDOW_Y 600
6
7int depth, res;
8
9#define DEGREES(x) int((x)/360.0*0xFFFFFF)
10#define RADIANS(x) int((x)/2/M_PI*0xFFFFFF)
11
12const double rad_to_deg = 180.0/M_PI;// 360.0/(2.0*M_PI);
13const double deg_to_adeg = 32.0/45.0;// 256.0/360.0;
14const double rad_to_adeg = 128.0/M_PI;
15
16bool console = false;
17
18double tab_sin[360];
19double tab_cos[360];
20
21void laduj_sin_cos()
22{
23 for(int i=0; i < 360; i ++)
24 {
25 tab_sin[i] = sin((M_PI*(i))/180);
26 tab_cos[i] = cos((M_PI*(i))/180);
27 }
28}
player files 1#include "player.h"
2
3Cplayer::Cplayer()
4{
5 x = 400;
6 y = 300;
7 w = 50;
8 h = 50;
9 speed = 5;
10 angle = 0;
11
12 life = 100;
13 score = 0;
14 wastedammo = 0;
15 ammo = 0;
16 killed_zombies = 0;
17
18 hlong = 0;
19}
20
21---
22
23class Cplayer
24{
25 public:
26
27 float x , y , w , h;
28
29 float angle;
30 float speed;
31
32 int life;
33 int score;
34 int wastedammo;
35 int ammo;
36 int killed_zombies;
37
38 float hlong;
39
40 Cplayer();
41};
I want to move player to mouse direction, after pressing W key. |
GullRaDriel
Member #3,861
September 2003
|
I don't know how to correct your code. I was lazy and I found it better to give you a working example. 1#include <math.h>
2#include <allegro.h>
3
4
5BITMAP *scrbuf = NULL ;
6BITMAP *sprite = NULL ;
7
8
9typedef struct PLAYER
10{
11 double x ,
12 y ;
13 fixed angle ;
14} PLAYER ;
15
16PLAYER player;
17
18
19double angle = 0 ;
20
21
22int main( int argc , char *argv[] )
23{
24 allegro_init();
25 install_keyboard();
26 install_mouse();
27 install_timer();
28 set_color_depth( 32 );
29 set_gfx_mode( GFX_AUTODETECT_WINDOWED , 800 , 600 , 0 , 0 );
30
31 scrbuf = create_bitmap( SCREEN_W , SCREEN_H );
32
33 sprite = create_bitmap( 64 , 256 );
34 clear_to_color( sprite , makecol( 255 , 0 , 255 ) );
35 rect( sprite , 10 , 10 , 54 , 246 , makecol( 255 , 0 , 0 ) );
36 line( sprite , 10 , 10 , 32 , 0 , makecol( 255 , 255 , 0 ) );
37 line( sprite , 32 , 0 , 54 , 10 , makecol( 255 , 255 , 0 ) );
38
39 player . x = SCREEN_W / 2 ;
40 player . y = SCREEN_H / 2 ;
41 player . angle = 0 ;
42
43
44 while( !key[ KEY_ESC ] )
45 {
46 player . angle = -fixatan2( ftofix( player . x - mouse_x ) , ftofix( player . y - mouse_y ) );
47
48 if( key[ KEY_SPACE ] )
49 {
50 int vx , vy ;
51 double size , cx , cy ;
52
53
54 vx = player . x - mouse_x ;
55 vy = player . y - mouse_y ;
56
57 if( vx || vy )
58 {
59 size = sqrt( vx*vx + vy*vy );
60
61 cx = vx/size ;
62 cy = vy/size ;
63 cx = 2 * cx ;
64 cy = 2 * cy ;
65
66 player . x = player . x - cx ;
67 player . y = player . y - cy ;
68
69 }
70 }
71
72
73 clear( scrbuf ) ;
74
75 textprintf_ex( scrbuf , font , 10 , 10 , makecol( 255 , 100 , 200 ) , -1 , "Angle: %0.0f" , fixtof( player.angle ) );
76
77 line( scrbuf , mouse_x - 5 , mouse_y , mouse_x + 5 , mouse_y , makecol( 255 , 255 , 255 ) );
78 line( scrbuf , mouse_x , mouse_y - 5 , mouse_x , mouse_y + 5 , makecol( 255 , 255 , 255 ) );
79
80
81 rotate_sprite( scrbuf , sprite , player . x - sprite -> w / 2 , player . y - sprite -> h / 2 , player . angle );
82 blit( scrbuf , screen , 0 , 0 , 0 , 0 , SCREEN_W , SCREEN_H );
83
84 }
85
86 destroy_bitmap( scrbuf );
87 destroy_bitmap( sprite );
88
89 allegro_exit();
90
91}END_OF_MAIN()
I attached source and (alleg4.4) binary. The sprite is rotating accordingly to the mouse position, and go in direction of the mouse when pressing SPACE. You were in need of rotation forumulae for the rotating part, but the move is only a vector story. I just calculated the normalised vector between mouse / player and used it at each frame. "Code is like shit - it only smells if it is not yours" |
Neomex
Member #11,618
January 2010
|
Works perfectly! Thanks a lot! I think I understand (mostly) how does it work. if( vx || vy ) It means: |
Arthur Kalliokoski
Second in Command
February 2005
|
nvrmnd They all watch too much MSNBC... they get ideas. |
GullRaDriel
Member #3,861
September 2003
|
I am not sure if it covers all the cases, but that if( vx ||vy ) is there to ensure that you'll never have a zero size (length) and thus not dividing by 0 in the next steps. Literately it means vx != 0 or vy != 0 "Code is like shit - it only smells if it is not yours" |
Neomex
Member #11,618
January 2010
|
One more question 1if( key[ KEY_SPACE ] )
2 {
3 int vx , vy ;
4 double size , cx , cy ;
5
6
7 vx = player . x - mouse_x ;
8 vy = player . y - mouse_y ;
9
10 if( vx || vy )
11 {
12 size = sqrt( vx*vx + vy*vy );
13
14 cx = vx/size ;
15 cy = vy/size ;
16 cx = 2 * cx ;
17 cy = 2 * cy ;
18
19 player . x = player . x - cx ;
20 player . y = player . y - cy ;
21
22 }
{"name":"infof.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/1\/4162db84b71cdf01c513ad41d140d0d9.jpg","w":324,"h":326,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/1\/4162db84b71cdf01c513ad41d140d0d9"} |
GullRaDriel
Member #3,861
September 2003
|
You have to do a little bit of vector math. http://stackoverflow.com/questions/1243614/how-do-i-calculate-the-normal-vector-of-a-line-segment said: The matrix representation of the general 2D transformation looks like this: x' = x cos(t) - y sin(t) If t = 90 degrees, then cos(90) = 0 and sin(90) = 1. Substituting and multiplying it out gives: x' = -y So, basically you'll have to modify it that way: 1if( keypressed() || mouse_b&1 || mouse_b&2 )
2{
3 int vx , vy ;
4 double size , cx , cy ;
5
6
7 vx = player . x - mouse_x ;
8 vy = player . y - mouse_y ;
9
10 if( vx || vy )
11 {
12 size = sqrt( vx*vx + vy*vy );
13
14 cx = vx/size ;
15 cy = vy/size ;
16 cx = 2 * cx ;
17 cy = 2 * cy ;
18
19 }
20
21 if( key[ KEY_SPACE ] )
22 {
23 player . x = player . x - cx ;
24 player . y = player . y - cy ;
25 }
26 else
27 {
28 if( mouse_b&1 )
29 {
30 player . x = player . x - cy ;
31 player . y = player . y + cx ;
32 }
33 else
34 {
35 if( mouse_b&2 )
36 {
37 player . x = player . x + cy ;
38 player . y = player . y - cx ;
39 }
40 }
41 }
42}
In that modification, I first test if there was a key pressed or a mouse button. We don't need to compute anything if there was no action. If I have an action, I first start to compute the vector going from object (sprite) to mouse pointer. When I have it, I apply it differently if it's SPACE, mouse button 1 or 2, accordingly to the explanation from stackoverflow. I attached you the whole thing again. Use SPACE to move to the mouse_pointer, and mouse button left/right for a perpendicular move against it. "Code is like shit - it only smells if it is not yours" |
Neomex
Member #11,618
January 2010
|
That's all that I wanted to know! |
|