mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-25 20:49:57 +03:00
Some fixes and can check area for boxes.
This commit is contained in:
parent
e8afbd08e8
commit
502498919c
3 changed files with 104 additions and 42 deletions
|
@ -3,9 +3,9 @@
|
|||
import parin;
|
||||
|
||||
auto world = BoxWorld();
|
||||
auto platformBoxId = WallId();
|
||||
auto groundBoxId = WallId();
|
||||
auto playerBoxId = ActorId();
|
||||
auto platformBoxId = WallBoxId();
|
||||
auto groundBoxId = WallBoxId();
|
||||
auto playerBoxId = ActorBoxId();
|
||||
auto playerMover = BoxMover(2, 4, 0.3, 1);
|
||||
auto groundY = 140;
|
||||
|
||||
|
|
|
@ -315,7 +315,13 @@ struct TextureId {
|
|||
|
||||
/// Retrieves the texture associated with the resource identifier.
|
||||
ref Texture get() {
|
||||
if (!isValid) assert(0, "Index `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
if (!isValid) {
|
||||
if (data) {
|
||||
assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
} else {
|
||||
assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
}
|
||||
return engineState.textures[GenerationalIndex(data.value - 1, data.generation)];
|
||||
}
|
||||
|
||||
|
@ -326,7 +332,7 @@ struct TextureId {
|
|||
|
||||
/// Frees the resource associated with the identifier.
|
||||
void free() {
|
||||
if (isValid) engineState.textures.remove(data);
|
||||
if (isValid) engineState.textures.remove(GenerationalIndex(data.value - 1, data.generation));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,7 +420,13 @@ struct FontId {
|
|||
|
||||
/// Retrieves the font associated with the resource identifier.
|
||||
ref Font get() {
|
||||
if (!isValid) assert(0, "Index `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
if (!isValid) {
|
||||
if (data) {
|
||||
assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
} else {
|
||||
assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
}
|
||||
return engineState.fonts[GenerationalIndex(data.value - 1, data.generation)];
|
||||
}
|
||||
|
||||
|
@ -425,7 +437,7 @@ struct FontId {
|
|||
|
||||
/// Frees the resource associated with the identifier.
|
||||
void free() {
|
||||
if (isValid) engineState.fonts.remove(data);
|
||||
if (isValid) engineState.fonts.remove(GenerationalIndex(data.value - 1, data.generation));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -574,7 +586,13 @@ struct SoundId {
|
|||
|
||||
/// Retrieves the sound associated with the resource identifier.
|
||||
ref Sound get() {
|
||||
if (!isValid) assert(0, "Index `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
if (!isValid) {
|
||||
if (data) {
|
||||
assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
} else {
|
||||
assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
}
|
||||
return engineState.sounds[GenerationalIndex(data.value - 1, data.generation)];
|
||||
}
|
||||
|
||||
|
@ -585,7 +603,7 @@ struct SoundId {
|
|||
|
||||
/// Frees the resource associated with the identifier.
|
||||
void free() {
|
||||
if (isValid) engineState.sounds.remove(data);
|
||||
if (isValid) engineState.sounds.remove(GenerationalIndex(data.value - 1, data.generation));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,14 +13,16 @@
|
|||
/// The `platformer` module provides a pixel-perfect physics engine.
|
||||
module parin.platformer;
|
||||
|
||||
import joka.ascii;
|
||||
import joka.containers;
|
||||
import joka.math;
|
||||
import joka.types;
|
||||
|
||||
@safe @nogc nothrow:
|
||||
|
||||
alias ActorId = Sz;
|
||||
alias WallId = Sz;
|
||||
alias BaseBoxId = int;
|
||||
alias ActorBoxId = BaseBoxId;
|
||||
alias WallBoxId = BaseBoxId;
|
||||
|
||||
enum RideSide : ubyte {
|
||||
none,
|
||||
|
@ -156,6 +158,11 @@ struct Box {
|
|||
position.y < area.position.y + area.size.y
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a string representation with a limited lifetime.
|
||||
IStr toStr() {
|
||||
return "({}, {}, {}, {})".format(position.x, position.y, size.x, size.y);
|
||||
}
|
||||
}
|
||||
|
||||
struct WallBoxProperties {
|
||||
|
@ -175,56 +182,93 @@ struct BoxWorld {
|
|||
List!Box actors;
|
||||
List!WallBoxProperties wallsProperties;
|
||||
List!ActorBoxProperties actorsProperties;
|
||||
List!ActorId squishedIdsBuffer;
|
||||
List!ActorBoxId squishedIdsBuffer;
|
||||
List!BaseBoxId collisionIdsBuffer;
|
||||
|
||||
@safe @nogc nothrow:
|
||||
|
||||
ref Box getWall(WallId id) {
|
||||
ref Box getWall(WallBoxId id) {
|
||||
if (id <= 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > walls.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
return walls[id - 1];
|
||||
}
|
||||
|
||||
ref Box getActor(ActorId id) {
|
||||
ref Box getActor(ActorBoxId id) {
|
||||
if (id <= 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > actors.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
return actors[id - 1];
|
||||
}
|
||||
|
||||
ref WallBoxProperties getWallProperties(WallId id) {
|
||||
ref WallBoxProperties getWallProperties(WallBoxId id) {
|
||||
if (id <= 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > wallsProperties.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
return wallsProperties[id - 1];
|
||||
}
|
||||
|
||||
ref ActorBoxProperties getActorProperties(ActorId id) {
|
||||
ref ActorBoxProperties getActorProperties(ActorBoxId id) {
|
||||
if (id <= 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > actorsProperties.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
return actorsProperties[id - 1];
|
||||
}
|
||||
|
||||
WallId appendWall(Box box) {
|
||||
WallBoxId appendWall(Box box) {
|
||||
walls.append(box);
|
||||
wallsProperties.append(WallBoxProperties());
|
||||
return walls.length;
|
||||
return cast(BaseBoxId) walls.length;
|
||||
}
|
||||
|
||||
ActorId appendActor(Box box, RideSide rideSide = RideSide.none) {
|
||||
ActorBoxId appendActor(Box box, RideSide rideSide = RideSide.none) {
|
||||
actors.append(box);
|
||||
actorsProperties.append(ActorBoxProperties());
|
||||
actorsProperties[$ - 1].rideSide = rideSide;
|
||||
return actors.length;
|
||||
return cast(BaseBoxId) actors.length;
|
||||
}
|
||||
|
||||
WallId hasWallCollision(Box box) {
|
||||
WallBoxId hasWallCollision(Box box) {
|
||||
foreach (i, wall; walls) {
|
||||
if (wall.hasIntersection(box) && !wallsProperties[i].isPassable) return i + 1;
|
||||
if (wall.hasIntersection(box) && !wallsProperties[i].isPassable) return cast(BaseBoxId) (i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ActorId hasActorCollision(Box box) {
|
||||
ActorBoxId hasActorCollision(Box box) {
|
||||
foreach (i, actor; actors) {
|
||||
if (actor.hasIntersection(box) && !actorsProperties[i].isPassable) return i + 1;
|
||||
if (actor.hasIntersection(box) && !actorsProperties[i].isPassable) return cast(BaseBoxId) (i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WallId moveActorX(ActorId id, float amount) {
|
||||
auto actor = &actors[id - 1];
|
||||
auto properties = &actorsProperties[id - 1];
|
||||
WallBoxId[] getWallCollisions(Box box) {
|
||||
collisionIdsBuffer.clear();
|
||||
foreach (i, wall; walls) {
|
||||
if (wall.hasIntersection(box) && !wallsProperties[i].isPassable) collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
}
|
||||
return collisionIdsBuffer[];
|
||||
}
|
||||
|
||||
ActorBoxId[] getActorCollisions(Box box) {
|
||||
collisionIdsBuffer.clear();
|
||||
foreach (i, actor; actors) {
|
||||
if (actor.hasIntersection(box) && !actorsProperties[i].isPassable) collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
}
|
||||
return collisionIdsBuffer[];
|
||||
}
|
||||
|
||||
WallBoxId moveActorX(ActorBoxId id, float amount) {
|
||||
auto actor = &getActor(id);
|
||||
auto properties = &getActorProperties(id);
|
||||
properties.remainder.x += amount;
|
||||
|
||||
auto move = cast(int) properties.remainder.x.round();
|
||||
|
@ -245,9 +289,9 @@ struct BoxWorld {
|
|||
return 0;
|
||||
}
|
||||
|
||||
WallId moveActorY(ActorId id, float amount) {
|
||||
auto actor = &actors[id - 1];
|
||||
auto properties = &actorsProperties[id - 1];
|
||||
WallBoxId moveActorY(ActorBoxId id, float amount) {
|
||||
auto actor = &getActor(id);
|
||||
auto properties = &getActorProperties(id);
|
||||
properties.remainder.y += amount;
|
||||
|
||||
auto move = cast(int) properties.remainder.y.round();
|
||||
|
@ -268,24 +312,24 @@ struct BoxWorld {
|
|||
return 0;
|
||||
}
|
||||
|
||||
IVec2 moveActor(ActorId id, Vec2 amount) {
|
||||
IVec2 moveActor(ActorBoxId id, Vec2 amount) {
|
||||
auto result = IVec2();
|
||||
result.x = cast(int) moveActorX(id, amount.x);
|
||||
result.y = cast(int) moveActorY(id, amount.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
ActorId[] moveWallX(WallId id, float amount) {
|
||||
ActorBoxId[] moveWallX(WallBoxId id, float amount) {
|
||||
return moveWall(id, Vec2(amount, 0.0f));
|
||||
}
|
||||
|
||||
ActorId[] moveWallY(WallId id, float amount) {
|
||||
ActorBoxId[] moveWallY(WallBoxId id, float amount) {
|
||||
return moveWall(id, Vec2(0.0f, amount));
|
||||
}
|
||||
|
||||
ActorId[] moveWall(WallId id, Vec2 amount) {
|
||||
auto wall = &walls[id - 1];
|
||||
auto properties = &wallsProperties[id - 1];
|
||||
ActorBoxId[] moveWall(WallBoxId id, Vec2 amount) {
|
||||
auto wall = &getWall(id);
|
||||
auto properties = &getWallProperties(id);
|
||||
properties.remainder += amount;
|
||||
|
||||
squishedIdsBuffer.clear();
|
||||
|
@ -319,13 +363,13 @@ struct BoxWorld {
|
|||
auto actorLeft = actor.position.x;
|
||||
auto actorRight = actor.position.x + actor.size.x;
|
||||
auto actorPushAmount = (move.x > 0) ? (wallRight - actorLeft) : (wallLeft - actorRight);
|
||||
if (moveActorX(i + 1, actorPushAmount)) {
|
||||
if (moveActorX(cast(BaseBoxId) (i + 1), actorPushAmount)) {
|
||||
// Squish actor.
|
||||
squishedIdsBuffer.append(i + 1);
|
||||
squishedIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
}
|
||||
} else if (actorsProperties[i].isRiding) {
|
||||
// Carry actor.
|
||||
moveActorX(i + 1, move.x);
|
||||
moveActorX(cast(BaseBoxId) (i + 1), move.x);
|
||||
}
|
||||
}
|
||||
properties.isPassable = false;
|
||||
|
@ -345,13 +389,13 @@ struct BoxWorld {
|
|||
auto actorTop = actor.position.y;
|
||||
auto actorBottom = actor.position.y + actor.size.y;
|
||||
auto actorPushAmount = (move.y > 0) ? (wallBottom - actorTop) : (wallTop - actorBottom);
|
||||
if (moveActorY(i + 1, actorPushAmount)) {
|
||||
if (moveActorY(cast(BaseBoxId) (i + 1), actorPushAmount)) {
|
||||
// Squish actor.
|
||||
squishedIdsBuffer.append(i + 1);
|
||||
squishedIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
}
|
||||
} else if (actorsProperties[i].isRiding) {
|
||||
// Carry actor.
|
||||
moveActorY(i + 1, move.y);
|
||||
moveActorY(cast(BaseBoxId) (i + 1), move.y);
|
||||
}
|
||||
}
|
||||
properties.isPassable = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue