everyone! I’ve been writing simple 2D gameo on sfml. I’ve done draft version of game, but when I run the program, it returns “Pure virtual method called” error. The debugger wrote problem in GameObject->Update() method. Precisely in Player->Update(). As you see I’ve wrode abstract class GameObject to use subclasses in main function properly
GameObject.h
#include <memory>
#include "Window.h"
class GameObject
{
public:
GameObject() = default;
virtual void Update(const float& frametime) = 0;
virtual void Render(const std::shared_ptr<Window>& window) = 0;
virtual sf::Vector2f getPosition() = 0;
virtual ~GameObject() = default;
};
Player.h
#include "Graphics.hpp"
#include"Audio.hpp"
#include "Window.h"
#include "ObjectConstructor.h"
#include "GameObject.h"
#include <chrono>
#include <memory>
using namespace std::chrono;
class Player : public GameObject {
public:
Player();
void Update(const float& frametime) override;
void Render(const std::shared_ptr<Window>& window) override;
sf::Vector2f getPosition() override;
~Player() override;
void SetOC(ObjectConstructor* oc);
private:
float speed = 125; //default speed
ObjectConstructor* OC = nullptr; //Object constructor to get game data
sf::Vector2f m_pos;
sf::Texture m_playerTexture;
sf::SoundBuffer buffer;
sf::Sound ShotSound;
steady_clock::time_point lastShotTime;
duration<float> timeBetweenShots = 0.45s;
};
Player. cpp
#include "../include/Player.h"
#include "../include/Bullet.h"
Player::Player()
{
m_playerTexture.loadFromFile("../assets/ship.png");
m_pos = sf::Vector2f(sf::VideoMode::getDesktopMode().width / 8, sf::VideoMode::getDesktopMode().height / 2);
lastShotTime = steady_clock::now();
buffer.loadFromFile("../assets/shootSFX.mp3");
ShotSound.setBuffer(buffer);
}
void Player::Update(const float& frametime)
{
sf::Event event;
sf::RenderWindow& m_window = OC->GetWindow()->GetRenderWindow();
while(m_window.pollEvent(event))
{
if(event.type == sf::Event::KeyPressed)
{
if(event.key.code == sf::Keyboard::W && m_pos.y > 64)
m_pos.y += speed * frametime;
else if(event.key.code == sf::Keyboard::S && m_pos.y < m_window.getSize().y -64)
m_pos.y -= speed * frametime;
if(event.key.code == sf::Keyboard::Space && lastShotTime + timeBetweenShots <= steady_clock::now()){
//some shooting logic
Bullet newBullet(m_pos,OC->GetWindow());
newBullet.SetOC(OC);
OC->GetObjects()->push_back(&newBullet);
ShotSound.play();
lastShotTime = steady_clock::now();
}
}
}
}
void Player::Render(const std::shared_ptr<Window>& window)
{
sf::RenderWindow& m_window = OC->GetWindow()->GetRenderWindow();
sf::Sprite sprite(m_playerTexture, sf::IntRect(m_pos.x - m_playerTexture.getSize().x /2,
m_pos.y - m_playerTexture.getSize().y /2,m_playerTexture.getSize().x,m_playerTexture.getSize().y));
m_window.draw(sprite);
}
void Player::SetOC(ObjectConstructor* oc){
OC = oc;
}
sf::Vector2f Player::getPosition()
{
return m_pos;
}
main.cpp
#include "../RegularGame/include/Player.h"
#include "../RegularGame/include/Bullet.h"
#include "../RegularGame/include/ObjectConstructor.h"
#include "../RegularGame/include/Game.h"
int main()
{
ObjectConstructor objects;
while (objects.GetWindow().get()->IsDone() == 0)
{
for (auto& gameObject : *objects.GetObjects())
{
gameObject->Update(0.015);
objects.GetWindow().get()->Update();
}
for (auto& gameObject : *objects.GetObjects())
{
gameObject->Render(objects.GetWindow());
}
}
objects.~ObjectConstructor();
return 0;
}