C ++ SDL2圆周运动

时间:2017-04-20 22:18:25

标签: c++ visual-c++ sdl-2

我目前正在制作简单的太阳系轨道计划。到目前为止,我已经设法在窗口中显示行星和太阳,但是我还没有弄清楚如何获得行星所需的基于时间的圆周运动。这个动作只是一个没有深度物理学的简单圆圈。我的下面的代码将显示地球的类(此刻没有其他行星)以及时间函数如何工作以及我在网上找到的原始直线运动,以了解运动如何在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  

地球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

Enitity 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

Main 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;
}

1 个答案:

答案 0 :(得分:0)

圆周运动通常通过以下方式完成:

angle += orbit_speed * delta_time;
x = center_x + radius * cos(angle);
y = center_y + radius * sin(angle);