위 알고리즘을 사용해 두 물체의 충돌 여부를 구현합니다.
물체 출력은 SFML 프레임워크를 사용합니다.
먼저 위의 공식에 대한 함수는 다음과 같이 작성 할 수 있습니다.
bool MyCircle::collisionTest(MyCircle c1, MyCircle c2) {
double distance;
distance = sqrt(pow(abs(c1.posX - c2.posX), 2) + pow(abs(c1.posY - c2.posY), 2));
// cmath 라이브러리 사용
if (distance <= c1.radius + c2.radius) {
return true;
}
else {
return false;
}
}
거리가 두 원의 반지름보다 큰지 작은지에 따라 충돌 여부를 따집니다.
전체 코드를 보면
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
using namespace sf;
class MyCircle {
public:
CircleShape circle;
double radius;
double diameter;
double posX;
double posY;
double velocity;
MyCircle() {
posX = 0;
posY = 0;
radius = 10;
diameter = radius * 2;
velocity = 2;
circle.setPosition(posX, posY);
circle.setRadius(radius);
circle.setFillColor(Color(0, 255, 0));
circle.setPointCount(30);
}
MyCircle(double x, double y, double rad) {
posX = x;
posY = y;
radius = rad;
diameter = radius * 2;
velocity = 2;
circle.setPosition(posX, posY);
circle.setRadius(radius);
circle.setFillColor(Color(0, 255, 0));
circle.setPointCount(30);
}
void setVelocity(double vel) {
velocity = vel;
}
double getVelocity() {
return velocity;
}
void setRadius(double rad) {
radius - rad;
diameter = radius * 2;
circle.setRadius(radius);
}
void setPosition(double x, double y) {
posX = x;
posY = y;
circle.setPosition(x, y);
}
void move(double dx, double dy) {
circle.move(dx, dy);
}
bool collisionTest(MyCircle c1, MyCircle c2);
CircleShape getCircle() {
return circle;
}
};
bool MyCircle::collisionTest(MyCircle c1, MyCircle c2) {
double distance;
distance = sqrt(pow(abs(c1.posX - c2.posX), 2) + pow(abs(c1.posY - c2.posY), 2));
if (distance <= c1.radius + c2.radius) {
return true;
}
else {
return false;
}
}
int main()
{
int nX = 600;
int nY = 600;
RenderWindow window(VideoMode(nX, nY), "Moving Ball");
window.setFramerateLimit(150);
double radius = 20;
double diameter = radius * 2;
double posX = 0;
double posY = nY - diameter;
double velocity = 4;
CircleShape circle(radius); //반지름
circle.setPosition(posX, posY);
circle.setFillColor(Color(0, 255, 0));
circle.setPointCount(50);
MyCircle circleM1(posX + 50, posY - 300, radius);
MyCircle circleM2(posX + 450, posY - 300, radius);
MyCircle obj;
// 여기서부터 게임 루프
while (window.isOpen())
{
// 이벤트 검사 및 처리
Event e;
while (window.pollEvent(e)) {
if (e.type == Event::Closed)
window.close();
}
if (Keyboard::isKeyPressed(Keyboard::Up)) {
circleM1.move(0, -circleM1.getVelocity());
circleM1.posY += -circleM1.getVelocity();
}
else if (Keyboard::isKeyPressed(Keyboard::Down)) {
circleM1.move(0, circleM1.getVelocity());
circleM1.posY += circleM1.getVelocity();
}
if (Keyboard::isKeyPressed(Keyboard::Left)) {
circleM1.move(-circleM1.getVelocity(), 0);
circleM1.posX += -circleM1.getVelocity();
}
else if (Keyboard::isKeyPressed(Keyboard::Right)) {
circleM1.move(circleM1.getVelocity(), 0);
circleM1.posX += circleM1.getVelocity();
}
// 화면을 지운다.
window.clear();
// 화면에 원을 그린다.
window.draw(circleM1.getCircle());
window.draw(circleM2.getCircle());
// 화면을 표시한다.
window.display();
cout << obj.collisionTest(circleM1, circleM2) << endl;
}
return 0;
}
과 같이 작성 가능합니다.
프로그램을 실행하는 동안 충돌 여부를 프린트하고 충돌할 시 true를 반환합니다.
충돌하면 1, 아니면 0을 출력하는걸 확인할 수 있습니다.