The player will be respawned, their lives decreased, and the board
cleared. The UI doesn't update, and the sudden snap to a freshly reset
board is quite jarring. The state transition to GameOver stops the game,
but there isn't anything else running in that state so it just looks
frozen.
Basically, there's a ton left to do, but technically I have handled
player ship destruction!
I actually have most of the asteroid's destruction handling system done
and found this bug.
Asteroid *assets* are selected based on the size set in the spawn event,
but the `Asteroid` Component itself was left hard-coded to the smallest
size.
The spacebar fires the gun, bullets are spawned on top of the ship with
a velocity that sends them forward (relative to the ship).
I still need a despawn mechanism, and a fire rate control. To despawn
things, I'm already planning a `Lifetime` component. For rate of fire,
an additional component will be created and attached to the player ship.
The ship in Asteroids isn't expected to spin up while holding a steering
direction, but that's exactly what I just made it do.
Fix that problem by assigning, not accumulating, the angular velocity
for the ship.
Something something quaternions are hard. I thought I would take the two
"things", add them together, and then put them back into the transform.
That's clearly not how it works :v
The rotation component is also redundant with Bevy's transform
component.
This new component and system fill the physics role, but the input
handling code needs to be updated.
Player steering still functions because it uses the `Rotation` component
to direct the force vector. The force is correctly applied to the linear
velocity vector. An improvement would be to have a force/impulse
accumulator so I could account for mass, but I'm not going to do that
right now.
Replacing the `Position` component with direct manipulation of the
transform functionally completed the TODO. The functions weren't exactly
combined, but the resulting behavior might as well have been.
I've updated the docstring to (exist, actually. yay syntax) describe the
system accurately.
The position component is redundant with the built-in Bevy Transform.
I've updated the velocity integrator to use the transform directly.
Physics still works, but things still set their initial locations
through the Position component. I'll need to fix all those call sites.
The physics sim bits (that aren't Rapier2d) are now in their own
submodule. I've included the `Wrapping` marker component because it
doesn't really have anywhere else to live, and it's kinda sorta related
to the physics. It controls the motion of objects... that's physics. :p
There are name collisions between Rapier2d's `Velocity` and my own, but
that's a problem for later. I've used more specific type paths where
necessary to maintain the previous behavior.
The `physics::Position` component can go away completely. It's just an
extra copy of some of the built-in `Transform` data. I'm pretty sure it
only exists because I didn't realize I could rely on directly
manipulating the transform when I started this project.
I've added a new `event` module to contain all the game's events (which
it does not. I'll collect them all later).
Using these events, the CollisionEvent listening system can watch for
any two colliders intersecting, check on what role they play (asteroid,
ship, bullet, etc), and re-emit an event for that specific thing. Each
component can then handle it's own destruction process.
Rapier expects to have a RigidBody attached to the entity, but I do not.
I'm not going to make one, either, because the objects in a game of
Asteroids don't need collision handling the way most games do. I just
need to know if two objects have started overlapping.
According to this: https://rapier.rs/docs/user_guides/bevy_plugin/colliders#collision-groups-and-solver-groups
only one of the two objects involved needs to have the ActiveEvents and
ActiveCollisionTypes components attached, so I've placed them on the
player ship.
I'm going to grab the Rapier physics library so that I don't have to do
my own collision detection mechanism. The last time I did this, I
simplified everything into circles. This time I'd like to have convex
hulls, particularly for the player ship.
Also the last time, I ended up rolling my own quadtree impl. I'm not
particularly interested in doing that again, and I'd like to learn more
of the broader Bevy ecosystem.
I need to close the circle down to touch the corners of the play area,
but this demonstrates the principle.
Next, I need to generate a velocity and "fix" it so that the asteroid
crosses through the viewport. I left a TODO about this, which I think
will work well enough. Although it might allow for some asteroids to
slip past, or bias the density in a funny way.
Oh well, it's just an Asteroids game.
The events are being emitted by the spawn manager, and consumed by the
spawn_asteroid system. Now to wire in the spawn properties, and then
make a good spawning manager.
I'm finally getting around to centralizing all the assets instead of
letting spawners load their own.
I'm missing some assets, which may eventually be filled by textures
instead of solid-colors and simple shapes
I also need to hook up all the functions to use this thing instead.
Not everything needs to wrap, so I'll use a marker component for the
ones that do. At the moment, I'm thinking only the player's ship will
wrap around. Asteroids can be de-spawned and re-spawned, and bullets can
simply evaporate.