Как мне сделать движение кораблика через кнопки вверх или вниз, а за угол направление будут отвечать кнопки влево или вправо SDL

В общем я эту идею хотел реализовать через нахождения расстояния от ширины и высоты окна, потом по уравнению прямой найти направление кораблика через угол и потом начать движение, но как-то все очень грустно получается.

Исходники:

Game.h


#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <math.h>

struct Vector
{
    float x; 
    float y;
};

class Game
{
public:

    Game();

    void Update();
    void Render();
    void Run();

    void InitPlayer();
    void AddVector(Vector NewVec);
    void Move();


    ~Game();

private:

    SDL_Rect srcRect = { 0, 0, 100, 100 };
    SDL_Rect desRect = { 100, 100, 50, 50 };

    float x;
    float y; 

    float angle;
    float radian;

    SDL_Window* g_window;
    SDL_Renderer* g_renderer;
    SDL_Texture* g_texture;

    int height = 0;
    int width = 0;

    SDL_Point point;

    bool run;
};

Game.cpp

#include "Game.h"

Game::Game()
{
    SDL_Init(SDL_INIT_EVERYTHING);

    g_window = SDL_CreateWindow("SMT", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500, 500, 0);

    g_renderer = SDL_CreateRenderer(g_window, -1, 0);

    InitPlayer();

    x = 0;

    y = 0;

    width = 500;

    height = 500;

    run = true;
}

void Game::Update()
{
    SDL_Event event;
    SDL_PollEvent(&event);
    switch (event.type)
    {
    case SDL_QUIT:
        run = false;

    default:
        break;
    }

    Move();
}

void Game::Render()
{
    SDL_Rect srcRect = { 0, 0, 100, 100 };
    SDL_Rect desRect = { x, y, 50, 50 };

    point.x = desRect.w / 2;
    point.y = desRect.h / 2;

    SDL_RenderClear(g_renderer);

    SDL_RenderCopyEx(g_renderer, g_texture, &srcRect, &desRect, angle, &point, SDL_FLIP_NONE);

    SDL_RenderPresent(g_renderer);
}

void Game::Run()
{
    const int FPS = 60;
    const int frameDelay = 1000 / FPS;

    Uint32 frameStart;
    int frameTime;

    while (run)
    {

        frameStart = SDL_GetTicks();


        Update();
        Render();

        frameTime = SDL_GetTicks() - frameStart;

        if (frameDelay > frameTime)
        {
            SDL_Delay(frameDelay - frameTime);
        }
    }


}

void Game::InitPlayer()
{


    SDL_Surface* surface = IMG_Load("space.png");
    g_texture = SDL_CreateTextureFromSurface(g_renderer, surface);

}

void Game::Move()
{
    const Uint8* key_state = SDL_GetKeyboardState(NULL);

    if (key_state[SDL_SCANCODE_RIGHT])
    {
        angle += 5;

        if (angle == 360)
        {
            angle = 0;
        }

        radian = (angle * M_PI) / 180;

    }
    if (key_state[SDL_SCANCODE_LEFT])
    {
        angle -= 5;

        if (angle == -360)
        {
            angle = 0;
        }
        radian = (angle * M_PI) / 180;
    }

    if (key_state[SDL_SCANCODE_UP])
    {
        float xz = x;
        
        float yz = y;

        
        float vx = tan(radian) * xz;
        float vy = tan(radian) * yz;

        system("cls");

        std::cout << "XZ: " << xz << " " << "YZ: " << yz << "\n";
        std::cout << "VX: " << vx << " " << "VY: " << vy << "\n";
        std::cout << "ANGLERAD: " << tan((angle * M_PI) / 180)  << " " << "ANGLE: " << angle << "\n";

    }

    if (key_state[SDL_SCANCODE_DOWN])
    {
    }


}

Game::~Game()
{
}

Ответы (1 шт):

Автор решения: HolyBlackCat

Не в ту степь пошли. Достаточно сделать вот так:

float speed = 5;
x += std::cos(radian) * speed;
y += std::sin(radian) * speed;

Еще, SDL_PollEvent() использован неправильно. Правильно так:

SDL_Event event;
while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
        // ...
    }
}

Move();

Еще, очень советую добавить проверку на ошибки при инициализации SDL и создании окна.

→ Ссылка