Как инициализировать все переменные из пространства имен в одном классе - PullRequest
0 голосов
/ 08 апреля 2020

Я делаю небольшую игру с использованием SFML. Я хочу загрузить все свои ресурсы за один go при запуске игры, поэтому каждый раз, когда создается новая сущность, новые ресурсы не нужно загружать в память, что замедляет игру.

Я сделал файл заголовка с пространством имен для каждого вида ресурсов, который мне нужен:

#pragma once

#include <SFML/Graphics.hpp>

#include <iostream>

#include "spritesheet.h"

namespace PlayerSprite {
    extern Spritesheet playerSpritesheet;
    extern sf::Sprite sp1, sp2, sp3, sp4, sp5, sp6;
    extern int width = 16;
    extern int height = 16;
}

namespace ButtonSprite {
    extern Spritesheet buttonSpritesheet;
    extern sf::Sprite button;
    extern int width = 32;
    extern int height = 16;
}

class Resources {
    public:
        Resources() = default;
        void loadResources();
};

Теперь я не знаю много о пространствах имен, только очень базовые c вещи, это первая причина, чтобы использовать один.

Теперь в файле cpp:

#include <iostream>

#include "../headers/resources.h"

void Resources::loadResources() {
    // PLAYER
    PlayerSprite::playerSpritesheet.setSprite("./res/img/tiles.png");
    PlayerSprite::sp1 = PlayerSprite::playerSpritesheet.getSprite(0, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp2 = PlayerSprite::playerSpritesheet.getSprite(32, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp3 = PlayerSprite::playerSpritesheet.getSprite(48, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp4 = PlayerSprite::playerSpritesheet.getSprite(64, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp5 = PlayerSprite::playerSpritesheet.getSprite(80, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp6 = PlayerSprite::playerSpritesheet.getSprite(0, 16, PlayerSprite::width, 
    PlayerSprite::height);
    // PLAYER

    // BUTTONS
    ButtonSprite::buttonSpritesheet.setSprite("./res/img/tiles.png");
    ButtonSprite::button = ButtonSprite::buttonSpritesheet.getSprite(48, 16, 32, 16);
    // BUTTONS
}

Затем я вызываю эту функцию в основном файле игры, но при запуске я получаю эту ошибку в классе игрока:

undefined reference to 'PlayerSprite:sp1'

Я не знаю, если это из-за объявления пространства имен, или я неправильно кодирую систему.


После просмотра некоторых комментариев по этому вопросу я добавили это:

void Resources::allocateStorage() {
    sf::Sprite PlayerSprite::spritesheet;
    sf::Sprite PlayerSprite::sp1;
}

В файле cpp, но теперь я получаю эту ошибку:

unqualified-id in declaration before ';' token в 1-й строке после реализации функции.

1 Ответ

4 голосов
/ 08 апреля 2020

Кажется, проблема в том, что переменные фактически нигде не определены, просто объявлены. При использовании extern компилятор будет предполагать, что эта переменная существует, поэтому компилятор может продолжить предполагать, что переменная существует. Затем войдет компоновщик и увидит , где эта переменная существует. Если это не так, вы получите неопределенную ошибку ссылки. Чтобы это исправить, вам нужно где-то определить переменные.

Например, скажем, resources.cpp, вы должны иметь:

#include "../headers/resources.h"

sf::Sprite PlayerSpriter::sp1;
sf::Sprite PlayerSpriter::sp2;
sf::Sprite PlayerSpriter::sp3;
// etc...


void Resources::loadResources() { 
    // …
}

Это в дополнение к тому, что у вас уже есть в Ваш заголовок.

ПРИМЕЧАНИЕ. При редактировании это будет происходить вне любой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...