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

Author Topic: sf::Sprite deletes the constructor in header file  (Read 212 times)

0 Members and 1 Guest are viewing this topic.

NAGIRA

  • Newbie
  • *
  • Posts: 3
    • View Profile
sf::Sprite deletes the constructor in header file
« on: January 04, 2025, 05:21:50 pm »
So I way organizing my code by creating a separate class for my main character, when I noticed that when I declare a Sprite in header, in my main file the class returns an error: "the default constructor of MainCharacter cannot be referenced -- it is a deleted function" when i declare it (MainCharacter mc).
here is the code for MainCharacter.h:
#pragma once
#include<SFML/Graphics.hpp>
using namespace sf;
class MainCharacter
{
private:
       
        Texture texture;
        Clock clock;
       
        int indexX = 0;
        int indexY = 2;
       
public:
       
        void init();
        void Update();
        Sprite s;
};


 

MainCharacter.cpp:
#include "MainCharacter.h"


void MainCharacter::init()
{
        if (texture.loadFromFile("Assets/Player/Textures/BODY_skeleton.png")) {
                s.setTexture(texture);
        }
}

void MainCharacter::Update()
{
        if (Keyboard::isKeyPressed(Keyboard::Key::A))
        {
                // left key is pressed: move our character
                s.move({ -.1f, 0.f });
                indexY = 1;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else if (Keyboard::isKeyPressed(Keyboard::Key::D))
        {
                // left key is pressed: move our character
                s.move({ .1f, 0.f });
                indexY = 3;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else if (Keyboard::isKeyPressed(Keyboard::Key::W))
        {
                // left key is pressed: move our character
                s.move({ 0.f, -.1f });
                indexY = 0;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else if (Keyboard::isKeyPressed(Keyboard::Key::S))
        {
                // left key is pressed: move our character
                s.move({ 0.f, .1f });
                indexY = 2;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else {
                indexX = 0;
                indexX = 0;
        }

        s.setTextureRect(IntRect({ indexX * 64,indexY * 64 }, { 64, 64 }));
}
 
main.cpp:
#include<SFML/Graphics.hpp>
#include<SFML/Window.hpp>
#include<SFML/System.hpp>
#include<iostream>
#include<vector>
#include<cmath>
#include"MainCharacter.h"
using namespace sf;
using namespace std;

void Normalize(Vector2f& vec) {
        float m = sqrt(vec.x * vec.x + vec.y * vec.y);
        vec.x = vec.x / m;
        vec.y = vec.y / m;
}

int main() {
        RenderWindow window(VideoMode({ 1280, 720 }), "mywindow");
        Texture bullettexture("Assets/Player/Textures/WEAPON_arrow.png");
    MainCharacter mc;
        Clock disappear;
        vector<Sprite> bullets;
        vector<Vector2f> directions;
        mc.init();
        bool isshooting = false;
        while (window.isOpen()) {
                while (const optional event = window.pollEvent())
                {
                       
                        // "close requested" event: we close the window
                        if (event->is<sf::Event::Closed>())
                                window.close();
                }

                mc.Update();
               
               
                if (Mouse::isButtonPressed(Mouse::Button::Left)&& !isshooting) {
                        isshooting = true;
                        bullets.push_back(Sprite(bullettexture));
                        Vector2f mousepos = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));
                        Vector2f offset = { 32,32 };
                        bullets[bullets.size() - 1].setPosition(mc.s.getPosition()+offset);
                        directions.push_back(mousepos - bullets[bullets.size() - 1].getPosition());
                        Normalize(directions[directions.size() - 1]);
                }
                else if (!Mouse::isButtonPressed(Mouse::Button::Left)) {
                        isshooting = false;
                }
                for (int i = 0; i < bullets.size(); i++) {
                        float ang = directions[i].x / directions[i].y;
                        Vector2f offset = { 16,8 };
                        bullets[i].setOrigin( offset);
                        if (directions[i].y < 0) {
                                bullets[i].setRotation(degrees(-(atan(ang) * 180 / 3.14) - 90));
                        }
                        else {
                                bullets[i].setRotation(degrees(-(atan(ang) * 180 / 3.14) + 90));
                        }
                       
                        bullets[i].move(directions[i]*0.2f);
                }
                if (disappear.getElapsedTime().asSeconds() > 5) {
                        if (bullets.size() > 0) {
                                bullets.erase(bullets.begin());
                                directions.erase(directions.begin());
                                disappear.restart();
                        }
                       
                }
                if (mc.s.getPosition().x < 0) {
                        mc.s.setPosition({ 0, mc.s.getPosition().y });
                }
                if (mc.s.getPosition().y < 0) {
                        mc.s.setPosition({ mc.s.getPosition().x,0});
                }
                if (mc.s.getPosition().x + 100 > 1280) {
                        mc.s.setPosition({1180,mc.s.getPosition().y});
                }
                if (mc.s.getPosition().y + 100 > 720) {
                        mc.s.setPosition({ mc.s.getPosition().x,620 });
                }
               


                window.clear(Color::Black);
                window.draw(mc.s);
                for (int i = 0; i < bullets.size(); i++) {
                        window.draw(bullets[i]);
                }
                window.display();
        }
        return 0;
}
I'm a beginner so this question can be stupid, so thank you for your patience in advance:).
« Last Edit: January 04, 2025, 05:25:44 pm by NAGIRA »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11073
    • View Profile
    • development blog
    • Email
Re: sf::Sprite deletes the constructor in header file
« Reply #1 on: January 04, 2025, 08:39:07 pm »
Sprite doesn't have a default constructor (anymore), as such you need to pass in a texture at construction, which you can do by giving your MainCharacter a constructor and in the initialization list pass the texture to the sprite.

Better yet, don't let your entities/players/etc hold a copy of the texture themselves, but use something like a ResourceHolder or similar to manage the texture life-time and ownership.
Official FAQ: https://www.sfml-dev.org/faq/
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

NAGIRA

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: sf::Sprite deletes the constructor in header file
« Reply #2 on: January 07, 2025, 09:10:33 am »
Can you show me an example? I cant quite understand what do you mean. Again, sorry for wasting your time.
« Last Edit: January 07, 2025, 09:15:51 am by NAGIRA »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11073
    • View Profile
    • development blog
    • Email
Re: sf::Sprite deletes the constructor in header file
« Reply #3 on: January 07, 2025, 09:19:17 am »
In a simple case you can add a default constructor and call the sprite's constructor with the texture.
Additionally, this lets you remove the init function.

#pragma once
#include<SFML/Graphics.hpp>
using namespace sf;
class MainCharacter
{
private:
       
        Texture texture;
        Clock clock;
       
        int indexX = 0;
        int indexY = 2;
       
public:
       
        MainCharacter();
        void Update();
        Sprite s;
};


 

#include "MainCharacter.h"

MainCharacter::MainCharacter() : s(texture)
{
        if (texture.loadFromFile("Assets/Player/Textures/BODY_skeleton.png")) {
                s.setTexture(texture);
        }    
}

void MainCharacter::Update()
{
        if (Keyboard::isKeyPressed(Keyboard::Key::A))
        {
                // left key is pressed: move our character
                s.move({ -.1f, 0.f });
                indexY = 1;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else if (Keyboard::isKeyPressed(Keyboard::Key::D))
        {
                // left key is pressed: move our character
                s.move({ .1f, 0.f });
                indexY = 3;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else if (Keyboard::isKeyPressed(Keyboard::Key::W))
        {
                // left key is pressed: move our character
                s.move({ 0.f, -.1f });
                indexY = 0;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else if (Keyboard::isKeyPressed(Keyboard::Key::S))
        {
                // left key is pressed: move our character
                s.move({ 0.f, .1f });
                indexY = 2;
                if (clock.getElapsedTime().asSeconds() > 0.1f) {
                        indexX++;
                        clock.restart();
                }
                if (indexX > 8) {
                        indexX = 1;
                }
        }
        else {
                indexX = 0;
                indexX = 0;
        }

        s.setTextureRect(IntRect({ indexX * 64,indexY * 64 }, { 64, 64 }));
}
 

#include<SFML/Graphics.hpp>
#include<SFML/Window.hpp>
#include<SFML/System.hpp>
#include<iostream>
#include<vector>
#include<cmath>
#include"MainCharacter.h"
using namespace sf;
using namespace std;

void Normalize(Vector2f& vec) {
        float m = sqrt(vec.x * vec.x + vec.y * vec.y);
        vec.x = vec.x / m;
        vec.y = vec.y / m;
}

int main() {
        RenderWindow window(VideoMode({ 1280, 720 }), "mywindow");
        Texture bullettexture("Assets/Player/Textures/WEAPON_arrow.png");
    MainCharacter mc;
        Clock disappear;
        vector<Sprite> bullets;
        vector<Vector2f> directions;
        bool isshooting = false;
        while (window.isOpen()) {
                while (const optional event = window.pollEvent())
                {
                       
                        // "close requested" event: we close the window
                        if (event->is<sf::Event::Closed>())
                                window.close();
                }

                mc.Update();
               
               
                if (Mouse::isButtonPressed(Mouse::Button::Left)&& !isshooting) {
                        isshooting = true;
                        bullets.push_back(Sprite(bullettexture));
                        Vector2f mousepos = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));
                        Vector2f offset = { 32,32 };
                        bullets[bullets.size() - 1].setPosition(mc.s.getPosition()+offset);
                        directions.push_back(mousepos - bullets[bullets.size() - 1].getPosition());
                        Normalize(directions[directions.size() - 1]);
                }
                else if (!Mouse::isButtonPressed(Mouse::Button::Left)) {
                        isshooting = false;
                }
                for (int i = 0; i < bullets.size(); i++) {
                        float ang = directions[i].x / directions[i].y;
                        Vector2f offset = { 16,8 };
                        bullets[i].setOrigin( offset);
                        if (directions[i].y < 0) {
                                bullets[i].setRotation(degrees(-(atan(ang) * 180 / 3.14) - 90));
                        }
                        else {
                                bullets[i].setRotation(degrees(-(atan(ang) * 180 / 3.14) + 90));
                        }
                       
                        bullets[i].move(directions[i]*0.2f);
                }
                if (disappear.getElapsedTime().asSeconds() > 5) {
                        if (bullets.size() > 0) {
                                bullets.erase(bullets.begin());
                                directions.erase(directions.begin());
                                disappear.restart();
                        }
                       
                }
                if (mc.s.getPosition().x < 0) {
                        mc.s.setPosition({ 0, mc.s.getPosition().y });
                }
                if (mc.s.getPosition().y < 0) {
                        mc.s.setPosition({ mc.s.getPosition().x,0});
                }
                if (mc.s.getPosition().x + 100 > 1280) {
                        mc.s.setPosition({1180,mc.s.getPosition().y});
                }
                if (mc.s.getPosition().y + 100 > 720) {
                        mc.s.setPosition({ mc.s.getPosition().x,620 });
                }
               


                window.clear(Color::Black);
                window.draw(mc.s);
                for (int i = 0; i < bullets.size(); i++) {
                        window.draw(bullets[i]);
                }
                window.display();
        }
        return 0;
}
Official FAQ: https://www.sfml-dev.org/faq/
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

NAGIRA

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: sf::Sprite deletes the constructor in header file
« Reply #4 on: January 07, 2025, 10:00:13 am »
Wow, thank you for the quick reply. Everything worked!:)