-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblock.cpp
More file actions
145 lines (116 loc) · 3.62 KB
/
block.cpp
File metadata and controls
145 lines (116 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "block.h"
Block::Block(float start_x, float start_y, float width, float height, int durability) :
GameObject(sf::Vector2f(start_x, start_y),
new sf::RectangleShape(), sf::Color::Yellow)
{
life_cnt = (durability <= 3 && durability > 0) ? durability : 3;
updateShapeColor();
setSize(sf::Vector2f(width, height));
dynamic_cast<sf::RectangleShape*>(shape)->setOrigin(width / 2.f, height / 2.f);
}
Block::~Block() {
if(shape != nullptr)
delete dynamic_cast<sf::RectangleShape*>(shape);
shape = nullptr;
}
void Block::setSize(const sf::Vector2f &size) {
dynamic_cast<sf::RectangleShape*>(shape)->setSize(size);
}
float Block::getWidth() const {
return dynamic_cast<sf::RectangleShape*>(shape)->getSize().x;
}
float Block::getHeight() const {
return dynamic_cast<sf::RectangleShape*>(shape)->getSize().y;
}
float Block::getRight() const {
return getPosition().x + getWidth() / 2.f;
}
float Block::getLeft() const {
return getPosition().x - getWidth() / 2.f;
}
float Block::getTop() const {
return getPosition().y - getHeight() / 2.f;
}
float Block::getBottom() const {
return getPosition().y + getHeight() / 2.f;
}
bool Block::isAlive() const {
return life_cnt != 0;
}
void Block::updateShapeColor() {
switch (life_cnt) {
case 3:
shape->setFillColor(sf::Color(90, 0, 0));
break;
case 2:
shape->setFillColor(sf::Color(160, 85, 0));
break;
case 1:
shape->setFillColor(sf::Color::Yellow);
break;
default:
break;
}
}
void Block::onHint() {
life_cnt--;
updateShapeColor();
score++;
}
void Block::draw(sf::RenderTarget& target, sf::RenderStates states) const {
target.draw(*dynamic_cast<sf::RectangleShape*>(shape), states);
}
void Block::handleBallPosChange(Ball &ball) {
if(!isIntersects(ball)) return;
onHint();
float overlapLeft = ball.getRight() - getLeft();
float overlapRight = getRight() - ball.getLeft();
float overlapTop= ball.getBottom() - getTop();
float overlapBottom = getBottom() - ball.getTop();
bool ballFromLeft = std::abs(overlapLeft) < std::abs(overlapRight);
bool ballFromTop = std::abs(overlapTop) < std::abs(overlapBottom);
float minOverlapX = ballFromLeft ? overlapLeft : overlapRight;
float minOverlapY = ballFromTop ? overlapTop : overlapBottom;
if(std::abs(minOverlapX) < std::abs(minOverlapY))
ball.setVelocityX(ballFromLeft ? -ball.getMoveRate() : ball.getMoveRate());
else
ball.setVelocityY(ballFromTop ? -ball.getMoveRate() : ball.getMoveRate());
}
Block* Block::clone() {
return new Block(getPosition().x, getPosition().y, getWidth(), getHeight(), life_cnt);
}
unsigned Block::score = 0;
unsigned Block::getScore() {
return score;
}
void Block::resetScore() {
Block::score = 0;
}
/** Prototype pattern implementation **/
BlockSpawner::BlockSpawner(float width, float height) {
easyBlock = new Block(0.f, 0.f, width, height, 1);
mediumBlock = new Block(0.f, 0.f, width, height, 2);
strongBlock = new Block(0.f, 0.f, width, height, 3);
}
BlockSpawner::~BlockSpawner() {
delete easyBlock;
delete mediumBlock;
delete strongBlock;
}
Block* BlockSpawner::getBlock(int type) const {
Block *out = nullptr;
switch (type) {
case 3:
out = strongBlock->clone();
break;
case 2:
out = mediumBlock->clone();
break;
case 1:
out = easyBlock->clone();
break;
default:
break;
}
return out;
}