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

Author Topic: Failing to correctly render sprites to the screen from a separate class.  (Read 1221 times)

0 Members and 1 Guest are viewing this topic.

KellenJCole

  • Newbie
  • *
  • Posts: 1
    • View Profile
Hello, so I am trying to render chess pieces onto a board in SFML. The hierarchy of my classes goes as follows:
Main->Game->PieceMap->Piece. Attachment shows what board currently displays, and it kind of flickers once and then just stays. I will do my best to attach minimal code:

Game.cpp
#include "Game.hpp"

Game::Game() : mWindow(sf::VideoMode(512, 512), "Chess") {
        if (!mBoardTexture.loadFromFile("Media/Textures/Board.png"))
                throw std::runtime_error("Board image not loaded successfully.");

        mBoard.setTexture(mBoardTexture);
        mBoard.setPosition(0.f, 0.f);
}

void Game::run() {
        while (mWindow.isOpen()) {
                processEvents();
                update();
                render();
        }
}

void Game::render() {
        mWindow.clear();
        mWindow.draw(mBoard);

        // Draw each piece sprite on the board
        for (int y = 0; y < 8; y++) {
                for (int x = 0; x < 8; x++) {
                        mWindow.draw(board.getPieceFromMap(y, x)->getSprite());
                }
        }
        mWindow.display();
}

PieceMap.cpp
#include "PieceMap.hpp"

PieceMap::PieceMap() {
    for (int j = 0; j < 8; j++) {
        for (int i = 0; i < 8; i++) {
            if ((i == 0) && ((j == 0) || (j == 7))) { // Black Rooks
                pieceMap[i][j] = Piece(8);
            }
            else if ((i == 0) && ((j == 1) || (j == 6))) { // Black Knights
                pieceMap[i][j] = Piece(4);
            }
            else if ((i == 0) && ((j == 2) || (j == 5))) { // Black Bishops
                pieceMap[i][j] = Piece(6);
            }
            else if ((i == 0) && (j == 4)) { // Black Queen
                pieceMap[i][j] = Piece(10);
            }
            else if ((i == 0) && (j == 3)) { // Black King
                pieceMap[i][j] = Piece(12);
            }
            else if (i == 1) { // Black Pawns
                pieceMap[i][j] = Piece(2);
            }
            else if (i == 6) { // White Pawns
                pieceMap[i][j] = Piece(1);
            }
            else if ((i == 7) && ((j == 0) || (j == 7))) { // White Rooks
                pieceMap[i][j] = Piece(7);
            }
            else if ((i == 7) && ((j == 1) || (j == 6))) { // White Knights
                pieceMap[i][j] = Piece(3);
            }
            else if ((i == 7) && ((j == 2) || (j == 5))) { // White Bishops
                pieceMap[i][j] = Piece(5);
            }
            else if ((i == 7) && (j == 3)) { // White Queen
                pieceMap[i][j] = Piece(9);
            }
            else if ((i == 7) && (j == 4)) { // White King
                pieceMap[i][j] = Piece(11);
            }
            else {
                // Default empty piece
                pieceMap[i][j] = Piece();
            }
            pieceMap[i][j].setPosition(i * 64.f, j * 64.f);
        }
    }
}

Piece* PieceMap::getPieceFromMap(int i, int j) {
    return &(pieceMap[i][j]);
}

Piece.cpp
#include "Piece.hpp"
#include <iostream>

Piece::Piece() {
        setPieceId(0);
        setTexture(getPieceId());
}

Piece::Piece(int piece) {
        setPieceId(piece);
        setTexture(getPieceId());
}

void Piece::setPieceId(int piece) {
        id = piece;
}

int Piece::getPieceId() const {
        return id;
}

void Piece::setTexture(int id) {
        if (!textures[0][0].loadFromFile("Media/Textures/WhitePawn.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[0][1].loadFromFile("Media/Textures/BlackPawn.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[0][2].loadFromFile("Media/Textures/WhiteKnight.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[0][3].loadFromFile("Media/Textures/BlackKnight.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[0][4].loadFromFile("Media/Textures/WhiteBishop.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[0][5].loadFromFile("Media/Textures/BlackBishop.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[1][0].loadFromFile("Media/Textures/WhiteRook.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[1][1].loadFromFile("Media/Textures/BlackRook.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[1][2].loadFromFile("Media/Textures/WhiteQueen.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[1][3].loadFromFile("Media/Textures/BlackQueen.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[1][4].loadFromFile("Media/Textures/WhiteKing.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!textures[1][5].loadFromFile("Media/Textures/BlackKing.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (!emptyTexture.loadFromFile("Media/Textures/EmptySpace.png"))
                throw std::runtime_error("Failed to load" + std::to_string(getPieceId()));
        if (getPieceId() == 0) {
                pSprite.setTexture(emptyTexture);
        }
        else {
                pSprite.setTexture(textures[getPieceId() / 6][getPieceId() % 6]);
        }
}

sf::Sprite Piece::getSprite() const {
        return pSprite;
}

void Piece::setPosition(float x, float y) {
        pSprite.setPosition(x, y);
}

The sprites are 45x45 pixels and the board is 512x512. EmptySpace.png is the exception, at 64x64 pixels. When I try to just draw an individual piece to the screen I can do it, however I can't adjust it's position.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Hard to say from just the screenshot what's really going on, i.e. what is intentional and what isn't.
I recommend to try and solve one thing at a time, for example pick one piece and get that to render correctly.

Most likely you have issues with life-time management of SFML resources and your own object.
Every time you assign the piece to the map, you create a copy and it also copies your texture and sprite.
Additionally, every time you retrieve the sprite from your piece, you're create a copy of the sprite.

I recommend to use something like a ResourceHolder to manage your textures and not make it part of your pieces class.
Also make yourself familiar with references and how C++ handles copying of objects.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/