简体   繁体   English

C++ SFML,轨道运行

[英]C++ SFML, orbiting

I recently started to learn SFML, and I have a question, how to make what would be the second body moving in an orbit, help please.我最近开始学习 SFML,我有一个问题,如何制作第二个在轨道上移动的物体,请帮忙。

#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
   RenderWindow window(VideoMode(800, 600), "Hello, world!");

    CircleShape shape(50.f);
    shape.setFillColor(Color::Black);
    shape.setPosition(400,300);
    shape.setOrigin(50,50);

    CircleShape shape2(10.f);
    shape2.setFillColor(Color::Black);
    shape2.setPosition(700,500);
    shape2.setOrigin(10,10);

    while (window.isOpen())
    {
        Event event;
        while (window.pollEvent(event)) 
        {       
            if (event.type == sf::Event::Closed)        
                window.close();

        }
        window.clear(Color::White);
        window.draw(shape);
        window.draw(shape2);
        window.display();
    }
    return 0;
}

Well... I will not post full solution. 好吧...我不会发布完整的解决方案。 It would not be educational to give you complete code. 为您提供完整的代码是没有教育意义的。 But I will give you some hints :) . 但我会给你一些提示:)。

  1. Your world update should happen in the loop. 您的世界更新应该在循环中发生。 In the while loop. 在while循环中。 You have two there. 你那里有两个。 Which one do you think is the one which updates your world? 您认为哪一个是可以改变您的世界的人?
  2. Circle equation in Cartesian coordinate system is: (xa)^2 + (yb)^2 = r^2 笛卡尔坐标系中的圆方程为: (xa)^2 + (yb)^2 = r^2
  3. In the loop from 1 you should use equation from 2 to update coordinates of second object (shape2). 在从1开始的循环中,应使用从2开始的方程式更新第二个对象(shape2)的坐标。
  4. To perform action from point 3 you have two possibilities: function setPosition and function move , both members of class CircleShape . 要从第3点开始执行操作,您有两种可能性:函数setPosition和函数move ,都是CircleShape类的CircleShape

If you have further questions ask them in the comments. 如果您还有其他问题,请在评论中提问。

For your future questions on stack: give us proof that you put some effort in resolving problem. 对于您将来遇到的问题:请提供给我们证明,您在解决问题上付出了一些努力。 If question looks like the one I'm answering now we have the idea that you did not think about it just posted it here and you are waiting for someone to write your code for you. 如果问题看起来像我现在要回答的问题,我们认为您没有考虑它,只是将其发布在这里,您正在等待有人为您编写代码。

The easiest and i think most precise way would be to use two perpendicular sine waves with the origin being your well origin and the amplitude being the distance for which you want to orbit.最简单也是我认为最精确的方法是使用两个垂直的正弦波,原点是你的井原点,幅度是你想要绕轨道运行的距离。

#include <cmath> -- sin(), cos functions #include <cmath> -- sin(), cos 函数

As you probably know sin goes from 0 to 1 then -1 and it repeats.你可能知道 sin 从 0 到 1 然后 -1 并且重复。 cos is identical but shifted. cos 是相同的,但发生了变化。 If you use both for the position then you're left with the sine and cosine values of a given number.如果您将两者都用于 position,那么您将获得给定数字的正弦和余弦值。 If you use one for 'x' and the other for 'y' you're left with circular motion (perpendicular waves).如果您将一个用于“x”而另一个用于“y”,则您将进行圆周运动(垂直波)。 Try out the code below:试试下面的代码:

int main()
{

    CircleShape shape(50.f);
    shape.setFillColor(Color::Black);
    shape.setPosition(400,300);
    shape.setOrigin(50,50);

    CircleShape shape2(10.f);
    shape2.setFillColor(Color::Black);
    shape2.setPosition(700,500);
    shape2.setOrigin(10,10);

    CircleShape shape3(10.f);
    shape3.setFillColor(Color::Black);
    shape3.setPosition(700,500);
    shape3.setOrigin(10,10);

    CircleShape shape4(10.f);
    shape4.setFillColor(Color::Black);
    shape4.setPosition(700,500);
    shape4.setOrigin(10,10);


    float speed = 0.01;
    float distance = 100;
    // create the window
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
    window.setFramerateLimit(60);
    float counter = 0;
    // run the program as long as the window is open
    while (window.isOpen())
    {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
        counter += speed;
        // clear the window with black color
        window.clear(Color::White);
        shape2.setPosition(shape.getPosition().x+distance*sin(counter),shape.getPosition().y+distance*cos(counter));
        shape3.setPosition(shape.getPosition().x+distance*sin(counter),shape.getPosition().y+distance*sin(counter));
        shape4.setPosition(shape.getPosition().x+2*distance*sin(counter),shape.getPosition().y+distance*cos(counter));

        // draw everything here...
        // window.draw(...);
        window.draw(shape);
        window.draw(shape2);
        window.draw(shape3);
        window.draw(shape4);
        // end the current frame
        window.display();
    }
    return 0;
}

As you can see shape2 is oribitng shape1.正如你所看到的,shape2 是围绕 shape1 的。 Shape2 and shape3's position is dependant on the position of shape1 (our origin) as well as the sine and cosine values generated. Shape2 和 shape3 的 position 取决于 shape1 的 position(我们的原点)以及生成的正弦和余弦值。 I marked distinct places in the code with variables to show you the possibilities you can have with this setup.我用变量标记了代码中的不同位置,以向您展示使用此设置可以拥有的可能性。 Let's go through the setposition function:让我们 go 通过设置位置 function:

For both x and y we need a base position from which the shape will orbit.对于 x 和 y,我们需要一个基础 position ,形状将从该基础轨道运行。 we use shape1's position.我们使用 shape1 的 position。 The sine and cos need some type of number input from which to generate a value.正弦和余弦需要某种类型的数字输入来生成值。 I just used a normal iterator that grows every frame by 'speed' amount.我只是使用了一个普通的迭代器,它使每一帧都按“速度”量增长。 the more it is the faster the sine will repeat thus faster orbiting around the shape1.它越多,正弦重复的速度越快,因此围绕 shape1 运行的速度越快。 The next part is the addition of the sine and cos values to the origin.下一部分是将正弦和余弦值添加到原点。 this is where things get fun.这就是事情变得有趣的地方。 we're essentially adding the sine value to the position to move it by that much in any direction.我们实质上是将正弦值添加到 position 以将其向任何方向移动那么多。 'Distance' is how much we multiply the sine cos values. “距离”是我们将正弦 cos 值乘以多少。 Thus bigger distance = further away.因此更大的距离=更远。

Note:笔记:

  • using sine for x and cos for y you get a normal circular orbit.对 x 使用正弦,对 y 使用 cos,你会得到一个正常的圆形轨道。
  • using sine for both x and y you get a 3D-looking orbit to and from the screen (shape3)对 x 和 y 使用正弦,您会得到一个往返于屏幕的 3D 轨道(shape3)
  • multiplying sine and cos value additions by a non identical number will result in eliptical rotations (shape4)将正弦和余弦值相加乘以不相等的数字将导致椭圆旋转(shape4)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM