add whale #3
@@ -6,6 +6,7 @@
|
||||
#include "Seaweed.h"
|
||||
#include "Ship.h"
|
||||
#include "Waterline.h"
|
||||
#include "Whale.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
@@ -135,20 +136,26 @@ void Aquarium::addWaterline() { addEntityImpl<Waterline>(); }
|
||||
void Aquarium::addCastle() { addEntityImpl<Castle>(); }
|
||||
void Aquarium::addShip() { addEntityImpl<Ship>(); }
|
||||
void Aquarium::addSeaMonster() { addEntityImpl<SeaMonster>(); }
|
||||
void Aquarium::addWhale() { addEntityImpl<Whale>(); }
|
||||
|
||||
void Aquarium::ensureBigEntityExists() {
|
||||
// Check if any big entities exist on screen
|
||||
for (const auto &entity : entities) {
|
||||
if (dynamic_cast<Ship *>(entity.get()) ||
|
||||
dynamic_cast<SeaMonster *>(entity.get())) {
|
||||
dynamic_cast<SeaMonster *>(entity.get()) ||
|
||||
dynamic_cast<Whale *>(entity.get())) {
|
||||
return; // Big entity found, do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// No big entity found, spawn next in cycle
|
||||
if (big_entity_index % 2 == 0) {
|
||||
// No big entity found, spawn next in cycle (Ship, SeaMonster, Whale)
|
||||
int entity_type = big_entity_index % 3;
|
||||
if (entity_type == 0) {
|
||||
addEntityImpl<Ship>();
|
||||
} else {
|
||||
} else if (entity_type == 1) {
|
||||
addEntityImpl<SeaMonster>();
|
||||
} else {
|
||||
addEntityImpl<Whale>();
|
||||
}
|
||||
++big_entity_index;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
void addCastle();
|
||||
void addShip();
|
||||
void addSeaMonster();
|
||||
void addWhale();
|
||||
|
||||
void redraw();
|
||||
void initColors();
|
||||
|
||||
60
src/Whale.cpp
Normal file
60
src/Whale.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "Whale.h"
|
||||
#include "Aquarium.h"
|
||||
#include "Random.h"
|
||||
#include "assets/WhaleAssets.h"
|
||||
|
||||
Whale::Whale() : Whale(getRandomDirection()) {}
|
||||
|
||||
Whale::Whale(int asset_index)
|
||||
: Entity(), frames(whaleAssets[asset_index].frames),
|
||||
mask(whaleAssets[asset_index].mask), speed(WHALE_SPEED),
|
||||
moving_right(asset_index == 0) {
|
||||
|
||||
const auto &aquarium = Aquarium::getInstance();
|
||||
y = 0;
|
||||
|
||||
// Use first frame for positioning calculations
|
||||
const auto &first_frame = frames[0];
|
||||
if (moving_right) {
|
||||
x = -static_cast<float>(first_frame[6].length());
|
||||
} else {
|
||||
x = static_cast<float>(aquarium.getWidth());
|
||||
}
|
||||
|
||||
current_image = first_frame;
|
||||
}
|
||||
|
||||
int Whale::getRandomDirection() { return Random::intInRange(0, 1); }
|
||||
|
||||
void Whale::update() noexcept {
|
||||
x += moving_right ? speed : -speed;
|
||||
|
||||
++animation_counter;
|
||||
|
||||
// Use longer delay for first frame (no water spout)
|
||||
int current_delay =
|
||||
(current_frame_index == 0) ? FIRST_FRAME_PAUSE : ANIMATION_DELAY;
|
||||
|
||||
if (animation_counter >= current_delay) {
|
||||
current_frame_index = (current_frame_index + 1) % frames.size();
|
||||
animation_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string> &Whale::getImage() const {
|
||||
current_image = frames[current_frame_index];
|
||||
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[0].length())) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
int Whale::getPreferredLayer() const noexcept { return 8; }
|
||||
34
src/Whale.h
Normal file
34
src/Whale.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "Entity.h"
|
||||
#include "assets/WhaleAssets.h"
|
||||
|
||||
class Whale : public Entity {
|
||||
private:
|
||||
static constexpr float WHALE_SPEED = 1.0f;
|
||||
|
||||
const std::vector<std::vector<std::string>> frames;
|
||||
const std::vector<std::string> &mask;
|
||||
const float speed;
|
||||
const bool moving_right;
|
||||
|
||||
int current_frame_index = 0;
|
||||
int animation_counter = 0;
|
||||
mutable std::vector<std::string> current_image;
|
||||
|
||||
static constexpr int ANIMATION_DELAY = 1;
|
||||
static constexpr int FIRST_FRAME_PAUSE = 10;
|
||||
|
||||
explicit Whale(int asset_index);
|
||||
static int getRandomDirection();
|
||||
|
||||
public:
|
||||
Whale();
|
||||
|
||||
void update() noexcept override;
|
||||
const std::vector<std::string> &getImage() const override;
|
||||
const std::vector<std::string> &getMask() const override { return mask; }
|
||||
char getDefaultColor() const noexcept override { return 'B'; }
|
||||
|
||||
bool shouldBeRemoved() const noexcept override;
|
||||
int getPreferredLayer() const noexcept override;
|
||||
};
|
||||
53
src/assets/WhaleAssets.h
Normal file
53
src/assets/WhaleAssets.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include "../Entity.h"
|
||||
#include <vector>
|
||||
|
||||
struct WhaleAsset {
|
||||
std::vector<std::vector<std::string>> frames;
|
||||
std::vector<std::string> mask;
|
||||
};
|
||||
|
||||
inline const std::vector<WhaleAsset> whaleAssets = {
|
||||
{{{{R"()", R"()", R"()", R"( .-----.)", R"( .' `.)",
|
||||
R"(,????/ (o) \)", R"(\`._/ ,__)"},
|
||||
{R"()", R"()", R"( :)", R"( .-----.)",
|
||||
R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"},
|
||||
{R"()", R"( :)", R"( :)", R"( .-----.)",
|
||||
R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"},
|
||||
{R"( . .)", R"( -:-)", R"( :)",
|
||||
R"( .-----.)", R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"},
|
||||
{R"( . .)", R"( .-.-.)", R"( :)",
|
||||
R"( .-----.)", R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"},
|
||||
{R"( . .)", R"( '.-:-.')", R"( ' : ')",
|
||||
R"( .-----.)", R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"},
|
||||
{R"()", R"( .- -.)", R"( ; : ;)", R"( .-----.)",
|
||||
R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"},
|
||||
{R"()", R"()", R"( ; ;)", R"( .-----.)",
|
||||
R"( .' `.)", R"(,????/ (o) \)",
|
||||
R"(\`._/ ,__)"}},
|
||||
{R"( C C)", R"( CCCCCCC)", R"( C C C)", R"()",
|
||||
R"()", R"( W)", R"()"}},
|
||||
{{{R"()", R"()", R"()", R"( .-----.)", R"( .' `.)",
|
||||
R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"()", R"()", R"( :)", R"( .-----.)", R"( .' `.)",
|
||||
R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"()", R"( :)", R"( :)", R"( .-----.)",
|
||||
R"( .' `.)", R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"( . .)", R"( -:-)", R"( :)", R"( .-----.)",
|
||||
R"( .' `.)", R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"( . .)", R"( .-.-.)", R"( :)", R"( .-----.)",
|
||||
R"( .' `.)", R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"( . .)", R"( '.-:-.')", R"( ' : ')", R"( .-----.)",
|
||||
R"( .' `.)", R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"()", R"( .- -.)", R"( ; : ;)", R"( .-----.)",
|
||||
R"( .' `.)", R"( / (o) \????)", R"((__, \_.'/)"},
|
||||
{R"()", R"()", R"( ; ;)", R"( .-----.)", R"( .' `.)",
|
||||
R"( / (o) \????)", R"((__, \_.'/)"}},
|
||||
{R"( C C)", R"( CCCCCCC)", R"( C C C)", R"()", R"()",
|
||||
R"( W)", R"()"}}}};
|
||||
Reference in New Issue
Block a user