#pragma once
#include <string>
#include <vector>
#include <map>
#include "BaseStruct.h"
struct Tile{
int type; // 砖块类型
int row; // 行
int col; // 列
int layer; // 所在图层
bool visible; // 可见性标志
bool isCollision; // 是否具有碰撞属性
};
class TiledMap {
private:
int m_cols;
int m_rows;
int m_size;
int m_layerNum;
std::map<int,std::vector<Tile*>> m_TileLayers;
std::map<int,SDL_Texture*> m_tex_types;
SDL_Renderer* m_renderer;
SDL_Texture* m_targetTexture;
public:
TiledMap()=default;
~TiledMap()=default;
void Init(int rows, int cols, int size,int layerNum,SDL_Renderer* renderer);
void loadTexture(int type, std::string fileName);
void setTile(int type, int row, int col,int layer = 0, bool visible = true, bool isCollision =false);
void setIsVisible(int row, int col,int layer ,bool visible);
void setIsVisible(int type , int layer ,bool visible);
void setIsCollision(int row, int col, int layer, bool isCollision);
void setIsCollision(int type, int layer, bool isCollision);
void render();
};
#include "TiledMap.h"
#include <SDL.h>
#include <SDL_image.h>
void TiledMap::Init(int rows, int cols, int size, int layerNum, SDL_Renderer* renderer)
{
m_rows = rows;
m_cols = cols;
m_size = size;
m_layerNum = layerNum;
m_renderer = renderer;
for (int i = 0; i < layerNum; i++)
{
m_TileLayers.insert(std::make_pair(i, std::vector<Tile*>()));
}
SDL_Texture* targetTexture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, m_rows * m_size, m_cols * m_size);
if (targetTexture)
{
m_targetTexture = targetTexture;
}
}
void TiledMap::loadTexture(int type, std::string fileName)
{
if (m_renderer != nullptr)
{
SDL_Texture* tileTex = IMG_LoadTexture(m_renderer, fileName.c_str());
if (tileTex != nullptr)
{
m_tex_types.insert(std::make_pair(type, tileTex));
}
}
}
void TiledMap::setTile(int type, int row, int col, int layer, bool isVisual, bool isCollision)
{
Tile* tile = new Tile;
if (tile != nullptr)
{
tile->type = type;
tile->row = row;
tile->col = col;
tile->layer = layer;
tile->visible = isVisual;
tile->isCollision = isCollision;
std::vector<Tile*>& tileLayer = m_TileLayers.at(layer);
tileLayer.push_back(tile);
}
}
void TiledMap::setIsVisible(int row, int col, int layer, bool visible)
{
if (m_TileLayers.find(layer) != m_TileLayers.end())
{
std::vector<Tile*>& tiles = m_TileLayers.at(layer);
for (int i = 0; i < tiles.size(); i++)
{
if (tiles[i]->row == row && tiles[i]->col == col)
{
tiles[i]->visible = visible;
}
}
}
}
void TiledMap::setIsVisible(int type, int layer, bool visible)
{
if (m_TileLayers.find(layer) != m_TileLayers.end())
{
std::vector<Tile*>& tiles = m_TileLayers.at(layer);
for (int i = 0; i < tiles.size(); i++)
{
if (tiles[i]->type == type)
{
tiles[i]->visible = visible;
}
}
}
}
void TiledMap::setIsCollision(int row, int col, int layer, bool isCollision)
{
if (m_TileLayers.find(layer) != m_TileLayers.end())
{
std::vector<Tile*>& tiles = m_TileLayers.at(layer);
for (int i = 0; i < tiles.size(); i++)
{
if (tiles[i]->row == row && tiles[i]->col == col)
{
tiles[i]->isCollision = isCollision;
}
}
}
}
void TiledMap::setIsCollision(int type, int layer, bool isCollision)
{
if (m_TileLayers.find(layer) != m_TileLayers.end())
{
std::vector<Tile*>& tiles = m_TileLayers.at(layer);
for (int i = 0; i < tiles.size(); i++)
{
if (tiles[i]->type == type)
{
tiles[i]->isCollision = isCollision;
}
}
}
}
void TiledMap::render()
{
std::vector<int> tileNum;
std::vector<Tile*> visibleTile;
for (int i = 0; i < m_TileLayers.size(); i++)
{
int size = m_TileLayers[i].size();
tileNum.push_back(size);
}
for (int k = 0; k < m_TileLayers.size(); k++)
{
for (int j = 0; j < tileNum[k]; j++)
{
if (m_TileLayers[k][j]->visible)
{
visibleTile.push_back(m_TileLayers[k][j]);
break;
}
}
}
for (int i = 0; i < visibleTile.size(); i++)
{
if (m_tex_types.find(visibleTile[i]->type) != m_tex_types.end())
{
SDL_Texture* tileTex = m_tex_types.at(visibleTile[i]->type);
SDL_Rect srcRect = { 0,0,m_size,m_size };
SDL_Rect dstRect = { visibleTile[i]->row * m_size,visibleTile[i]->col * m_size,m_size,m_size };
SDL_RenderCopy(m_renderer, tileTex, &srcRect, &dstRect);
}
}
}