-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstageonefactory.cpp
More file actions
executable file
·183 lines (145 loc) · 5.96 KB
/
stageonefactory.cpp
File metadata and controls
executable file
·183 lines (145 loc) · 5.96 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "stageonefactory.h"
#include "utils.h"
#include <iostream>
#include <QJsonObject>
#include <QJsonArray>
#include <QLineF>
Ball* StageOneFactory::makeBall(const QJsonObject& ballData) {
// construct a ball from its values
QString col = ballData.value("colour").toString();
// extract pos into two doubles
QJsonObject tPos = ballData.value("position").toObject();
double xpos = tPos.value("x").toDouble();
double ypos = tPos.value("y").toDouble();
// extract velocity into two doubles
QJsonObject tVel = ballData.value("velocity").toObject();
double xvel = tVel.value("x").toDouble();
double yvel = tVel.value("y").toDouble();
double mass = ballData.value("mass").toDouble();
double radius = ballData.value("radius").toDouble();
return new StageOneBall(
QColor(col),
QVector2D(xpos, ypos),
QVector2D(xvel, yvel),
mass,
radius
);
}
Table* StageOneFactory::makeTable(const QJsonObject& tableData) {
// create a stage one table based on the fed in json data
QString colour = tableData.value("colour").toString();
// extract width and height from json vals
QJsonObject tSize = tableData.value("size").toObject();
double width = tSize.value("x").toDouble();
double height = tSize.value("y").toDouble();
double friction = tableData.value("friction").toDouble();
return new StageOneTable(width, height, QColor(colour), friction);
}
Ball* StageTwoFactory::makeBall(const QJsonObject &ballData) {
StageTwoBall* ball = makeChildBall(ballData, nullptr);
// but its velocity won't be set, so set it
QJsonObject tVel = ballData.value("velocity").toObject();
double xvel = tVel.value("x").toDouble();
double yvel = tVel.value("y").toDouble();
ball->setVelocity(QVector2D(xvel, yvel));
return ball;
}
StageTwoBall* StageTwoFactory::makeChildBall(const QJsonObject &ballData, StageTwoBall* parent) {
// child balls do not have a 'velocity field'
// for m_brush
QString defaultColour = DEFAULT_BALL_COLOUR;
if (parent != nullptr) defaultColour = parent->getColour();
QString col = ballData.value("colour").toString(defaultColour);
// for m_pos
QJsonObject tPos = ballData.value("position").toObject();
double xpos = tPos.value("x").toDouble();
double ypos = tPos.value("y").toDouble();
// for mass and radius
double mass = ballData.value("mass").toDouble(DEFAULT_BALL_MASS);
double radius = ballData.value("radius").toDouble(DEFAULT_BALL_RADIUS);
double strength = ballData.value("strength").toDouble(DEFAULT_BALL_STRENGTH);
// make the result now so that we can
// give the child ball (if there is one) a parent to refer to
StageTwoBall* result = new StageTwoBall (
QColor(col),
QVector2D(xpos, ypos),
QVector2D(0, 0),
mass,
radius,
parent,
strength
);
// they may or may not have a 'balls' field
if (ballData.contains("balls")) {
// then this ball has children, make them
QJsonArray childBallData = ballData.value("balls").toArray();
for (const auto& ball : childBallData) {
// check if it's actually a valid coordinate
StageTwoBall* child = makeChildBall(ball.toObject(), result);
if (properlyContained(child, result))
result->addChild(child);
// otherwise ignore that whole thing going on there
else {
std::cerr << "warning! Child ball not properly contained within parent ball, "
<< "This ball will be ignored...\n";
}
}
}
// ###### Return the Resultant Ball with #########
// ###### all its children constructed nicely #########
return result;
}
Table* StageTwoFactory::makeTable(const QJsonObject &tableData) {
//construct a Table that has pockets
// create a stage one table based on the fed in json data
QString colour = tableData.value("colour").toString();
// extract width and height from json vals
QJsonObject tSize = tableData.value("size").toObject();
double width = tSize.value("x").toDouble();
double height = tSize.value("y").toDouble();
double friction = tableData.value("friction").toDouble();
// an empty pocketResults array that will get filled
// as long as the key exists in the thing
std::vector<Pocket*>* pocketResults = new std::vector<Pocket*>;
if (tableData.contains("pockets")) {
for (auto pocket : tableData.value("pockets").toArray()) {
QJsonObject pocketPos = pocket.toObject().value("position").toObject();
if (!pocketPos.contains("x") || !pocketPos.contains("y")) {
std::cerr << "Warning! This pocket has no x or y position.. going to ignore...\n";
continue;
}
Pocket* p = makePocket(pocket.toObject());
pocketResults->push_back(p);
}
}
return new StageTwoTable (
width, height,
QColor(colour), friction,
pocketResults
);
}
Pocket* StageTwoFactory::makePocket(const QJsonObject& pocketData) {
// check out what data pocket has
// position key
// radius key (maybe)
QJsonObject position = pocketData.value("position").toObject();
double x_pos = position.value("x").toDouble();
double y_pos = position.value("y").toDouble();
double radius = DEFAULT_POCKET_RADIUS;
if (pocketData.contains("radius"))
radius = pocketData.value("radius").toDouble();
return new Pocket(radius, QVector2D(x_pos, y_pos));
}
bool StageTwoFactory::properlyContained(StageTwoBall* child, StageTwoBall* parent) {
/* If you take the difference between their two positions, and then add
* the baby's radius size,
* this should be STRICTLY LESS than the parent's
* radius size.
*/
return child->getPosition()
.distanceToPoint (
parent->getPosition()
)
+ child->getRadius()
<= parent->getRadius();
}