#include #include #include "bonus.hpp" #include "arkanoid.hpp" #include "ball.hpp" #include "paddle.hpp" /* ============= * ===Bonuses=== * ============= * */ Bonus::Bonus(sf::Vector2f position): m_position(position) { m_time = 0; } void Bonus::update(float dt) { m_time += dt; m_position.y += speed * dt; } bool Bonus::isColiding(const Paddle& paddle) const { bool result = paddle.getBorder().intersects({m_position.x - radius, m_position.y - radius, 2 * radius, 2 * radius}); return result; } /* * TripleBallBonus * */ void TripleBallBonus::draw(sf::RenderWindow& window) const { static sf::CircleShape shape(radius); shape.setOrigin(radius, radius); shape.setFillColor(sf::Color{100, 200, 100}); shape.setPosition(m_position); window.draw(shape); float angle = 0; static Ball ball {5, {0, 0}, {0, 0}}; float ballRotationRadius = 7; ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle)); ball.draw(window); angle += 2.0 * M_PI / 3.0; ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle)); ball.draw(window); angle += 2.0 * M_PI / 3.0; ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle)); ball.draw(window); } void TripleBallBonus::activate(Arkanoid& game) { int numBalls = game.m_balls.size(); std::list::iterator it = game.m_balls.begin(); bool isSlowed = false; bool toApply = true; Effect* slowing_effect = nullptr; for (auto it = game.m_effects.begin(); it != game.m_effects.end();) { if ((*it)->effectId == _EFFECT_SLOWING_ID) { isSlowed = true; slowing_effect = *it; break; } it++; } for (int i = 0; i < numBalls; i++) { float angle, vx, vy; if (game.isMaxBalls()) { toApply = false; } if (toApply) { angle = rand() % 1000 * (2 * M_PI / 1000); vx = Ball::initialVelocity * sin(angle); vy = Ball::initialVelocity * cos(angle); game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}}); if (isSlowed) { slowing_effect->activate(game.m_balls.back()); } } if (game.isMaxBalls()) { toApply = false; } if (toApply) { angle = rand() % 1000 * (2 * M_PI / 1000); vx = Ball::initialVelocity * sin(angle); vy = Ball::initialVelocity * cos(angle); game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}}); if (isSlowed) { slowing_effect->activate(game.m_balls.back()); } } it++; } } /* * EnlargePaddleBonus * */ void EnlargePaddleBonus::draw(sf::RenderWindow& window) const { static sf::CircleShape shape(radius); shape.setOrigin(radius, radius); shape.setFillColor(sf::Color{100, 200, 100}); shape.setPosition(m_position); window.draw(shape); static sf::RectangleShape rect(sf::Vector2f{radius, radius / 2}); rect.setFillColor(sf::Color::Green); rect.setPosition(m_position - sf::Vector2f{radius /2, radius / 4}); window.draw(rect); } void EnlargePaddleBonus::activate(Arkanoid& game) { if (game.m_paddle.size.x < 300) { game.m_paddle.size.x *= 1.5; } } /* * ShrinkPaddleBonus * */ void ShrinkPaddleBonus::draw(sf::RenderWindow& window) const { static sf::CircleShape shape(radius); shape.setOrigin(radius, radius); shape.setFillColor(sf::Color{100, 200, 100}); shape.setPosition(m_position); window.draw(shape); static sf::RectangleShape rect(sf::Vector2f{radius, radius / 2}); rect.setFillColor(sf::Color::Red); rect.setPosition(m_position - sf::Vector2f{radius /2, radius / 4}); window.draw(rect); } void ShrinkPaddleBonus::activate(Arkanoid& game) { if (game.m_paddle.size.x > 40) { game.m_paddle.size.x *= 0.8; } } /* * SlowingBonus * */ void SlowingBonus::draw(sf::RenderWindow& window) const { static sf::CircleShape shape(radius); shape.setOrigin(radius, radius); shape.setFillColor(sf::Color{100, 200, 100}); shape.setPosition(m_position); window.draw(shape); static sf::CircleShape clock(radius / 2); clock.setOutlineColor(sf::Color::Red); clock.setOutlineThickness(3); clock.setPosition(m_position - sf::Vector2f{radius /2, radius / 2}); window.draw(clock); } void SlowingBonus::activate(Arkanoid& game) { bool isAlreadySlowed = false; for (auto it = game.m_effects.begin(); it != game.m_effects.end();) { if ((*it)->effectId == _EFFECT_SLOWING_ID) { (*it)->mDuration += mDuration; isAlreadySlowed = true; break; } it++; } if (!isAlreadySlowed) { game.m_effects.push_back(new SlowingEffect(game.m_time, mDuration)); game.m_effects.back()->activate(game); } } /* ============= * ===Effects=== * ============= * */ Effect::Effect(char id, double start_time, double duration) : effectId(id), mStartTime(start_time), mDuration(duration) {}; bool Effect::isExpired(double time) { if (mStartTime + mDuration > time) return false; return true; } SlowingEffect::SlowingEffect(double start_time, double duration) : Effect(_EFFECT_SLOWING_ID, start_time, duration) {}; void SlowingEffect::activate(Arkanoid& game) { for (Ball& ball : game.m_balls) { ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor}; } } void SlowingEffect::activate(Ball& ball) { ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor}; } void SlowingEffect::deactivate(Arkanoid& game) { for (Ball& ball : game.m_balls) { ball.velocity = sf::Vector2f{ball.velocity.x / mSlowingFactor, ball.velocity.y / mSlowingFactor}; } }