commit feb37900a804a5727cab6165bf3d35f47dade0f6
parent 4a5ddc7c624231f99e97c6810a08c3ffb3d307fa
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Thu, 7 Apr 2022 23:31:22 +0100
gl-asteroids: Add powerups
Diffstat:
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);
}