-
Notifications
You must be signed in to change notification settings - Fork 1
/
Flatland.cpp
212 lines (188 loc) · 6.91 KB
/
Flatland.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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/* CSCI 261B : Final Project: Flatland Class Implementation File
*
* Description: Contains record of flatland world. Handles the rotation tranfor-
* mations and transformation, but not the position and rotations of the indiv-
* dual objects.
*
* Author: Joseph McKinsey
*
*/
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <vector>
#include <cmath>
#include "FlatShape.h"
#include "Flatland.h"
using namespace sf;
// Default constructor.
Flatland::Flatland() {
_cameraAngle = 0;
_cameraPosition.x = 0;
_cameraPosition.y = -200;
}
// Constructor but with shapes.
Flatland::Flatland(std::vector<FlatShape> shapes) {
_population = shapes;
_cameraAngle = 0;
_cameraPosition.x = 0;
_cameraPosition.y = -200;
}
// Helper function that preserves precision by adjusting the camera angle
// if it exceeds 2 * PI or is less than 0. It wraps the values around to
// the other end.
void Flatland::normalizeAngle() {
if (_cameraAngle >= 2 * PI) {
// Make the value fall between 0 and 2 * PI
_cameraAngle += -2 * PI * ceil((_cameraAngle - 2 * PI) / (2 * PI));
}
else if (_cameraAngle < 0) {
// Make the value fall between 0 and 2 * PI
_cameraAngle += -2 * PI * floor(_cameraAngle / (2 * PI));
}
}
// Offsets rotation. Uses normalizeAngle
void Flatland::offsetRotation(const float &angle) {
_cameraAngle += angle;
normalizeAngle();
}
// Offsets position.
void Flatland::offsetPosition(const Vector2f &position) {
_cameraPosition += position;
}
// Sets rotation (uses normalizeAngle);
void Flatland::setRotation(const float &angle) {
_cameraAngle = angle;
normalizeAngle();
}
// Sets position.
void Flatland::setPosition(const Vector2f &position) {
_cameraPosition = position;
}
// Get rotation.
float Flatland::getRotation() const {
return _cameraAngle;
}
// Get position.
Vector2f Flatland::getPosition() const {
return _cameraPosition;
}
// Add Shape to Flatland.
// TODO Because of how minimal the derived classes are to everything,
// some object slicing occurs. Currently its not a problem, but definitely in the future
// it could be a big problem. I'm not sure if you can use the derived member functions
// from main.cpp because of that.
void Flatland::addShape(const FlatShape &shape) {
_population.push_back(shape);
}
// Remove shape.
void Flatland::removeShape() {
_population.pop_back();
}
// Get shape as reference (allows for assignment and such in main.cpp
// See above TODO.
FlatShape& Flatland::at(unsigned int i) {
return _population.at(i);
}
// Draw objects in flatland.
void Flatland::draw() {
// Rotate camera. (also adjusts for radians)
glRotatef(_cameraAngle / PI * 180, 0, 1, 0);
// Positions camera.
glTranslatef(_cameraPosition.x, 0, _cameraPosition.y);
// Draw all of the objects.
for (unsigned int i = 0; i < _population.size(); i++) {
_population.at(i).draw();
}
}
// Draws hud with specified font (so that the font can be loaded once
// in the main.cpp
void Flatland::drawHUD(const Font &myFont, RenderWindow* window) {
// Currently the HUD consists only of a basic compass.
Text compass;
compass.setFont(myFont);
compass.setColor(Color::White);
// Makes the font relatively small
compass.setCharacterSize(15);
if (_cameraAngle < PI / 4 || _cameraAngle >= 7 * PI / 4) {
compass.setString("N");
// Because the FOV is always 90 degrees. This simplies the
// placement of the center of the compass easily.
FloatRect textRect = compass.getLocalBounds();
// Sets position of text to the center.
compass.setOrigin(textRect.left + textRect.width/2.0f,
textRect.top + textRect.height/2.0f);
// Sets the compass just above the other stuff. Sets the x variation with the FOV parameter from before.
compass.setPosition(-sin(_cameraAngle) * window->getSize().x + window->getSize().x / 2.0, 11 * window->getSize().y / 25.0);
}
else if (_cameraAngle >= PI / 4 && _cameraAngle < 3 * PI / 4) {
compass.setString("E");
FloatRect textRect = compass.getLocalBounds();
compass.setOrigin(textRect.left + textRect.width/2.0f,
textRect.top + textRect.height/2.0f);
compass.setPosition(-sin(_cameraAngle - PI / 2) * window->getSize().x + window->getSize().x / 2.0, 11 * window->getSize().y / 25.0);
}
else if (_cameraAngle >= 3 * PI / 4 && _cameraAngle < 5 * PI / 4) {
compass.setString("S");
FloatRect textRect = compass.getLocalBounds();
compass.setOrigin(textRect.left + textRect.width/2.0f,
textRect.top + textRect.height/2.0f);
compass.setPosition(-sin(_cameraAngle - PI) * window->getSize().x + window->getSize().x / 2.0, 11 * window->getSize().y / 25.0);
}
else if (_cameraAngle >= 5 * PI / 4 && _cameraAngle < 7 * PI / 4) {
compass.setString("W");
FloatRect textRect = compass.getLocalBounds();
compass.setOrigin(textRect.left + textRect.width/2.0f,
textRect.top + textRect.height/2.0f);
compass.setPosition(-sin(_cameraAngle - 3 * PI / 2) * window->getSize().x + window->getSize().x / 2.0, 11 * window->getSize().y / 25.0);
}
window->draw(compass);
}
// Test cube. Rotates in 3D space. Very confusing, may cause headaches.
// Very very simple execution. Hard coded so nothing can go wrong.
// Some people can actually see that this thing is a cube. Uses very basic code.
void Flatland::draw3DRect(const float &angle) {
glPushMatrix();
glRotatef(angle * 60, 1, 0, 0);
glRotatef(angle * 20, 0, 1, 0);
glRotatef(angle * 95, 0, 0, 1);
// GL_QUADS is deprecated past OpenGL 2.0, so be warned.
glBegin(GL_QUADS);
glColor3f(0, 1, 1); //cyan
glNormal3f(0, 0, -1);
glVertex3f(-50.f, -50.f, -50.f);
glVertex3f(-50.f, 50.f, -50.f);
glVertex3f( 50.f, 50.f, -50.f);
glVertex3f( 50.f, -50.f, -50.f);
glColor3f(0, 0, 1); //blue
glNormal3f(0, 0, 1);
glVertex3f( 50.f, -50.f, 50.f);
glVertex3f( 50.f, 50.f, 50.f);
glVertex3f(-50.f, 50.f, 50.f);
glVertex3f(-50.f, -50.f, 50.f);
glColor3f(1, 0, 1); //magenta
glNormal3f(-1, 0, 0);
glVertex3f(-50.f, -50.f, 50.f);
glVertex3f(-50.f, 50.f, 50.f);
glVertex3f(-50.f, 50.f, -50.f);
glVertex3f(-50.f, -50.f, -50.f);
glColor3f(0, 1, 0); //green
glNormal3f(1, 0, 0);
glVertex3f(50.f, -50.f, -50.f);
glVertex3f(50.f, 50.f, -50.f);
glVertex3f(50.f, 50.f, 50.f);
glVertex3f(50.f, -50.f, 50.f);
glColor3f(1, 1, 0); //yellow
glNormal3f(0, -1, 0);
glVertex3f(-50.f, -50.f, 50.f);
glVertex3f(-50.f, -50.f, -50.f);
glVertex3f( 50.f, -50.f, -50.f);
glVertex3f( 50.f, -50.f, 50.f);
glColor3f(1, 0, 0); //red
glNormal3f(0, 1, 0);
glVertex3f( 50.f, 50.f, 50.f);
glVertex3f( 50.f, 50.f, -50.f);
glVertex3f(-50.f, 50.f, -50.f);
glVertex3f(-50.f, 50.f, 50.f);
glEnd();
glPopMatrix();
}