视觉C SDL2圆形运动

visual C++ SDL2 circular motion

本文关键字:运动 SDL2 视觉      更新时间:2023-10-16

我当前正在制作一个简单的太阳系轨道程序。到目前为止,我已经设法在窗户中显示了行星和太阳,但是我还没有弄清楚如何获得行星所需的基于时间的循环运动。该运动只是一个简单的圆形物理学。下面的我的代码将显示地球上的课程(目前没有其他行星(以及时间功能的工作原理以及我在网上发现的原始直运动,以查看运动如何在C 中起作用。我在网上看到了许多不同的方程式,但我不确定如何将它们实施到代码中。

地球头:

#ifndef Earth_H_
#define Earth_H_
#include "Entity.h"
#include <math.h>
// Define a Sun speed in pixels per second
//const double Degree= 180/ M_PI;
class Earth : public Entity {
    const float Earth_Speed = 100;
public:
    Earth(SDL_Renderer* renderer);
    ~Earth();
    void Update(float delta);
    void Render(float delta);
    void SetDirection(float dirx, float diry);
    const double Degree = 180 / M_PI;
    /*float Orbital_Speed=0.01;*/
    double Angle;
    /*float Speed= 900;*/
    double Radius=100;
    float dirx, diry;
private:
    SDL_Texture* texture;
};
    #endif  

Earth CPP:

#include "Earth.h"

Earth::Earth(SDL_Renderer* renderer) : Entity(renderer) {
    SDL_Surface* surface = IMG_Load("Earth.png");
    texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);
    x = 0;
    y = 0;
    width = 20;
    height = 20;

}
Earth::~Earth() {
    // Clean resources
    SDL_DestroyTexture(texture);
}
void Earth::Update(float delta) {
    // Move the Sun, time based
    x +=  dirx  * delta;
    y += diry * delta; 
    //Angle = atan2(diry / Degree, dirx / Degree);
    //x += ((dirx*Degree) - cos(Angle)*Radius)* delta;
    //y += ((diry*Degree) - sin(Angle)*Radius)* delta;
}
void Earth::Render(float delta) {
    SDL_Rect rect;
    rect.x = (int)(x + 0.5f); // Round the float to the nearest integer
    rect.y = (int)(y + 0.5f); // Round the float to the nearest integer
    rect.w = width;
    rect.h = height;
    SDL_RenderCopy(renderer, texture, 0, &rect);
}
void Earth::SetDirection(float dirx, float diry) {

    //Angle = atan2(diry/ Degree, dirx/ Degree);
    //this->dirx = ((dirx*Degree) - cos(Angle)*Radius)*Earth_Speed;
    //this->diry = ((diry*Degree) - sin(Angle)*Radius)*Earth_Speed;
    float length = sqrt(dirx * dirx + diry * diry);
    this->dirx = Earth_Speed * (dirx / length);
    this->diry = Earth_Speed * (diry / length);
 }

模拟标头:

#ifndef Simulation_H_
#define Simulation_H_
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
#include <vector>

#include "Sun.h"
#include "Mercury.h"
#include "Venus.h"
#include "Earth.h"
#include "Mars.h"
#include "Jupiter.h"
#include "Saturn.h"
#include "Uranus.h"
#include "Neptune.h"
#define FPS_DELAY 500

class Simulation {
public:
    Simulation();
    ~Simulation();
    bool Init();
    void Run();
private:
    SDL_Window* window;
    SDL_Renderer* renderer;
    // Timing
    unsigned int lasttick, fpstick, fps, framecount;
    float width= 650, height= 650;

    Sun* sun;
    Mercury* mercury;
    Venus* venus;
    Earth* earth;
    Mars* mars;
    Jupiter* jupiter;
    Saturn* saturn;
    Uranus* uranus;
    Neptune* neptune;
    void Clean();
    void Update(float delta);
    void Render(float delta);
    void NewSimulation();

};
#endif

模拟CPP:

#include "Simulation.h"
Simulation::Simulation() {
    window = 0;
    renderer = 0;
}
Simulation::~Simulation() {
}
bool Simulation::Init() {
    // Initialize SDL and the video subsystem
    SDL_Init(SDL_INIT_VIDEO);
    // Create window
    window = SDL_CreateWindow("Suraj's Solar System Simulator",
        100, 100,
        width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
    if (!window) {
        // Error creating window
        return false;
    }
    // Create renderer
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (!renderer) {
        // Error creating renderer
        return false;
    }
    // Initialize timing
    lasttick = SDL_GetTicks();

    return true;
}
void Simulation::Clean() {
    // Clean renderer and window
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
}
void Simulation::Run() {
    // Create Sun and Planets
    sun = new Sun(renderer);
    mercury = new Mercury(renderer);
    venus= new Venus(renderer);
    earth = new Earth(renderer);
    mars= new Mars(renderer);
    jupiter = new Jupiter(renderer);
    saturn = new Saturn(renderer);
    uranus = new Uranus(renderer);
    neptune = new Neptune(renderer);

    NewSimulation();
    // Main loop
    while (1) {
        // Handler events
        SDL_Event e;
        if (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                break;
            }
        }
        // Calculate delta and fps
        unsigned int curtick = SDL_GetTicks();
        float delta = (curtick - lasttick) / 1000.0f;
        lasttick = curtick;
        // Update and render the Simulation
        Update(delta);
        Render(delta);
    }
    // Delete objects
    delete sun;
    delete mercury;
    delete venus;
    delete earth;
    delete mars;
    delete jupiter;
    delete saturn;
    delete uranus;
    delete neptune;
    Clean();
    SDL_Quit();
}
void Simulation::NewSimulation() {

    // Center the Sun horizontally and vertically
    sun->x = width / 2 - sun->width / 2;
    sun->y = height / 2 - sun->height / 2;
    mercury->x = width / 2.4 - mercury->width / 2.4;
    mercury->y = height / 2 - mercury->height / 2;
    venus->x = width / 2.7 - venus->width / 2.7;
    venus->y = height / 2 - venus->height / 2;
    earth->x = width / 3 - earth->width / 3;
    earth->y = height / 2 - earth->height / 2;
    mars->x = width / 3.4 - mars->width / 3.4;
    mars->y = height / 2 - mars->height / 2;
    jupiter->x = width / 5 - jupiter->width / 5;
    jupiter->y = height / 2 - jupiter->height / 2;
    saturn->x = width / 9- saturn->width / 9;
    saturn->y = height / 2 - saturn->height / 2;
    uranus->x = width / 15 - uranus->width / 15;
    uranus->y = height / 2 - uranus->height / 2;
    neptune->x = width / 50 - neptune->width / 50;
    neptune->y = height / 2 - neptune->height / 2;
    //// Set the initial direction of the planets
    /*mercury->SetDirection(1, -1);
    venus->SetDirection(1, -1);*/
    earth->SetDirection((earth->x - sun->x)*cos(M_PI/180)+ sun->x, - ((earth->x - sun->x)*sin(M_PI / 180) + sun->y));
    //mars->SetDirection(1, -1  );
    //jupiter->SetDirection(1, -1);
    //saturn->SetDirection(1, -1);
    //uranus->SetDirection(1, -1);
    //neptune->SetDirection(1, -1);
}
void Simulation::Update(float delta) {

    // Update Earth and Sun
    sun->Update(delta);
    mercury->Update(delta);
    venus->Update(delta);
    earth->Update(delta);
    mars->Update(delta);
    jupiter->Update(delta);
    saturn->Update(delta);
    uranus->Update(delta);
    neptune->Update(delta);
}

void Simulation::Render(float delta) {
    // Clear the screen to black
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    // Render board and Sun
    sun->Render(delta);
    mercury->Render(delta);
    venus->Render(delta);
    earth->Render(delta);
    mars->Render(delta);
    jupiter->Render(delta);
    saturn->Render(delta);
    uranus->Render(delta);
    neptune->Render(delta);
    // Update the screen
    SDL_RenderPresent(renderer);
}

实体标题:

#ifndef ENTITY_H_
#define ENTITY_H_
#include "SDL.h"
#include "SDL_image.h"
class Entity {
public:
    Entity(SDL_Renderer* renderer);
    virtual ~Entity();
    float x, y, width, height;
    virtual void Update(float delta);
    virtual void Render(float delta);

protected:
    SDL_Renderer* renderer;
};
#endif

unitity cpp:

#include "Entity.h"
Entity::Entity(SDL_Renderer* renderer) {
    this->renderer = renderer;
    x = 0;
    y = 0;
    width = 1;
    height = 1;
}
Entity::~Entity() {
}
void Entity::Update(float delta) {
}
void Entity::Render(float delta) {
}

主标头:

#ifndef MAIN_H_
#define MAIN_H_
#include "Simulation.h"
int main(int argc, char* argv[]);
#endif

主CPP:

#include "main.h"
int main(int argc, char* argv[]) {
    // Create the game object
    Simulation* simulation = new Simulation();
    // Initialize and run the game
    if (simulation->Init()) {
        simulation->Run();
    }
    // Clean up
    delete simulation;
    return 0;
}

通常以:

来完成循环运动
angle += orbit_speed * delta_time;
x = center_x + radius * cos(angle);
y = center_y + radius * sin(angle);