More physics code
This commit is contained in:
parent
e8f0b0c63a
commit
663a3401e6
@ -12,6 +12,18 @@
|
||||
double physics_Gravity = 5.0;
|
||||
|
||||
|
||||
Box2 physics_HitboxAbsolute(Component_Hitbox *hitbox) {
|
||||
Entity *super = hitbox->super;
|
||||
if (!super->position)
|
||||
return hitbox->box;
|
||||
else {
|
||||
Box2 box = hitbox->box;
|
||||
box.lefttop = vec2_Add(box.lefttop, super->position->position);
|
||||
return box;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System_Physics *physics_NewSystem() {
|
||||
System_Physics *sys = malloc(sizeof(System_Physics));
|
||||
|
||||
@ -43,9 +55,13 @@ void physics_DeleteEntity(System_Physics *sys, uintptr_t id) {
|
||||
}
|
||||
|
||||
|
||||
inline void _physics_AdvanceEntity(Entity *e, Duration deltaTime) {
|
||||
if (!e->position)
|
||||
return;
|
||||
// Defined in Physics_Move.c
|
||||
void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime);
|
||||
void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime);
|
||||
|
||||
|
||||
inline void _physics_AdvanceEntity(System_Physics *sys, Entity *e, Duration deltaTime) {
|
||||
ASSERT(e->position && "_physics_AdvanceEntity() called on entity with no position");
|
||||
|
||||
// Short path
|
||||
if (!e->hitbox || e->hitbox->fixed) {
|
||||
@ -59,6 +75,8 @@ inline void _physics_AdvanceEntity(Entity *e, Duration deltaTime) {
|
||||
}
|
||||
|
||||
// Long path
|
||||
_physics_MoveX(sys, e, deltaTime);
|
||||
_physics_MoveY(sys, e, deltaTime);
|
||||
}
|
||||
|
||||
|
||||
@ -81,6 +99,6 @@ void physics_Advance(System_Physics *sys, Duration deltaTime) {
|
||||
i != NULL;
|
||||
i = tree_Node_Next(i)) {
|
||||
Component_Position *pos = *((Component_Position **)i->data);
|
||||
_physics_AdvanceEntity(pos->super, deltaTime);
|
||||
_physics_AdvanceEntity(sys, pos->super, deltaTime);
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ typedef struct {
|
||||
bool fixed;
|
||||
} Component_Hitbox;
|
||||
|
||||
// Returns the absolute version of the hitbox.
|
||||
Box2 physics_HitboxAbsolute(Component_Hitbox *hitbox);
|
||||
|
||||
|
||||
// Physics manager
|
||||
typedef struct {
|
||||
|
@ -139,6 +139,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Types.c" />
|
||||
<ClCompile Include="Component_Physics.c" />
|
||||
<ClCompile Include="Physics_Move.c" />
|
||||
<ClCompile Include="util\queue.c" />
|
||||
<ClCompile Include="util\tree.c" />
|
||||
<ClCompile Include="util\vector.c" />
|
||||
|
@ -58,6 +58,9 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="Component_Physics.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Physics_Move.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
79
Physics_Move.c
Normal file
79
Physics_Move.c
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
#include "Component_Physics.h"
|
||||
#include "Entity.h"
|
||||
#include "Types.h"
|
||||
#include "util/tree.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static const double EPS = 1e-6;
|
||||
|
||||
static inline double dabs(double x) {
|
||||
return x < 0 ? -x : x;
|
||||
}
|
||||
|
||||
|
||||
void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime) {
|
||||
double delta = e->position->velocity.x * duration_Seconds(deltaTime);
|
||||
if (dabs(delta) < EPS)
|
||||
return;
|
||||
|
||||
for (tree_Node *i = tree_FirstNode(sys->hit);
|
||||
i != NULL;
|
||||
i = tree_Node_Next(i)) {
|
||||
Component_Hitbox *tohit = *((Component_Hitbox **)i->data);
|
||||
if (!tohit->fixed)
|
||||
continue;
|
||||
|
||||
if (box2_Intersects(tohit->box, box2_OffsetX(e->hitbox->box, delta), NULL)) {
|
||||
if (delta > 0) {
|
||||
// Moves right, hits left edge
|
||||
double maxdelta = tohit->box.lefttop.x - e->hitbox->box.lefttop.x - e->hitbox->box.size.x;
|
||||
delta = maxdelta - EPS;
|
||||
} else {
|
||||
// Moves left, hits right edge
|
||||
double maxdelta = tohit->box.lefttop.x - e->hitbox->box.lefttop.x + tohit->box.size.x;
|
||||
delta = maxdelta + EPS;
|
||||
}
|
||||
}
|
||||
|
||||
if (dabs(delta) < EPS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dabs(delta) > EPS)
|
||||
e->position->position.x += delta;
|
||||
}
|
||||
|
||||
void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime) {
|
||||
double delta = e->position->velocity.y * duration_Seconds(deltaTime);
|
||||
if (dabs(delta) < EPS)
|
||||
return;
|
||||
|
||||
for (tree_Node *i = tree_FirstNode(sys->hit);
|
||||
i != NULL;
|
||||
i = tree_Node_Next(i)) {
|
||||
Component_Hitbox *tohit = *((Component_Hitbox **)i->data);
|
||||
if (!tohit->fixed)
|
||||
continue;
|
||||
|
||||
if (box2_Intersects(tohit->box, box2_OffsetY(e->hitbox->box, delta), NULL)) {
|
||||
if (delta > 0) {
|
||||
// Moves down, hits top edge
|
||||
double maxdelta = tohit->box.lefttop.y - e->hitbox->box.lefttop.y - e->hitbox->box.size.y;
|
||||
delta = maxdelta - EPS;
|
||||
} else {
|
||||
// Moves up, hits bottom edge
|
||||
double maxdelta = tohit->box.lefttop.y - e->hitbox->box.lefttop.y + tohit->box.size.y;
|
||||
delta = maxdelta + EPS;
|
||||
}
|
||||
}
|
||||
|
||||
if (dabs(delta) < EPS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dabs(delta) > EPS)
|
||||
e->position->position.y += delta;
|
||||
}
|
13
Types.c
13
Types.c
@ -55,3 +55,16 @@ bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Box2 box2_Offset(Box2 box, Vec2 offset) {
|
||||
box.lefttop = vec2_Add(box.lefttop, offset);
|
||||
return box;
|
||||
}
|
||||
Box2 box2_OffsetX(Box2 box, double offsetX) {
|
||||
box.lefttop.x += offsetX;
|
||||
return box;
|
||||
}
|
||||
Box2 box2_OffsetY(Box2 box, double offsetY) {
|
||||
box.lefttop.y += offsetY;
|
||||
return box;
|
||||
}
|
||||
|
4
Types.h
4
Types.h
@ -28,6 +28,10 @@ typedef struct {
|
||||
// Intersection test.
|
||||
bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection);
|
||||
|
||||
Box2 box2_Offset(Box2 box, Vec2 offset);
|
||||
Box2 box2_OffsetX(Box2 box, double offsetX);
|
||||
Box2 box2_OffsetY(Box2 box, double offsetY);
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t microseconds;
|
||||
|
Loading…
Reference in New Issue
Block a user