如何在SFML中添加冲突

时间:2018-03-08 03:10:22

标签: c++ sfml

我正在努力创建乒乓球,但我遇到了碰撞问题。如何添加像素精确碰撞?我只在使用主文件时创建了一个碰撞,但在使用头文件时我无法弄明白。有人写出了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 个答案:

答案 0 :(得分:1)

由于Pong是一个非常简单的游戏,我建议你创建一个以sf::CircleShapesf::RectangleShape作为参数的交叉函数,因为这就是你分别代表球和桨的方式。

我建议你进行以下实施,但有better ones

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

基于this问题,但为了更好地理解,我在每个步骤中将其分开。

修改

请注意,此方法仅适用于矩形处于垂直/水平方向,即无旋转。