Since I'm not very familiar with SFML and C++ I probably picked a bad tittle but I hope you forgive me. My problem is that I'm trying to make a bouncing circle but I couldn't find where is my problem. Also do you think this game structure is appropriate for small games(I'm sure it's not). I really need to understand if I'm going in right way or not in terms of design. Anyway here is the code.
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
const unsigned int SCREEN_WIDTH = 640;
const unsigned int SCREEN_HEIGHT = 480;
const unsigned int BIT_PER_PIXEL = 32;
const unsigned int DEPTH_BITS = 24;
const unsigned int STENCIL_BITS = 8;
const unsigned int ANTI_ALIASING = 16;
struct Point2D
{
float x;
float y;
};
struct Primitive
{
Point2D position;
float radius;
sf::Color fillerColor;
float outlineThickness;
sf::Color outlineColor;
};
class Ball
{
private:
Primitive circle;
Point2D velocity;
Point2D displacement;
sf::Color color;
sf::Shape shape;
public:
Ball();
void initialize(const Primitive&, const Point2D&);
void detectAndProcessCollision();
sf::Shape getDrawableObject() const { return shape; }
void move(const float&);
};
Ball::Ball()
{
circle.position.x = 0.0f;
circle.position.y = 0.0f;
circle.radius = 0.0f;
circle.fillerColor = sf::Color(0, 0, 0);
circle.outlineThickness = 0.0f;
circle.outlineColor = sf::Color(0, 0, 0);
shape = sf::Shape::Circle(circle.position.x, circle.position.y, circle.radius,
circle.fillerColor, circle.outlineThickness, circle.outlineColor);
}
void Ball::initialize(const Primitive &givenCircle, const Point2D &givenVelocity)
{
circle.position.x = givenCircle.position.x;
circle.position.y = givenCircle.position.y;
circle.radius = givenCircle.radius;
circle.fillerColor = givenCircle.fillerColor;
circle.outlineThickness = givenCircle.outlineThickness;
circle.outlineColor = givenCircle.outlineColor;
velocity.x = givenVelocity.x;
velocity.y = givenVelocity.y;
}
void Ball::move(const float &deltaTime)
{
displacement.x = deltaTime * velocity.x;
displacement.y = deltaTime * velocity.y;
circle.position.x += displacement.x;
circle.position.y += displacement.y;
std::cout << "x pos = " << circle.position.x << std::endl;
std::cout << "y pos = " << circle.position.y << std::endl;
shape.SetPosition(circle.position.x, circle.position.y);
}
void Ball::detectAndProcessCollision()
{
if((circle.position.y - circle.radius <= 0) && velocity.y < 0)
{
velocity.y = -velocity.y;
float outedFraction = -(circle.position.y - circle.radius);
circle.position.y += outedFraction;
}
else if((circle.position.y + circle.radius >= SCREEN_HEIGHT) && velocity.y > 0)
{
velocity.y = -velocity.y;
float outedFraction = -((circle.position.y - circle.radius) - SCREEN_HEIGHT);
circle.position.y += outedFraction;
}
if((circle.position.x - circle.radius <= 0) && velocity.x < 0)
{
velocity.x = -velocity.x;
float outedFraction = -(circle.position.x - circle.radius);
circle.position.x += outedFraction;
}
else if((circle.position.x + circle.radius >= SCREEN_WIDTH) && velocity.x > 0)
{
velocity.x = -velocity.x;
float outedFraction = -((circle.position.x - circle.radius) - SCREEN_WIDTH);
circle.position.x += outedFraction;
}
}
class Game
{
private:
sf::RenderWindow gameArea;
sf::VideoMode videoMode;
sf::WindowSettings windowSettings;
sf::Clock timer;
sf::Event gameEvents;
Ball bouncer;
bool isGameFinished;
public:
Game();
~Game();
void processEvents();
void draw() { gameArea.Draw(bouncer.getDrawableObject()); }
void main();
};
Game::Game(): videoMode(SCREEN_WIDTH, SCREEN_HEIGHT, BIT_PER_PIXEL),
windowSettings(DEPTH_BITS, STENCIL_BITS, ANTI_ALIASING)
{
isGameFinished = false;
Point2D initialVelocity;
initialVelocity.x = 30.0f;
initialVelocity.y = 30.0f;
Primitive tempCircle;
tempCircle.position.x = SCREEN_WIDTH / 2;
tempCircle.position.y = SCREEN_HEIGHT / 2;
tempCircle.radius = 10.0f;
tempCircle.fillerColor = sf::Color(255, 0, 255);
tempCircle.outlineThickness = 1;
tempCircle.outlineColor = sf::Color(230, 0, 0);
bouncer.initialize(tempCircle, initialVelocity);
gameArea.Create(videoMode, "Pong++", sf::Style::Close, windowSettings);
}
Game::~Game()
{
gameArea.Close();
}
void Game::main()
{
while(!isGameFinished)
{
gameArea.Clear();
processEvents();
draw();
gameArea.Display();
}
}
void Game::processEvents()
{
const sf::Input& input = gameArea.GetInput();
while (gameArea.GetEvent(gameEvents))
{
// Window closed
if (gameEvents.Type == sf::Event::Closed)
isGameFinished = true;
}
float deltaTime = timer.GetElapsedTime();
timer.Reset();
bouncer.move(deltaTime);
}
int main()
{
Game pong;
pong.main();
return EXIT_SUCCESS;
}
Thank you!
--edit--
I found few bugs in my code and changed it but it still does not show ball on the screen.