#include "Fish.h" #include "Aquarium.h" #include "Random.h" #include "assets/FishAssets.h" #include Fish::Fish() : Fish(getRandomFishAsset()) {} Fish::Fish(const FishAssetRef &pair) : Entity(), speed((pair.index % 2 == 0) ? Random::floatInRange(0.25, 2.25) : -Random::floatInRange(0.25, 2.25)), image(pair.asset.image), mask(pair.asset.mask) { y = Random::intInRange(image.size() + 6, Aquarium::getInstance().getHeight() - image.size()); x = (speed < 0) ? Aquarium::getInstance().getWidth() : -20; randomizeMask(); } void Fish::randomizeMask() { std::unordered_map colorMap{{'4', 'W'}}; for (char digit = '1'; digit <= '9'; ++digit) { if (digit != '4') { colorMap[digit] = availableColors[Random::intInRange(0, availableColors.size() - 1)]; } } for (auto &line : mask) { for (char &ch : line) { if (auto it = colorMap.find(ch); it != colorMap.end()) { ch = it->second; } } } } Fish::FishAssetRef Fish::getRandomFishAsset() { int index = Random::intInRange(0, static_cast(fishAssetPairs.size()) - 1); return FishAssetRef{index, fishAssetPairs[index]}; } void Fish::update() { x += speed; } void Fish::draw(int layer) { Aquarium &aq = Aquarium::getInstance(); for (size_t i = 0; i < image.size(); ++i) { const std::string &row = image[i]; const std::string &maskRow = (i < mask.size()) ? mask[i] : ""; int baseY = y + static_cast(i); int cursorX = static_cast(x); std::string currentSegment; std::string currentColors; for (size_t j = 0; j < row.size(); ++j) { char ch = row[j]; if (ch == '?') { if (!currentSegment.empty()) { aq.drawToBackBuffer(baseY, cursorX, layer, currentSegment, currentColors); cursorX += currentSegment.size(); currentSegment.clear(); currentColors.clear(); } cursorX += 1; continue; } currentSegment.push_back(ch); currentColors.push_back((j < maskRow.size()) ? maskRow[j] : 'k'); } if (!currentSegment.empty()) { aq.drawToBackBuffer(baseY, cursorX, layer, currentSegment, currentColors); } } }