1 year ago

#360618

test-img

Justro

c++ sfml - changing the sprite isn't working

I was working on changing sprite in my SFML project but it just doesn't want to wark. I tried everything - pointers, refrences and normal string objects. You can see in debug console i printed out this->path that containted a path to file to change but when it left the function this->path was null (empty "" string). Can you please help me? Here's the code:

Player.cpp

#include "Player.h"
#include <iostream>

    Player::Player(std::string path)
    {
        this->path = path;
    
        texture.loadFromFile(path);
        sprite.setTexture(texture);
    
        sprite.setPosition(500.f, 700.f);
    }
    void Player::update()
    {
        // Movement //
        //if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
            //sprite.move(0.f, -velocity);
        //if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
            //sprite.move(0.f, velocity);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
            sprite.move(-velocity, 0.f);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
            sprite.move(velocity, 0.f);
        // Movement //
        float szerokosc = sprite.getGlobalBounds().width;
        float wysokosc = sprite.getGlobalBounds().height;
        // Collision with screen //
            // Left
        if (sprite.getPosition().x < 0.f)
            sprite.setPosition(0.f, sprite.getPosition().y);
        // Top
        if (sprite.getPosition().y < 0.f)
            sprite.setPosition(sprite.getPosition().x, 0.f);
        // Right
        if (sprite.getPosition().x + szerokosc > 1000)
            sprite.setPosition(1000 - szerokosc, sprite.getPosition().y);
        // Bottom
        if (sprite.getPosition().y + wysokosc > 800)
            sprite.setPosition(sprite.getPosition().x, 800 - wysokosc);
        // Collision with screen //
    }
    sf::Sprite Player::getSprite()
    {
        return sprite;
    }
    bool Player::collides(Food obj)
    {
        if (sprite.getGlobalBounds().intersects(obj.getSprite().getGlobalBounds()))
            return true;
        else
            return false;
    }
    void Player::changeSkin(std::string path)
    {
        this->path = path;
        std::cout << "changeSkin(): *this->path" << this->path << std::endl;
        std::cout << "changeSkin(): *path" << path << std::endl;
        texture.loadFromFile(path);
        sprite.setTexture(texture);
    }
    void Player::updateSkin()
    {
        std::cout << "updateSkin() *this->path: " << this->path << std::endl;
        std::cout << "updateSkin() *path: " << path << std::endl;
    }
    Player::~Player()
    {
        //delete texture;
        //delete sprite;
    }

Player.h

#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <time.h>
#include "Food.h"
#include "ShopItem.h"

class Player
{
    sf::Texture texture;
    sf::Sprite sprite;
    std::string path;

    bool has_skin = false;
    float velocity = 5.f;
public:
    explicit Player(std::string path);
    ~Player();
    void update();
    sf::Sprite getSprite();
    bool collides(Food obj);
    void changeSkin(std::string path);
    void updateSkin();
};

main.cpp - main() has Player::updateSkin() call

int main()
{
    RenderWindow window(VideoMode(1000, 800), "Tomczyszyn Eater v0.21 BETA");
    window.setFramerateLimit(60);
    srand(time(nullptr));

    Texture bg_text;
    bg_text.loadFromFile("Assets/Textures/bg.png");
    Sprite bg{ bg_text };

    Player player{ "Assets/Textures/player.png" };
    time_t start{};

    Event event;
    Intro* intro = new Intro{window};
    MainMenu* menu = new MainMenu{&window};
    Shop shop(&window);

    Game game{player, &window};
    bool intro_deleted{ false };
    bool menu_deleted{ false };
    bool game_started{ false };
    int menuState{ 2 };
    while (window.isOpen())
    {
        while (window.pollEvent(event))
        {
            if (event.type == Event::EventType::Closed)
                window.close();
            if (Keyboard::isKeyPressed(Keyboard::Space) && game.gameRunning() == false)
            {
                start = time(nullptr);
                game.runGame();
            }            
            else if (Keyboard::isKeyPressed(Keyboard::Escape) && game.gameRunning() == false)
            {
                menuState = 0;
            }
        }
        window.clear();

        if (game.gameRunning() == true && menuState == 1) // Main Game
        {
            if (game_started == false)
            {
                start = time(nullptr);
                game_started = true;
            }
            if (intro_deleted == false)
            {
                delete intro;
                intro_deleted = true;
            }            
            if (menu_deleted == false)
            {
                delete menu;
                menu_deleted = true;
            }
            window.draw(bg);
            game.drawMoney();
            player.update();
            window.draw(player.getSprite());

            // Player::updateSkin() - source of the problem
            player.updateSkin();

            game.update();
            game.draw();
            if (time(nullptr) - start == 2)
            {
                start = time(nullptr);
                int liczba = rand() % 6 + 1;
                string file_name{ "Assets/Textures/food" + to_string(liczba) + ".png" };
                Food* newFood = new Food{file_name};
                game.spawn(newFood);
            }
            game.catched();
            game.fell();
        }
        else if (menuState == 0) // Menu
        {
            if (menu_deleted == true)  menu = new MainMenu{ &window };
            menu->draw();

            menu->update(menuState);

            menu_deleted = false;
        }
        else if (menuState == -1) // Intro
        {
            start = time(nullptr);
            intro->play();
            if (intro->intro_started() == true) menuState = 0;
        } 
        else if (menuState == 2) // Shop
        {
            shop.draw();
            shop.backIfClicked(menuState);
            shop.checkIfBought(player, game.balance());
            
            game.drawMoney();
        }
        else
        {
            game.drawDeathScreen();
        }

        window.display();
    }
}

Shop.cpp - checkIfBought() has Player::changeSkin() call

void Shop::checkIfBought(Player player, int& money)
{
    for (int i = 0; i < skins.size(); i++)
    {
        if (isClicking(skins[i].getSprite()) == true)
        {
            skins[i].buy(money);
            player.changeSkin(skins[i].getPath()); //Plaer::changeSkin() here - source of the problem 
            std::cout << skins[i].getPath() << std::endl;
        }
    }
    for (int i = 0; i < bg_skins.size(); i++)
    {
        if (isClicking(bg_skins[i].getSprite()) == true)
        {
            bg_skins[i].buy(money);
            player.changeSkin(bg_skins[i].getPath()); //Plaer::changeSkin() here - source of the problem 
        }
    }
}

Debug Console output:

changeSkin(): this->path = Assets/Textures/skin1.png changeSkin(): path = Assets/Textures/skin1.png Assets/Textures/skin1.png updateSkin() this->path = Assets/Textures/player.png updateSkin() path = Assets/Textures/player.png

Sorry if you didn't understand my english is bad. I really do need help i've spent so much time on fixing this that i just gave up.

c++

sprite

sfml

0 Answers

Your Answer

Accepted video resources