I'm attempting to make Pong in SFML and trying to make a bot to play against. But when I try to reference for the balls Y position inside of the bot it's only giving me the initialized position and not updating for the current position. The position does update inside of the ball script itself but when taking it to the bot it just stays put.I'll include the two CPP files just in case it can help.
Bot
#include "Albert.h"
#include <iostream>
void Albert::initVariables()
{
this->moveSpeed = 5.f;
}
void Albert::initShape()
{
this->shape.setFillColor(sf::Color::White);
this->shape.setSize(sf::Vector2f(10.f, 40.f));
this->shape.setOrigin(20.f, 10.f);
this->shape.setPosition(775.f, 300.f);
}
Albert::Albert()
{
this->initVariables();
this->initShape();
}
Albert::~Albert()
{
}
void Albert::Update(const sf::RenderTarget* target)
{
this->Brain();
this->ball.ballPos = this->ball.getBall().getPosition().y;
std::cout << this->ball.ballPos << "\n";
}
void Albert::Brain()
{
}
void Albert::Render(sf::RenderTarget* target)
{
target->draw(this->shape);
}
Ball#include "Ball.h"
#include <iostream>
void Ball::initVariables()
{
this->start = true;
this->velocity = sf::Vector2f(-5.f, 0.f);
this->idfk = 0.f;
this->ballPos = this->ball.getPosition().y;
}
void Ball::initBall()
{
this->ball.setFillColor(sf::Color::White);
this->ball.setSize(sf::Vector2f(10.f, 10.f));
this->ball.setOrigin(10.f, 10.f);
this->ball.setPosition(400.f, 150.f);
}
Ball::Ball()
{
this->initVariables();
this->initBall();
}
Ball::~Ball()
{
}
const sf::RectangleShape Ball::getBall() const
{
return this->ball;
}
void Ball::Update(const sf::RenderTarget* target)
{
if (start)
{
GameStart();
start = false;
}
this->ballPos = this->ball.getPosition().y;
//std::cout << ballPos << "\n";
this->UpdateCollisions(target);
this->ball.move(velocity);
}
void Ball::UpdateCollisions(const sf::RenderTarget* target)
{
if (this->ball.getGlobalBounds().left <= 0.f)
{
this->ball.setPosition(400.f, 300.f);
start = true;
}
//Right
if (this->ball.getGlobalBounds().left + this->ball.getGlobalBounds().width >= target->getSize().x)
{
this->velocity.x *= -1;
//std::cout << velocity.x << ", " << velocity.y;
}
//Top
if (this->ball.getGlobalBounds().top <= 0.f)
{
this->velocity.y *= -1;
//std::cout << velocity.x << ", " << velocity.y;
}
//Bottom
if (this->ball.getGlobalBounds().top + this->ball.getGlobalBounds().height >= target->getSize().y)
{
this->velocity.y *= -1;
//std::cout << velocity.x << ", " << velocity.y;
}
}
void Ball::Bounce(const sf::RenderTarget* target)
{
std::cout << this->ball.getPosition().y << ", " << this->player.getPlayer().getPosition().y << ", " << this->player.getPlayer().getGlobalBounds().height << "\n";
idfk = (this->ball.getPosition().y - this->player.getPlayer().getPosition().y) / this->player.getPlayer().getSize().y;
std::cout << "NUMBER: " << idfk << "\n";
float y = idfk;
sf::Vector2f dir = sf::Vector2f(5.f, y);
this->velocity = dir;
std::cout << dir.x << ", " << dir.y << "\n";
}
void Ball::GameStart()
{
int random = rand() % 2;
if (random == 0)
this->velocity = sf::Vector2f(-5.f, 2.5f);
else
this->velocity = sf::Vector2f(5.f, 2.5f);
}
void Ball::Render(sf::RenderTarget* target)
{
target->draw(this->ball);
}
New to SFML so my code probably looks weird.
well, if I understood correctly (hard to tell without the classes) this function inside Albert::Update doesn't seems to do anything:
this->ball.ballPos = this->ball.getBall().getPosition().y;
you are getting the position of the ball and setting it to the same position it already is?
These are the header files
Ball
#pragma once
#include "Player.h"
#include "Include.h"
class Ball
{
private:
bool start;
bool bounce;
sf::RectangleShape ball;
Player player;
sf::Vector2f starterVelocity;
sf::Vector2f velocity;
float idfk;
void initVariables();
void initBall();
public:
Ball();
virtual ~Ball();
const sf::RectangleShape getBall() const;
float ballPos;
void Update(const sf::RenderTarget* target);
void Bounce(const sf::RenderTarget* target);
void UpdateCollisions(const sf::RenderTarget* target);
void GameStart();
void Render(sf::RenderTarget* target);
};
Bot
#pragma once
#include "Include.h"
#include "Ball.h"
class Albert
{
private:
sf::RectangleShape shape;
Ball ball;
float moveSpeed;
void initVariables();
void initShape();
public:
Albert();
virtual ~Albert();
void Update(const sf::RenderTarget* target);
void Brain();
void Render(sf::RenderTarget* target);
};
Since it's not working then I'm guessing this is the wrong way to reference it to get stuff from it.
Ok, Albert contains a Ball member.
Does the main game contain a ball too, or is it directly accessing Albert's ball?
If the game has a ball, then the issue is that the game's ball is the one that's updating and Albert's ball isn't updated. There's two balls, one is moving and rendering and the other (not rendered or updated) is the one Albert is watching.
The easiest way to handle that case would be to change Albert's ball to a ball pointer:
Ball *ball;
Then get the game to set that pointer to the address of the game's ball.
//Something like:
albert.ball = &mainBall;
You'll also need to change all of Albert's code that accesses the ball from ball. to ball-> as it's now a pointer.
Here's an example of what I mean (not working code, just an outline):
// Ball.h
class Ball
{
// Stuff
};
// Albert.h
class Albert
{
// Stuff
Ball *ball;
public:
void setBall(Ball *b) { ball = b; }
};
//main.cpp
#include "Ball.h"
#include "Albert.h"
int main()
{
Ball mainBall;
Albert albert;
albert.setBall(&mainBall);
// Do all the game stuff
return 0;
}