finish mirroring. abstract entity removal
This commit is contained in:
4
Makefile
4
Makefile
@@ -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
|
||||||
|
|||||||
@@ -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; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 ¤t_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()));
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/Entity.h
18
src/Entity.h
@@ -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;
|
|
||||||
};
|
};
|
||||||
|
|||||||
14
src/Fish.cpp
14
src/Fish.cpp
@@ -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>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ private:
|
|||||||
const std::vector<std::string> ℑ
|
const std::vector<std::string> ℑ
|
||||||
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;
|
||||||
|
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
16
src/Ship.cpp
16
src/Ship.cpp
@@ -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; }
|
||||||
|
|||||||
@@ -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> ℑ
|
const std::vector<std::string> ℑ
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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)
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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"()"}}};
|
|
||||||
|
|||||||
@@ -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)",
|
|
||||||
}}};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user