Added static tileset world optimization and generation features.

pull/28/head
sigonasr2 1 year ago
parent ee5f6f9598
commit 203290c94a
  1. 164
      Crawler/Crawler.cpp
  2. 18
      Crawler/Crawler.tiled-project
  3. 5
      Crawler/TMXParser.h
  4. 2
      Crawler/Version.h
  5. 5
      Crawler/assets/Campaigns/World_Map.tmx

@ -570,7 +570,7 @@ void Crawler::RenderTile(TileRenderData&tileSheet,Pixel col){
}
void Crawler::RenderWorld(float fElapsedTime){
Clear(BLANK);
LayerTag*bridgeLayer=nullptr;
bool bridgeLayerFade=false;
Player*pl=GetPlayer();
@ -623,37 +623,67 @@ void Crawler::RenderWorld(float fElapsedTime){
}
SetDecalMode(DecalMode::NORMAL);
}
for (int x = view.GetTopLeftTile().x/GetCurrentMap().tilewidth-1; x <= view.GetBottomRightTile().x/GetCurrentMap().tilewidth; x++){
for (int y = view.GetTopLeftTile().y/GetCurrentMap().tilewidth-1; y <= view.GetBottomRightTile().y/GetCurrentMap().tilewidth; y++){
if(x>=0&&x<GetCurrentMap().width&&y>=0&&y<GetCurrentMap().height){
switch(mode){
case RenderMode::NORMAL_TILES:{
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
if(IsBridgeLayer(layer)){
bridgeLayer=&layer;
if(!bridgeLayerFade&&!player->upperLevel){
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
int playerXTruncated=int(player->GetPos().x)/GetCurrentMap().tilewidth;
int playerYTruncated=int(player->GetPos().y)/GetCurrentMap().tilewidth;
if(playerXTruncated==x&&playerYTruncated==y){
bridgeLayerFade=true;
if(GetCurrentMap().optimized){
view.FillRectDecal(-WINDOW_SIZE,vf2d{float(GetCurrentMap().width),float(GetCurrentMap().height)}*GetCurrentMap().tilewidth+WINDOW_SIZE*2,{100,180,100});
view.DrawDecal({0,0},MAP_DATA[GetCurrentLevel()].optimizedTile->Decal());
}else{
for (int x = view.GetTopLeftTile().x/GetCurrentMap().tilewidth-1; x <= view.GetBottomRightTile().x/GetCurrentMap().tilewidth; x++){
for (int y = view.GetTopLeftTile().y/GetCurrentMap().tilewidth-1; y <= view.GetBottomRightTile().y/GetCurrentMap().tilewidth; y++){
if(x>=0&&x<GetCurrentMap().width&&y>=0&&y<GetCurrentMap().height){
switch(mode){
case RenderMode::NORMAL_TILES:{
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
if(IsBridgeLayer(layer)){
bridgeLayer=&layer;
if(!bridgeLayerFade&&!player->upperLevel){
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
int playerXTruncated=int(player->GetPos().x)/GetCurrentMap().tilewidth;
int playerYTruncated=int(player->GetPos().y)/GetCurrentMap().tilewidth;
if(playerXTruncated==x&&playerYTruncated==y){
bridgeLayerFade=true;
}
}
}
continue;
}
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
int tileSheetX=tileSheetIndex%tileSheetWidth;
int tileSheetY=tileSheetIndex/tileSheetWidth;
if(!IsForegroundTile(tileSheet,tileSheetIndex)&&!IsUpperForegroundTile(tileSheetIndex)&&!IsReflectiveTile(tileSheet,tileSheetIndex)){
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
if("debug_collision_boxes"_I){
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY);
}
}
}
}
continue;
}
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
int tileSheetX=tileSheetIndex%tileSheetWidth;
int tileSheetY=tileSheetIndex/tileSheetWidth;
if(!IsForegroundTile(tileSheet,tileSheetIndex)&&!IsUpperForegroundTile(tileSheetIndex)&&!IsReflectiveTile(tileSheet,tileSheetIndex)){
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
}break;
case RenderMode::REFLECTIVE_TILES:{
visibleTiles.insert({x,y});
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
int tileSheetX=tileSheetIndex%tileSheetWidth;
int tileSheetY=tileSheetIndex/tileSheetWidth;
if(IsReflectiveTile(tileSheet,tileSheetIndex)){
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
}
if("debug_collision_boxes"_I){
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
@ -663,41 +693,16 @@ void Crawler::RenderWorld(float fElapsedTime){
}
}
}
}
}break;
case RenderMode::REFLECTIVE_TILES:{
visibleTiles.insert({x,y});
for(LayerTag&layer:MAP_DATA[currentLevel].LayerData){
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
TilesheetData tileSheet=GetTileSheet(currentLevel,tileID);
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
int tileSheetX=tileSheetIndex%tileSheetWidth;
int tileSheetY=tileSheetIndex/tileSheetWidth;
if(IsReflectiveTile(tileSheet,tileSheetIndex)){
if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});}
RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY});
}
if("debug_collision_boxes"_I){
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY);
}
}
}break;
case RenderMode::EMPTY_TILES:{
if(visibleTiles.count({x,y})){
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
}
}
}break;
case RenderMode::EMPTY_TILES:{
if(visibleTiles.count({x,y})){
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
}
}break;
}break;
}
}else{
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
}
}else{
view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth,{float(GetCurrentMap().tilewidth),float(GetCurrentMap().tilewidth)},{100,180,100});
}
}
}
@ -1147,6 +1152,38 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
r->Load("assets/maps/"+tileset.GetData().ImageData.data["source"]);
}
}
if(MAP_DATA[map].MapData.optimized){
std::cout<<"Generating optimized map for Map "<<map<<std::endl;
MAP_DATA[map].optimizedTile=new Renderable();
MAP_DATA[map].optimizedTile->Create(MAP_DATA[map].MapData.width*MAP_DATA[map].MapData.tilewidth,MAP_DATA[map].MapData.height*MAP_DATA[map].MapData.tileheight);
SetDrawTarget(MAP_DATA[map].optimizedTile->Sprite());
Pixel::Mode prevMode=GetPixelMode();
SetPixelMode(Pixel::Mode::MASK);
Clear(BLANK);
for(int y=0;y<MAP_DATA[map].MapData.height;y++){
for(int x=0;x<MAP_DATA[map].MapData.width;x++){
for(auto&layer:MAP_DATA[map].LayerData){
int tileID=layer.tiles[y][x]-1;
if(tileID!=-1){
TilesheetData tileSheet=GetTileSheet(map,tileID);
int tileSheetWidth=tileSheet.tileset->tileset->Sprite()->width/tileSheet.tileset->tilewidth;
int tileSheetHeight=tileSheet.tileset->tileset->Sprite()->height/tileSheet.tileset->tileheight;
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
int tileSheetX=tileSheetIndex%tileSheetWidth;
int tileSheetY=tileSheetIndex/tileSheetWidth;
vi2d pos=vi2d{x,y}*tileSheet.tileset->tilewidth;
DrawPartialSprite(pos,tileSheet.tileset->tileset->Sprite(),vi2d{tileSheetX,tileSheetY}*tileSheet.tileset->tilewidth,{tileSheet.tileset->tilewidth,tileSheet.tileset->tileheight});
}
}
}
}
SetPixelMode(prevMode);
MAP_DATA[map].optimizedTile->Decal()->Update();
SetDrawTarget(nullptr);
std::cout<<" Clearing Layer Data..."<<std::endl;
MAP_DATA[map].LayerData.clear();
}
}
void Crawler::LoadLevel(MapName map){
@ -1557,6 +1594,11 @@ bool Crawler::IsReflectiveTile(TilesheetData tileSheet,int tileID){
bool Crawler::OnUserDestroy(){
GFX.Reset();
for(auto&data:MAP_DATA){
if(MAP_DATA[data.first].optimizedTile!=nullptr){
delete MAP_DATA[data.first].optimizedTile;
}
}
return true;
}

@ -140,6 +140,24 @@
],
"valuesAsFlags": false
},
{
"color": "#ff2f62a4",
"drawFill": true,
"id": 19,
"members": [
{
"name": "Optimize",
"type": "bool",
"value": false
}
],
"name": "Map",
"type": "class",
"useAs": [
"property",
"map"
]
},
{
"color": "#fffa00f6",
"drawFill": true,

@ -20,6 +20,7 @@ struct XMLTag{
struct MapTag{
int width=0,height=0;
int tilewidth=0,tileheight=0;
bool optimized=false; //An optimized map will require us to flatten it out and use it as a single tile.
vi2d playerSpawnLocation;
vi2d MapSize; //The number of tiles in width and height of this map.
vi2d TileSize; //How large in pixels the map's tiles are.
@ -45,6 +46,7 @@ struct SpawnerTag{
struct Map{
MapTag MapData;
Renderable*optimizedTile=nullptr;
std::vector<XMLTag> TilesetData;
std::vector<LayerTag> LayerData;
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
@ -238,6 +240,9 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag};
prevSpawner=newTag.GetInteger("id");
} else
if (newTag.tag=="property"&&newTag.data["name"]=="Optimize"&&newTag.data["value"]=="true") {
parsedMapInfo.MapData.optimized=true;
} else
if (newTag.tag=="property"&&newTag.data["name"]=="Boss Title Display") {
parsedMapInfo.SpawnerData[prevSpawner].bossNameDisplay=newTag.data["value"];
} else

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 0
#define VERSION_BUILD 1741
#define VERSION_BUILD 1753
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="left-down" width="142" height="176" tilewidth="4" tileheight="4" infinite="0" nextlayerid="5" nextobjectid="3">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="left-down" width="142" height="176" tilewidth="4" tileheight="4" infinite="0" nextlayerid="5" nextobjectid="3">
<properties>
<property name="Optimize" type="bool" value="true"/>
</properties>
<tileset firstgid="1" source="../maps/Minifantasy_TinyOverworldAllTiles.tsx"/>
<tileset firstgid="8138" source="../maps/Minifantasy_TinyOverworldConstructions.tsx"/>
<tileset firstgid="9286" source="../maps/Minifantasy_TinyOverworldAllProps.tsx"/>

Loading…
Cancel
Save