Add support for mirrored horizontal tiles.

sigonasr2 6 months ago
parent faa063a11c
commit 9d56e9c564
  1. 4488
      assets/StageI.tmx
  2. 6
      src/Hamster.cpp
  3. 2
      src/Hamster.h
  4. 20
      src/HamsterGame.cpp
  5. 12
      src/TMXParser.h

File diff suppressed because it is too large Load Diff

@ -213,14 +213,14 @@ void Hamster::UpdateHamsters(const float fElapsedTime){
}
}
void Hamster::LoadHamsters(const vf2d startingLoc){
void Hamster::LoadHamsters(const geom2d::rect<int>startingLoc){
HAMSTER_LIST.clear();
playerHamster.reset();
HAMSTER_LIST.reserve(MAX_HAMSTER_COUNT);
if(NPC_HAMSTER_COUNT+1>MAX_HAMSTER_COUNT)throw std::runtime_error{std::format("WARNING! Max hamster count is too high! Please expand the MAX_HAMSTER_COUNT if you want more hamsters. Requested {} hamsters.",MAX_HAMSTER_COUNT)};
playerHamster=&HAMSTER_LIST.emplace_back(startingLoc,PLAYER_HAMSTER_IMAGE,PLAYER_CONTROLLED);
playerHamster=&HAMSTER_LIST.emplace_back(vf2d{util::random_range(startingLoc.pos.x,startingLoc.pos.x+startingLoc.size.x),util::random_range(startingLoc.pos.y,startingLoc.pos.y+startingLoc.size.y)},PLAYER_HAMSTER_IMAGE,PLAYER_CONTROLLED);
for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){
Hamster&npcHamster{HAMSTER_LIST.emplace_back(startingLoc,NPC_HAMSTER_IMAGES.at(util::random()%NPC_HAMSTER_IMAGES.size()),NPC)};
Hamster&npcHamster{HAMSTER_LIST.emplace_back(vf2d{util::random_range(startingLoc.pos.x,startingLoc.pos.x+startingLoc.size.x),util::random_range(startingLoc.pos.y,startingLoc.pos.y+startingLoc.size.y)},NPC_HAMSTER_IMAGES.at(util::random()%NPC_HAMSTER_IMAGES.size()),NPC)};
npcHamster.ai.LoadAI(HamsterGame::Game().GetCurrentMapName(),HamsterAI::AIType(util::random()%int(HamsterAI::AIType::END)));
}
}

@ -129,7 +129,7 @@ public:
Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled=NPC);
static const Hamster&GetPlayer();
static void UpdateHamsters(const float fElapsedTime);
static void LoadHamsters(const vf2d startingLoc);
static void LoadHamsters(const geom2d::rect<int>startingLoc);
static void DrawHamsters(TransformedView&tv);
static void DrawOverlay();
const Animate2D::Frame&GetCurrentAnimation()const;

@ -27,7 +27,7 @@ bool HamsterGame::OnUserCreate(){
LoadGraphics();
LoadAnimations();
currentTileset=TSXParser{ASSETS_DIR+std::string("Terrain.tsx")};
LoadLevel("TestLevel.tmx"); //THIS IS TEMPORARY.
LoadLevel("StageI.tmx"); //THIS IS TEMPORARY.
border.ChangeBorder(Border::DEFAULT);
@ -118,8 +118,6 @@ void HamsterGame::LoadAnimations(){
}
void HamsterGame::LoadLevel(const std::string&mapName){
const vf2d levelSpawnLoc{50,50}; //TEMPORARY
currentMap=TMXParser{ASSETS_DIR+mapName};
currentMapName=mapName;
cloudSpd.x=util::random_range(-12.f,12.f);
@ -127,10 +125,9 @@ void HamsterGame::LoadLevel(const std::string&mapName){
cloudOffset.x=util::random();
cloudOffset.y=util::random();
Hamster::LoadHamsters(levelSpawnLoc);
Hamster::LoadHamsters(currentMap.value().GetData().GetSpawnZone());
camera.SetTarget(Hamster::GetPlayer().GetPos());
mapImage.Create(currentMap.value().GetData().GetMapData().width*16,currentMap.value().GetData().GetMapData().height*16);
SetDrawTarget(mapImage.Sprite());
Clear(BLANK);
@ -143,7 +140,7 @@ void HamsterGame::LoadLevel(const std::string&mapName){
for(const LayerTag&layer:currentMap.value().GetData().GetLayers()){
for(size_t y:std::ranges::iota_view(0U,layer.tiles.size())){
for(size_t x:std::ranges::iota_view(0U,layer.tiles[y].size())){
const int tileID{layer.tiles[y][x]-1};
unsigned int tileID{unsigned int(layer.tiles[y][x]-1)};
if(Powerup::TileIDIsUpperLeftPowerupTile(tileID))mapPowerups.emplace_back(vf2d{float(x),float(y)}*16+vf2d{16,16},Powerup::TileIDPowerupType(tileID));
if(tileID==1484)checkpoints.emplace_back(vf2d{float(x),float(y)}*16+vf2d{64,64});
@ -151,10 +148,15 @@ void HamsterGame::LoadLevel(const std::string&mapName){
const int numTilesWide{GetGFX("gametiles.png").Sprite()->width/16};
const int numTilesTall{GetGFX("gametiles.png").Sprite()->height/16};
int imgTileX{tileID%numTilesWide};
int imgTileY{tileID/numTilesWide};
Sprite::Flip flip{Sprite::Flip::NONE};
if(tileID&0x80'00'00'00)flip=Sprite::Flip::HORIZ;
tileID&=0x7FFFFFFF;
int imgTileX{int(tileID%numTilesWide)};
int imgTileY{int(tileID/numTilesWide)};
if(tileID==-1||Powerup::TileIDIsPowerupTile(tileID))continue;
DrawPartialSprite(vf2d{float(x),float(y)}*16,GetGFX("gametiles.png").Sprite(),vf2d{float(imgTileX),float(imgTileY)}*16.f,vf2d{16.f,16.f});
DrawPartialSprite(vf2d{float(x),float(y)}*16,GetGFX("gametiles.png").Sprite(),vf2d{float(imgTileX),float(imgTileY)}*16.f,vf2d{16.f,16.f},1U,flip);
}
}
}

@ -110,6 +110,7 @@ private:
std::set<std::string>spawns;
std::map<std::string,std::vector<::ZoneData>>ZoneData;
std::unordered_map<TunnelId,Tunnel>TunnelData;
geom2d::rect<int>SpawnZone;
public:
Map();
void _SetMapData(MapTag data);
@ -122,6 +123,7 @@ public:
const std::string_view GetMapDisplayName()const;
const Renderable*const GetOptimizedMap()const;
const std::map<std::string,std::vector<::ZoneData>>&GetZones()const;
const geom2d::rect<int>&GetSpawnZone()const;
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles);
friend std::ostream& operator << (std::ostream& os, Map& rhs);
friend std::ostream& operator << (std::ostream& os, std::vector<XMLTag>& rhs);
@ -217,6 +219,9 @@ class TMXParser{
ZoneData["UpperZone"];
ZoneData["LowerZone"];
}
const geom2d::rect<int>&Map::GetSpawnZone()const{
return SpawnZone;
}
MapTag::MapTag(){}
MapTag::MapTag(int width,int height,int tilewidth,int tileheight)
:width(width),height(height),tilewidth(tilewidth),tileheight(tileheight),MapSize({width,height}),TileSize({tilewidth,tileheight}){}
@ -356,6 +361,9 @@ class TMXParser{
if (newTag.GetString("type")=="Tunnel"){
previousTunnelId=newTag.GetInteger("id");
parsedMapInfo.TunnelData.insert({previousTunnelId,Tunnel{vi2d{newTag.GetInteger("x"),newTag.GetInteger("y")}/16*16}});
}else
if (newTag.GetString("type")=="SpawnZone"){
parsedMapInfo.SpawnZone={vi2d{newTag.GetInteger("x"),newTag.GetInteger("y")},vi2d{newTag.GetInteger("width"),newTag.GetInteger("height")}};
}else{
//This is an object with a type that doesn't fit into other categories, we can add it to ZoneData.
std::vector<ZoneData>&zones=parsedMapInfo.ZoneData[newTag.data["type"]];
@ -402,10 +410,10 @@ class TMXParser{
while (data.find(",")!=std::string::npos) {
std::string datapiece = data.substr(0,data.find(","));
data = data.substr(data.find(",")+1,std::string::npos);
rowData.push_back(stoi(datapiece));
rowData.push_back(stoul(datapiece));
}
if (data.length()) {
rowData.push_back(stoi(data));
rowData.push_back(stoul(data));
}
parsedMapInfo.LayerData[parsedMapInfo.LayerData.size()-1].tiles.push_back(rowData);
}

Loading…
Cancel
Save