Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Shape not moving after implementation of collision  (Read 1504 times)

0 Members and 1 Guest are viewing this topic.

PompousCrotch

  • Newbie
  • *
  • Posts: 2
    • View Profile
Shape not moving after implementation of collision
« on: September 14, 2015, 08:14:28 pm »
Hi all,
 I have recently started using sfml, and have encountered an issue while implementing collisions in a simple pong game
In the code below, the ball does not move even though it is supposed to, but instead just stays stationary

//Main.cpp

#include <SFML/Graphics.hpp>
#include <iostream>
#include "Player.h"
#include "ball.h"

int main();
sf::RenderWindow window(sf::VideoMode(720, 480), "Pong");
Player player(285, 420);
Ball ball(100, 500);





int main() {
   
   
   player.setPos();
   ball.setPos();

   window.setFramerateLimit(60);
   window.setVerticalSyncEnabled(true);
   
   while (window.isOpen()) {
      sf::Event event;
      while (window.pollEvent(event)) {
         if (event.type == sf::Event::Closed) {
            window.close();
         }
      }
      window.clear(sf::Color::Black);
      window.draw(player.getrPlayer());
      window.draw(ball.getBall());
      player.update();
      ball.ballCollisions(player.getrPlayer());
      ball.update();
      
      window.display();
   }

   return 0;
}

//ball.h

#pragma once
#include <SFML\Graphics.hpp>

class Ball {
public:
   Ball(int x, int y);
   sf::CircleShape getBall();
   void setPos();
   void ballMovement();
   void update();
   int xVel;
   int yVel;
   void ballCollisions(sf::RectangleShape rectangle);
private :
   int x;
   int y;
public:
   int getX();
   int getY();
   int getXVel();
   int getYVel();
   
};

//ball.cpp

#include "ball.h"
#include "Player.h"

sf::CircleShape ball(10);
int xVel = 5;
int yVel = 5;


Ball::Ball(int x, int y) {
   this->x = x;
   this->y = x;
}

int Ball::getX() { return x; }
int Ball::getY() { return y; }

sf::CircleShape Ball::getBall() {
   return ball;
}
void Ball::setPos() {
   ball.setPosition(x, y);
}



void Ball::ballMovement() {

   ball.move(xVel, yVel);

}

void Ball::update() {
   ballMovement();
}

int Ball::getXVel() { return xVel; }
int Ball::getYVel() { return yVel; }

void Ball::ballCollisions(sf::RectangleShape rectangle) {
   if (ball.getGlobalBounds().intersects(rectangle.getGlobalBounds())) {
      xVel *= -1;
      yVel *= -1;
   }
}


« Last Edit: September 14, 2015, 08:18:21 pm by PompousCrotch »

Satus

  • Guest
Re: Shape not moving after implementation of collision
« Reply #1 on: September 14, 2015, 08:44:46 pm »
I think intersects will always return true because your rect is always inside world bound.
If I remember correctly, there was bouncing ball example on SFML wiki.
« Last Edit: September 14, 2015, 08:49:26 pm by Satus »

PompousCrotch

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Shape not moving after implementation of collision
« Reply #2 on: September 14, 2015, 08:53:23 pm »
Thanks for the reply , but in the end I did manage to figure It out!:)
btw, do you know how I can delete this post as when I try it says:
You cannot delete your own topics in this board. Check to make sure this topic wasn't just moved to another board.?

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Shape not moving after implementation of collision
« Reply #3 on: September 14, 2015, 09:46:57 pm »
//Main.cpp

#include <SFML/Graphics.hpp>
#include <iostream>
 
Why include iostream? You don't use aything from that header.
#include "Player.h"
#include "ball.h"

int main();
 
No need to forward declare main - it's the first function in the file.
sf::RenderWindow window(sf::VideoMode(720, 480), "Pong");
Player player(285, 420);
Ball ball(100, 500);
 
Try to avoid global variables, they increase coupling and cause many other problems (search the forum for examples). Especially avoid globals of SFML types (again, search the forum for more).



int main() {
       
       
 
Why all the vertical whitespace?
        player.setPos();
        ball.setPos();
 
Why doesn't the constructor(s) just do this?
        window.setFramerateLimit(60);
        window.setVerticalSyncEnabled(true);
 
Use one or the other, not both, they can interact badly. See the tutorial for details.
       
        while (window.isOpen()) {
                sf::Event event;
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed) {
                                window.close();
                        }
                }
                window.clear(sf::Color::Black);
                window.draw(player.getrPlayer());
                window.draw(ball.getBall());
 
Youv'e just declared player and ball as globals (btw; just declare them inside main()), so why the getXXX functions?
                player.update();
                ball.ballCollisions(player.getrPlayer());
                ball.update();
               
                window.display();
        }

        return 0;
 
Unneeded. Falling off the end of main without returning a value is guaranteed by the standard to return EXIT_SUCCESS.
}

//ball.h

#pragma once
 
Classic header guards are more broadly supported than #pragma once and does the same thing.
#include <SFML\Graphics.hpp>
 
Don't use backslashes in includes (or other file paths). They only work on Windows, but front-slash "/" works on all platforms including Windows.

class Ball {
public:
        Ball(int x, int y);
        sf::CircleShape getBall();
        void setPos();
        void ballMovement();
        void update();
        int xVel;
        int yVel;
 
Why not use sf::Vector2i here? Velocity is a Vector and that's exactly what that class is designed to hold.
        void ballCollisions(sf::RectangleShape rectangle);
 
sf::RectangleShape is a fairly small class, but since you don't modify it or otherwise need a copy, I'd suggest passing it as a const reference instead of by value.
private :
        int x;
        int y;
 
Suggest using sf::Vector2 here.
public:
        int getX();
        int getY();
        int getXVel();
        int getYVel();
 
Why are these not together with the other public members?
       
};

//ball.cpp

#include "ball.h"
#include "Player.h"
 
Why is this file including Player.h?

sf::CircleShape ball(10);
int xVel = 5;
int yVel = 5;
 
More global variables. You really should stop using those.


Ball::Ball(int x, int y) {
        this->x = x;
        this->y = x;
}
 
The use of this-> here is completly superfluous.
You really should use an initializer list rather than the constructor body to initialize members.
You are not initializing xVel and yVel - leaving them uninitialized means they will get 'random' values at runtime (at least in release builds).

int Ball::getX() { return x; }
int Ball::getY() { return y; }

sf::CircleShape Ball::getBall() {
        return ball;
}
void Ball::setPos() {
        ball.setPosition(x, y);
}
 
This function will set your balls position to its initial position every time it is called.


void Ball::ballMovement() {

        ball.move(xVel, yVel);

}

void Ball::update() {
        ballMovement();
}
 
Why have two functions when all one does is just call the other?

int Ball::getXVel() { return xVel; }
int Ball::getYVel() { return yVel; }

void Ball::ballCollisions(sf::RectangleShape rectangle) {
        if (ball.getGlobalBounds().intersects(rectangle.getGlobalBounds())) {
                xVel *= -1;
                yVel *= -1;
        }
}
 
Think a bit about the size of rectangle in this function.

Also, the bouncing ball example Satus hints at is here: https://github.com/SFML/SFML/wiki/Source:-Bouncing-ball

And don't delete topics/posts please. Others may come by and find them useful.
« Last Edit: September 14, 2015, 09:52:14 pm by Jesper Juhl »