Tilowanie mapy

0

Siemka! Pisze z zapytaniem o tile mapy. Sądzę, że mój kod lekko mówiąc jest troszeczkę prymitywny. Dokładnie chciałbym się dowiedzieć co mógłbym zmienić, jak mógłbym zmienić i mniej więcej jak mógłbym zmienić.

void Game::Init(SDL_Renderer *renderer)
{
    LoadGameDate(renderer);
    Load("tileMap");
}
void Game::Draw(SDL_Renderer *renderer)
{
	for (int y = 0; y < tileMap.size(); y++)
		for (int x = tileMap[y].size(); x++)
			if (tileMap[y][x] != '0')
			{			
                                SDL_Rect destination;
				SDL_Rect source;

				source.w = 40;
				source.h = 40;
				source.x = blockChar * srcRect.w;
				source.y = 0;

				destination.x = x * 40;	
				destination.y = y * 40;		
				destination.w = 40;									
				destination.h = 40;	

				tile.Render(source, destination, renderer);
			}
}

void Game::Load(std::string fileName)
{
	fileName = "Files/" + fileName + ".map";
	std::ifstream openFile(fileName);

	tileMap.clear();

	if (openFile.is_open())
	{
		while (!openFile.eof())
		{
			std::string line;
			std::getline(openFile, line);

			std::vector<char> tempVector;

			if (line.find("[map]") != std::string::npos)
			{
				state = MAP;
				tempVector.clear();
				continue;
			}

			std::stringstream str(line);

			while (str)
			{
				std::getline(str, line, ' ');

				if (line != "")
					if (state == MAP)
					{
						tempVector.push_back(line);
					}
			}

			if (state == MAP)
			{
				tileMap.push_back(tempVector);
			}
		}
	}

	openFile.clear();
	openFile.close();
}
void LoadGameDate(SDL_Renderer *renderer)
{
       tile.LoadFromFile("TileMap.png", renderer);
}

Jak widać, to tylko klika krótkich metod.

0

Co to te tilowanie?

0

Dzielenie obrazka na parę części(na kafelki - tiles) i render tych części w zależności od tego jaką mapę chcesz.
Mapa może mieć postać niedynamiczniej tablicy albo dynamicznej

W postaci niedynamicznej tablicy dajmy na przykład map[5][5] mapa mogłaby wyglądać tak

0 0 0 0 0
0 0 0 0 0
0 0 0 2 0
0 0 0 2 0
1 1 1 1 1

gdzie 0 oznacza pustkę
1 np. klocek trawy
2 np. drabię

Przynajmniej jak to tak rozumiem.

0

jest git, ładowanie mapy i tak robisz tylko raz na początku, a musisz sprawdzić dla wszystkich pól, chyba że byś zrobił mapę, która zawiera tylko istniejące elementy.
Wtedy byś mniej punktów sprawdził, ale to i tak jest małe obciążenie, karty graficzne dla każdego pixela wykonują obliczenia, to są dopiero obliczenia.

Chyba, że te Game::Draw jest za każdym razem wywoływany jak trzeba klatkę narysować to wtedy jest dupa, bo marnujesz zasoby.
Ale wystarczy raz wczytać mapę + elementy na mapie i potem tylko odrysowywać z bufora zbudowanego wcześniej, a nie budować za każdym razem.

0

Nie za bardzo rozumiem o co ci chodzi.
Jakiś dłuższy czas temu oglądałem sobie coding made easy allegro 5 platformer tutorial ( ) i tam koleś pokazywał trochę inny sposób. Teraz sobie przeglądam 2 kody


i też jakoś inaczej jest robione.
Ogólnie to chciałbym nauczyć się czegoś co mogłoby się przydać już do późniejszych projektów oraz żeby była możliwość łatwej implementacji kolizji, poruszania się różnych obiektów.

0

Dla dynamicznych obiektów masz jak najbardziej dobrze, bo musisz tam ciągle jakieś obliczenia robić po prostu zrób całą grę, bo zadawanie do przodu pytań bez problemów jest zbędne.

0

To wtedy w jaki sposób mogłbym zrobić do tego jeszcze kolizję i gdzie ją updateować? W klasie gracza czy w klasie gry/mapy?

Bo gdy robię coś takiego

void Game::UpdateCollision()
{
    for (int y = 0; y < tileMap.size(); ++y)
        for (int x = 0; x < tileMap[y].size() ++x)
            if (map[y][x] == '1')
            {  
                SDL_Rect player;
                player.y = cPlayer.X();
                player.y = cPlayer.Y();
                player.w =cPlayer.X() + player.W();
                player.h = cPlayer.Y() + player.H();

 	        SDL_Rect localMapR;
	        localMapR.x = x * 32;
	        localMapR.y = y * 32;
	        localMapR.w = x * 32 + 32; // próbowałem też (x + 32) * 32 - jakoś mało sensowne mi się to wydawało, ale spróbować można
	        localMapR.h = y * 32 + 32; // tak samo z tym (y + 32) * 32
           
 
                AABB aabb(player);
                if(aabb.Intersect(localMapR))
                {
                    if(player.x <= localMapR.w)
                    {
                        cPlayer.setX(localMapR.x + player.getW());
                        //próbowałem też .setX(localMapR.w); i .setX(localMapR.x + 32);
                    }
                    else if(player.w >= localMapR.w)
                    {
                        cPlayer.setX(localMapR.x);
                    }
                    else if(player.y <= localMapR.h)
                    {
                        cPlayer.setY(localMapR.y + player.getH());
                        //próbowałem też .setY(mapH) i .setY(mapX + 32);
                        cPlayer.setVelY(0);
                    }
                    else if(player.h >= localMapR.y)
                    {
                        cPlayer.setY(localMapR.y);
                    }
                }
            }
}
AABB::AABB(SDL_Rect rc)
{
    this->x = rc.x;
    this->y = rc.y;
    this->w = rc.w;
    this->h = rc.h;
}
bool AABB::Intersect(SDL_Rect r)
{
    if(x <= r.w && w >= r.x && y <= r.h && h >= r.y)
    {
        return true;
    }
    return false;
}

I za jasną ciasną nie chce działać :C
Postać teleportuje się w dziwne miejsca, czasami czyta, że 0 to też jest kolider

0

Co tam, jak tam, wiecie jak już to ogarnąć, bo jestem ciekawy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1