//TODO: implement this. #ifndef creature_2d #define creature_2d #include "../util/vec2.hpp" #include "../util/ray2.hpp" #include "../util/grid2.hpp" #include #include class Crea2 { public: Vec2 position; Vec2 facing; float currentSpeed; float maxSpeed; float currentHealth; float maxHealth; Grid2 visualRepresentation; Crea2() : position(Vec2(0, 0)), facing(Vec2(1, 0)), currentSpeed(0), maxSpeed(1), currentHealth(1), maxHealth(1) { createDefaultVisual(); } Crea2(const Vec2& pos, const Vec2& faceDir, float speed, float health) : position(pos), facing(faceDir.normalized()), currentSpeed(speed), maxSpeed(speed), currentHealth(health), maxHealth(health) { createDefaultVisual(); } // Random initialization method void randomInit(int size = 5) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution posDist(-10.0f, 10.0f); std::uniform_real_distribution angleDist(0.0f, 2.0f * M_PI); std::uniform_real_distribution speedDist(0.5f, 3.0f); std::uniform_real_distribution healthDist(50.0f, 150.0f); // Random position position = Vec2(posDist(gen), posDist(gen)); // Random facing direction float angle = angleDist(gen); facing = Vec2(std::cos(angle), std::sin(angle)); // Random speed maxSpeed = speedDist(gen); currentSpeed = maxSpeed * 0.7f; // Start at 70% of max speed // Random health maxHealth = healthDist(gen); currentHealth = maxHealth * 0.8f; // Start at 80% of max health // Create random visual representation createRandomVisual(size); } // Movement methods void move(float deltaTime) { position += facing * currentSpeed * deltaTime; } void rotate(float angle) { facing = facing.rotate(angle).normalized(); updateVisualRotation(); } void setFacing(const Vec2& newFacing) { facing = newFacing.normalized(); updateVisualRotation(); } // Health methods void takeDamage(float damage) { currentHealth = std::max(0.0f, currentHealth - damage); updateVisualHealth(); } void heal(float amount) { currentHealth = std::min(maxHealth, currentHealth + amount); updateVisualHealth(); } bool isAlive() const { return currentHealth > 0; } // Speed methods void accelerate(float acceleration, float deltaTime) { currentSpeed = std::min(maxSpeed, currentSpeed + acceleration * deltaTime); } void decelerate(float deceleration, float deltaTime) { currentSpeed = std::max(0.0f, currentSpeed - deceleration * deltaTime); } // Get ray representing creature's forward direction Ray2 getForwardRay() const { return Ray2(position, facing); } // Get ray representing creature's view direction Ray2 getViewRay(float length = 10.0f) const { return Ray2(position, facing * length); } // Get bounding circle radius for collision detection float getBoundingRadius() const { return 0.5f; // Approximate radius based on visual size } // Check if point is inside creature's bounding area bool containsPoint(const Vec2& point) const { return position.distance(point) <= getBoundingRadius(); } // Get health percentage (0.0 to 1.0) float getHealthPercentage() const { return currentHealth / maxHealth; } private: void createDefaultVisual() { visualRepresentation.clear(); // Simple triangle shape pointing forward visualRepresentation.addPoint(Vec2(0.3f, 0.0f), Vec4(1, 1, 1, 1)); // Nose - white visualRepresentation.addPoint(Vec2(-0.2f, 0.2f), Vec4(0, 1, 0, 1)); // Left - green visualRepresentation.addPoint(Vec2(-0.2f, -0.2f), Vec4(0, 1, 0, 1)); // Right - green visualRepresentation.addPoint(Vec2(-0.1f, 0.0f), Vec4(0, 0.5f, 0, 1)); // Center back - dark green updateVisualRotation(); updateVisualHealth(); } void createRandomVisual(int size) { visualRepresentation.clear(); std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution colorDist(0.2f, 1.0f); std::uniform_real_distribution offsetDist(-0.1f, 0.1f); // Create a random creature shape int points = std::max(3, size); // At least 3 points // Main body points in a circular pattern for (int i = 0; i < points; i++) { float angle = 2.0f * M_PI * i / points; float radius = 0.2f + offsetDist(gen) + 0.1f * (points / 5.0f); Vec2 point(std::cos(angle) * radius, std::sin(angle) * radius); // Shift points slightly backward to create forward direction point.x -= 0.1f; // Random color based on creature properties Vec4 color(colorDist(gen), colorDist(gen), colorDist(gen), 1.0f); // Health affects red component, speed affects blue component color.x *= getHealthPercentage(); color.z *= (currentSpeed / maxSpeed); visualRepresentation.addPoint(point, color); } // Add a "head" or forward indicator visualRepresentation.addPoint(Vec2(0.3f, 0.0f), Vec4(1, 1, 1, 1)); updateVisualRotation(); updateVisualHealth(); } void updateVisualRotation() { // Rotate all position points to match facing direction float currentAngle = facing.angle(); for (auto& pos : visualRepresentation.positions) { pos = pos.rotate(currentAngle); } } void updateVisualHealth() { // Update colors based on health float healthPercent = getHealthPercentage(); for (auto& color : visualRepresentation.colors) { // Fade to red as health decreases color.x = color.x * healthPercent; color.y = color.y * healthPercent; color.z = color.z * (1.0f - healthPercent) * 0.5f; // Add some blue when injured } } }; #endif