Пишу приложение которое визуализирует физику используя Box2D.
Объект в виде квадрата перемещается по клику мыши.
Отскоки и изменение поворота при ударах об стенки нормально работает, всё хорошо.
Сделал препятствие и тут увидел, при падении с края препятствия, объект крутится неверно. Ну я думал это с SFML проблема, мол поворачивает не в ту сторону, но увы, проблема в движке, он неверно поворачивает объект.
Вот, залил 2 видео на YouTube, вот они.
Первое видео
Второе видео
На первом видео показывается как всё происходит.
На втором видео, в консоли, когда я останавливаю вывод консоли, видно что в строке Engine, третий параметр которой отображает угол фигуры всегда увеличивается, а должен падать, это проблема движка. Как решать эту проблему?
Код:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>
#include <Windows.h>
using namespace std;
using namespace sf;
float Radians2Degrees(float Radians)
{
return ((Radians / b2_pi) * 180.0f);
}
float Degress2Radians(float Degrees)
{
return ((Degrees * b2_pi) / 180.0);
}
int main()
{
RenderWindow window(VideoMode(800, 600), "Box2D + SFML");
sf::View view;
view.setCenter(sf::Vector2f(0.0f, -300.0f));
view.setSize(800, 600);
window.setView(view);
window.clear(Color::Cyan);
RectangleShape rect;
rect.setOrigin(25, 25);
rect.setFillColor(Color::Black);
rect.setSize(Vector2f(50, 50));
rect.setPosition(Vector2f(0, 0));
//устанавливаем гравитацию
b2Vec2 gravity(0.0f, -50.0f);
//создаём мир
b2World world(gravity);
//создаём определение земли
b2BodyDef groundBodyDef;
//устанавливаем позицию
groundBodyDef.position.Set(0.0f, 0.0);
//создаём тело земли на основе определения
b2Body* groundBody = world.CreateBody(&groundBodyDef);
//создаём фигуру земли
b2PolygonShape groundBox;
//делаем её прямоугольником и скрепляем тело с фигурой
groundBox.SetAsBox(600.0f, 0.0f);
groundBody->CreateFixture(&groundBox, 0.0f);
//отсчёт идёт сверху внихз, левый верхний угол это (0.0)
//ставим границы слева снизу и сверху
{
b2BodyDef wall;
b2PolygonShape wallShape;
//левая стенка
wall.position.Set(-400.0f, 0.0f);
b2Body* wallBody = world.CreateBody(&wall);
wallShape.SetAsBox(0.0f, 600.0f, b2Vec2(0.0f, 0.0f), 0.0);
wallBody->CreateFixture(&wallShape, 5.0f);
//правая стенка
wall.position.Set(400.0f, 0.0f);
wallBody = world.CreateBody(&wall);
wallShape.SetAsBox(0.0f, 600.0f, b2Vec2(0.0f, 0.0f), 0.0);
wallBody->CreateFixture(&wallShape, 5.0f);
//верхняя стенка
wall.position.Set(0.0f, 600.0f);
wallBody = world.CreateBody(&wall);
wallShape.SetAsBox(800.0f, 0.0f, b2Vec2(0.0f, 0.0f), 0.0);
wallBody->CreateFixture(&wallShape, 5.0f);
}
b2PolygonShape shape;
shape.SetAsBox(25.0f, 25.0f);
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.angularDamping = 0.3f; //снижение угловой скорости
bodyDef.position.Set(0.0f, 550.0f);
bodyDef.angle = Degress2Radians(65.0f); //угол в радианах
b2Body* body = world.CreateBody(&bodyDef);
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 1.0f; //плотность
fd.restitution = 0.25f; //упргугость
fd.friction = 0.4f; //трение
body->CreateFixture(&fd);
//привятсвие
//SFML
RectangleShape sfmlRect;
sfmlRect.setFillColor(Color::Green);
sfmlRect.setSize(Vector2f(400.0f, 100.0f));
sfmlRect.setPosition(Vector2f(-200.0f, -100.0f));
//box2d
b2PolygonShape shapeWall;
shapeWall.SetAsBox(200.0f, 50.0f);
b2BodyDef bodyDefWall;
bodyDefWall.angularDamping = 0.3; //снижение угловой скорости
bodyDefWall.position.Set(0.0f, 50.0f);
bodyDefWall.angle = Degress2Radians(0.0f); //угол в радианах
b2Body* bodyWall = world.CreateBody(&bodyDefWall);
bodyWall->CreateFixture(&shapeWall, 1.0f);
while (window.isOpen())
{
window.clear(Color::Cyan);
Event event;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
window.close();
}
//обработка нажатий
if (Mouse::isButtonPressed(Mouse::Button::Left))
{
Vector2i pixelPos = Mouse::getPosition(window); //забираем координаты курсора
Vector2f pos = window.mapPixelToCoords(pixelPos); //переводим их в игровые (уходим от коорд окна)
pos.y = -pos.y; //убираем минус
if ((pos.x >= -(800 / 2) && pos.x <= (800 / 2)) && ((pos.y >= 0) && (pos.y <= 600))) //проверяем в окне ли они(по y отрицательное)
{
if (body->GetLinearVelocity().x == 0 && body->GetLinearVelocity().y == 0)
body->SetLinearVelocity(b2Vec2(1, 1));
b2Vec2 position = body->GetPosition();
b2Vec2 impulseVector(body->GetPosition().x - pos.x, body->GetPosition().y - pos.y);
body->ApplyLinearImpulseToCenter(-impulseVector, false);
//cout << pos.x << " " << pos.y << "\n";
}
}
if (Keyboard::isKeyPressed(Keyboard::J))
{
b2Vec2 vel = body->GetLinearVelocity();
vel.y = 50;
body->SetLinearVelocity(vel);
}
if (Keyboard::isKeyPressed(Keyboard::R))
{
if (body->GetLinearVelocity().x == 0 && body->GetLinearVelocity().y == 0)
body->SetLinearVelocity(b2Vec2(1, 1));
float32 angle = body->GetAngle();
body->SetTransform(body->GetPosition(), angle += float32(0.001));
}
//позиция и угол
cout << "Engine: x - " << body->GetPosition().x << " y - " << body->GetPosition().y << " " << (body->GetAngle() / b2_pi) * 180.0f << "\n";
cout << "SFML: x - " << rect.getPosition().x << " y - " << rect.getPosition().y << " " << rect.getRotation() << "\n";
//cout << body->GetLinearVelocity().x << " " << body->GetLinearVelocity().y << "\n";
world.Step(0.025f / 60.0f, 6, 2);
rect.setPosition(Vector2f(body->GetPosition().x, -body->GetPosition().y)); //позиция,
//не забываем привести позицию по y в отрицательное значение
rect.setRotation(Radians2Degrees(body->GetAngle())); //угол в градусах
window.draw(rect);
window.draw(sfmlRect);
window.display();
}
return 0;
}
Коробка рисуется с обратным вращением. Оттого и смотрится странно.
rect.setRotation(-Radians2Degrees(body->GetAngle())); //угол в градусах
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Нужно написать keylogger в qt c++Как это можно сделать? Какие библиотеки нужно подключать?
начал изучать QtПреподаватель дал готовый код калькулятора на 4
Программа пытается запуститься, но не запускаетсяКомпилируется с предупреждением что не тестировалось в Windows 8, но у меня 10