seminar13 - arkanoid, working slow motion bonus
This commit is contained in:
parent
a6b1bccd37
commit
7697130f21
5 changed files with 105 additions and 41 deletions
|
@ -16,19 +16,23 @@ void Arkanoid::addRandomBonus(sf::Vector2f position)
|
|||
int max_rand = 10000;
|
||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
||||
{
|
||||
m_bonuses.push_back(new TripleBallBonus(position));
|
||||
}
|
||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
||||
{
|
||||
m_bonuses.push_back(new EnlargePaddleBonus(position));
|
||||
}
|
||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
||||
{
|
||||
m_bonuses.push_back(new ShrinkPaddleBonus(position));
|
||||
}
|
||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
||||
{
|
||||
m_bonuses.push_back(new SlowingBonus(position));
|
||||
int max = 4; int min = 1;
|
||||
int range = max - min + 1;
|
||||
int num = rand() % range + min;
|
||||
switch (num) {
|
||||
case 1:
|
||||
m_bonuses.push_back(new TripleBallBonus(position));
|
||||
break;
|
||||
case 2:
|
||||
m_bonuses.push_back(new EnlargePaddleBonus(position));
|
||||
break;
|
||||
case 3:
|
||||
m_bonuses.push_back(new ShrinkPaddleBonus(position));
|
||||
break;
|
||||
case 4:
|
||||
m_bonuses.push_back(new SlowingBonus(position));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +91,11 @@ void Arkanoid::addBall(const Ball& ball)
|
|||
m_balls.push_back(ball);
|
||||
}
|
||||
|
||||
bool Arkanoid::isMaxBalls()
|
||||
{
|
||||
return m_balls.size() == kMaxNumBalls - 1;
|
||||
}
|
||||
|
||||
// Эта функция вызывается каждый кадр
|
||||
void Arkanoid::update(const sf::RenderWindow& window, float dt)
|
||||
{
|
||||
|
@ -114,6 +123,7 @@ void Arkanoid::update(const sf::RenderWindow& window, float dt)
|
|||
// Если шариков нет, то переходи в режим начала игры и уменьшаем кол-во жизней
|
||||
if (m_gameState == GameState::running && m_balls.size() == 0)
|
||||
{
|
||||
m_effects.clear();
|
||||
m_gameState = GameState::stuck;
|
||||
m_numLives--;
|
||||
}
|
||||
|
@ -154,7 +164,6 @@ void Arkanoid::update(const sf::RenderWindow& window, float dt)
|
|||
/* Обработка эффектов */
|
||||
for (auto it = m_effects.begin(); it != m_effects.end();)
|
||||
{
|
||||
std::cout << "meow1" << std::endl;
|
||||
if ((*it)->isExpired(m_time))
|
||||
{
|
||||
(*it)->deactivate(*this);
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
|
||||
void draw(sf::RenderWindow& window);
|
||||
void onMousePressed(sf::Event& event);
|
||||
bool isMaxBalls();
|
||||
|
||||
// Класс бонус должен быть дружественным, так как он может менять внутреннее состояние игры
|
||||
friend class Bonus;
|
||||
|
|
|
@ -13,9 +13,6 @@ struct Ball
|
|||
sf::Vector2f position;
|
||||
sf::Vector2f velocity;
|
||||
|
||||
/* Every bit is responsible for ball being affected by some effect */
|
||||
char affectedBy = 0;
|
||||
|
||||
Ball(float radius, sf::Vector2f position, sf::Vector2f velocity);
|
||||
|
||||
void update(float dt);
|
||||
|
|
|
@ -53,17 +53,48 @@ void TripleBallBonus::activate(Arkanoid& game)
|
|||
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++;
|
||||
}
|
||||
for (int i = 0; i < numBalls; i++)
|
||||
{
|
||||
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}});
|
||||
float angle, vx, vy;
|
||||
if (game.isMaxBalls()) {
|
||||
toApply = false;
|
||||
}
|
||||
|
||||
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 (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++;
|
||||
}
|
||||
|
@ -90,7 +121,9 @@ void EnlargePaddleBonus::draw(sf::RenderWindow& window) const
|
|||
|
||||
void EnlargePaddleBonus::activate(Arkanoid& game)
|
||||
{
|
||||
game.m_paddle.size.x *= 1.5;
|
||||
if (game.m_paddle.size.x < 300) {
|
||||
game.m_paddle.size.x *= 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
EnlargePaddleBonus::~EnlargePaddleBonus() {}
|
||||
|
@ -113,7 +146,9 @@ void ShrinkPaddleBonus::draw(sf::RenderWindow& window) const
|
|||
}
|
||||
void ShrinkPaddleBonus::activate(Arkanoid& game)
|
||||
{
|
||||
game.m_paddle.size.x *= 0.8;
|
||||
if (game.m_paddle.size.x > 40) {
|
||||
game.m_paddle.size.x *= 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
ShrinkPaddleBonus::~ShrinkPaddleBonus() {}
|
||||
|
@ -137,8 +172,19 @@ void SlowingBonus::draw(sf::RenderWindow& window) const
|
|||
}
|
||||
void SlowingBonus::activate(Arkanoid& game)
|
||||
{
|
||||
game.m_effects.push_back(new SlowingEffect(game.m_time, 10));
|
||||
game.m_effects.back()->activate(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);
|
||||
}
|
||||
}
|
||||
|
||||
SlowingBonus::~SlowingBonus() {}
|
||||
|
@ -147,7 +193,7 @@ SlowingBonus::~SlowingBonus() {}
|
|||
* Effects
|
||||
* */
|
||||
|
||||
Effect::Effect(double start_time, double duration) : mStartTime(start_time), mDuration(duration) {};
|
||||
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)
|
||||
|
@ -155,27 +201,30 @@ bool Effect::isExpired(double time) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SlowingEffect::SlowingEffect(double start_time, double duration) : Effect(start_time, duration) {};
|
||||
SlowingEffect::SlowingEffect(double start_time, double duration) : Effect(0, 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;
|
||||
//if (!(ball.affectedBy & 0b00000001)) {
|
||||
//ball.affectedBy |= 0b00000001;
|
||||
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
void SlowingEffect::activate(Ball& ball) {
|
||||
//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) {
|
||||
//if (ball.affectedBy & 0b00000001) {
|
||||
ball.velocity = sf::Vector2f{ball.velocity.x / mSlowingFactor, ball.velocity.y / mSlowingFactor};
|
||||
ball.affectedBy &= 0b11111110;
|
||||
}
|
||||
// ball.affectedBy &= 0b11111110;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,20 +66,28 @@ public:
|
|||
|
||||
class Effect {
|
||||
private:
|
||||
char effectId;
|
||||
double mStartTime;
|
||||
double mDuration;
|
||||
public:
|
||||
Effect(double start_time, double duration);
|
||||
Effect(char id, double start_time, double duration);
|
||||
virtual void activate(Arkanoid& game) {};
|
||||
virtual void activate(Ball& ball) {};
|
||||
virtual void deactivate(Arkanoid& game) {};
|
||||
bool isExpired(double time);
|
||||
|
||||
friend class SlowingBonus;
|
||||
friend class TripleBallBonus;
|
||||
friend class Arkanoid;
|
||||
};
|
||||
|
||||
class SlowingEffect : public Effect {
|
||||
private:
|
||||
double mSlowingFactor = 0.1;
|
||||
char id = 0;
|
||||
public:
|
||||
SlowingEffect(double start_time, double duration);
|
||||
void activate(Arkanoid& game);
|
||||
void activate(Ball& ball);
|
||||
void deactivate(Arkanoid& game);
|
||||
};
|
||||
|
|
Reference in a new issue