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;
|
int max_rand = 10000;
|
||||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
||||||
{
|
{
|
||||||
m_bonuses.push_back(new TripleBallBonus(position));
|
int max = 4; int min = 1;
|
||||||
}
|
int range = max - min + 1;
|
||||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
int num = rand() % range + min;
|
||||||
{
|
switch (num) {
|
||||||
m_bonuses.push_back(new EnlargePaddleBonus(position));
|
case 1:
|
||||||
}
|
m_bonuses.push_back(new TripleBallBonus(position));
|
||||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
break;
|
||||||
{
|
case 2:
|
||||||
m_bonuses.push_back(new ShrinkPaddleBonus(position));
|
m_bonuses.push_back(new EnlargePaddleBonus(position));
|
||||||
}
|
break;
|
||||||
if ((rand() % max_rand) * 1.0f / max_rand < m_bonusProbability)
|
case 3:
|
||||||
{
|
m_bonuses.push_back(new ShrinkPaddleBonus(position));
|
||||||
m_bonuses.push_back(new SlowingBonus(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);
|
m_balls.push_back(ball);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Arkanoid::isMaxBalls()
|
||||||
|
{
|
||||||
|
return m_balls.size() == kMaxNumBalls - 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Эта функция вызывается каждый кадр
|
// Эта функция вызывается каждый кадр
|
||||||
void Arkanoid::update(const sf::RenderWindow& window, float dt)
|
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)
|
if (m_gameState == GameState::running && m_balls.size() == 0)
|
||||||
{
|
{
|
||||||
|
m_effects.clear();
|
||||||
m_gameState = GameState::stuck;
|
m_gameState = GameState::stuck;
|
||||||
m_numLives--;
|
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();)
|
for (auto it = m_effects.begin(); it != m_effects.end();)
|
||||||
{
|
{
|
||||||
std::cout << "meow1" << std::endl;
|
|
||||||
if ((*it)->isExpired(m_time))
|
if ((*it)->isExpired(m_time))
|
||||||
{
|
{
|
||||||
(*it)->deactivate(*this);
|
(*it)->deactivate(*this);
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
|
|
||||||
void draw(sf::RenderWindow& window);
|
void draw(sf::RenderWindow& window);
|
||||||
void onMousePressed(sf::Event& event);
|
void onMousePressed(sf::Event& event);
|
||||||
|
bool isMaxBalls();
|
||||||
|
|
||||||
// Класс бонус должен быть дружественным, так как он может менять внутреннее состояние игры
|
// Класс бонус должен быть дружественным, так как он может менять внутреннее состояние игры
|
||||||
friend class Bonus;
|
friend class Bonus;
|
||||||
|
|
|
@ -13,9 +13,6 @@ struct Ball
|
||||||
sf::Vector2f position;
|
sf::Vector2f position;
|
||||||
sf::Vector2f velocity;
|
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);
|
Ball(float radius, sf::Vector2f position, sf::Vector2f velocity);
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
|
@ -53,17 +53,48 @@ void TripleBallBonus::activate(Arkanoid& game)
|
||||||
int numBalls = game.m_balls.size();
|
int numBalls = game.m_balls.size();
|
||||||
std::list<Ball>::iterator it = game.m_balls.begin();
|
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++)
|
for (int i = 0; i < numBalls; i++)
|
||||||
{
|
{
|
||||||
float angle = rand() % 1000 * (2 * M_PI / 1000);
|
float angle, vx, vy;
|
||||||
float vx = Ball::initialVelocity * sin(angle);
|
if (game.isMaxBalls()) {
|
||||||
float vy = Ball::initialVelocity * cos(angle);
|
toApply = false;
|
||||||
game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});
|
}
|
||||||
|
|
||||||
angle = rand() % 1000 * (2 * M_PI / 1000);
|
if (toApply) {
|
||||||
vx = Ball::initialVelocity * sin(angle);
|
angle = rand() % 1000 * (2 * M_PI / 1000);
|
||||||
vy = Ball::initialVelocity * cos(angle);
|
vx = Ball::initialVelocity * sin(angle);
|
||||||
game.addBall({game.m_initialBall.radius, (*it).position, {vx, vy}});
|
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++;
|
it++;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +121,9 @@ void EnlargePaddleBonus::draw(sf::RenderWindow& window) const
|
||||||
|
|
||||||
void EnlargePaddleBonus::activate(Arkanoid& game)
|
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() {}
|
EnlargePaddleBonus::~EnlargePaddleBonus() {}
|
||||||
|
@ -113,7 +146,9 @@ void ShrinkPaddleBonus::draw(sf::RenderWindow& window) const
|
||||||
}
|
}
|
||||||
void ShrinkPaddleBonus::activate(Arkanoid& game)
|
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() {}
|
ShrinkPaddleBonus::~ShrinkPaddleBonus() {}
|
||||||
|
@ -137,8 +172,19 @@ void SlowingBonus::draw(sf::RenderWindow& window) const
|
||||||
}
|
}
|
||||||
void SlowingBonus::activate(Arkanoid& game)
|
void SlowingBonus::activate(Arkanoid& game)
|
||||||
{
|
{
|
||||||
game.m_effects.push_back(new SlowingEffect(game.m_time, 10));
|
bool isAlreadySlowed = false;
|
||||||
game.m_effects.back()->activate(game);
|
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() {}
|
SlowingBonus::~SlowingBonus() {}
|
||||||
|
@ -147,7 +193,7 @@ SlowingBonus::~SlowingBonus() {}
|
||||||
* Effects
|
* 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) {
|
bool Effect::isExpired(double time) {
|
||||||
if (mStartTime + mDuration > time)
|
if (mStartTime + mDuration > time)
|
||||||
|
@ -155,27 +201,30 @@ bool Effect::isExpired(double time) {
|
||||||
return true;
|
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) {
|
void SlowingEffect::activate(Arkanoid& game) {
|
||||||
std::cout << "Activated slow motion" << std::endl;
|
|
||||||
for (Ball& ball : game.m_balls)
|
for (Ball& ball : game.m_balls)
|
||||||
{
|
{
|
||||||
//std::cout << "meow" << std::endl;
|
//if (!(ball.affectedBy & 0b00000001)) {
|
||||||
if (!(ball.affectedBy & 0b00000001)) {
|
//ball.affectedBy |= 0b00000001;
|
||||||
ball.affectedBy |= 0b00000001;
|
|
||||||
ball.velocity = sf::Vector2f{ball.velocity.x * mSlowingFactor, ball.velocity.y * mSlowingFactor};
|
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) {
|
void SlowingEffect::deactivate(Arkanoid& game) {
|
||||||
std::cout << "Deactivated slow motion" << std::endl;
|
|
||||||
for (Ball& ball : game.m_balls)
|
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.velocity = sf::Vector2f{ball.velocity.x / mSlowingFactor, ball.velocity.y / mSlowingFactor};
|
||||||
ball.affectedBy &= 0b11111110;
|
// ball.affectedBy &= 0b11111110;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,20 +66,28 @@ public:
|
||||||
|
|
||||||
class Effect {
|
class Effect {
|
||||||
private:
|
private:
|
||||||
|
char effectId;
|
||||||
double mStartTime;
|
double mStartTime;
|
||||||
double mDuration;
|
double mDuration;
|
||||||
public:
|
public:
|
||||||
Effect(double start_time, double duration);
|
Effect(char id, double start_time, double duration);
|
||||||
virtual void activate(Arkanoid& game) {};
|
virtual void activate(Arkanoid& game) {};
|
||||||
|
virtual void activate(Ball& ball) {};
|
||||||
virtual void deactivate(Arkanoid& game) {};
|
virtual void deactivate(Arkanoid& game) {};
|
||||||
bool isExpired(double time);
|
bool isExpired(double time);
|
||||||
|
|
||||||
|
friend class SlowingBonus;
|
||||||
|
friend class TripleBallBonus;
|
||||||
|
friend class Arkanoid;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SlowingEffect : public Effect {
|
class SlowingEffect : public Effect {
|
||||||
private:
|
private:
|
||||||
double mSlowingFactor = 0.1;
|
double mSlowingFactor = 0.1;
|
||||||
|
char id = 0;
|
||||||
public:
|
public:
|
||||||
SlowingEffect(double start_time, double duration);
|
SlowingEffect(double start_time, double duration);
|
||||||
void activate(Arkanoid& game);
|
void activate(Arkanoid& game);
|
||||||
|
void activate(Ball& ball);
|
||||||
void deactivate(Arkanoid& game);
|
void deactivate(Arkanoid& game);
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue