(SFML) Issues with inheritance (C++) - c++

So, I'm using SFML and I'm trying to setup an entity class and a player sub-class that inherits from it, but this is my first time working with inheritance and I'm having issues:
First, I have an AssetManager class that I cobbled together from different sources, since I don't quite understand how they work yet:
AssetManager.h:
class AssetManager {
public:
AssetManager();
static sf::Texture& LoadTexture(std::string const& path);
static sf::SoundBuffer& LoadSoundBuffer(std::string const& path);
static sf::Font& LoadFont(std::string const& path);
private:
std::map<std::string, sf::Texture> m_Textures;
std::map<std::string, sf::SoundBuffer> m_SoundBuffers;
std::map<std::string, sf::Font> m_Fonts;
static AssetManager* sInstance;
};
But you can only need to see the part relating to textures, here is that part from AssetManager.cpp:
AssetManager* AssetManager::sInstance = nullptr;
AssetManager::AssetManager() {
assert(sInstance == nullptr);
sInstance = this;
}
sf::Texture& AssetManager::LoadTexture(std::string const& path) {
auto& texMap = sInstance->m_Textures;
auto pairFound = texMap.find(path);
if (pairFound != texMap.end()) {
return pairFound->second;
}
else {
auto& texture = texMap[path];
texture.loadFromFile(path);
return texture;
}
}
Then an object of that class is included inside a Sprite class, that facilitates declaring sprites for me.
Sprite.h:
class Sprite {
public:
AssetManager manager;
sf::Texture m_Texture;
sf::Sprite m_Sprite;
sf::Vector2f sprite_scale;
sf::Vector2u original_size;
sf::Vector2f texture_size;
Sprite(std::string path,sf::IntRect rect,sf::Vector2f size);
};
Sprite.cpp:
Sprite::Sprite(std::string path, sf::IntRect rect, sf::Vector2f size) {
m_Texture = sf::Texture(AssetManager::LoadTexture(path));
m_Sprite.setTextureRect(rect);
m_Sprite.setTexture(m_Texture);
original_size = m_Texture.getSize();
texture_size.x = static_cast<float>(original_size.x);
texture_size.y = static_cast<float>(original_size.y);
sprite_scale.x = size.x / texture_size.x;
sprite_scale.y = size.y / texture_size.y;
m_Sprite.setScale(sf::Vector2f(sprite_scale.x, sprite_scale.y));
m_Sprite.setOrigin(sf::Vector2f(original_size.x / 2, original_size.y / 2));
}
Then, an object of the Sprite class is itself included within an Entity class.
Entity.h:
class Entity {
public:
Sprite entity_sprite;
int health;
float speed;
bool collision = false;
bool entity_collision(sf::Sprite entity2_sprite);// Entity.cpp only contains the declaration of this function so far so no need to post it.
};
Now, for a reason I don't understand, I'm not able to directly assign any arguments to the entity_sprite object when declaring it, and I'm only able to declare it with no arguments, despite the class having not a default constructor.
However I am able to get around it using assignment:
Entity entity_sprite = Entity("res/wildcard.png", { 0,0,36,63 }, { 36,63 });
But this isn't the main issue, and using the Entity class directly is not what I'm trying to do, I'm trying to write the Player sub-class and use that instead:
Player.h:
class Player:public Entity {
Player() {
entity_sprite = Sprite("res/wildcard.png", { 0,0,36,63 }, { 36,63 });
}
};
Now I'm once again not able to directly assign arguments to the object directly, because the call of an object of a class type without appropriate operator() or conversion function to pointer-to-function type (Interestingly enough if I go back to the Entity object and assign the arguments there and pretend the errors don't exist, the error produced by the Player class changes to Too many arguments' and 'Too many initializers
This is getting too confusing.
Nonetheless, I am once again able to get around it using assignment, exactly the same as before, except this time I get an error saying the default constructor "Entity" cannot be referenced -- its a deleted function., so I go back to the Entity class and add an empty constructor like this: Entity() { } but then this constructor gives me another error saying no default constructor exists for class "Sprite", even though the Entity class doesn't exactly inherit from the Sprite class, so I go back even further to the Sprite class and give that an empty constructor: Sprite(){}, and the errors seemingly disappear, that is until I declare a Player object in the main.cpp file and try to compile and get a debug error pointing to the following line in AssetManager.cpp: assert(sInstance == nullptr);
So many problems for such a seemingly simple task, how do I pull myself out of this?

Ok, after consulting the SFML Forums, I have refactored the code to the following:
Sprite.h:
#include "AssetManager.h"
class Sprite{
public:
sf::Sprite m_sprite;
sf::Vector2f sprite_scale;
sf::Vector2u original_size;
sf::Vector2f texture_size;
Sprite(){}
sf::Sprite set_sprite(sf::Texture& tx, sf::IntRect rect, sf::Vector2f size);
};
Sprite.cpp:
#include "Sprite.h"
sf::Sprite Sprite::set_sprite(sf::Texture& tx, sf::IntRect rect, sf::Vector2f size) {
sf::Sprite spr(tx);
spr.setTextureRect(rect);
original_size =tx.getSize();
texture_size.x = static_cast<float>(original_size.x);
texture_size.y = static_cast<float>(original_size.y);
sprite_scale.x = size.x / texture_size.x;
sprite_scale.y = size.y / texture_size.y;
spr.setScale(sf::Vector2f(sprite_scale.x, sprite_scale.y));
spr.setOrigin(sf::Vector2f(original_size.x / 2, original_size.y / 2));
return spr;
}
Entity.h:
#pragma once
#include "Sprite.h"
#include "collision.h"
#include "Timer.h"
class Entity {
public:
Sprite spr;
sf::Sprite entity_sprite;
int health;
float max_speed;
sf::Vector2f speed;
sf::Vector2f direction;
float acceleration;
bool collision = false;
timer t;
float acc_time;
};
Player.h:
#pragma once
#include "Entity.h"
class Player:public Entity {
public:
Player();
float acc_time = t.accumulate_time();
void keyboard_controls();
void mouse_controls(sf::Vector2f cursor);
};
Player.cpp:
#include "Player.h"
#include <math.h>
Player::Player() {
speed = { 0,0 };
acceleration = 2;
max_speed = 500 + acceleration;
entity_sprite = spr.set_sprite(AssetManager::LoadTexture("res/wildcard.png"), { 0,0,60,63 }, { 60,63 });
}
In short, the Sprite class' constructor is replaced with a method that has the same exact role, that way I can simply declare a Sprite object with no parameters inside the Entity class, and I won't have any issues with the derived Player class since I won't be asked to create default constructors for both the Sprite and Entity classes.

Related

C2259: 'Object' cannot instantiate Error, I'm not instantiating any 'Object' objects?

I'm quite sure I'm not creating a pure 'Object' variable. I am declaring a vector consisting of Objects though, but I believe that should be legal even though 'Object' it is a abstract class/struct?
Header file:
#pragma once
#include <glm/glm.hpp>
#include "Collider.h"
#include "Renderer.h"
struct Object
{
public:
float mass = 10;
float Resititution = 0.7;
glm::vec2 velocity;
glm::vec2 force = glm::vec2(0, 0);
bool isDynamic = true;
bool isKinematic = true;
Collider* collider;
Transform* transform;
virtual void submitToRenderer(Renderer* renderer) const = 0;
};
struct SphereObj : Object
{
void submitToRenderer(Renderer* renderer) const override;
};
struct PlaneObj : Object
{
void submitToRenderer(Renderer* renderer) const override;
};
cpp file:
#include "Object.h"
void SphereObj::submitToRenderer(Renderer* renderer) const
{
renderer->submitObject(this);
}
void PlaneObj::submitToRenderer(Renderer* renderer) const
{
renderer->submitObject(this);
}
in main()
std::vector<Object> objList;
in another file:
std::vector<Object*> m_objects;
std::vector uses the new operator to allocate it's objects. If you have std::vector<Object> objList, the std::vector is going to allocate objects for it. Object, however, is an abstract class, so when new attempts to allocate and initialize these objects, it won't work.
An Object* is a different, thing, as it is a pointer, not the abstract class itself. This will work, because the pointer is not an abstract class.
Looking at your code, I guess that you are working in a 3D engine [Game Engine].
So, you should instantiate your Object like this:
Object* object = Instantiate<SphereObj>(...);
I have assumed that you have implemented your Insantiate template function.

Cannot get class data in box2d collision callback

I'm building a simple 2D game in C++ and am using Box2D for collision detection.
I have an Entity class from which an Enemy and Bullet class is derived, and an EnemySquare class is derived from the Enemy class.
I'm trying to detect collisions between the EnemySquare class and the Bullet class (will have more collision combinations to process later in development). To do this I have created a CollisionManager class deriving from the Box2D class b2ContactListener which handles the collision callbacks.
Each Entity instance has a private variable m_collisionObjectType which is an enum class of object types (shown below).
In the BeginContact() callback, I'm trying to cast the box2d fixture's user data to the correct class type so I can apply damage, mark bullets for removal etc.
(non-relevant code removed for simplicity)
Object Type Enum:
enum class COLLISION_OBJECT_TYPE {BULLET, ENEMY, PLAYER};
Entity class
.h
class Entity
{
public:
Entity();
~Entity();
COLLISION_OBJECT_TYPE getCollisionObjectType() { return m_collisionObjectType; }
protected:
b2Body* m_body = nullptr;
b2Fixture* m_fixtures[3];
COLLISION_OBJECT_TYPE m_collisionObjectType;
};
Enemy Class
.h
class Enemy : public Entity
{
public:
Enemy();
~Enemy();
virtual void init(glm::vec2 position, float health, float speed, Player* player, b2World* physicsWorld) = 0;
virtual void update(float deltaTime) = 0;
protected:
float m_health;
float m_speed;
Player* m_playerTarget;
};
Enemy Square Class
.h
class EnemySquare : public Enemy
{
public:
EnemySquare();
~EnemySquare();
void init(glm::vec2 position, float health, float speed, Player* player, b2World* physicsWorld) override;
void update(float deltaTime) override;
};
.cpp
void EnemySquare::init(glm::vec2 position, float health, float speed, Player * player, b2World* physicsWorld) {
// init physics body
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(m_position.x, m_position.y);
bodyDef.fixedRotation = false;
bodyDef.angle = 0;
bodyDef.userData = this;
m_body = physicsWorld->CreateBody(&bodyDef);
// init physics fixtures
b2PolygonShape squareShape;
squareShape.SetAsBox(m_width * 0.5f, m_height * 0.5f);
b2FixtureDef fixtureDef;
fixtureDef.shape = &squareShape;
m_fixtures[0] = m_body->CreateFixture(&fixtureDef);
}
Bullet Class
.h
class Bullet : public Entity
{
public:
Bullet(
b2World* world,
glm::vec2 startPosition,
glm::vec2 direction,
Tempest::glTexture texture,
float width,
float height,
float damage,
float speed,
float range
);
~Bullet();
// methods are unrelated
private:
// private variables are unrelated
};
.cpp
Bullet::Bullet(
b2World* world,
glm::vec2 startPosition,
glm::vec2 direction,
Tempest::glTexture texture,
float width,
float height,
float damage,
float speed,
float range
) {
// Make the body
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(m_position.x, m_position.y);
bodyDef.fixedRotation = true;
bodyDef.angle = 0;
bodyDef.userData = this;
m_body = world->CreateBody(&bodyDef);
// Create the box
b2PolygonShape boxShape;
boxShape.SetAsBox(m_height * 0.4f, m_width * 0.5f);
b2FixtureDef boxDef;
boxDef.shape = &boxShape;
m_fixtures[0] = m_body->CreateFixture(&boxDef);
m_collided = false;
m_collisionObjectType = COLLISION_OBJECT_TYPE::BULLET;
}
In my the CollisionManager class I'm trying to retrieve the colliding fixture's userData (which is a void*) then cast it to an Entity* to call the getCollisionObjectType() method. When I know what type of entity I'm dealing with I then want to cast it to the correct object type and do things like apply damage, mark bullets for removal etc. Code below:
void CollisionManager::BeginContact(b2Contact * contact) {
void* fixtureABodyData = contact->GetFixtureA()->GetBody()->GetUserData();
void* fixtureBBodyData = contact->GetFixtureB()->GetBody()->GetUserData();
if (fixtureABodyData && fixtureBBodyData) {
Entity* fixtureAData = static_cast<Entity*>(fixtureABodyData);
Entity* fixtureBData = static_cast<Entity*>(fixtureBBodyData);
if (fixtureAData->getCollisionObjectType() == COLLISION_OBJECT_TYPE::BULLET) {
std::cout << "A BULLET" << std::endl;
}
if (fixtureBData->getCollisionObjectType() == COLLISION_OBJECT_TYPE::BULLET) {
std::cout << "B BULLET" << std::endl;
}
if (fixtureAData->getCollisionObjectType() == COLLISION_OBJECT_TYPE::ENEMY) {
std::cout << "A ENEMY" << std::endl;
}
if (fixtureBData->getCollisionObjectType() == COLLISION_OBJECT_TYPE::ENEMY) {
std::cout << "B ENEMY" << std::endl;
}
std::cout << "----------------------" << std::endl;
}
}
For some reason, the casting works for the Bullet class but not for the Enemy class. I think it returns a nullptr. So I know one of the colliding bodies is a bullet, but I can't tell what the second body is.
I have a feeling I'm doing something wrong with the static_cast calls or it might be because the EnemySquare class is twice removed from the Entity class? or I could be doing something wrong in the Box2D code. Any advice would be appreciated!
Set the m_collisionObjectType member variable for the Enemy derived class. Preferably to COLLISION_OBJECT_TYPE::ENEMY.
As the code appears now, it's only setting m_collisionObjectType in the code for the Bullet derived class. So the Enemy derived class instances are getting constructed with their m_collisionObjectType member variables uninitialized. I.e. the value out of the getCollisionObjectType() method could be whatever was in the memory location of m_collisionObjectType before it got used by the constructor.
Hope this helps!

How does c++ keep things in scope?

To be more specific, I have a class that looks like this:
class Ball {
public:
unsigned collider_size;
scionofbytes::MovementComponent movement;
scionofbytes::GraphicComponent graphic;
Ball(u_int init_collider_size, std::string texture_path) {
collider_size = init_collider_size;
movement = scionofbytes::MovementComponent();
graphic = scionofbytes::GraphicComponent(
(u_int) collider_size/2,
(u_int) collider_size/2,
texture_path
);
}
};
I'm accepting the texture_path and passing it on to the graphic component, which looks like this:
class GraphicComponent {
unsigned height;
unsigned width;
public:
sf::Texture texture;
sf::Sprite sprite;
GraphicComponent() {}
GraphicComponent(unsigned init_height, unsigned init_width, std::string texture_path) {
width = init_width;
height = init_height;
texture.loadFromFile(texture_path);
sprite.setTexture(texture);
}
};
When I instantiate a ball object by passing in the texture_path, I'm creating a texture as a member of the graphic component and then assigning that texture to the graphic component's sprite member.
When using this sprite member to draw to the screen, I'm facing SFML's known white box problem.
Now from my understanding, of the ball objects stays alive, the graphic component member also stays alive as does the texture member of the graphic component.
So my question is, why does this not work? When using the sprite to draw on screen, I still get a white box. Why is the texture getting destroyed?
In your Ball class constructor you are making a copy of your GraphicComponent. IIRC sf::Sprite only holds a reference to the sf::Texture so your copy may end up with the sf::Sptite pointing to the deleted sf::Texture from the object it got copied from.
Try constructing your Ball without making a copy of your GraphicComponent:
class Ball {
public:
unsigned collider_size;
scionofbytes::MovementComponent movement;
scionofbytes::GraphicComponent graphic;
// Use initializer-list
Ball(u_int init_collider_size, std::string texture_path)
: collider_size(init_collider_size)
, movement()
, graphic((u_int) collider_size/2, (u_int) collider_size/2, texture_path)
{
// don't assign stuff here if you can avoid it
}
};
In addition to that you may also want to create a copy constructor for your GraphicComponent class to prevent corruption elsewhere:
class GraphicComponent
{
unsigned height;
unsigned width;
public:
sf::Texture texture;
sf::Sprite sprite;
GraphicComponent()
{
}
GraphicComponent(unsigned init_height, unsigned init_width,
std::string texture_path)
{
width = init_width;
height = init_height;
texture.loadFromFile(texture_path);
sprite.setTexture(texture);
}
// Give it a copy constructor
GraphicComponent(GraphicComponent const& other)
: height(other.height)
, width(other.width)
, texture(other.texture)
, sprite(texture) // make it point to the new Texture not the other one
{
}
};

Inheriting from Transformable and Drawable in SFML

I'm trying to inherit from Transformable and Drawable in SFML in order to make my objects... well, transformable and drawable. I'm making a simple breakout game, but perhaps I'm going about this the wrong way. Here's my code:
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
class Player : public sf::Transformable, public sf::Drawable {
public:
Player(int x, int y);
~Player() {};
sf::RectangleShape p_rect;
void doMovement(const sf::RenderWindow& window);
sf::FloatRect getGlobalBounds() const;
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const {
states.transform *= getTransform();
target.draw(p_rect, states);
}
};
class Ball : public sf::Transformable, public sf::Drawable {
public:
Ball(int r, int x, int y);
~Ball() {};
sf::CircleShape b_circle;
void doXMovement();
void doYMovement();
bool doXCollisions(const Player& player);
bool doYCollisions(const Player& player);
sf::FloatRect getGlobalBounds() const;
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const {
states.transform *= getTransform();
target.draw(b_circle, states);
}
bool right;
bool up;
};
Player::Player(int x, int y) {
p_rect = sf::RectangleShape(sf::Vector2f(x, y));
}
void Player::doMovement(const sf::RenderWindow& window) {
setPosition(sf::Mouse::getPosition(window).x, 500);
if (getPosition().x < 0)
setPosition(0, 500);
else if (getPosition().x > 720)
setPosition(720, 500);
}
sf::FloatRect Player::getGlobalBounds() const {
return getTransform().transformRect(p_rect.getGlobalBounds());
}
Ball::Ball(int r, int x, int y) {
b_circle = sf::CircleShape(r);
b_circle.setPosition(x, y);
right = true;
up = false;
}
void Ball::doXMovement() {
if (right)
move(1, 0);
else
move(-1, 0);
}
void Ball::doYMovement() {
if (up)
move(0, -1);
else
move(0, 1);
}
bool Ball::doXCollisions(const Player& player) {
bool coll;
if (getGlobalBounds().intersects(player.getGlobalBounds())) {
right = !right;
coll = true;
} else
coll = false;
if (getPosition().x >= 800 - b_circle.getRadius())
right = false;
else if (getPosition().x <= 0)
right = true;
return coll;
}
bool Ball::doYCollisions(const Player& player) {
bool coll;
if (getGlobalBounds().intersects(player.getGlobalBounds())) {
up = !up;
coll = true;
} else
coll = false;
if (getPosition().x <= 0)
up = false;
return coll;
}
sf::FloatRect Ball::getGlobalBounds() const {
return getTransform().transformRect(b_circle.getGlobalBounds());
}
int main() {
sf::RenderWindow window(sf::VideoMode(800, 600), "Breakout");
window.setMouseCursorVisible(false);
Player player(80, 10);
Ball ball(3, 100, 100);
sf::Clock clock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
player.doMovement(window);
if (clock.getElapsedTime().asMilliseconds() >= 3) {
clock.restart();
if (!ball.doYCollisions(player))
ball.doXCollisions(player);
ball.doYMovement();
ball.doXMovement();
}
window.clear(sf::Color::Black);
window.draw(player);
window.draw(ball);
window.display();
}
return 0;
}
Now moving and drawing work (nearly) as expected, however collisions are a bit wonky. First my collisions problems:
Do I need to implement the getGlobalBounds function the way I did? Or is there a better way to do it with things included in Transformable and Drawable?
Should I be performing transformations on the shapes directly, or should I pass the transformations to the draw function like I currently am?
Something strange is also happening with the drawing which is probably a quick fix. Right now the getPosition method returns incorrect values for my ball object. The area it returns seems to be shifted down and to the right a bit. Any reason that might be?
Thanks for any help you are able to give!
EDIT: Also any general C++ tips are welcome, I'm still a beginner.
If I were you I would define a new class, called TransformableAndDrawable like this:
class TransformableAndDrawable : public sf::Transformable, public sf::Drawable {
// Your code here
}
In this class you should define all the members which are generally needed by your transformable and drawable classes. Also, in this class you should define all the methods which can be generally implemented in your transformable and drawable classes. Then, your classes should be inherited from TransformableAndDrawable, like this:
class Player : TransformableAndDrawable {
// Your code here
}
Now, the answer to the first question is: I would implement in the TransformableAndDrawable class the given method if it is a general method, so all the classes inherited from TransformableAndDrawable will have this method.
Instead of giving different names, like p_rect and p_circle, name these members with the same name, like p_shape, so you will have no naming issues. Also, I believe that you can declare your p_shape to be of an ancestor class or interface (I do not know what classes are defined in the library you are working with) and only when needed specify the nature of the shape (whether it is a circle or a rectangle or something else).
As for the second questions: I like the way you have implemented things, but you have made two mistakes:
it is not scalable: we want a general solution, a class which can be used for any shape you are working with now and in the future, don't we?
it is not general enough: When I want to know the global bounds of a shape, then I am not interested of the nature of the shape, I would prefer your code to handle the nature of the shape without me knowing it
In short, you should do the following:
Create a wrapper class which will be inherited from Transformable and Drawable
In your wrapper class, be agnostic to the nature of the shape, be as general as possible, hopefully there is some class or interface which is ancestor to both RectangleShape and CircleShape.
Inherit all your drawable and transformable classes from your wrapper class, so you will have a shared functionality among your classes
If something in your wrapper class is not good for a class which was inherited from it, overwrite the method in that class.
EDIT:
I have looked into the library you are using in more detail and found out that there is a class called Shape, which is the ancestor to both CircleShape and RectangleShape. So, instead of these classes use Shape and your code will be more general and reusable.

C++ Referencing an objects current state within another object

I've searched high and low for an answer to this question and have attempted many solutions including forward declaration, pointers, and references. I'm sure I'm just using incorrect syntax somewhere. After many wasted hours, I've decided to turn to stack overflow.
I am attempting to code one of my first CPP applications as a learning experience. Right now I have a Player and a Ball object. My Ball object must be able to access some of the member variables and methods in my player object. I have been unable to figure out how to do this. Below is an extremely simplified version of my code. I've commented the code that is particularly important.
PlayState.hpp
#ifndef PLAYSTATE_HPP
#define PLAYSTATE_HPP
#include "Player.hpp"
#include "Ball.hpp"
class Player;
class Ball;
class PlayState
{
public:
PlayState();
Player player;
Ball ball;
};
#endif
PlayState.cpp
#include "PlayState.hpp"
PlayState::PlayState() {
}
void PlayState::update() {
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
ball.checkCollision();
player.move(1);
}
ball.update();
}
void PlayState::draw()
{
m_game.screen.clear();
m_game.screen.draw( player.getSprite() );
m_game.screen.draw( ball.getSprite() );
m_game.screen.display();
}
Player.hpp
#ifndef PLAYER_HPP
#define PLAYER_HPP
class Player
{
public:
Player();
~Player();
void create();
void setRotation(float);
void setPosition(float, float);
};
#endif
Player.cpp shouldn't really be all that important to see.
Ball.hpp
#ifndef BALL_HPP
#define BALL_HPP
class Player; // I don't think forward declaration is what I need???
class Ball
{
public:
bool picked_up;
bool throwing;
Player *player; // this isn't working
Ball();
~Ball();
bool checkCollision();
};
#endif
Ball.cpp
#include "Ball.hpp"
Ball::Ball() {
Ball::picked_up = false;
Ball::throwing = false;
}
Ball::~Ball() {
}
bool Ball::checkCollision()
{
float ball_position_x = Ball::getPosition().x;
float ball_position_y = Ball::getPosition().y;
// I need to access the player object here.
float x_distance = abs(player.getPosition().x - ball_position_x);
float y_distance = abs(player.getPosition().y - ball_position_y);
bool is_colliding = (x_distance * 2 < (player.IMG_WIDTH + Ball::width)) && (y_distance * 2 < (player.IMG_HEIGHT + Ball::height));
return is_colliding;
}
When you say player, do you mean the exact same player that is in the same playstate object as the current ball object? If so you want to first set up that link, it cannot be done automatically.
PlayState::PlayState() :ball(&player){ //pass pointer to ball of its player?
}
class Ball
...
Ball(Player *myPlayer);
...
}
Ball::Ball(Player *myPlayer):player(myPlayer) {
...
// I need to access the player object here.
float x_distance = abs(player->getPosition().x - ball_position_x);
You also need to use a pointer to use the player since it is a pointer to a player object.
You do need the forward declaration to Player above the Ball class. The one above Playstate is unnecessary.
Also your player doesnt seem to have a GetPosition function, I am assuming it is a public member function you forgot to include above.