Added tile render depth ordering for bullets and effects to prevent ordering weirdness.

pull/28/head
sigonasr2 1 year ago
parent bc23188d60
commit 1cabb34b94
  1. 2
      Crawler/Bullet.h
  2. 172
      Crawler/Crawler.cpp
  3. 1
      Crawler/Crawler.h
  4. 1
      Crawler/Effect.h
  5. 1
      Crawler/Map.h
  6. 1
      Crawler/Meteor.cpp
  7. 2
      Crawler/Version.h
  8. 2
      Crawler/assets/Campaigns/1_1_v2.tmx
  9. 2
      Crawler/assets/config/Player.txt
  10. 2
      Crawler/assets/config/configuration.txt

@ -20,6 +20,8 @@ struct Bullet{
float fadeOutTime=0; //Setting the fade out time causes the bullet's lifetime to be set to the fadeout time as well, as that's when the bullet's alpha will reach 0, so it dies.
bool friendly=false; //Whether or not it's a player bullet or enemy bullet.
bool upperLevel=false;
bool rendered=false;
bool alwaysOnTop=false;
protected:
float fadeOutTimer=0;
private:

@ -481,6 +481,9 @@ void Crawler::PopulateRenderLists(){
foregroundEffectsLower.clear();
foregroundEffectsUpper.clear();
tilePreparationList.clear();
tileForegroundList.clear();
Player*pl=GetPlayer();
for(auto it=MONSTER_LIST.begin();it!=MONSTER_LIST.end();++it){
Monster&m=*it;
@ -574,6 +577,9 @@ void Crawler::RenderWorld(float fElapsedTime){
pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35);
}
view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);
if(player->GetState()==State::BLOCK){
view.DrawDecal(player->GetPos()-vf2d{12,12},GFX["block.png"].Decal());
}
};
enum class RenderMode{
@ -700,7 +706,7 @@ void Crawler::RenderWorld(float fElapsedTime){
view.DrawDecal(player->GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*player->GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
}
for(Effect*e:backgroundEffectsLower){
e->Draw();
e->rendered=false;
}
for(Monster*m:monstersBeforeLower){
m->Draw();
@ -708,17 +714,11 @@ void Crawler::RenderWorld(float fElapsedTime){
if(!player->upperLevel){
RenderPlayer(player->GetPos(),{1,1});
}
if(player->GetState()==State::BLOCK){
view.DrawDecal(player->GetPos()-vf2d{12,12},GFX["block.png"].Decal());
}
for(Monster*m:monstersAfterLower){
m->Draw();
}
for(Effect*e:foregroundEffectsLower){
e->Draw();
}
for(Bullet*b:bulletsLower){
b->Draw();
b->rendered=false;
}
auto RenderPrecastTargetingIndicator=[&](){
if(player->GetState()==State::PREP_CAST){
@ -740,7 +740,8 @@ void Crawler::RenderWorld(float fElapsedTime){
if(!player->OnUpperLevel()){
RenderPrecastTargetingIndicator();
}
#pragma region Foreground Rendering
#pragma region Foreground Rendering Preparation
for(TileGroup&group:foregroundTileGroups){
if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){
if(geom2d::overlaps(group.GetFadeRange(),player->pos)){
@ -751,19 +752,80 @@ void Crawler::RenderWorld(float fElapsedTime){
group.fadeFactor=std::max(group.fadeFactor-fElapsedTime,0.f);
}
for(TileRenderData&tile:group.GetTiles()){
RenderTile(tile,{255,255,255,uint8_t(255-group.fadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile.pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&group.fadeFactor>0&&tile.tileSheet.tileset->collision.find(tile.tileID)!=tile.tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile.tileSheet.tileset->collision[tile.tileID].collision;
tile.tileOpacity=group.fadeFactor;
if(tile.tileSheet.tileset->collision.find(tile.tileID)!=tile.tileSheet.tileset->collision.end()){
tilePreparationList.push_back(&tile);
}else{
tileForegroundList.push_back(&tile);
}
}
}
}
#pragma endregion
std::sort(tilePreparationList.begin(),tilePreparationList.end(),[](TileRenderData*tile1,TileRenderData*tile2){return tile1->pos.y<tile2->pos.y||tile1->pos.y==tile2->pos.y&&tile1->layerID<tile2->layerID;});
#pragma region Foreground Rendering w/Depth
int tilePrevY=0;
for(TileRenderData*tile:tilePreparationList){
tilePrevY=tile->pos.y+12;
#pragma region Depth Ordered Rendering
for(Effect*e:backgroundEffectsLower){
if(!e->rendered&&e->pos.y<tilePrevY){
e->rendered=true;
e->Draw();
}
}
for(Bullet*b:bulletsLower){
if(!b->rendered&&b->pos.y<tilePrevY){
b->rendered=true;
b->Draw();
}
}
#pragma endregion
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile.pos+collision.pos,collision.size,{255,0,0,uint8_t(128*group.fadeFactor/sqrt(distToPlayer))});
view.DrawRectDecal(tile.pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
}
}
#pragma endregion
#pragma region Remaining Bullet and Effect Rendering
for(Effect*e:backgroundEffectsLower){
if(!e->rendered){
e->Draw();
}
}
for(Bullet*b:bulletsLower){
if(!b->rendered){
b->Draw();
}
}
#pragma endregion
#pragma region Permanent Foreground Rendering
for(TileRenderData*tile:tileForegroundList){
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
}
}
#pragma endregion
for(Effect*e:foregroundEffectsLower){
e->Draw();
}
tilePreparationList.clear();
tileForegroundList.clear();
#pragma region Bridge Layer Rendering
if(bridgeLayer!=nullptr){
for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){
@ -792,7 +854,7 @@ void Crawler::RenderWorld(float fElapsedTime){
}
#pragma endregion
for(Effect*e:backgroundEffectsUpper){
e->Draw();
e->rendered=false;
}
for(Monster*m:monstersBeforeUpper){
m->Draw();
@ -803,17 +865,16 @@ void Crawler::RenderWorld(float fElapsedTime){
for(Monster*m:monstersAfterUpper){
m->Draw();
}
for(Effect*e:foregroundEffectsUpper){
e->Draw();
}
for(Bullet*b:bulletsUpper){
b->Draw();
b->rendered=false;
}
if(player->OnUpperLevel()){
RenderPrecastTargetingIndicator();
}
#pragma region Upper Foreground Rendering
#pragma region Upper Foreground Rendering Preparation
for(TileGroup&group:upperForegroundTileGroups){
if(view.IsRectVisible(group.GetRange().pos,group.GetRange().size)){
if(geom2d::overlaps(group.GetFadeRange(),player->pos)){
group.playerBehind=true;
group.fadeFactor=std::min(group.fadeFactor+fElapsedTime,TileGroup::FADE_TIME);
@ -822,10 +883,77 @@ void Crawler::RenderWorld(float fElapsedTime){
group.fadeFactor=std::max(group.fadeFactor-fElapsedTime,0.f);
}
for(TileRenderData&tile:group.GetTiles()){
RenderTile(tile,{255,255,255,uint8_t(255-group.fadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
tile.tileOpacity=group.fadeFactor;
if(tile.tileSheet.tileset->collision.find(tile.tileID)!=tile.tileSheet.tileset->collision.end()){
tilePreparationList.push_back(&tile);
}else{
tileForegroundList.push_back(&tile);
}
}
}
}
#pragma endregion
std::sort(tilePreparationList.begin(),tilePreparationList.end(),[](TileRenderData*tile1,TileRenderData*tile2){return tile1->pos.y<tile2->pos.y||tile1->pos.y==tile2->pos.y&&tile1->layerID<tile2->layerID;});
#pragma region Upper Foreground Rendering w/Depth
tilePrevY=0;
for(TileRenderData*tile:tilePreparationList){
tilePrevY=tile->pos.y+12;
#pragma region Depth Ordered Upper Rendering
for(Effect*e:backgroundEffectsUpper){
if(!e->rendered&&e->pos.y<tilePrevY){
e->rendered=true;
e->Draw();
}
}
for(Bullet*b:bulletsUpper){
if(!b->rendered&&b->pos.y<tilePrevY){
b->rendered=true;
b->Draw();
}
}
#pragma endregion
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
}
}
#pragma endregion
#pragma region Remaining Upper Bullet and Effect Rendering
for(Effect*e:backgroundEffectsUpper){
if(!e->rendered){
e->Draw();
}
}
for(Bullet*b:bulletsUpper){
if(!b->rendered){
b->Draw();
}
}
#pragma endregion
#pragma region Permanent Upper Foreground Rendering
for(TileRenderData*tile:tileForegroundList){
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
}
}
#pragma endregion
for(Effect*e:foregroundEffectsUpper){
e->Draw();
}
for(std::vector<std::shared_ptr<DamageNumber>>::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){
DamageNumber*dn=(*it).get();
if(dn->pauseTime>0){

@ -27,6 +27,7 @@ public:
float levelTime;
private:
std::vector<std::unique_ptr<Effect>>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted;
std::vector<TileRenderData*>tilePreparationList,tileForegroundList;
std::map<MapName,Map>MAP_DATA;
std::map<std::string,TilesetData>MAP_TILESETS;
vf2d worldShake={};

@ -14,6 +14,7 @@ struct Effect{
float rotation=0;
float rotationSpd=0;
bool additiveBlending=false;
bool rendered=false;
private:
bool dead=false;
public:

@ -36,6 +36,7 @@ struct TileRenderData{
vi2d tileSheetPos;
int tileID;
int layerID;
float tileOpacity;
};
struct TileGroup{

@ -10,7 +10,6 @@ INCLUDE_GFX
Meteor::Meteor(vf2d pos, float lifetime, std::string imgFile, bool upperLevel, vf2d size, float fadeout, vf2d spd, Pixel col, float rotation, float rotationSpd, bool additiveBlending)
:Effect(pos,lifetime,imgFile,upperLevel,size,fadeout,spd,col,rotation,rotationSpd,additiveBlending),startLifetime(lifetime){
}
bool Meteor::Update(float fElapsedTime){

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

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="205" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="9" nextobjectid="134">
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="205" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="9" nextobjectid="136">
<tileset firstgid="1" source="../maps/Tilesheet_No_Shadow24x24.tsx"/>
<tileset firstgid="2913" source="../maps/Decorations_c1_No_Shadow24x24.tsx"/>
<tileset firstgid="4533" source="../maps/24x24_Waterfall.tsx"/>

@ -7,7 +7,7 @@ Player
BaseAtk = 10
# Amount of spd to increase/decrease vertically as you climb staircases
StaircaseClimbSpd = 60
StaircaseClimbSpd = 45
# How much speed the player loses while no momentum is being added.
Friction = 400

@ -10,7 +10,7 @@ gfx_config = gfx/gfx.txt
map_config = levels.txt
# Starting map when loading the game.
starting_map = BOSS_1
starting_map = CAMPAIGN_1_1
# Player Properties Loading Config
player_config = Player.txt

Loading…
Cancel
Save