SpriteUtils.h (2222B)
1 #pragma once 2 #include <algorithm> 3 #include <string> 4 #include <unordered_map> 5 #include <vector> 6 7 struct AssetPair; 8 9 // Character mapping for directional elements 10 const std::unordered_map<char, char> charFlipMap = { 11 {'(', ')'}, {')', '('}, {'[', ']'}, {']', '['}, {'{', '}'}, 12 {'}', '{'}, {'<', '>'}, {'>', '<'}, {'/', '\\'}, {'\\', '/'}}; 13 14 inline char mirrorChar(char c) { 15 auto it = charFlipMap.find(c); 16 return (it != charFlipMap.end()) ? it->second : c; 17 } 18 19 inline std::string mirrorRow(std::string row) { 20 std::reverse(row.begin(), row.end()); 21 for (char &c : row) { 22 c = mirrorChar(c); 23 } 24 return row; 25 } 26 27 // Mirror an entire sprite (vector of strings) 28 inline std::vector<std::string> 29 mirrorSprite(const std::vector<std::string> &sprite) { 30 std::vector<std::string> mirrored; 31 mirrored.reserve(sprite.size()); 32 for (const auto &row : sprite) { 33 mirrored.push_back(mirrorRow(row)); 34 } 35 return mirrored; 36 } 37 38 inline AssetPair mirrorAssetPair(const AssetPair &asset) { 39 return {mirrorSprite(asset.image), mirrorSprite(asset.mask)}; 40 } 41 42 // Create bidirectional assets from simple AssetPair vector 43 inline std::vector<AssetPair> 44 createBidirectionalAssets(const std::vector<AssetPair> &rightFacingAssets) { 45 std::vector<AssetPair> result; 46 result.reserve(rightFacingAssets.size() * 2); 47 48 for (const auto &asset : rightFacingAssets) { 49 result.push_back(asset); // Right-facing 50 result.push_back(mirrorAssetPair(asset)); // Left-facing (mirrored) 51 } 52 53 return result; 54 } 55 56 // Generic template for any asset type with frames and mask 57 template <typename AssetType> 58 AssetType mirrorFramedAsset(const AssetType &asset) { 59 AssetType mirrored; 60 61 // Mirror all frames 62 for (const auto &frame : asset.frames) { 63 mirrored.frames.push_back(mirrorSprite(frame)); 64 } 65 66 // Mirror mask 67 mirrored.mask = mirrorSprite(asset.mask); 68 69 return mirrored; 70 } 71 72 // Create bidirectional assets from single framed asset 73 template <typename AssetType> 74 std::vector<AssetType> 75 createBidirectionalFramedAssets(const AssetType &rightFacingAsset) { 76 return { 77 rightFacingAsset, // [0] = Right-facing 78 mirrorFramedAsset(rightFacingAsset) // [1] = Left-facing (mirrored) 79 }; 80 }