Answer the question
In order to leave comments, you need to log in
How to organize movement in 2D at a certain angle?
There is an object. With the "right" and "left" buttons, it rotates to a certain angle. When you press the "forward" and "backward" buttons, it should move accordingly, at a certain angle. I don't understand how to implement this in C++. Because I only know the coordinates of the object (i.e. x and y), the hypotenuse (i.e. speed) and the angle with respect to the axes, I tried through a right triangle and its legs, i.e. through sines and cosines, but in the end the object did not move at the angle that was given to it. How can this be implemented?
Who does/did how?
The function that produces the movement:
void MoveAhead(int& x, int& y, int imageRad, int speed)
{
int xangle = 0;
int yangle = 0;
if (imageRad >= 0 && imageRad <= 90)
{
xangle = 90 - imageRad;
yangle = 0 - imageRad;
xangle = (xangle < 0) ? xangle * -1 : xangle;
yangle = (yangle < 0) ? yangle * -1 : yangle;
}
else if (imageRad >= 90 && imageRad <= 180)
{
xangle = 90 - imageRad;
yangle = 180 - imageRad;
xangle = (xangle < 0) ? xangle * -1 : xangle;
yangle = (yangle < 0) ? yangle * -1 : yangle;
}
else if (imageRad >= 180 && imageRad <= 270)
{
xangle = 180 - imageRad;
yangle = 270 - imageRad;
xangle = (xangle < 0) ? xangle * -1 : xangle;
yangle = (yangle < 0) ? yangle * -1 : yangle;
}
else if (imageRad >= 270 && imageRad <= 360)
{
xangle = 270 - imageRad;
yangle = 360 - imageRad;
xangle = (xangle < 0) ? xangle * -1 : xangle;
yangle = (yangle < 0) ? yangle * -1 : yangle;
}
float ycoord = speed * sin(yangle * 3.14159 / 180);
float xcoord = speed * sin(xangle * 3.14159 / 180);
x += xcoord;
y += ycoord;
}
imageRad - градусы поворота изображения/градусы угла относительно осей.
speed - скорость движения/длина вектора/для гипотенузы.
al_draw_rotated_bitmap(image, x,y , imX, imY, imageRad+(3.14159/180), 0);
#include <allegro5\allegro.h>
#include <allegro5\allegro_image.h>
#include <math.h>
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
enum KEYS { UP, DOWN, LEFT, RIGHT };
void MoveAhead(int& imX, int& imY, int imageRad, int speed, int x, int y);
int main(void)
{
//variables
int width = 640;
int height = 480;
bool done = false;
int FPS = 60;
bool keys[4] = { false, false, false, false };
int imageWidth = 0;
int imageHeight = 0;
int imageRad = 0;
int speed = 10;
int x, y;
int imX;
int imY;
//allegro variable
ALLEGRO_DISPLAY* display = NULL;
ALLEGRO_EVENT_QUEUE* event_queue = NULL;
ALLEGRO_BITMAP* image = NULL;
ALLEGRO_TIMER* timer = NULL;
ALLEGRO_FONT* font18 = NULL;
//program init
if (!al_init()) //initialize Allegro
return -1;
display = al_create_display(width, height); //create our display object
timer = al_create_timer(1.0 / FPS);
if (!display) //test display object
return -1;
//addon init
al_install_keyboard();
al_init_image_addon();
al_init_font_addon();
al_init_ttf_addon();
font18 = al_load_font("arial.ttf", 18, 0);
image = al_load_bitmap("spider.png");
imageWidth = al_get_bitmap_width(image);
imageHeight = al_get_bitmap_height(image);
x = imageWidth / 2;
y = imageHeight / 2;
imX = width / 2 - imageWidth / 2;
imY = height / 2 - imageHeight / 2;
event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_start_timer(timer);
while (!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch (ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_RIGHT:
case ALLEGRO_KEY_D:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_LEFT:
case ALLEGRO_KEY_A:
keys[LEFT] = true;
break;
case ALLEGRO_KEY_UP:
case ALLEGRO_KEY_W:
keys[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
case ALLEGRO_KEY_S:
keys[DOWN] = true;
break;
}
}
else if (ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch (ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = false;
break;
case ALLEGRO_KEY_RIGHT:
case ALLEGRO_KEY_D:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_LEFT:
case ALLEGRO_KEY_A:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_UP:
case ALLEGRO_KEY_W:
keys[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
case ALLEGRO_KEY_S:
keys[DOWN] = false;
break;
}
}
else if (ev.type == ALLEGRO_EVENT_TIMER)
{
if (keys[UP])
MoveAhead(imX, imY, imageRad, speed, x, y);
if (keys[DOWN])
MoveAhead(imX, imY, imageRad, -speed, x, y);
if (keys[LEFT])
{
imageRad -= 5;
if (imageRad <= 0)
imageRad = 360;
}
if (keys[RIGHT])
{
imageRad += 5;
if (imageRad >= 360)
imageRad = 0;
}
}
al_draw_textf(font18, al_map_rgb(255, 255, 255), 20, 10, ALLEGRO_ALIGN_CENTRE, "%i", imageRad);
al_draw_textf(font18, al_map_rgb(255, 255, 255), width-50, 10, ALLEGRO_ALIGN_CENTRE, "%f", (imageRad*3.14159)/180.0);
al_draw_rotated_bitmap(image, x,y , imX, imY, imageRad*(3.14159/180), 0);
al_flip_display();
al_clear_to_color(al_map_rgb(0, 0, 0));
}
al_destroy_font(font18);
al_destroy_bitmap(image);
al_destroy_event_queue(event_queue);
al_destroy_timer(timer);
al_destroy_display(display); //destroy our display object
return 0;
}
Answer the question
In order to leave comments, you need to log in
That's just the sines and cosines and are the answer to the question.
And if you can't, then there's an error somewhere. What units are you using for the angle? Give a small example of the piece of code that calculates the new coordinates. And also the results are an example of what is obtained and what is expected for different input parameters.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question