This repository has been archived on 2023-05-13. You can view files and clone it, but cannot push or open issues or pull requests.
mipt_cpp/seminar13_polymorphism/arkanoid/bonus.cpp

231 lines
6.3 KiB
C++
Raw Normal View History

2023-01-04 14:37:54 +03:00
#include <cmath>
2023-01-06 00:44:44 +03:00
#include <iostream>
2023-01-04 14:37:54 +03:00
#include "bonus.hpp"
#include "arkanoid.hpp"
2023-01-04 14:56:03 +03:00
#include "ball.hpp"
#include "paddle.hpp"
2023-01-04 14:37:54 +03:00
Bonus::Bonus(sf::Vector2f position): m_position(position)
{
m_time = 0;
}
void Bonus::update(float dt)
{
m_time += dt;
m_position.y += speed * dt;
}
2023-01-06 00:44:44 +03:00
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
2023-01-04 14:37:54 +03:00
{
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;
2023-01-06 00:44:44 +03:00
2023-01-04 14:37:54 +03:00
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);
2023-01-06 00:44:44 +03:00
angle += 2.0 * M_PI / 3.0;
2023-01-04 14:37:54 +03:00
ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
ball.draw(window);
2023-01-06 00:44:44 +03:00
angle += 2.0 * M_PI / 3.0;
2023-01-04 14:37:54 +03:00
ball.position = m_position + ballRotationRadius * sf::Vector2f(std::cos(angle), std::sin(angle));
ball.draw(window);
}
2023-01-06 00:44:44 +03:00
void TripleBallBonus::activate(Arkanoid& game)
2023-01-04 14:37:54 +03:00
{
int numBalls = game.m_balls.size();
std::list<Ball>::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 == 0) {
isSlowed = true;
slowing_effect = *it;
break;
}
it++;
}
2023-01-04 14:37:54 +03:00
for (int i = 0; i < numBalls; i++)
{
float angle, vx, vy;
if (game.isMaxBalls()) {
toApply = false;
}
2023-01-04 14:37:54 +03:00
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());
}
}
2023-01-04 14:37:54 +03:00
it++;
}
}
2023-01-06 00:44:44 +03:00
TripleBallBonus::~TripleBallBonus() {}
/*
* EnlargePaddleBonus
* */
void EnlargePaddleBonus::draw(sf::RenderWindow& window) const
2023-01-04 14:37:54 +03:00
{
2023-01-06 00:44:44 +03:00
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;
}
2023-01-04 14:37:54 +03:00
}
2023-01-06 00:44:44 +03:00
EnlargePaddleBonus::~EnlargePaddleBonus() {}
2023-01-04 14:37:54 +03:00
2023-01-06 00:44:44 +03:00
/*
* 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;
}
2023-01-06 00:44:44 +03:00
}
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)
{
bool isAlreadySlowed = false;
for (auto it = game.m_effects.begin(); it != game.m_effects.end();) {
if ((*it)->effectId == 0) {
(*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);
}
2023-01-06 00:44:44 +03:00
}
SlowingBonus::~SlowingBonus() {}
/*
* Effects
* */
Effect::Effect(char id, double start_time, double duration) : effectId(id), mStartTime(start_time), mDuration(duration) {};
2023-01-06 00:44:44 +03:00
bool Effect::isExpired(double time) {
if (mStartTime + mDuration > time)
return false;
return true;
}
SlowingEffect::SlowingEffect(double start_time, double duration) : Effect(0, start_time, duration) {};
2023-01-06 00:44:44 +03:00
void SlowingEffect::activate(Arkanoid& game) {
for (Ball& ball : game.m_balls)
{
//if (!(ball.affectedBy & 0b00000001)) {
//ball.affectedBy |= 0b00000001;
2023-01-06 00:44:44 +03:00
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
//}
2023-01-06 00:44:44 +03:00
}
}
void SlowingEffect::activate(Ball& ball) {
//if (!(ball.affectedBy & 0b00000001)) {
//ball.affectedBy |= 0b00000001;
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
}
2023-01-06 00:44:44 +03:00
void SlowingEffect::deactivate(Arkanoid& game) {
for (Ball& ball : game.m_balls)
{
//if (ball.affectedBy & 0b00000001) {
2023-01-06 00:44:44 +03:00
ball.velocity = sf::Vector2f{ball.velocity.x / mSlowingFactor, ball.velocity.y / mSlowingFactor};
// ball.affectedBy &= 0b11111110;
//}
2023-01-06 00:44:44 +03:00
}
}
2023-01-04 14:37:54 +03:00