Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[c++] Klasa wczytująca plik (tilemapa)

19 Aug 2010 21:46 1587 7
  • Level 10  
    Witam,
    Mam klasę która ma za zadanie załadować dane z pliku i wyrysować mapkę. Mam problem ponieważ mój sposób który wymyśliłem nie jest efektywny za każdym razem po narysowanej klatce, ponownie wczytywany jest plik, a to obciąża procesor i przy prostej scenie jest ok 30fps.
    Zasada działania jest taka, że ładuje najpierw plik, sprawdzam ilość warstw podanych w pliku, robię pętlę wykonującą się tyle razy ile jest warstw, później dane o kaflach do rysowanej mapy są wrzucane do tablicy dwu wymiarowej, z tej tablicy rysowane są kafle, a potem jeżeli występuje następna warstwa robi jeszcze raz to samo.
    Chciałem wczytywać go w osobnej funkcji, a rysować w osobnej lecz nie działa to w taki sposób, tzn nie wyświetla nic. W telegraficznym skrócie, miało wyglądać to tak:


    Code:

    void Map::OpenFile(){
    std::fstream plik;
    plik.open("mapa.map",std::ios::in);
    }

    void Map::DrawMap(){
    if(plik.good()==true){
    for(int i=0;i<40;i++){
                for(int j=0;j<40;j++){
                   plik>>map[i][j];
                }
             }
    //dalej rysowanie [...]
    }

    Rysuję to w darmowej bibliotece SFML.
    A w wersji nie efektywnej wygląda to tak.
    Deklaracja klasy:
    Code:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <SFML/Graphics.hpp>
    class Map{
    private:
       std::fstream plik;
       std::string bufor;
       int map[40][40];
       sf::Sprite sprite[40][40];
       sf::Image TileSet;
       sf::Sprite Tile;
       int tile_numb;
       std::string layer;
       int layernumber;
       
    public:
       Map();
       void LoadMap();
       void DrawMap(sf::RenderWindow & App);
    };


    Definicja funkcji klasy:
    Code:

    //Deklaracja funkcji
    #include "CMap.h"
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <SFML/Graphics.hpp>

    Map::Map(){
          TileSet.LoadFromFile("../data/123.png");
          TileSet.SetSmooth(true);
          licznik_x=0;
          licznik_y=0;
          size_x = TileSet.GetWidth();
          tiles_in_row =  size_x / 32;
          rows = size_y / 32;
          
    }
    void Map::DrawMap(sf::RenderWindow & App){
          plik.open("../data/mapa.lvl",std::ios::in); //zakładamy ze istnieje
          
          if(plik.good()==true)
          {
             plik>>layer;
             if(layer=="Layers"){ plik>>layernumber;
             //std::cout<<layernumber;
             }

             for(int j=1; j<=layernumber;j++){
                plik>>layer;
                if(layer=="Layer"){
                   //std::cout<<j<<std::endl<<std::endl;
             for(int i=0;i<40;i++)
             {
                for(int j=0;j<40;j++)
                {
                   plik>>map[i][j];
                }
             }
                }

          licznik_x=0;
          licznik_y=0;
          for(int i=0;i<40;i++){
          if(i>0&&i<40){ licznik_x=0;
          licznik_y+=32;
          }
                for(int j=0;j<40;j++){
                tile_numb = map[i][j];
                Tile.SetPosition(licznik_x, licznik_y);
                Tile.SetImage( TileSet );
                sf::IntRect Rect(0+(32*tile_numb), 0, 32+(32*tile_numb), 32);
                Tile.SetSubRect(Rect);
                App.Draw(Tile);            
                licznik_x+=32;               
                }
             }
             }
                plik.close();
          }
       
       
    }

    Niestety w bibliotece tej nie da się raz wczytać i raz wyrysować. Musi być rysowane co klatkę. Niestety nie znalazłem w Google żadnych informacji.
    Dlatego pytam tutaj, bo ma problem jest z biblioteką <iostream> nie z libem do rysowania :) Może ktoś ma jakiś inny pomysł na rozwiązanie:)
    [/quote]
  • Level 29  
    Wczytaj mapę RAZ do tablicy, a potem odczytuj dane z tej tabicy. To sporo przyspieszy ;P
  • Level 10  
    Quote:
    Wczytaj mapę RAZ do tablicy, a potem odczytuj dane z tej tabicy. To sporo przyspieszy ;P


    Wszystko fajnie tylko, że taki sposób by zadziałał gdybym miał jedną warstwę do wyrysowania. A w pliku jest informacja o kliku warstwach do wyrysowania ;)
    Plik wygląda tak:
    Code:

    Layers
    2
    Layer
    2 2 2 2
    2 2 2 2
    2 2 2 2
    2 2 2 2
    Layer
    0 0 0 1
    1 1 0 1
    0 0 0 0
    0 1 1 0

    Gdzie Layers to ilość warstw, a Layer to informacje juz o konkretnej warstwie (gdzie zero to jest rysowany przeźroczysty kafel)
  • Moderator of Programming
    prondzyk wrote:
    Wszystko fajnie tylko, że taki sposób by zadziałał gdybym miał jedną warstwę do wyrysowania. A w pliku jest informacja o kliku warstwach do wyrysowania ;)

    Stwórz obiekt/strukturę, który będzie odczytywał/zawierał całą zawartość pliku, wraz z podziałem na warstwy (rozumiem że w różnych klatkach może być różna ilość warstw) i rysuj posiłkując się zawartością tego obiektu.
    To pozwoli na drastyczne przyspieszenie twojej aplikacji.
  • Level 10  
    Dzięki za pomysł, będę próbował.
    Bo wogóle o tym nie pomyślałem :D
  • Level 29  
    prondzyk wrote:
    Quote:
    Wczytaj mapę RAZ do tablicy, a potem odczytuj dane z tej tabicy. To sporo przyspieszy ;P


    Wszystko fajnie tylko, że taki sposób by zadziałał gdybym miał jedną warstwę do wyrysowania. A w pliku jest informacja o kliku warstwach do wyrysowania ;)
    Plik wygląda tak:
    Code:

    Layers
    2
    Layer
    2 2 2 2
    2 2 2 2
    2 2 2 2
    2 2 2 2
    Layer
    0 0 0 1
    1 1 0 1
    0 0 0 0
    0 1 1 0

    Gdzie Layers to ilość warstw, a Layer to informacje juz o konkretnej warstwie (gdzie zero to jest rysowany przeźroczysty kafel)


    A o tablicach wielowymiarowych słyszał? :-)
  • Level 10  
    Przepraszam, a czy kolega chociaż patrzał w kod?
    Ja pisałem nie jak zrobić tilemapy, tylko jak zoptymalizować ten kod.
    A w kodzie wyraźnie chyba widać, że użyta jest tablica dwuwymiarowa ;)
  • Level 29  
    prondzyk wrote:
    Przepraszam, a czy kolega chociaż patrzał w kod?
    Ja pisałem nie jak zrobić tilemapy, tylko jak zoptymalizować ten kod.
    A w kodzie wyraźnie chyba widać, że użyta jest tablica dwuwymiarowa ;)


    Ale wielowymiarowa != dwuwymiarowa :-) Możesz zrobić dodatkowy wymiar na warstwy, dzięki czemu da radę upchnąć wszystkie warstwy w jednej tablicy.