Как добавить столкновение в SFML
Я работаю над созданием понга, но у меня возникли проблемы с Collision. Как я могу добавить Collision с точностью до пикселя? Я создал коллизию при использовании только основного файла, но не могу понять это при использовании заголовочных файлов. Может кто-нибудь написать код для Collision и добавить его в Collision.h и Collision.cpp для удобства хранения и модификации.
main.cpp
#include "stdafx.h"
#include <SFML\Graphics.hpp>
#include "Paddle.h"
#include "Ball.h"
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "Pong",
sf::Style::Close| sf::Style::Resize| sf::Style::Titlebar);
Paddle paddle1;
Paddle paddle2;
Ball ball;
while (window.isOpen()) {
sf::Event evnt;
while (window.pollEvent(evnt))
{
switch (evnt.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
paddle1.Update();
paddle2.Update();
ball.Update(ballDirectionX,ballDirectionY);
window.clear();
paddle1.Draw(window);
paddle2.Draw(window);
ball.Draw(window);
window.display();
}
return 0;
}
Paddle.h
#pragma once
#include <SFML\Graphics.hpp>
class Paddle
{
public:
Paddle();
~Paddle();
void Draw(sf::RenderWindow& window);
void Update();
sf::RectangleShape paddle1;
sf::RectangleShape paddle2;
private:
};
Paddle.cpp
#include "stdafx.h"
#include "Paddle.h"
Paddle::Paddle()
{
paddle1.setSize(sf::Vector2f(20.0f, 120.0f));
paddle1.setFillColor(sf::Color::Red);
paddle2.setSize(sf::Vector2f(20.0f, 120.0f));
paddle2.setFillColor(sf::Color::Green);
paddle2.setPosition(sf::Vector2f(1900.0f, 0.0f));
}
Paddle::~Paddle()
{
}
void Paddle::Draw(sf::RenderWindow& window)
{
window.draw(paddle1);
window.draw(paddle2);
}
void Paddle::Update()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
paddle1.move(sf::Vector2f(0, -3));
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
paddle1.move(sf::Vector2f(0, 3));
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
paddle2.move(sf::Vector2f(0, -3));
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
paddle2.move(sf::Vector2f(0, 3));
}
}
Ball.h
#pragma once
#include <SFML\Graphics.hpp>
class Ball
{
public:
Ball();
~Ball();
void Draw(sf::RenderWindow& window);
void Update() {
}
sf::CircleShape ball;
private:
};
Ball.cpp
#include "stdafx.h"
#include "Ball.h"
Ball::Ball()
{
ball.setRadius(20);
ball.setPosition(sf::Vector2f(400, 540));
}
Ball::~Ball()
{
}
void Ball::Draw(sf::RenderWindow & window)
{
window.draw(ball);
}
void Ball::Update()
{
}
1 ответ
Поскольку Pong - очень простая игра, я предлагаю вам создать функцию пересечения с sf::CircleShape
и sf::RectangleShape
в качестве аргументов, потому что именно так вы представляете свой мяч и весла соответственно.
Я предлагаю вам следующую реализацию, но есть и лучшие:
bool intersects(const sf::CircleShape &c, const sf::RectangleShape &r){
sf::FloatRect fr = r.getGlobalBounds();
sf::Vector2f topLeft(fr.left, fr.top);
sf::Vector2f topRight(fr.left + fr.width, fr.top);
sf::Vector2f botLeft(fr.left, fr.top + fr.height);
sf::Vector2f botRight(fr.left + fr.width, fr.top + fr.height);
return contains(c, topLeft) ||
contains(c, topRight) ||
contains(c, botLeft) ||
contains(c, botRight);
}
Это легко, просто проверьте, находится ли каждый угол прямоугольника внутри круга, если ни один из них не содержится, этот круг и этот прямоугольник не пересекаются.
Если какой-либо из углов содержится в круге, они пересекаются.
contains()
функция довольно простая на самом деле:
bool contains(const sf::CircleShape &c, const sf::Vector2f &p){
sf::Vector2f center = c.getPosition();
float a = (p.x - center.x);
float b = (p.y - center.y);
a *= a;
b *= b;
float r = c.getRadius() * c.getRadius();
return (( a + b ) < r);
}
Основан на этом вопросе, но я разделил его на каждом шаге для лучшего понимания.
РЕДАКТИРОВАТЬ
Обратите внимание, что этот метод работает, только если прямоугольники находятся в вертикальной / горизонтальной ориентации, то есть без поворотов.