-
Notifications
You must be signed in to change notification settings - Fork 0
/
Node.cpp
executable file
·185 lines (156 loc) · 4.46 KB
/
Node.cpp
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
179
180
181
182
183
184
185
#include "Node.h"
/*
* Created by Stuart Irwin on 4/16/2019.
* Sprite with collision
*/
//Base constructor
Node::Node(Layer layer, sf::Vector2i size, bool hidden, Node *parent) {
if(layer >= MAXLAYER)
throw new std::invalid_argument(LAYERERROR);
this->layer = layer;
setSize(size);
setHidden(hidden);
setParent(parent);
}
//Get node layer variable
int Node::getLayer() {
return layer;
}
sf::Vector2i Node::getSize() {
return size;
}
//Create full collision box
sf::FloatRect Node::getRect() {
sf::Vector2f pos = this->getGPosition();
sf::FloatRect rec;
rec.left = pos.x - (this->getOrigin().x * this->getScale().x);
rec.top = pos.y - (this->getOrigin().y * this->getScale().y);
rec.width = this->size.x * this->getScale().x;
rec.height = this->size.y * this->getScale().y;
return rec;
}
//Get parent node
Node *Node::getParent() {
return parent;
}
//Get global position
sf::Vector2f Node::getGPosition() {
if(parent != NULL)
return getPosition() + parent->getGPosition();
return getPosition();
}
//Check if node is hidden
bool Node::isHidden() {
return hidden || deleted || (parent != NULL && parent->isHidden());
}
//Set collision box size
void Node::setSize(sf::Vector2i size) {
this->size = size;
setOrigin(size.x / 2, size.y / 2);
}
//Set whether node is hidden
void Node::setHidden(bool hidden) {
this->hidden = hidden;
}
//Set parent node
void Node::setParent(Node *parent) {
this->parent = parent;
}
//Set position in global coordinates
void Node::setGPosition(sf::Vector2f pos) {
if(parent != NULL)
pos -= parent->getGPosition();
setPosition(pos);
}
void Node::setGPosition(float x, float y) {
setGPosition(sf::Vector2f(x, y));
}
//Get full collision bitset
std::bitset<MAXLAYER> Node::getCollisionLayers() {
return collisionLayers;
}
//Check if node collides with layer
bool Node::getCollisionLayer(Layer layer) {
if(layer >= MAXLAYER)
throw new std::invalid_argument(LAYERERROR);
return collisionLayers[layer];
}
//Set if node collides with layer
void Node::collideWith(Layer layer, bool collide) {
if(layer >= MAXLAYER)
throw new std::invalid_argument(LAYERERROR);
collisionLayers[layer] = collide;
}
//Check collision box against other node
bool Node::checkCollision(Node *other) {
if(other == NULL || other->isDeleted())
return false;
return getRect().intersects(other->getRect());
}
//Move node with a specific direction and distance
sf::Vector2f Node::move(sf::Vector2f dir, double distance, int collideOffset) {
sf::Vector2f target = getPosition() + vectorLength(dir, distance);
setPosition(target);
return target;
}
sf::Vector2f Node::move(sf::Vector2f dir, Indexer *indexes, double distance, int collideOffset) {
sf::Vector2f target = gridCollision(getPosition(),
vectorLength(dir, distance), indexes, collideOffset);
setPosition(target);
return target;
}
//Create a vector with fixed length in any direction
sf::Vector2f Node::vectorLength(sf::Vector2f dir, double distance) {
float xOffset = 0;
float yOffset = 0;
if(dir.x == 0 && dir.y == 0)
return sf::Vector2f(0, 0);
if(dir.x == 0)
yOffset = copysign(distance, dir.y);
else if(dir.y == 0)
xOffset = copysign(distance, dir.x);
else if(abs(dir.x) == abs(dir.y)) {
float adjustment = sqrt(2) / 2.0;
xOffset = adjustment * copysign(distance, dir.x);
yOffset = adjustment * copysign(distance, dir.y);
} else {
float angle = std::atan2(dir.y, dir.x);
xOffset = cos(angle) * distance;
yOffset = sin(angle) * distance;
}
return sf::Vector2f(xOffset, yOffset);
}
//Adjust vector for collision with grid
sf::Vector2f Node::gridCollision(sf::Vector2f start, sf::Vector2f move, Indexer *indexes, int collideOffset) {
sf::Vector2f end = start + move;
if(indexes->getTile(end) <= collideOffset) {
sf::Vector2f horizontal = sf::Vector2f(start.x, end.y);
sf::Vector2f vertical = sf::Vector2f(end.x, start.y);
if(indexes->getTile(horizontal) > collideOffset &&
indexes->getTile(vertical) > collideOffset)
end = (abs(move.x) > abs(move.y)) ? horizontal : vertical;
else if(indexes->getTile(horizontal) > collideOffset)
end = horizontal;
else if(indexes->getTile(vertical) > collideOffset)
end = vertical;
else
end = start;
}
return end;
}
//Get next node in list
Node *Node::getNext() {
return next;
}
//Add new node after this
void Node::addNode(Node *node) {
if(next == NULL)
next = node;
else
next->addNode(node);
}
//Remove node immdiately after this from list
void Node::deleteNext() {
if(next != NULL && next->isDeleted())
next = next->getNext();
}