79 lines
5.7 KiB
HTML
79 lines
5.7 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Fencer Collision - Sara Gerretsen</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<script type="text/javascript" src="../shared/jquery.min.js"></script>
|
|
<link rel="stylesheet" href="../shared/style.css">
|
|
|
|
<div id="site-header">
|
|
<script>$(function(){$("#site-header").load("../shared/header.html");});</script>
|
|
</div>
|
|
</head>
|
|
<body>
|
|
<img src="../assets/fencer.png" style="width:100%">
|
|
<h1>Fencer Collision</h1>
|
|
<section class="project">
|
|
<h2>Info</h2>
|
|
<div indented>
|
|
<p>Project Type: SDL2 Toy Engine</p>
|
|
<p>Project Timeframe: November 2023</p>
|
|
</div>
|
|
<a class="git-block" href="https://git.objectionable.solutions/Sara/fencer" target="_blank">
|
|
<div class="git-logo"></div><h2>Sara/fencer.git</h2>
|
|
</a>
|
|
<h2>Project Summary</h2>
|
|
<p>
|
|
The goal of the project was to build, from theory and whitepapers, a simple 2d physics engine that can be used to make games. Mainly as a practice project to teach myself the basics of how physics engines work.
|
|
</p>
|
|
<h2>Snippets</h2>
|
|
<p>
|
|
(Linked text directs to the relevant spot in
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/branch/main/src">the code repository</a>)
|
|
</p>
|
|
<p>
|
|
The start of the project was building a 2-body arbitrary shape collision solver. For this I used the
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/commit/c3f059eeb78db6a4b60ccdbf5928ad32d3ce55b9/src/collision.c">Separating Axis Theorem</a>,
|
|
as it is relatively simple to implement.
|
|
</p>
|
|
<p>
|
|
With a working 2-body solver in hand, the next step was to implement an iterative multi-body solver. But this requires a lot more than a toy SAT implementation. So first I went and figured out world and object representations.
|
|
</p>
|
|
<h3>World Representation</h3>
|
|
<p>
|
|
Although I really like using C for quick toy examples, I had now reached the point at which I usually switch to C++, and in hindsight that would've probably been the better option. However, my recent explorations of Rust meant that I had learned of the joy of "Trait"-style polymorphism (most comparable to C++ interfaces). So I wanted to try using those in C. For this I found an approach to implementing typeclasses in C (the article for which isn't online anymore, but I explained my version over on
|
|
<a href="https://blog.winter-software.com/2024/02/22/typeclasses-in-c"> my blog</a>).
|
|
</p>
|
|
<p>
|
|
The requirements for any game object to be part of the physics world is that it has to at least implement
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/commit/c3f059eeb78db6a4b60ccdbf5928ad32d3ce55b9/src/physics_entity.h"><code>PhysicsEntity</code></a>,
|
|
which in turn requires
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/commit/c3f059eeb78db6a4b60ccdbf5928ad32d3ce55b9/src/transformable.h"><code>Transformable</code></a>
|
|
to be implemented. As solving collisions requires modifying the transform of the object.
|
|
In order to be rendered, and for the update function to be called, the object also has to implement
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/branch/main/src/behaviour_entity.h"><code>BehaviourEntity</code></a>,
|
|
which exposes the object lifetime functions spawn, update, start, and draw. And itself requires
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/branch/main/src/drop.h"><code>Drop</code></a>
|
|
to be implemented. <code>Drop</code> being pretty much the best destructor implementation you can get in C without implementing a garbage collector.
|
|
</p>
|
|
<p>
|
|
With the world represented, the work on the collision solver could start. Objects that implement <code>PhysicsEntity</code> can then register themselves with the
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/branch/main/src/physics_world.h">physics world</a>.
|
|
Once an object is registered to the physics world it will use the SAT to check for collisions, and finally, that comes to the multi-body iterative collision solver.
|
|
</p>
|
|
<img src="../assets/fencer-collisions.png" style="width:50%">
|
|
<p>
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/commit/c3f059eeb78db6a4b60ccdbf5928ad32d3ce55b9/src/physics_entity.c#L50">The iterative solver</a>
|
|
is implemented in the static functions of the <code>PhysicsEntity</code> typeclass.
|
|
</p>
|
|
<p>
|
|
This all then comes together in something like the
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/branch/archive/platformer-prototype/src/player.h"><code>Player</code></a>
|
|
struct, which implements all these typeclasses and uses them to create a platformer character. Or the
|
|
<a href="https://git.objectionable.solutions/Sara/fencer/src/branch/archive/platformer-prototype/src/tilemap.c"><code>Tilemap</code></a>
|
|
object that can be loaded from <a href="https://ldtk.io/" target="_blank">LDTK</a> levels to create a renderable physics entity that can be hit and interacted with by the player.
|
|
</p>
|
|
</section>
|
|
</body>
|
|
</html>
|