examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

commit feb37900a804a5727cab6165bf3d35f47dade0f6
parent 4a5ddc7c624231f99e97c6810a08c3ffb3d307fa
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Thu,  7 Apr 2022 23:31:22 +0100

gl-asteroids: Add powerups

Diffstat:
Msrc/gl-asteroids.cpp | 50++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/src/gl-asteroids.cpp b/src/gl-asteroids.cpp @@ -8,6 +8,7 @@ #include <algorithm> #include <thread> #include <chrono> +#include <optional> struct coord { @@ -47,6 +48,7 @@ coord const rockv3[] = {{0, 0}, {1, 0}, {.7,.4}, {0, 1}, {-.8,.6}, {-1, 0}, {-.6 coord const rockv4[] = {{0, 0}, {1, 0}, {.6,.4}, {0, .5}, {-.3,.6}, {-1, 0}, {-.6,-.5}, {0, -1}, {1, 0}}; color const rockc[] = {{.5,.5,.5}, {.2,.2,.2}}; +color const powerupc[] = {{.2,.4,.8}, {.1,.2,.4}}; coord const bulletv[] = {{0, 1}, {.25, .25}, {-.25, .25}, {.25, -1}, {-.25, -1}}; color const bulletc[] = {{.0,.8,.0}, {.0,.4,.0}, {.0,.4,.0}, {.0,.0,.0}}; @@ -60,6 +62,7 @@ visual rock1{GL_TRIANGLE_FAN, rockv1, rockc}; visual rock2{GL_TRIANGLE_FAN, rockv2, rockc}; visual rock3{GL_TRIANGLE_FAN, rockv3, rockc}; visual rock4{GL_TRIANGLE_FAN, rockv4, rockc}; +visual powerup{GL_TRIANGLE_FAN, rockv1, powerupc}; std::array<visual const*, 4> rock_types = {&rock1, &rock2, &rock3, &rock4}; float wrap(float n, float min, float max) @@ -241,6 +244,7 @@ bool is_pressed(int key) std::vector<entity> rocks; std::vector<entity> bullets; +std::optional<entity> powerups; physics s{{}, {}, 0.f, 0.f, .06f}; bool up = false; @@ -260,6 +264,8 @@ void draw_scene(float t) r.draw(); for (auto& b : bullets) b.draw(); + if (powerups) + powerups->draw(); if (up) { @@ -287,6 +293,7 @@ int main(int argc, char* argv[]) { signed score = 0; unsigned ammo = 10; + float firerate = 2; std::random_device rd; std::default_random_engine gen(rd()); @@ -304,7 +311,7 @@ int main(int argc, char* argv[]) float last_t = glfwGetTime(); - float rock_time = 1, bullet_time = 0, ammo_refill_time = .3; + float rock_time = 1, bullet_time = 0, ammo_refill_time = .3, powerup_time = 10; for (auto& c : starsv) c.x = dis_p(gen), c.y = dis_p(gen); @@ -324,7 +331,7 @@ int main(int argc, char* argv[]) coord p = {dis_p(gen) / 2 - .5f, -1 - scale}; coord v(dis_v(gen), dis_v(gen)); - v *= log(t+1); + v *= 1+log(t+1); if (dir & 1) v.x = -v.x, p.x = -p.x; @@ -339,6 +346,26 @@ int main(int argc, char* argv[]) rocks.emplace_back(random_rock_visual(), physics{p, v, 0, dis_a(gen), scale}); } + if (powerup_time < t) + { + powerup_time += 15; + int dir = dis_d(gen); + auto scale = .03f; + coord p = {dis_p(gen) / 2 - .5f, -1 - scale}; + coord v = {0, .3f}; + if (dir & 1) + v.x = -v.x, p.x = -p.x; + if (dir & 2) + p.y = -p.y, v.y = -v.y; + if (dir & 4) + { + std::swap(p.x, p.y); + std::swap(v.x, v.y); + } + + powerups.emplace(powerup, physics{p, v, 0, 0, scale}); + } + if (ammo < 20 && ammo_refill_time < t) { ++ammo; @@ -348,7 +375,7 @@ int main(int argc, char* argv[]) if (is_pressed(GLFW_KEY_SPACE) && bullet_time < t && ammo) { --ammo; - bullet_time = t + .15f; + bullet_time = t + 1/firerate; bullets.emplace_back(bullet, s); auto& b = bullets.back().p; @@ -364,7 +391,7 @@ int main(int argc, char* argv[]) int kr = is_pressed(GLFW_KEY_RIGHT); if (kl ^ kr) - s.ang_mom = kr ? 2 : -2; + s.ang_mom = (kr ? 1 : -1) * (up ? 3 : 2); else s.ang_mom = 0; @@ -382,6 +409,8 @@ int main(int argc, char* argv[]) r.p.move(dt); for (auto& b : bullets) b.p.move(dt); + if (powerups) + powerups->p.move(dt); s.move(dt); s.wrap_pos(); @@ -430,6 +459,13 @@ int main(int argc, char* argv[]) bang: continue; } + if (powerups && is_colliding(s, powerups->p)) + { + powerups.reset(); + score += 10; + ++firerate; + } + if(any_of(rocks.begin(), rocks.end(), [](auto& r) { return is_colliding(s, r.p); })) { using namespace std::chrono_literals; @@ -444,6 +480,12 @@ int main(int argc, char* argv[]) score -= std::erase_if(bullets, [](auto const& e) { return e.p.left_arena(); }); score -= std::erase_if(rocks, [](auto const& e) { return e.p.left_arena(); }); + if (powerups && powerups->p.left_arena()) + { + powerups.reset(); + --score; + } + draw_scene(t); }