One-way collisions are working.

This commit is contained in:
Kapendev 2025-02-18 13:53:00 +02:00
parent 197a9f48ba
commit 767dd82ab2
3 changed files with 61 additions and 11 deletions

View file

@ -84,3 +84,16 @@ sudo pacman -S alsa-lib mesa libx11 libxrandr libxi libxcursor libxinerama
Start with the [examples](./examples/) folder or the [cheatsheet](https://kapendev.github.io/parin-website/pages/cheatsheet.html) for a quick overview.
For more details, check the [tour](https://kapendev.github.io/parin-website/pages/tour.html) page.
## Building Without DUB
Parin has the following dependencies:
* [Joka](https://github.com/Kapendev/joka)
* [raylib](https://github.com/raysan5/raylib)
To create a simple one-file game, run something like:
```cmd
dmd -i -Ijoka/source -Iparin/source -Jparin/assets -L-L. -L-lraylib app.d
```

View file

@ -8,7 +8,7 @@
// TODO: Update all the doc comments here.
// TODO: Add spatial partitioning after testing this in a game.
// TODO: Add simple jump-through walls. No idea how, so this will have to wait.
// TODO: Add one-way collision support for moving walls.
// NOTE: Maybe a world pixel size value could be useful.
/// The `platformer` module provides a pixel-perfect physics engine.
@ -24,6 +24,7 @@ import joka.types;
alias BaseBoxId = int;
alias ActorBoxId = BaseBoxId;
alias WallBoxId = BaseBoxId;
alias OneWaySide = RideSide;
enum RideSide : ubyte {
none,
@ -168,6 +169,7 @@ struct Box {
struct WallBoxProperties {
Vec2 remainder;
OneWaySide oneWaySide;
bool isPassable;
}
@ -224,9 +226,10 @@ struct BoxWorld {
return actorsProperties[id - 1];
}
WallBoxId appendWall(Box box) {
WallBoxId appendWall(Box box, OneWaySide oneWaySide = OneWaySide.none) {
walls.append(box);
wallsProperties.append(WallBoxProperties());
wallsProperties[$ - 1].oneWaySide = oneWaySide;
return cast(BaseBoxId) walls.length;
}
@ -280,6 +283,25 @@ struct BoxWorld {
while (move != 0) {
auto tempBox = Box(actor.position + IVec2(moveSign, 0), actor.size);
auto wallId = hasWallCollision(tempBox);
if (wallId) {
// One way stuff.
auto wall = &getWall(wallId);
auto wallProperties = &getWallProperties(wallId);
final switch (wallProperties.oneWaySide) with (OneWaySide) {
case none:
break;
case top:
case bottom:
wallId = 0;
break;
case left:
if (wall.position.x < actor.position.x || wall.hasIntersection(*actor)) wallId = 0;
break;
case right:
if (wall.position.x > actor.position.x || wall.hasIntersection(*actor)) wallId = 0;
break;
}
}
if (!properties.isPassable && wallId) {
return wallId;
} else {
@ -315,6 +337,25 @@ struct BoxWorld {
while (move != 0) {
auto tempBox = Box(actor.position + IVec2(0, moveSign), actor.size);
auto wallId = hasWallCollision(tempBox);
if (wallId) {
// One way stuff.
auto wall = &getWall(wallId);
auto wallProperties = &getWallProperties(wallId);
final switch (wallProperties.oneWaySide) with (OneWaySide) {
case none:
break;
case left:
case right:
wallId = 0;
break;
case top:
if (wall.position.y < actor.position.y || wall.hasIntersection(*actor)) wallId = 0;
break;
case bottom:
if (wall.position.y > actor.position.y || wall.hasIntersection(*actor)) wallId = 0;
break;
}
}
if (!properties.isPassable && wallId) {
return wallId;
} else {
@ -393,6 +434,11 @@ struct BoxWorld {
auto properties = &getWallProperties(id);
properties.remainder += amount;
// NOTE: Will be removed when I want to work on that...
if (properties.oneWaySide) {
assert(0, "One-way collisions are not yet supported for moving walls.");
}
squishedIdsBuffer.clear();
auto move = properties.remainder.round().toIVec();
if (move.x != 0 || move.y != 0) {

View file

@ -9,9 +9,6 @@
/// The `rayib` module provides access to the raylib.h functions.
module parin.rl.raylib;
import joka.traits;
import joka.types;
@nogc nothrow extern(C):
enum RAYLIB_VERSION_MAJOR = 5;
@ -55,8 +52,6 @@ struct Vector2
{
float x = 0.0f; // Vector x component
float y = 0.0f; // Vector y component
mixin addXyzwOps!(float, 2);
}
// Vector3, 3 components
@ -65,8 +60,6 @@ struct Vector3
float x = 0.0f; // Vector x component
float y = 0.0f; // Vector y component
float z = 0.0f; // Vector z component
mixin addXyzwOps!(float, 3);
}
// Vector4, 4 components
@ -76,8 +69,6 @@ struct Vector4
float y = 0.0f; // Vector y component
float z = 0.0f; // Vector z component
float w = 0.0f; // Vector w component
mixin addXyzwOps!(float, 4);
}
// Quaternion, 4 components (Vector4 alias)