Skocz do zawartości

Wskazywanie na tekstury w wektorze


Exigo

Rekomendowane odpowiedzi

Wszystko zaczyna się od wczytania tego wszystkiego z pliku XML. Treść wygląda mniej-więcej tak:

<GfxDef name = "covername" file = "cover.png"/>

<GfxDef name = "pipesname" file = "pipes.png"/>

<MapGfx spr = "pipesname" x = "0" y = "0"/>

<MapGfx spr = "covername" x = "0" y = "128"/>

<MapGfx spr = "covername" x = "128" y = "0"/>

<MapGfx spr = "pipesname" x = "128" y = "128"/>

Pomysł jest taki, że mam dwie klasy: pierwszą, definicję tekstury (GfxDef), drugą (MapGfx), jej instancji na mapie.

Przy tworzeniu w każdej definicji dodaję sf:Texture z odpowiednio wczytanego pliku, plus offset i inne pierdoły oby dodane w przyszłości.

Jak teraz to wszystko podłączyć, aby instancje rysowały tekstury pobrane z definicji?

 

To co dotychczas wymyśliłem, to trzymanie obydwu klas na oddzielnych, wielkich wektorach. Kod wczytywania:

pugi::xml_document doc;

doc.load_file("map.xml");

printf("Wczytywanie XML...\n");

pugi::xml_node node;

 

/// Wczytywanie definicji gfx

typedef std::vector <CGfxDef> VGfxDefT;

VGfxDefT VGfxDef;

CGfxDef gfxdef_n;

for (node = doc.child("GfxDef"); node; node = node.next_sibling("GfxDef")) {

gfxdef_n.Name = node.attribute("name").value();

gfxdef_n.File = node.attribute("file").value();

gfxdef_n.Texture.loadFromFile(gfxdef_n.File);

gfxdef_n.Texture.setSmooth(true);

printf("add GfxDef: %s %s \n", gfxdef_n.Name.c_str(), gfxdef_n.File.c_str());

VGfxDef.push_back(gfxdef_n);

}

 

/// Wczytywanie MapGfx

typedef std::vector <CMapGfx> VMapGfxT;

VMapGfxT VMapGfx;

CMapGfx mapgfx_n;

for (node = doc.child("MapGfx"); node; node = node.next_sibling("MapGfx")) {

mapgfx_n.Pos.x = StrToInt(node.attribute("x").value());

mapgfx_n.Pos.y = StrToInt(node.attribute("y").value());

printf("add MapGfx: (%i, %i) \n", mapgfx_n.Pos.x, mapgfx_n.Pos.y);

VMapGfx.push_back(mapgfx_n);

}

 

Generalnie nie wiem czy trzymanie tego w wektorach jest dobrym pomysłem. Nie wiem też jak to wszystko połączyć (jak powyżej opisałem). Ogólnie, to mało wiem, więc proszę o wyrozumiałość. :)

Będę wdzięczny za jakąkolwiek pomoc w ogarnięciu tematu.

Odnośnik do komentarza
Udostępnij na innych stronach

Ja bym gfx zamiast vector użył map, i dodał sf::Sprite jeśli masz zamiar to rysować:

typedef  std::map <std::string, CGfxDef> VGfxDefT;
VGfxDefT VGfxDef;
CGfxDef gfxdef_n;
for(node = doc.child("GfxDef"); node; node = node.next_sibling("GfxDef")) 
{
    gfxdef_n.Name = node.attribute("name").value();
    gfxdef_n.File = node.attribute("file").value();
    gfxdef_n.Texture.loadFromFile(gfxdef_n.File);
        gfxdef_n.Sprite.setTexture(gfxdef_n.Texture);
    gfxdef_n.Texture.setSmooth(true);
    VGfxDefT[gfxdef_n.Name] = gfxdef_n;
    printf("add GfxDef: %s %s \n", gfxdef_n.Name.c_str(), gfxdef_n.File.c_str());
}

typedef std::vector <CMapGfx> VMapGfxT;
VMapGfxT VMapGfx;
CMapGfx mapgfx_n;
for (node = doc.child("MapGfx"); node; node = node.next_sibling("MapGfx")) 
{
    mapgfx_n.gfxdef = VGfxDefT[node.attribute("name").value()];
    mapgfx_n.Pos.x = StrToInt(node.attribute("x").value());
    mapgfx_n.Pos.y = StrToInt(node.attribute("y").value());
    printf("add MapGfx: (%i, %i) \n", mapgfx_n.Pos.x, mapgfx_n.Pos.y);
    VMapGfx.push_back(mapgfx_n);
}

i na końcu rysowanie:

instancja_okna.clear( kolor );
for(int i = 0;i<VMapGfxT.size();i++)
{
    VMapGfxT[i].gfxdef.Sprite.setPosition(VMapGfxT[i].Pos.x, VMapGfxT[i].Pos.y);
        instancja_okna.draw(VMapGfxT[i].gfxdef.Sprite);
}
instancja_okna.display();

 

Aczkolwiek nie daje gwarancji na poprawność kodu ;P

Odnośnik do komentarza
Udostępnij na innych stronach

Zastosuj system komponentowy:

 

Masz jeden główny mgr np: class GameMgr

W nim masz obiekty typu vector<Scene> m_Scenes + ResourceMgr *resMgr.

 

m_Scene trzyma w wszystkie sceny w grze a resMgr wszystkie zasoby.

 

Idąc dalej, obiekt Scene to obiekt, który trzyma wszystkie obiekty gry dla danej sceny najlepiej w pojemniku podobnym lub samym wektorze. Wtedy np możesz obiekty posortować wedle uznania(odległość, pozycja względem punktu itp itd).

 

np: vector<GameObject> m_SceneObjects;

 

Każdy obiekt gry posiada komponenty dziedziczące z jakiejś bazy np: RenderSpriteComponent * renderSprite, ColliderComponent* collider.

Jeśli potrzeba ich w większej ilośći jak to np może być dla typu: textureComponent także trzymasz je w wektorze. Jeśli dany obiekt nie ma posiadać danego komponentu np collider zostawia się go na null.

 

Potem dla danej sceny jedziesz po prostu po wszystkich komponentach, najłatwiejsza wersja to przelecenie wszystkich i np jeśli renderujesz to spr przy każdym czy ma komponent sprite/texture czy co tam potrzebujesz do renderingu, jeśli ma.. rysujesz obiekt z danym materiałem/teksturą, jeśli nie lecisz do następnego.

 

Opis bardzo uproszczony.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 2 tygodnie później...

Mapy stały się faktycznie przydatne. Wszystko działa. Dzięki za pomoc z waszej strony. :)

 

Poniżej załączam treść klasy trzymającej to wszystko dla potomnych.

(jak ktoś czuje się na siłach w języku, może spróbować się doszukać jakichś brzydkich linii/prostszych rozwiązań, wszyscy się czegoś nauczą)

 

gfx_manager.hpp

GML
#ifndef GFX_MANAGER_H

#define GFX_MANAGER_H

 

#include "pugixml.hpp"

 

// Klasa

class CGfxManager {

private:

class CGfx {

public:

sf::Vector2i Pos;

int SpriteId;

float Dir;

float Scale;

};

class CGfxDef {

public:

int Id;

std::string Filename;

sf::Texture Tex;

sf::Vector2f Off;

};

typedef std::map <int, CGfxDef> MGfxDefT;

typedef std::vector <CGfx> VGfxT;

MGfxDefT::iterator Cursor;

MGfxDefT MGfxDef;

CGfxDef GfxDefNode;

VGfxT VGfx;

CGfx GfxNode;

pugi::xml_document doc;

pugi::xml_node node;

public:

void LoadGfxDefinitions(std::string file);

void LoadGfx(std::string file);

void DrawGfx(sf::RenderTexture& TargetTex);

};

 

// Wczytywanie definicji grafik z pliku XML

void CGfxManager::LoadGfxDefinitions(std::string file) {

doc.load_file(file.c_str());

printf("Wczytywanie GfxDef, %s \n", file.c_str());

for (node = doc.child("GfxDef"); node; node = node.next_sibling("GfxDef")) {

GfxDefNode.Id = StrToInt(node.attribute("id").value());

GfxDefNode.Filename = node.attribute("filename").value();

GfxDefNode.Off.x = StrToInt(node.attribute("offx").value());

GfxDefNode.Off.y = StrToInt(node.attribute("offx").value());

GfxDefNode.Tex.loadFromFile(GfxDefNode.Filename);

GfxDefNode.Tex.setSmooth(true);

printf(" %i %s \n", GfxDefNode.Id, GfxDefNode.Filename.c_str());

MGfxDef.insert(std::make_pair(GfxDefNode.Id, GfxDefNode));

}

}

 

// Wczytywanie grafik z pliku XML

void CGfxManager::LoadGfx(std::string file) {

doc.load_file(file.c_str());

printf("Wczytywanie Gfx, %s \n", file.c_str());

for (node = doc.child("Gfx"); node; node = node.next_sibling("Gfx")) {

GfxNode.SpriteId = StrToInt(node.attribute("sprid").value());

GfxNode.Pos.x = StrToInt(node.attribute("x").value());

GfxNode.Pos.y = StrToInt(node.attribute("y").value());

GfxNode.Dir = StrToInt(node.attribute("dir").value());

GfxNode.Scale = StrToInt(node.attribute("scale").value());

printf(" %i (%i, %i) \n", GfxNode.SpriteId, GfxNode.Pos.x, GfxNode.Pos.y);

VGfx.push_back(GfxNode);

}

}

 

// Funkcja rysujaca grafiki do danego RenderTexture

void CGfxManager::DrawGfx(sf::RenderTexture& TargetTex) {

MGfxDefT::iterator Cursor;

for (VGfxT::const_iterator i = VGfx.begin(); i != VGfx.end(); ++i) {

int id = i->SpriteId;

Cursor = MGfxDef.find(id);

CGfxDef Handle = (*Cursor).second;

 

sf::Sprite SprNode;

SprNode.setTexture(Handle.Tex);

SprNode.setPosition(i->Pos.x, i->Pos.y);

SprNode.setOrigin(Handle.Off.x, Handle.Off.y);

SprNode.setRotation(i->Dir);

SprNode.setScale(i->Scale, i->Scale);

TargetTex.draw(SprNode);

}

}

 

#endif

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...