|
|
|
@ -1,28 +1,33 @@
|
|
|
|
|
#include <cmath>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
#include "bonus.hpp"
|
|
|
|
|
#include "arkanoid.hpp"
|
|
|
|
|
#include "ball.hpp"
|
|
|
|
|
#include "paddle.hpp"
|
|
|
|
|
|
|
|
|
|
const double pi = 3.14159265358979323846;
|
|
|
|
|
|
|
|
|
|
Bonus::Bonus(sf::Vector2f position): m_position(position)
|
|
|
|
|
{
|
|
|
|
|
m_time = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Двигаем бонус
|
|
|
|
|
void Bonus::update(float dt)
|
|
|
|
|
{
|
|
|
|
|
m_time += dt;
|
|
|
|
|
m_position.y += speed * dt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Рисуем бонус
|
|
|
|
|
void Bonus::draw(sf::RenderWindow& window) const
|
|
|
|
|
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});
|
|
|
|
@ -30,49 +35,32 @@ void Bonus::draw(sf::RenderWindow& window) const
|
|
|
|
|
window.draw(shape);
|
|
|
|
|
|
|
|
|
|
float angle = 0;
|
|
|
|
|
// Рисуем 3 шарика на этом круге
|
|
|
|
|
|
|
|
|
|
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 * pi / 3.0;
|
|
|
|
|
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 * pi / 3.0;
|
|
|
|
|
angle += 2.0 * M_PI / 3.0;
|
|
|
|
|
ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
|
|
|
|
|
ball.draw(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Функция Bonus::activate
|
|
|
|
|
|
|
|
|
|
Применяем эффект бонуса (в данном случае - утроение шариков)
|
|
|
|
|
numBalls - Количество шариков до утроения
|
|
|
|
|
Шарики хранятся в связном списке m_balls
|
|
|
|
|
Так как мы работаем со связным списком, то придётся использовать итератор it
|
|
|
|
|
|
|
|
|
|
Проходим итератором по изначальным элементам списка и добавляем новые шарики в список
|
|
|
|
|
В данном случае простой цикл через итераторы не сработает, так как массив game.m_balls увеличивается в процессе выполнения цикла.
|
|
|
|
|
|
|
|
|
|
Внутри цикла выбираем случайный вектор скорости и добавляем шарик в список game.m_balls
|
|
|
|
|
Делаем то же самое для ещё одного шарика
|
|
|
|
|
В конце цикла переходим ко следующему шарику в списке, т.е. увеличивем итератор it
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
void Bonus::activate(Arkanoid& game)
|
|
|
|
|
void TripleBallBonus::activate(Arkanoid& game)
|
|
|
|
|
{
|
|
|
|
|
int numBalls = game.m_balls.size();
|
|
|
|
|
std::list<Ball>::iterator it = game.m_balls.begin();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < numBalls; i++)
|
|
|
|
|
{
|
|
|
|
|
float angle = rand() % 1000 * (2 * pi / 1000);
|
|
|
|
|
float angle = rand() % 1000 * (2 * M_PI / 1000);
|
|
|
|
|
float vx = Ball::initialVelocity * sin(angle);
|
|
|
|
|
float vy = Ball::initialVelocity * cos(angle);
|
|
|
|
|
game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});
|
|
|
|
|
|
|
|
|
|
angle = rand() % 1000 * (2 * pi / 1000);
|
|
|
|
|
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}});
|
|
|
|
@ -81,11 +69,113 @@ void Bonus::activate(Arkanoid& game)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Bonus::isColiding(const Paddle& paddle) const
|
|
|
|
|
TripleBallBonus::~TripleBallBonus() {}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* EnlargePaddleBonus
|
|
|
|
|
* */
|
|
|
|
|
void EnlargePaddleBonus::draw(sf::RenderWindow& window) const
|
|
|
|
|
{
|
|
|
|
|
bool result = paddle.getBorder().intersects({m_position.x - radius, m_position.y - radius, 2 * radius, 2 * radius});
|
|
|
|
|
return result;
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
game.m_paddle.size.x *= 1.5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EnlargePaddleBonus::~EnlargePaddleBonus() {}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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)
|
|
|
|
|
{
|
|
|
|
|
game.m_paddle.size.x *= 0.8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ShrinkPaddleBonus::~ShrinkPaddleBonus() {}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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::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 SlowingBonus::activate(Arkanoid& game)
|
|
|
|
|
{
|
|
|
|
|
game.m_effects.push_back(new SlowingEffect(game.m_time, 10));
|
|
|
|
|
game.m_effects.back()->activate(game);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SlowingBonus::~SlowingBonus() {}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Effects
|
|
|
|
|
* */
|
|
|
|
|
|
|
|
|
|
Effect::Effect(double start_time, double duration) : 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(start_time, duration) {};
|
|
|
|
|
|
|
|
|
|
void SlowingEffect::activate(Arkanoid& game) {
|
|
|
|
|
std::cout << "Activated slow motion" << std::endl;
|
|
|
|
|
for (Ball& ball : game.m_balls)
|
|
|
|
|
{
|
|
|
|
|
//std::cout << "meow" << std::endl;
|
|
|
|
|
if (!(ball.affectedBy & 0b00000001)) {
|
|
|
|
|
ball.affectedBy |= 0b00000001;
|
|
|
|
|
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void SlowingEffect::deactivate(Arkanoid& game) {
|
|
|
|
|
std::cout << "Deactivated slow motion" << std::endl;
|
|
|
|
|
for (Ball& ball : game.m_balls)
|
|
|
|
|
{
|
|
|
|
|
if (ball.affectedBy & 0b00000001) {
|
|
|
|
|
ball.velocity = sf::Vector2f{ball.velocity.x / mSlowingFactor, ball.velocity.y / mSlowingFactor};
|
|
|
|
|
ball.affectedBy &= 0b11111110;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|