More physics code
This commit is contained in:
parent
e8f0b0c63a
commit
663a3401e6
@ -12,6 +12,18 @@
|
|||||||
double physics_Gravity = 5.0;
|
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 *physics_NewSystem() {
|
||||||
System_Physics *sys = malloc(sizeof(System_Physics));
|
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) {
|
// Defined in Physics_Move.c
|
||||||
if (!e->position)
|
void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime);
|
||||||
return;
|
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
|
// Short path
|
||||||
if (!e->hitbox || e->hitbox->fixed) {
|
if (!e->hitbox || e->hitbox->fixed) {
|
||||||
@ -59,6 +75,8 @@ inline void _physics_AdvanceEntity(Entity *e, Duration deltaTime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Long path
|
// 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 != NULL;
|
||||||
i = tree_Node_Next(i)) {
|
i = tree_Node_Next(i)) {
|
||||||
Component_Position *pos = *((Component_Position **)i->data);
|
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;
|
bool fixed;
|
||||||
} Component_Hitbox;
|
} Component_Hitbox;
|
||||||
|
|
||||||
|
// Returns the absolute version of the hitbox.
|
||||||
|
Box2 physics_HitboxAbsolute(Component_Hitbox *hitbox);
|
||||||
|
|
||||||
|
|
||||||
// Physics manager
|
// Physics manager
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -139,6 +139,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Types.c" />
|
<ClCompile Include="Types.c" />
|
||||||
<ClCompile Include="Component_Physics.c" />
|
<ClCompile Include="Component_Physics.c" />
|
||||||
|
<ClCompile Include="Physics_Move.c" />
|
||||||
<ClCompile Include="util\queue.c" />
|
<ClCompile Include="util\queue.c" />
|
||||||
<ClCompile Include="util\tree.c" />
|
<ClCompile Include="util\tree.c" />
|
||||||
<ClCompile Include="util\vector.c" />
|
<ClCompile Include="util\vector.c" />
|
||||||
|
@ -58,6 +58,9 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Component_Physics.c">
|
<ClCompile Include="Component_Physics.c">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Physics_Move.c">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</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;
|
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.
|
// Intersection test.
|
||||||
bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection);
|
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 {
|
typedef struct {
|
||||||
uint64_t microseconds;
|
uint64_t microseconds;
|
||||||
|
Loading…
Reference in New Issue
Block a user