devC++编写实现10个不同颜色小球在屏幕中以不同速度、方向移动,且碰到边界及两两碰撞时能合理变向的代码
时间: 2023-05-12 13:07:05 浏览: 159
以下是一个简单的实现,使用了 SFML 库:
```cpp
#include <SFML/Graphics.hpp>
#include <random>
int main()
{
constexpr int windowWidth = 800;
constexpr int windowHeight = 600;
constexpr int ballCount = 10;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> colorDist(0, 255);
std::uniform_real_distribution<> speedDist(50, 200);
std::uniform_real_distribution<> angleDist(0, 2 * M_PI);
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "Bouncing Balls");
std::vector<sf::CircleShape> balls(ballCount);
std::vector<sf::Vector2f> velocities(ballCount);
for (int i = 0; i < ballCount; ++i)
{
balls[i].setRadius(20);
balls[i].setFillColor(sf::Color(colorDist(gen), colorDist(gen), colorDist(gen)));
balls[i].setPosition(sf::Vector2f(windowWidth / 2, windowHeight / 2));
velocities[i] = sf::Vector2f(speedDist(gen) * std::cos(angleDist(gen)), speedDist(gen) * std::sin(angleDist(gen)));
}
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear();
for (int i = 0; i < ballCount; ++i)
{
balls[i].move(velocities[i] * window.getFrameTime().asSeconds());
if (balls[i].getPosition().x - balls[i].getRadius() < 0)
{
balls[i].setPosition(balls[i].getRadius(), balls[i].getPosition().y);
velocities[i].x = std::abs(velocities[i].x);
}
else if (balls[i].getPosition().x + balls[i].getRadius() > windowWidth)
{
balls[i].setPosition(windowWidth - balls[i].getRadius(), balls[i].getPosition().y);
velocities[i].x = -std::abs(velocities[i].x);
}
if (balls[i].getPosition().y - balls[i].getRadius() < 0)
{
balls[i].setPosition(balls[i].getPosition().x, balls[i].getRadius());
velocities[i].y = std::abs(velocities[i].y);
}
else if (balls[i].getPosition().y + balls[i].getRadius() > windowHeight)
{
balls[i].setPosition(balls[i].getPosition().x, windowHeight - balls[i].getRadius());
velocities[i].y = -std::abs(velocities[i].y);
}
for (int j = i + 1; j < ballCount; ++j)
{
if (std::hypot(balls[i].getPosition().x - balls[j].getPosition().x, balls[i].getPosition().y - balls[j].getPosition().y) < balls[i].getRadius() + balls[j].getRadius())
{
sf::Vector2f v1 = velocities[i];
sf::Vector2f v2 = velocities[j];
sf::Vector2f p1 = balls[i].getPosition();
sf::Vector2f p2 = balls[j].getPosition();
float m1 = balls[i].getRadius();
float m2 = balls[j].getRadius();
velocities[i] = v1 - (2 * m2 / (m1 + m2)) * ((v1 - v2) * (p1 - p2) / std::pow(std::hypot(p1 - p2), 2)) * (p1 - p2);
velocities[j] = v2 - (2 * m1 / (m1 + m2)) * ((v2 - v1) * (p2 - p1) / std::pow(std::hypot(p2 - p1), 2)) * (p2 - p1);
}
}
window.draw(balls[i]);
}
window.display();
}
return 0;
}
```
这个程序使用了随机数生成器来生成小球的颜色、速度和方向。每个小球都是一个圆形,使用 `sf::CircleShape` 类来表示。小球的位置和速度都是 `sf::Vector2f` 类型。在主循环中,每个小球都会根据其速度移动,并检查是否碰到了边界。如果碰到了边界,小球会被弹回,并且速度的 x 或 y 分量会取反。如果两个小球碰撞了,它们的速度会根据动量守恒和动能守恒的原理进行计算,并且会发生反弹。最后,每个小球都会被绘制到屏幕上。