finish mirroring. abstract entity removal

This commit is contained in:
user
2025-07-07 17:25:29 -04:00
parent 5706c90f87
commit c54089ae19
17 changed files with 193 additions and 231 deletions

View File

@@ -1,7 +1,7 @@
# Compiler and flags # Compiler and flags
CXX = g++ CXX = g++
CXXFLAGS = -std=c++17 -Wall -Wextra -Os -fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables CXXFLAGS = -std=c++17 -Wall -Wextra -O3
LDFLAGS = -lncurses -ltinfo -Wl,--gc-sections -s LDFLAGS = -lncurses -ltinfo
# Directories # Directories
SRC_DIR = src SRC_DIR = src

View File

@@ -14,7 +14,6 @@ public:
const std::vector<std::string> &getMask() const override { return mask; } const std::vector<std::string> &getMask() const override { return mask; }
char getDefaultColor() const noexcept override { return 'K'; } char getDefaultColor() const noexcept override { return 'K'; }
bool shouldBeRemoved() const noexcept override { return false; }
std::unique_ptr<Entity> createReplacement() const override { return nullptr; } std::unique_ptr<Entity> createReplacement() const override { return nullptr; }
int getPreferredLayer() const noexcept override { return 0; } int getPreferredLayer() const noexcept override { return 0; }
}; };

View File

@@ -1,6 +1,5 @@
#include "Entity.h" #include "Entity.h"
#include "Aquarium.h" #include "Aquarium.h"
#include <algorithm>
void Entity::draw() const { void Entity::draw() const {
auto &aquarium = Aquarium::getInstance(); auto &aquarium = Aquarium::getInstance();
@@ -57,25 +56,11 @@ void Entity::draw() const {
} }
} }
size_t Entity::getMaxRowWidth(const std::vector<std::string> &image) noexcept {
if (image.empty()) {
return 0;
}
size_t max_width = 0;
for (const auto &row : image) {
max_width = std::max(max_width, row.length());
}
return max_width;
}
bool Entity::shouldBeRemoved() const noexcept { bool Entity::shouldBeRemoved() const noexcept {
const auto &aquarium = Aquarium::getInstance(); const auto &aquarium = Aquarium::getInstance();
const auto &current_image = getImage(); if (moving_right) {
const float entity_width = static_cast<float>(getMaxRowWidth(current_image)); return x > static_cast<float>(aquarium.getWidth());
} else {
// Default implementation: remove if completely off-screen return (x + static_cast<float>(getWidth())) < 0;
return (x + entity_width < 0) || }
(x > static_cast<float>(aquarium.getWidth()));
} }

View File

@@ -10,33 +10,33 @@ struct AssetPair {
class Entity { class Entity {
protected: protected:
const bool moving_right;
float x; float x;
float y; float y;
static inline size_t next_id = 0; static inline size_t next_id = 0;
const size_t entity_id; const size_t entity_id;
virtual const std::vector<std::string> &getImage() const = 0;
virtual const std::vector<std::string> &getMask() const = 0;
virtual char getDefaultColor() const noexcept = 0;
public: public:
Entity() : x(0.0f), y(0.0f), entity_id(++next_id) {} Entity() : moving_right(false), x(0.0f), y(0.0f), entity_id(++next_id) {}
Entity(bool moving_right)
: moving_right(moving_right), x(0.0f), y(0.0f), entity_id(++next_id) {}
Entity(float init_x, float init_y) Entity(float init_x, float init_y)
: x(init_x), y(init_y), entity_id(++next_id) {} : moving_right(false), x(init_x), y(init_y), entity_id(++next_id) {}
virtual ~Entity() = default; virtual ~Entity() = default;
float getX() const noexcept { return x; } float getX() const noexcept { return x; }
float getY() const noexcept { return y; } float getY() const noexcept { return y; }
virtual size_t getWidth() const noexcept { return getImage()[0].length(); }
size_t getId() const noexcept { return entity_id; } size_t getId() const noexcept { return entity_id; }
virtual void update() noexcept = 0; virtual void update() noexcept = 0;
virtual const std::vector<std::string> &getImage() const = 0;
virtual const std::vector<std::string> &getMask() const = 0;
virtual char getDefaultColor() const noexcept = 0;
virtual bool shouldBeRemoved() const noexcept; virtual bool shouldBeRemoved() const noexcept;
virtual std::unique_ptr<Entity> createReplacement() const { return nullptr; } virtual std::unique_ptr<Entity> createReplacement() const { return nullptr; }
virtual int getPreferredLayer() const noexcept = 0; virtual int getPreferredLayer() const noexcept = 0;
void draw() const; void draw() const;
protected:
// Helper function to get the maximum width of any row in an image
static size_t getMaxRowWidth(const std::vector<std::string> &image) noexcept;
}; };

View File

@@ -9,10 +9,9 @@ std::unordered_map<char, char> Fish::color_map;
Fish::Fish() : Fish(getRandomAssetIndex()) {} Fish::Fish() : Fish(getRandomAssetIndex()) {}
Fish::Fish(int asset_index) Fish::Fish(int asset_index)
: Entity(), image(fishAssetPairs[asset_index].image), : Entity(asset_index % 2 == 0), image(fishAssetPairs[asset_index].image),
mask(fishAssetPairs[asset_index].mask), mask(fishAssetPairs[asset_index].mask),
speed(Random::floatInRange(0.25f, 2.25f)), speed(Random::floatInRange(0.25f, 2.25f)) {
moving_right(asset_index % 2 == 0) {
const auto &aquarium = Aquarium::getInstance(); const auto &aquarium = Aquarium::getInstance();
y = Random::intInRange(static_cast<int>(image.size()) + 6, y = Random::intInRange(static_cast<int>(image.size()) + 6,
@@ -50,15 +49,6 @@ int Fish::getRandomAssetIndex() {
void Fish::update() noexcept { x += moving_right ? speed : -speed; } void Fish::update() noexcept { x += moving_right ? speed : -speed; }
bool Fish::shouldBeRemoved() const noexcept {
const auto &aquarium = Aquarium::getInstance();
if (moving_right) {
return x > static_cast<float>(aquarium.getWidth());
} else {
return (x + static_cast<float>(image[0].length())) < 0;
}
}
std::unique_ptr<Entity> Fish::createReplacement() const { std::unique_ptr<Entity> Fish::createReplacement() const {
return std::make_unique<Fish>(); return std::make_unique<Fish>();
} }

View File

@@ -12,7 +12,6 @@ private:
const std::vector<std::string> &image; const std::vector<std::string> &image;
std::vector<std::string> mask; std::vector<std::string> mask;
const float speed; const float speed;
const bool moving_right;
static std::unordered_map<char, char> color_map; static std::unordered_map<char, char> color_map;
@@ -28,7 +27,6 @@ public:
const std::vector<std::string> &getMask() const override { return mask; } const std::vector<std::string> &getMask() const override { return mask; }
char getDefaultColor() const noexcept override { return 'k'; } char getDefaultColor() const noexcept override { return 'k'; }
bool shouldBeRemoved() const noexcept override;
std::unique_ptr<Entity> createReplacement() const override; std::unique_ptr<Entity> createReplacement() const override;
int getPreferredLayer() const noexcept override; int getPreferredLayer() const noexcept override;

View File

@@ -6,21 +6,21 @@
SeaMonster::SeaMonster() : SeaMonster(getRandomDirection()) {} SeaMonster::SeaMonster() : SeaMonster(getRandomDirection()) {}
SeaMonster::SeaMonster(int asset_index) SeaMonster::SeaMonster(int asset_index)
: Entity(), frame1(seaMonsterAssets[asset_index].frame1), : Entity(asset_index == 0), frames(seaMonsterAssets[asset_index].frames),
frame2(seaMonsterAssets[asset_index].frame2), mask(seaMonsterAssets[asset_index].mask), speed(SEAMONSTER_SPEED) {
mask(seaMonsterAssets[asset_index].mask), speed(SEAMONSTER_SPEED),
moving_right(asset_index == 0) {
const auto &aquarium = Aquarium::getInstance(); const auto &aquarium = Aquarium::getInstance();
y = WATER_SURFACE_OFFSET; y = WATER_SURFACE_OFFSET;
// Use first frame for positioning calculations
const auto &first_frame = frames[0];
if (moving_right) { if (moving_right) {
x = -static_cast<float>(frame1[0].length()); x = -static_cast<float>(first_frame[0].length());
} else { } else {
x = static_cast<float>(aquarium.getWidth()); x = static_cast<float>(aquarium.getWidth());
} }
current_image = frame1; current_image = first_frame;
} }
int SeaMonster::getRandomDirection() { return Random::intInRange(0, 1); } int SeaMonster::getRandomDirection() { return Random::intInRange(0, 1); }
@@ -30,27 +30,14 @@ void SeaMonster::update() noexcept {
++animation_counter; ++animation_counter;
if (animation_counter >= ANIMATION_DELAY) { if (animation_counter >= ANIMATION_DELAY) {
current_frame = !current_frame; current_frame_index = (current_frame_index + 1) % frames.size();
animation_counter = 0; animation_counter = 0;
} }
} }
const std::vector<std::string> &SeaMonster::getImage() const { const std::vector<std::string> &SeaMonster::getImage() const {
if (current_frame) { current_image = frames[current_frame_index];
current_image = frame2;
} else {
current_image = frame1;
}
return current_image; return current_image;
} }
bool SeaMonster::shouldBeRemoved() const noexcept {
const auto &aquarium = Aquarium::getInstance();
if (moving_right) {
return x > static_cast<float>(aquarium.getWidth());
} else {
return (x + static_cast<float>(frame1[0].length())) < 0;
}
}
int SeaMonster::getPreferredLayer() const noexcept { return 8; } int SeaMonster::getPreferredLayer() const noexcept { return 8; }

View File

@@ -7,13 +7,11 @@ private:
static constexpr float SEAMONSTER_SPEED = 0.8f; static constexpr float SEAMONSTER_SPEED = 0.8f;
static constexpr int WATER_SURFACE_OFFSET = 2; static constexpr int WATER_SURFACE_OFFSET = 2;
const std::vector<std::string> &frame1; const std::vector<std::vector<std::string>> frames;
const std::vector<std::string> &frame2;
const std::vector<std::string> &mask; const std::vector<std::string> &mask;
const float speed; const float speed;
const bool moving_right;
bool current_frame = false; int current_frame_index = 0;
int animation_counter = 0; int animation_counter = 0;
mutable std::vector<std::string> current_image; mutable std::vector<std::string> current_image;
@@ -30,6 +28,5 @@ public:
const std::vector<std::string> &getMask() const override { return mask; } const std::vector<std::string> &getMask() const override { return mask; }
char getDefaultColor() const noexcept override { return 'G'; } char getDefaultColor() const noexcept override { return 'G'; }
bool shouldBeRemoved() const noexcept override;
int getPreferredLayer() const noexcept override; int getPreferredLayer() const noexcept override;
}; };

View File

@@ -6,12 +6,11 @@
Ship::Ship() : Ship(getRandomDirection()) {} Ship::Ship() : Ship(getRandomDirection()) {}
Ship::Ship(int asset_index) Ship::Ship(int asset_index)
: Entity(), image(shipAssets[asset_index].image), : Entity(asset_index == 0), image(shipAssets[asset_index].image),
mask(shipAssets[asset_index].mask), speed(SHIP_SPEED), mask(shipAssets[asset_index].mask), speed(SHIP_SPEED) {
moving_right(asset_index == 0) {
const auto &aquarium = Aquarium::getInstance(); const auto &aquarium = Aquarium::getInstance();
y = WATER_SURFACE_OFFSET; y = 0;
if (moving_right) { if (moving_right) {
x = -static_cast<float>(image[0].length()); x = -static_cast<float>(image[0].length());
} else { } else {
@@ -23,13 +22,4 @@ int Ship::getRandomDirection() { return Random::intInRange(0, 1); }
void Ship::update() noexcept { x += moving_right ? speed : -speed; } void Ship::update() noexcept { x += moving_right ? speed : -speed; }
bool Ship::shouldBeRemoved() const noexcept {
const auto &aquarium = Aquarium::getInstance();
if (moving_right) {
return x > static_cast<float>(aquarium.getWidth());
} else {
return (x + static_cast<float>(image[0].length())) < 0;
}
}
int Ship::getPreferredLayer() const noexcept { return 9; } int Ship::getPreferredLayer() const noexcept { return 9; }

View File

@@ -5,12 +5,10 @@
class Ship : public Entity { class Ship : public Entity {
private: private:
static constexpr float SHIP_SPEED = 1.0f; static constexpr float SHIP_SPEED = 1.0f;
static constexpr int WATER_SURFACE_OFFSET = 0;
const std::vector<std::string> &image; const std::vector<std::string> &image;
const std::vector<std::string> &mask; const std::vector<std::string> &mask;
const float speed; const float speed;
const bool moving_right;
explicit Ship(int asset_index); explicit Ship(int asset_index);
static int getRandomDirection(); static int getRandomDirection();
@@ -23,6 +21,5 @@ public:
const std::vector<std::string> &getMask() const override { return mask; } const std::vector<std::string> &getMask() const override { return mask; }
char getDefaultColor() const noexcept override { return 'W'; } char getDefaultColor() const noexcept override { return 'W'; }
bool shouldBeRemoved() const noexcept override;
int getPreferredLayer() const noexcept override; int getPreferredLayer() const noexcept override;
}; };

View File

@@ -1,3 +1,4 @@
// SpriteUtils.h - Unified mirroring for all asset types
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <string> #include <string>
@@ -6,63 +7,75 @@
struct AssetPair; struct AssetPair;
namespace SpriteUtils {
// Character mapping for directional elements // Character mapping for directional elements
const std::unordered_map<char, char> charFlipMap = { const std::unordered_map<char, char> charFlipMap = {
{'(', ')'}, {')', '('}, {'[', ']'}, {']', '['}, {'{', '}'}, {'}', '{'}, {'(', ')'}, {')', '('}, {'[', ']'}, {']', '['}, {'{', '}'},
{'<', '>'}, {'>', '<'}, {'/', '\\'}, {'\\', '/'}, {'`', '\''}, {'\'', '`'}, {'}', '{'}, {'<', '>'}, {'>', '<'}, {'/', '\\'}, {'\\', '/'}};
};
// Mirror a single character (handle directional flipping)
inline char mirrorChar(char c) { inline char mirrorChar(char c) {
auto it = charFlipMap.find(c); auto it = charFlipMap.find(c);
return (it != charFlipMap.end()) ? it->second : c; return (it != charFlipMap.end()) ? it->second : c;
} }
// Mirror a single row with proper character flipping
inline std::string mirrorRow(std::string row) { inline std::string mirrorRow(std::string row) {
// First reverse the string
std::reverse(row.begin(), row.end()); std::reverse(row.begin(), row.end());
// Then flip directional characters
for (char &c : row) { for (char &c : row) {
c = mirrorChar(c); c = mirrorChar(c);
} }
return row; return row;
} }
// Mirror an entire sprite // Mirror an entire sprite (vector of strings)
inline std::vector<std::string> inline std::vector<std::string>
mirrorSprite(const std::vector<std::string> &sprite) { mirrorSprite(const std::vector<std::string> &sprite) {
std::vector<std::string> mirrored; std::vector<std::string> mirrored;
mirrored.reserve(sprite.size()); mirrored.reserve(sprite.size());
for (const auto &row : sprite) { for (const auto &row : sprite) {
mirrored.push_back(mirrorRow(row)); mirrored.push_back(mirrorRow(row));
} }
return mirrored; return mirrored;
} }
// Mirror an AssetPair
inline AssetPair mirrorAssetPair(const AssetPair &asset) { inline AssetPair mirrorAssetPair(const AssetPair &asset) {
return {mirrorSprite(asset.image), mirrorSprite(asset.mask)}; return {mirrorSprite(asset.image), mirrorSprite(asset.mask)};
} }
// Create bidirectional asset pairs from right-facing assets // Create bidirectional assets from simple AssetPair vector
inline std::vector<AssetPair> inline std::vector<AssetPair>
createBidirectionalAssets(const std::vector<AssetPair> &rightFacingAssets) { createBidirectionalAssets(const std::vector<AssetPair> &rightFacingAssets) {
std::vector<AssetPair> result; std::vector<AssetPair> result;
result.reserve(rightFacingAssets.size() * 2); result.reserve(rightFacingAssets.size() * 2);
for (const auto &asset : rightFacingAssets) { for (const auto &asset : rightFacingAssets) {
// Add right-facing version result.push_back(asset); // Right-facing
result.push_back(asset); result.push_back(mirrorAssetPair(asset)); // Left-facing (mirrored)
// Add left-facing (mirrored) version
result.push_back(mirrorAssetPair(asset));
} }
return result; return result;
} }
} // namespace SpriteUtils
// Generic template for any asset type with frames and mask
template <typename AssetType>
AssetType mirrorFramedAsset(const AssetType &asset) {
AssetType mirrored;
// Mirror all frames
for (const auto &frame : asset.frames) {
mirrored.frames.push_back(mirrorSprite(frame));
}
// Mirror mask
mirrored.mask = mirrorSprite(asset.mask);
return mirrored;
}
// Create bidirectional assets from single framed asset
template <typename AssetType>
std::vector<AssetType>
createBidirectionalFramedAssets(const AssetType &rightFacingAsset) {
return {
rightFacingAsset, // [0] = Right-facing
mirrorFramedAsset(rightFacingAsset) // [1] = Left-facing (mirrored)
};
}

View File

@@ -24,7 +24,6 @@ public:
const std::vector<std::string> &getMask() const override; const std::vector<std::string> &getMask() const override;
char getDefaultColor() const noexcept override { return WATERLINE_COLOR; } char getDefaultColor() const noexcept override { return WATERLINE_COLOR; }
bool shouldBeRemoved() const noexcept override { return false; }
std::unique_ptr<Entity> createReplacement() const override { return nullptr; } std::unique_ptr<Entity> createReplacement() const override { return nullptr; }
int getPreferredLayer() const noexcept override { return 0; } int getPreferredLayer() const noexcept override { return 0; }

View File

@@ -6,9 +6,8 @@
Whale::Whale() : Whale(getRandomDirection()) {} Whale::Whale() : Whale(getRandomDirection()) {}
Whale::Whale(int asset_index) Whale::Whale(int asset_index)
: Entity(), frames(whaleAssets[asset_index].frames), : Entity((asset_index = 0)), frames(whaleAssets[asset_index].frames),
mask(whaleAssets[asset_index].mask), speed(WHALE_SPEED), mask(whaleAssets[asset_index].mask), speed(WHALE_SPEED) {
moving_right(asset_index == 0) {
const auto &aquarium = Aquarium::getInstance(); const auto &aquarium = Aquarium::getInstance();
y = 0; y = 0;
@@ -46,15 +45,4 @@ const std::vector<std::string> &Whale::getImage() const {
return current_image; return current_image;
} }
bool Whale::shouldBeRemoved() const noexcept {
const auto &aquarium = Aquarium::getInstance();
const auto &first_frame = frames[0];
if (moving_right) {
return x > static_cast<float>(aquarium.getWidth());
} else {
return (x + static_cast<float>(first_frame[6].length())) < 0;
}
}
int Whale::getPreferredLayer() const noexcept { return 8; } int Whale::getPreferredLayer() const noexcept { return 8; }

View File

@@ -9,7 +9,6 @@ private:
const std::vector<std::vector<std::string>> frames; const std::vector<std::vector<std::string>> frames;
const std::vector<std::string> &mask; const std::vector<std::string> &mask;
const float speed; const float speed;
const bool moving_right;
int current_frame_index = 0; int current_frame_index = 0;
int animation_counter = 0; int animation_counter = 0;
@@ -28,7 +27,5 @@ public:
const std::vector<std::string> &getImage() const override; const std::vector<std::string> &getImage() const override;
const std::vector<std::string> &getMask() const override { return mask; } const std::vector<std::string> &getMask() const override { return mask; }
char getDefaultColor() const noexcept override { return 'B'; } char getDefaultColor() const noexcept override { return 'B'; }
bool shouldBeRemoved() const noexcept override;
int getPreferredLayer() const noexcept override; int getPreferredLayer() const noexcept override;
}; };

View File

@@ -1,53 +1,105 @@
#pragma once #pragma once
#include "../Entity.h" #include "../Entity.h"
#include "SpriteUtils.h" #include "../SpriteUtils.h"
#include <vector> #include <vector>
// Store only right-facing fish assets (half the data!) const std::vector<AssetPair> fishAssets = {
const std::vector<AssetPair> rightFacingFishAssets = { {
{{R"(???\??)", R"(??/ \?)", R"(>=_('>)", R"(??\_/?)", R"(???/??)"}, {
{R"( 1 )", R"( 1 1 )", R"(663745)", R"( 111 )", R"( 3 )"}}, R"(???\??)",
{{R"(?????,????)", R"(?????}\???)", R"(\??.' `\?)", R"(}}< ( 6>)", R"(??/ \?)",
R"(/??`, .'?)", R"(?????}/???)", R"(?????'????)"}, R"(>=_('>)",
{R"( 2 )", R"( 22 )", R"(6 11 11 )", R"(661 7 45)", R"(??\_/?)",
R"(6 11 11 )", R"( 33 )", R"( 3 )"}}, R"(???/??)"},
{{R"(???????,--,_????)", R"(__????_\.---'-.?)", R"(\ '.-" // o\)", {
R"(/_.'-._ \\ /)", R"(???????`"--(/"`?)"}, R"( 1 )",
{R"( 22222 )", R"(66 121111211 )", R"(6 6111 77 41)", R"( 1 1 )",
R"(6661111 77 1)", R"( 11113311 )"}}, R"(663745)",
{{R"(??__?)", R"(><_'>)", R"(???'?)"}, R"( 111 )",
{R"( 11 )", R"(61145)", R"( 3 )"}}, R"( 3 )"}},
{{R"(????????_.-`\??????)", R"(?????-:`_..,_\?????)", {
R"(('-..:-` , '-.,?)", R"(?} _ ;':( o :)", {
R"((.-`/'-.,__'` _.-`?)", R"(???`'-.,/??//`?????)"}, R"(?????,????)",
{R"( 22222 )", R"( 222111112 )", R"(?????}\???)",
R"(66661111 7 1111 )", R"( 6 1 7777 4 1)", R"(\??.' `\?)",
R"(6666211111177 1111 )", R"( 222222 333 )"}}, R"(}}< ( 6>)",
{{ R"(/??`, .'?)",
R"(????????/\??????)", R"(?????}/???)",
R"(????????\.\_????)", R"(?????'????)"},
R"(\'-,.:-` '-,?)", {
R"( ) _ (>( o <)", R"( 2 )",
R"(/.-`?':._ _.-`?)", R"( 22 )",
R"(??????;/?``?????)", R"(6 11 11 )",
R"(661 7 45)",
R"(6 11 11 )",
R"( 33 )",
R"( 3 )"}},
{
{
R"(???????,--,_????)",
R"(__????_\.---'-.?)",
R"(\ '.-" // o\)",
R"(/_.'-._ \\ /)",
R"(???????`"--(/"`?)"},
{
R"( 22222 )",
R"(66 121111211 )",
R"(6 6111 77 41)",
R"(6661111 77 1)",
R"( 11113311 )"}},
{
{
R"(??__?)",
R"(><_'>)",
R"(???'?)"},
{
R"( 11 )",
R"(61145)",
R"( 3 )"}},
{
{
R"(????????_.-`\??????)",
R"(?????-:`_..,_\?????)",
R"(('-..:-` , '-.,?)",
R"(?} _ ;':( o :)",
R"((.-`/'-.,__'` _.-`?)",
R"(???`'-.,/??//`?????)"},
{
R"( 22222 )",
R"( 222111112 )",
R"(66661111 7 1111 )",
R"( 6 1 7777 4 1)",
R"(6666211111177 1111 )",
R"( 222222 333 )"}},
{
{
R"(????????/\??????)",
R"(????????\.\_????)",
R"(\'-,.:-` '-,?)",
R"( ) _ (>( o <)",
R"(/.-`?':._ _.-`?)",
R"(??????;/?``?????)",
}, },
{ {
R"( 22 )", R"( 22 )",
R"( 2121 )", R"( 2121 )",
R"(66661111 111 )", R"(66661111 111 )",
R"( 6 1 777 4 1)", R"( 6 1 777 4 1)",
R"(6666 1111 1111 )", R"(6666 1111 1111 )",
R"( 22 33 )", R"( 22 33 )",}},
}}, {
{{R"(_?????????_.*"\??????)", R"(\'-._..-*` `'*-.??)", {
R"(?) , (( o >)", R"(/.`"*--.__)_.`_.-*`??)"}, R"(_?????????_.*"\??????)",
R"(\'-._..-*` `'*-.??)",
R"(?) , (( o >)",
R"(/.`"*--.__)_.`_.-*`??)"},
{ {
R"(6 11222 )", R"(6 11222 )",
R"(6661111111 11111 )", R"(6661111111 11111 )",
R"( 6 3 77 4 1)", R"( 6 3 77 4 1)",
R"(6661111111311311111 )", R"(6661111111311311111 )",
}}}; }}};
inline const std::vector<AssetPair> fishAssetPairs = inline const std::vector<AssetPair> fishAssetPairs =
SpriteUtils::createBidirectionalAssets(rightFacingFishAssets); createBidirectionalAssets(fishAssets);

View File

@@ -1,38 +1,30 @@
#pragma once #pragma once
#include "../Entity.h" #include "../Entity.h"
#include "../SpriteUtils.h"
#include <vector> #include <vector>
struct SeaMonsterAsset { struct SeaMonsterAsset {
std::vector<std::string> frame1; std::vector<std::vector<std::string>> frames;
std::vector<std::string> frame2;
std::vector<std::string> mask; std::vector<std::string> mask;
}; };
inline const std::vector<SeaMonsterAsset> seaMonsterAssets = { const SeaMonsterAsset seaMonster = {
{{ {// Frame 1
R"( _???_?????????????????????_???_???????_a_a)", {
R"( _{.`=`.}_??????_???_??????_{.`=`.}_????{/ ''\_)", R"(?????????_???_?????????????????????_???_???????_a_a???)",
R"(?_????{.' _ '.}????{.`'`.}????{.' _ '.}??{| ._oo))", R"(???????_{.`=`.}_??????_???_??????_{.`=`.}_????{/ ''\_?)",
R"({ \??{/ .'?'. \}??{/ .-. \}??{/ .'?'. \}?{/ |)", R"(?_????{.' _ '.}????{.`'`.}????{.' _ '.}??{| ._oo))",
}, R"({ \??{/ .'?'. \}??{/ .-. \}??{/ .'?'. \}?{/ |????)"},
{ {
R"( _???_????????????????????_a_a)", R"(??????????????????????_???_????????????????????_a_a???)",
R"(??_??????_???_??????_{.`=`.}_??????_???_??????{/ ''\_)", R"(??_??????_???_??????_{.`=`.}_??????_???_??????{/ ''\_?)",
R"(?{ \????{.`'`.}????{.' _ '.}????{.`'`.}????{| ._oo))", R"(?{ \????{.`'`.}????{.' _ '.}????{.`'`.}????{| ._oo))",
R"(??\ \??{/ .-. \}??{/ .'?'. \}??{/ .-. \}???{/ |)", R"(??\ \??{/ .-. \}??{/ .'?'. \}??{/ .-. \}???{/ |????)"}},
}, {
{ R"( W W )",
R"( W W)", R"()",
R"()", R"()",
R"()", R"()"}};
R"()",
}}, inline const std::vector<SeaMonsterAsset> seaMonsterAssets =
{{R"( a_a_???????_???_?????????????????????_???_)", createBidirectionalFramedAssets(seaMonster);
R"( _/'' \}????_{.`=`.}_??????_???_??????_{.`=`.}_)",
R"((oo_. |}??{.' _ '.}????{.`'`.}????{.' _ '.}????_)",
R"(????| \}?{/ .'?'. \}??{/ .-. \}??{/ .'?'. \}??/ })"},
{R"( a_a_????????????????????_ _)",
R"( _/'' \}??????_???_??????_{.`=`.}_??????_???_??????_)",
R"((oo_. |}????{.`'`.}????{.' _ '.}????{.`'`.}????/ })",
R"(????| \}???{/ .-. \}??{/ .'?'. \}??{/ .-. \}??/ /)"},
{R"( W W)", R"()", R"()", R"()"}}};

View File

@@ -1,37 +1,15 @@
#pragma once #pragma once
#include "../Entity.h" #include "../Entity.h"
#include "../SpriteUtils.h"
#include <vector> #include <vector>
inline std::vector<AssetPair> shipAssets = { const AssetPair ship = {
{{ {R"( | | | )", R"( )_) )_) )_) )",
R"( | | |)", R"( )___))___))___)\ )", R"( )____)____)_____)\\ )",
R"( )_) )_) )_))", R"(_____|____|____|____\\\__)", R"(\ /????)"},
R"( )___))___))___)\)", {R"( y y y )", R"()", R"( w )",
R"( )____)____)_____)\\)", R"( ww )", R"(yyyyyyyyyyyyyyyyyyyywwwyy)",
R"(_____|____|____|____\\\__)", R"(y y )"}};
R"(\ /)",
}, inline const std::vector<AssetPair> shipAssets =
{ createBidirectionalAssets({ship});
R"( y y y)",
R"()",
R"( w)",
R"( ww)",
R"(yyyyyyyyyyyyyyyyyyyywwwyy)",
R"(y y)",
}},
{{
R"( | | |)",
R"( (_( (_( (_()",
R"( /(___((___((___()",
R"( //(_____(____(____()",
R"(__///____|____|____|_____)",
R"(????\ /)",
},
{
R"( y y y)",
R"()",
R"( w)",
R"( ww)",
R"(yywwwyyyyyyyyyyyyyyyyyyyy)",
R"( y y)",
}}};