conditions for boom mode
This commit is contained in:
parent
c55bcd0ee8
commit
7cb7c2e806
14
config.json
14
config.json
|
@ -14,6 +14,7 @@
|
||||||
},
|
},
|
||||||
"keys":
|
"keys":
|
||||||
{
|
{
|
||||||
|
"toggle-boom": ["CTRL", "b"]
|
||||||
},
|
},
|
||||||
"input":
|
"input":
|
||||||
{
|
{
|
||||||
|
@ -31,8 +32,17 @@
|
||||||
},
|
},
|
||||||
"sim":
|
"sim":
|
||||||
{
|
{
|
||||||
"wall-count": 48,
|
"cuckoo-time": 10.0,
|
||||||
|
"cuckoo-wall-count": 48,
|
||||||
|
"cuckoo-outer-radius": 0.75,
|
||||||
|
"cuckoo-inner-radius": 0.65,
|
||||||
"ball-scale": 0.15,
|
"ball-scale": 0.15,
|
||||||
"spawn-radius": 0.35
|
"ball-count": 3,
|
||||||
|
"spawn-radius": 0.45,
|
||||||
|
"ball-bounce-speed": 0.0005,
|
||||||
|
"ball-shaking-friction": 0.00005,
|
||||||
|
"ball-not-shaking-friction": 0.0001,
|
||||||
|
"cuckoo-pull-factor": 1.2,
|
||||||
|
"cuckoo-return-speed": 0.0075
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
lib/sb
2
lib/sb
|
@ -1 +1 @@
|
||||||
Subproject commit 7e31b5a1c00f38dbd9d667f7e4174a5341ac550f
|
Subproject commit a3fba9c38aa344e8352abc101a4410bc544afcdf
|
122
src/Pepy.cpp
122
src/Pepy.cpp
|
@ -19,9 +19,9 @@ Pepy::Pepy()
|
||||||
get_delegate().subscribe(&Pepy::respond, this, SDL_MOUSEBUTTONDOWN);
|
get_delegate().subscribe(&Pepy::respond, this, SDL_MOUSEBUTTONDOWN);
|
||||||
get_delegate().subscribe(&Pepy::respond, this, SDL_MOUSEBUTTONUP);
|
get_delegate().subscribe(&Pepy::respond, this, SDL_MOUSEBUTTONUP);
|
||||||
/* create a glowing ring */
|
/* create a glowing ring */
|
||||||
int point_count = configuration()["sim"]["wall-count"].get<int>() + 1;
|
int point_count = configuration()["sim"]["cuckoo-wall-count"].get<int>() + 1;
|
||||||
std::vector<glm::vec2> outer_points = sb::points_on_circle(point_count, 0.75f, {0.0f, 0.0f});
|
std::vector<glm::vec2> outer_points = sb::points_on_circle(point_count, configuration()["sim"]["cuckoo-outer-radius"], {0.0f, 0.0f});
|
||||||
std::vector<glm::vec2> inner_points = sb::points_on_circle(point_count, 0.65f, {0.0f, 0.0f});
|
std::vector<glm::vec2> inner_points = sb::points_on_circle(point_count, configuration()["sim"]["cuckoo-inner-radius"], {0.0f, 0.0f});
|
||||||
float inner_saturation = 0.1f;
|
float inner_saturation = 0.1f;
|
||||||
float inner_value = 1.0f;
|
float inner_value = 1.0f;
|
||||||
float outer_saturation = 1.0f;
|
float outer_saturation = 1.0f;
|
||||||
|
@ -43,15 +43,13 @@ Pepy::Pepy()
|
||||||
cuckoo["color"]->add(glm::rgbColor(glm::vec3(next / static_cast<float>(point_count) * 255.0f, inner_saturation, inner_value)));
|
cuckoo["color"]->add(glm::rgbColor(glm::vec3(next / static_cast<float>(point_count) * 255.0f, inner_saturation, inner_value)));
|
||||||
cuckoo["color"]->add(glm::rgbColor(glm::vec3(next / static_cast<float>(point_count) * 255.0f, outer_saturation, outer_value)));
|
cuckoo["color"]->add(glm::rgbColor(glm::vec3(next / static_cast<float>(point_count) * 255.0f, outer_saturation, outer_value)));
|
||||||
}
|
}
|
||||||
/* create balls */
|
/* Create the playing balls */
|
||||||
float size = configuration()["sim"]["ball-scale"];
|
for (std::size_t ball_ii = 0; ball_ii < configuration()["sim"]["ball-count"]; ball_ii++)
|
||||||
auto spawn_points = sb::points_on_circle(5, configuration()["sim"]["spawn-radius"]);
|
|
||||||
for (auto spawn_point : spawn_points)
|
|
||||||
{
|
{
|
||||||
Plane ball;
|
Plane ball;
|
||||||
ball.transformation(glm::translate(glm::vec3{spawn_point.x, spawn_point.y, 1.0f}) * glm::scale(glm::vec3{size, size, 1.0f}));
|
|
||||||
wad.push_back(std::pair{ball, glm::vec2{0.0f, 0.0f}});
|
wad.push_back(std::pair{ball, glm::vec2{0.0f, 0.0f}});
|
||||||
}
|
}
|
||||||
|
situate_balls();
|
||||||
background.transformation(glm::scale(glm::vec3{5.0f, 5.0f, 1.0f}));
|
background.transformation(glm::scale(glm::vec3{5.0f, 5.0f, 1.0f}));
|
||||||
/* load Open GL */
|
/* load Open GL */
|
||||||
load_gl_context();
|
load_gl_context();
|
||||||
|
@ -59,7 +57,7 @@ Pepy::Pepy()
|
||||||
sb::Texture wad_texture {"resource/wad.png"};
|
sb::Texture wad_texture {"resource/wad.png"};
|
||||||
wad_texture.load();
|
wad_texture.load();
|
||||||
/* Apply the wad texture to each wad */
|
/* Apply the wad texture to each wad */
|
||||||
for (size_t wad_ii = 0; wad_ii < wad.size(); wad_ii++)
|
for (std::size_t wad_ii = 0; wad_ii < wad.size(); wad_ii++)
|
||||||
{
|
{
|
||||||
wad[wad_ii].first.texture(wad_texture);
|
wad[wad_ii].first.texture(wad_texture);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +66,17 @@ Pepy::Pepy()
|
||||||
background.texture(texture);
|
background.texture(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create GL context via super class and load vertices, UV data, and shaders */
|
void Pepy::situate_balls()
|
||||||
|
{
|
||||||
|
float size = configuration()["sim"]["ball-scale"];
|
||||||
|
auto spawn_points = sb::points_on_circle(wad.size(), configuration()["sim"]["spawn-radius"]);
|
||||||
|
int ii = 0;
|
||||||
|
for (auto& ball : wad)
|
||||||
|
{
|
||||||
|
ball.first.transformation(glm::translate(glm::vec3{spawn_points[ii].x, spawn_points[ii++].y, 1.0f}) * glm::scale(glm::vec3{size, size, 1.0f}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Pepy::load_gl_context()
|
void Pepy::load_gl_context()
|
||||||
{
|
{
|
||||||
super::load_gl_context();
|
super::load_gl_context();
|
||||||
|
@ -115,24 +123,41 @@ void Pepy::respond(SDL_Event& event)
|
||||||
{
|
{
|
||||||
/* Will check if reset should be triggered */
|
/* Will check if reset should be triggered */
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
|
if (Delegate::compare(event, "toggle-boom"))
|
||||||
|
{
|
||||||
|
boom = !boom;
|
||||||
|
}
|
||||||
/* Check for any direction key when waiting to reset */
|
/* Check for any direction key when waiting to reset */
|
||||||
if (stopped && delegate.compare(event, {"up", "down", "left", "right"}))
|
if (stopped && delegate.compare(event, {"up", "down", "left", "right"}))
|
||||||
{
|
{
|
||||||
reset = true;
|
reset = true;
|
||||||
}
|
}
|
||||||
/* Check mouse buttons for grabbing */
|
/* Check mouse buttons to initiate grabbing, thrusting, or reset */
|
||||||
if (event.type == SDL_MOUSEBUTTONDOWN)
|
if (event.type == SDL_MOUSEBUTTONDOWN)
|
||||||
{
|
{
|
||||||
if (shaking)
|
if (shaking)
|
||||||
|
{
|
||||||
|
/* In regular mode, a mouse click means grab the cuckoo */
|
||||||
|
if (!boom)
|
||||||
{
|
{
|
||||||
grabbed = true;
|
grabbed = true;
|
||||||
}
|
}
|
||||||
|
/* In BOOM mode, a mouse click means to thrust the cuckoo */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Point cuckoo in the direction of the mouse click relative to the center of the screen. Set the velocity to
|
||||||
|
* maximum so the cuckoo immediately moves in the calculated direction. */
|
||||||
|
cuckoo_velocity.x = sb::angle_between({0.0f, 0.0f}, mouse_ndc());
|
||||||
|
cuckoo_velocity.y = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Mouse button will trigger reset when game is waiting to reset */
|
/* Mouse button will trigger reset when game is waiting to reset */
|
||||||
else if (stopped)
|
else if (stopped)
|
||||||
{
|
{
|
||||||
reset = true;
|
reset = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Ungrab is the only thing mouse up does */
|
||||||
else if (event.type == SDL_MOUSEBUTTONUP && shaking)
|
else if (event.type == SDL_MOUSEBUTTONUP && shaking)
|
||||||
{
|
{
|
||||||
grabbed = false;
|
grabbed = false;
|
||||||
|
@ -140,23 +165,27 @@ void Pepy::respond(SDL_Event& event)
|
||||||
/* Reset to cuckoo time */
|
/* Reset to cuckoo time */
|
||||||
if (reset)
|
if (reset)
|
||||||
{
|
{
|
||||||
float size = configuration()["sim"]["ball-scale"];
|
situate_balls();
|
||||||
auto spawn_points = sb::points_on_circle(5, configuration()["sim"]["spawn-radius"]);
|
|
||||||
int ii = 0;
|
|
||||||
for (auto& ball : wad)
|
|
||||||
{
|
|
||||||
ball.first.transformation(glm::translate(glm::vec3{spawn_points[ii].x, spawn_points[ii++].y, 1.0f}) * glm::scale(glm::vec3{size, size, 1.0f}));
|
|
||||||
}
|
|
||||||
stopped = false;
|
stopped = false;
|
||||||
shaking = true;
|
shaking = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update state and draw the screen */
|
glm::vec2 Pepy::mouse_ndc()
|
||||||
|
{
|
||||||
|
glm::ivec2 mouse_pixel;
|
||||||
|
SDL_GetMouseState(&mouse_pixel.x, &mouse_pixel.y);
|
||||||
|
return {
|
||||||
|
static_cast<float>(mouse_pixel.x) / window_box().width() * 2.0f - 1.0f,
|
||||||
|
(1.0f - static_cast<float>(mouse_pixel.y) / window_box().height()) * 2.0f - 1.0f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void Pepy::update()
|
void Pepy::update()
|
||||||
{
|
{
|
||||||
/* number of seconds running */
|
/* number of seconds running */
|
||||||
time_seconds = SDL_GetTicks() / 1000.0f;
|
time_seconds = SDL_GetTicks() / 1000.0f;
|
||||||
|
/* Move countdown along during the shaking phase */
|
||||||
if (shaking)
|
if (shaking)
|
||||||
{
|
{
|
||||||
countdown -= last_frame_length / 1000.0f;
|
countdown -= last_frame_length / 1000.0f;
|
||||||
|
@ -164,20 +193,23 @@ void Pepy::update()
|
||||||
{
|
{
|
||||||
shaking = false;
|
shaking = false;
|
||||||
flying = true;
|
flying = true;
|
||||||
countdown = 10.0f;
|
countdown = configuration()["sim"]["cuckoo-time"];
|
||||||
|
/* During a BOOM shake, freeze motion at the release point. */
|
||||||
|
if (boom)
|
||||||
|
{
|
||||||
|
for (auto& ball : wad)
|
||||||
|
{
|
||||||
|
ball.second.y = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* move cuckoo with mouse */
|
}
|
||||||
|
}
|
||||||
|
/* Move cuckoo with mouse */
|
||||||
if (grabbed && shaking)
|
if (grabbed && shaking)
|
||||||
{
|
{
|
||||||
/* get mouse coordinates in NDC */
|
glm::vec2 ndc = mouse_ndc();
|
||||||
SDL_GetMouseState(&mouse_pixel.x, &mouse_pixel.y);
|
cuckoo_offset.x += weight(ndc.x / 20.0f) * std::max(std::min(std::abs(1.0f - cuckoo_offset.x), 1.0f), 0.1f);
|
||||||
glm::vec2 mouse_ndc {
|
cuckoo_offset.y += weight(ndc.y / 20.0f) * std::max(std::min(std::abs(1.0f - cuckoo_offset.y), 1.0f), 0.1f);
|
||||||
static_cast<float>(mouse_pixel.x) / window_box().width() * 2.0f - 1.0f,
|
|
||||||
(1.0f - static_cast<float>(mouse_pixel.y) / window_box().height()) * 2.0f - 1.0f
|
|
||||||
};
|
|
||||||
cuckoo_offset.x += weight(mouse_ndc.x / 20.0f) * std::max(std::min(std::abs(1.0f - cuckoo_offset.x), 1.0f), 0.1f);
|
|
||||||
cuckoo_offset.y += weight(mouse_ndc.y / 20.0f) * std::max(std::min(std::abs(1.0f - cuckoo_offset.y), 1.0f), 0.1f);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -230,9 +262,22 @@ void Pepy::update()
|
||||||
cuckoo_offset.x -= motion;
|
cuckoo_offset.x -= motion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cuckoo_offset.x -= weight(glm::sign(cuckoo_offset).x * return_speed);
|
cuckoo_offset.x -= weight(glm::sign(cuckoo_offset).x * configuration()["sim"]["cuckoo-return-speed"].get<float>());
|
||||||
cuckoo_offset.y -= weight(glm::sign(cuckoo_offset).y * return_speed);
|
cuckoo_offset.y -= weight(glm::sign(cuckoo_offset).y * configuration()["sim"]["cuckoo-return-speed"].get<float>());
|
||||||
|
/* In regular mode, apply the cuckoo offset */
|
||||||
|
if (!boom)
|
||||||
|
{
|
||||||
cuckoo.transformation(glm::translate(cuckoo_offset));
|
cuckoo.transformation(glm::translate(cuckoo_offset));
|
||||||
|
}
|
||||||
|
/* In boom mode, apply the cuckoo velocity */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Retract */
|
||||||
|
cuckoo_velocity.y = std::max(0.0f, cuckoo_velocity.y - weight(0.01f));
|
||||||
|
/* Change velocity to offset */
|
||||||
|
glm::vec2 delta = sb::velocity_to_delta(cuckoo_velocity);
|
||||||
|
cuckoo.transformation(glm::translate(glm::vec3{delta.x, delta.y, 0.0f}));
|
||||||
|
}
|
||||||
hue_offset += weight(0.002f);
|
hue_offset += weight(0.002f);
|
||||||
glm::vec2 x_range = {-1.0f, 1.0f};
|
glm::vec2 x_range = {-1.0f, 1.0f};
|
||||||
glm::vec2 y_range = {-1.0f, 1.0f};
|
glm::vec2 y_range = {-1.0f, 1.0f};
|
||||||
|
@ -246,11 +291,18 @@ void Pepy::update()
|
||||||
if (shaking)
|
if (shaking)
|
||||||
{
|
{
|
||||||
/* The ball will bounce back toward the center of the cuckoo if it's a certain distance away from it. */
|
/* The ball will bounce back toward the center of the cuckoo if it's a certain distance away from it. */
|
||||||
if (distance > 0.65f)
|
if (distance > configuration()["sim"]["cuckoo-inner-radius"])
|
||||||
{
|
{
|
||||||
/* Calculate the angle of the ball and add speed. */
|
/* Calculate the angle of the ball and add speed. */
|
||||||
ball.second.x = sb::angle_between(ball_center, cuckoo_center);
|
ball.second.x = sb::angle_between(ball_center, cuckoo_center);
|
||||||
ball.second.y += 0.0005f;
|
if (!boom)
|
||||||
|
{
|
||||||
|
ball.second.y += configuration()["sim"]["ball-bounce-speed"].get<float>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ball.second.y += cuckoo_velocity.y * std::abs(sb::angle_ratio(ball.second.x, cuckoo_velocity.x)) * 0.1f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glm::vec2 step = sb::velocity_to_delta(ball.second);
|
glm::vec2 step = sb::velocity_to_delta(ball.second);
|
||||||
|
@ -260,11 +312,11 @@ void Pepy::update()
|
||||||
float friction;
|
float friction;
|
||||||
if (shaking)
|
if (shaking)
|
||||||
{
|
{
|
||||||
friction = 0.00005f;
|
friction = configuration()["sim"]["ball-shaking-friction"];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
friction = 0.0001f;
|
friction = configuration()["sim"]["ball-not-shaking-friction"];
|
||||||
}
|
}
|
||||||
ball.second.y = std::max(0.0f, ball.second.y - friction);
|
ball.second.y = std::max(0.0f, ball.second.y - friction);
|
||||||
}
|
}
|
||||||
|
|
26
src/Pepy.hpp
26
src/Pepy.hpp
|
@ -59,22 +59,40 @@ private:
|
||||||
/* Convention for calling parent class in a consistent way across classes */
|
/* Convention for calling parent class in a consistent way across classes */
|
||||||
typedef Game super;
|
typedef Game super;
|
||||||
|
|
||||||
bool shaking = true, flying = false, stopped = false;
|
bool shaking = true, flying = false, stopped = false, boom = false, grabbed = false;
|
||||||
sb::VAO cuckoo_vao, wad_vao;
|
sb::VAO cuckoo_vao, wad_vao;
|
||||||
sb::VBO vbo;
|
sb::VBO vbo;
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
Model cuckoo;
|
Model cuckoo;
|
||||||
std::vector<std::pair<Plane, glm::vec2>> wad;
|
std::vector<std::pair<Plane, glm::vec2>> wad;
|
||||||
std::map<std::string, GLuint> uniform;
|
std::map<std::string, GLuint> uniform;
|
||||||
float hue_offset = 0.0f, time_seconds = 0.0f, aspect_ratio = 1.0f, return_speed = 0.0075f, cuckoo_speed = 0.0f, countdown = 10.0f;
|
float hue_offset = 0.0f, time_seconds = 0.0f, aspect_ratio = 1.0f, cuckoo_speed = 0.0f,
|
||||||
|
countdown = configuration()["sim"]["cuckoo-time"];
|
||||||
glm::mat4 orthographic_projection {1};
|
glm::mat4 orthographic_projection {1};
|
||||||
glm::vec3 cuckoo_offset {0.0f, 0.0f, 0.0f};
|
glm::vec3 cuckoo_offset {0.0f, 0.0f, 0.0f};
|
||||||
glm::vec2 cuckoo_velocity {0.0f, 0.0f};
|
glm::vec2 cuckoo_velocity {0.0f, 0.0f};
|
||||||
bool grabbed = false;
|
|
||||||
glm::ivec2 mouse_pixel = {0, 0};
|
|
||||||
Plane background;
|
Plane background;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Situate the balls in their starting position. Useful for reseting to initial state.
|
||||||
|
*/
|
||||||
|
void situate_balls();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Call the Game class's GL load functions then load graphics (vertices, UVs, shaders, buffers, uniforms) into OpenGL.
|
||||||
|
*/
|
||||||
void load_gl_context();
|
void load_gl_context();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get current mouse coordinates as NDC.
|
||||||
|
*
|
||||||
|
* @return vector of X/Y coordinates of current mouse position
|
||||||
|
*/
|
||||||
|
glm::vec2 mouse_ndc();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Update state and draw the screen.
|
||||||
|
*/
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue