From 240186c8dec9d386f4322844d773e582d1c9eb7d Mon Sep 17 00:00:00 2001 From: Sara Date: Sat, 25 Nov 2023 21:52:12 +0100 Subject: [PATCH] feat(physics): reworked physics to use colliders, allowing for bodies with multiple colliders --- core/src/collision.c | 37 ++++++++++++++---------------- core/src/collision.h | 30 +++++------------------- core/src/physics_entity.c | 24 +++++++++----------- core/src/physics_entity.h | 17 ++++++-------- core/src/physics_world.c | 48 +++++++++++++++++++++++++++++---------- core/src/physics_world.h | 2 +- core/src/rigidbody.c | 30 ++++++++++++++++-------- core/src/rigidbody.h | 10 +++++--- game/src/Player.c | 25 +++++++++----------- game/src/Player.h | 8 +++---- game/src/Prop.c | 17 +++++++------- game/src/Prop.h | 10 ++++---- game/src/beat-em-up.c | 11 +++++---- 13 files changed, 137 insertions(+), 132 deletions(-) diff --git a/core/src/collision.c b/core/src/collision.c index 173168a..84fdd3b 100644 --- a/core/src/collision.c +++ b/core/src/collision.c @@ -1,6 +1,7 @@ #include "collision.h" #include "vmath.h" #include "rigidbody.h" +#include "collider.h" // ===================================================== // Shape overlap test using the separating axis theorem @@ -49,18 +50,18 @@ Vector _internal_collision_overlap_on_axis(PhysicsQuery self, PhysicsQuery other } static -int _internal_collision_get_collisions(PhysicsEntity self, PhysicsEntity other, Collision* out) { +int _internal_collision_get_collisions(Collider* self, Collider* other, Collision* out) { // get components used - Shape* self_shape = self.tc->get_shape(self.data); - Transform* self_transform = self.transformable->get_transform(self.data); + Shape* self_shape = collider_get_shape(self); + Transform* self_transform = rigidbody_get_transform(collider_get_rigidbody(self)); PhysicsQuery self_query = { .shape = self_shape, .transform = self_transform, .mask = 0x0 // not used }; PhysicsQuery other_query = { - .shape = other.tc->get_shape(other.data), - .transform = other.transformable->get_transform(other.data), + .shape = collider_get_shape(other), + .transform = rigidbody_get_transform(collider_get_rigidbody(other)), .mask = 0x0 // not used }; @@ -77,8 +78,8 @@ int _internal_collision_get_collisions(PhysicsEntity self, PhysicsEntity other, // the next point on the line size_t next_index = (point_index + 1) % self_point_count; // get the two points defining the collision edge - Vector edge_lhs = shape_get_point_transformed(self.tc->get_shape(self.data), point_index, *self_transform); - Vector edge_rhs = shape_get_point_transformed(self.tc->get_shape(self.data), next_index, *self_transform); + Vector edge_lhs = shape_get_point_transformed(self_shape, point_index, *self_transform); + Vector edge_rhs = shape_get_point_transformed(self_shape, next_index, *self_transform); // the direction of the line Vector normal = vnormalizedf(vperpendicularf(vsubf(edge_rhs, edge_lhs))); @@ -96,8 +97,8 @@ int _internal_collision_get_collisions(PhysicsEntity self, PhysicsEntity other, } } - RigidBody* rba = self.tc->get_rigidbody(self.data); - RigidBody* rbb = other.tc->get_rigidbody(other.data); + RigidBody* rba = collider_get_rigidbody(self); + RigidBody* rbb = collider_get_rigidbody(other); const Vector velocity = vsubf(rigidbody_get_velocity(rba), rigidbody_get_velocity(rbb)); const Vector normal = vnormalizedf(shortest_escape); Vector world_point = _internal_collision_get_range_on_axis(self_query, normal).minpoint; @@ -118,9 +119,9 @@ int _internal_collision_get_collisions(PhysicsEntity self, PhysicsEntity other, return !veqf(shortest_escape, ZeroVector); } -Collision collision_invert(Collision collision_a, PhysicsEntity a) { - RigidBody* body = collision_a.other.tc->get_rigidbody(collision_a.other.data); - Shape* shape = collision_a.other.tc->get_shape(collision_a.other.data); +Collision collision_invert(Collision collision_a, Collider* a) { + RigidBody* body = collider_get_rigidbody(a); + Shape* shape = collider_get_shape(a); Transform* transform = rigidbody_get_transform(body); Vector world_point = _internal_collision_get_range_on_axis((PhysicsQuery){.shape = shape, .transform = transform }, collision_a.normal).maxpoint; @@ -136,7 +137,7 @@ Collision collision_invert(Collision collision_a, PhysicsEntity a) { }; } -int collision_check(PhysicsEntity a, PhysicsEntity b, Collision* out_a, Collision* out_b) { +int collision_check(Collider* a, Collider* b, Collision* out_a, Collision* out_b) { Collision collision_a, collision_b; int collision_a_overlaps = _internal_collision_get_collisions(a, b, &collision_a); int collision_b_overlaps = _internal_collision_get_collisions(b, a, &collision_b); @@ -180,11 +181,7 @@ int _internal_overlap_check(PhysicsQuery a, PhysicsQuery b) { return 1; } -int overlap_check(PhysicsQuery query, PhysicsEntity entity) { - PhysicsQuery entity_q = { - .shape = entity.tc->get_shape(entity.data), - .transform = entity.transformable->get_transform(entity.data), - .mask = rigidbody_get_layers(entity.tc->get_rigidbody(entity.data)), - }; - return (query.mask & entity_q.mask) != 0 && _internal_overlap_check(query, entity_q) || _internal_overlap_check(entity_q, query); +int overlap_check(PhysicsQuery query, Collider* collider) { + PhysicsQuery collider_query = collider_to_query(collider); + return (query.mask & collider_query.mask) != 0 && _internal_overlap_check(query, collider_query) || _internal_overlap_check(collider_query, query); } diff --git a/core/src/collision.h b/core/src/collision.h index 6e61ca6..4e83b40 100644 --- a/core/src/collision.h +++ b/core/src/collision.h @@ -3,31 +3,13 @@ #include "shape.h" #include "physics_entity.h" -#include +#include "rigidbody.h" +#include "physics.h" -typedef uint32_t PhysicsMask; +typedef struct Collider Collider; -typedef struct Collision { - PhysicsEntity other; - - Vector point; - Vector normal; - - Vector velocity; - Vector penetration_vector; - - Vector edge_left; - Vector edge_right; -} Collision; - -typedef struct PhysicsQuery { - Shape* shape; - Transform* transform; - PhysicsMask mask; -} PhysicsQuery; - -extern Collision collision_invert(Collision src, PhysicsEntity new_other); -extern int collision_check(PhysicsEntity a, PhysicsEntity b, Collision* out_a, Collision* out_b); -extern int overlap_check(PhysicsQuery query, PhysicsEntity entity); +extern Collision collision_invert(Collision src, Collider* new_other); +extern int collision_check(Collider* a, Collider* b, Collision* out_a, Collision* out_b); +extern int overlap_check(PhysicsQuery query, Collider* collider); #endif // !_fencer_collision_h diff --git a/core/src/physics_entity.c b/core/src/physics_entity.c index 2436dbe..1e47578 100644 --- a/core/src/physics_entity.c +++ b/core/src/physics_entity.c @@ -4,13 +4,15 @@ #include "shape.h" #include "render.h" #include "debug.h" +#include "collider.h" void physics_entity_debug_draw(PhysicsEntity self) { RigidBody* body = self.tc->get_rigidbody(self.data); - Shape* shape = self.tc->get_shape(self.data); - Transform* transform = self.transformable->get_transform(self.data); + Transform* transform = rigidbody_get_transform(body); - shape_draw(shape, *transform); + list_foreach(Collider**, collider, rigidbody_get_colliders(body)) { + shape_draw(collider_get_shape(*collider), *transform); + } rigidbody_debug_draw_contacts(body); Vector lhs = transform->position; @@ -81,16 +83,12 @@ void physics_entity_update(PhysicsEntity self) { List* contacts = rigidbody_get_contacts(body); if(contacts->len > 0) { - if(rigidbody_get_overlap(body) == 1) { - list_foreach(Contact*, contact, contacts) - self.tc->on_overlap(self.data, contact->hit.other); - } else { - if(rigidbody_is_static(body) == 0) { - physics_entity_solve_contacts(self, contacts); - } - list_foreach(Contact*, contact, contacts) { - self.tc->on_collision(self.data, contact->hit); - } + if (rigidbody_is_static(body) == 0) { + physics_entity_solve_contacts(self, contacts); + } + + list_foreach(Contact *, contact, contacts) { + self.tc->on_collision(self.data, contact->hit); } } rigidbody_collect_contacts(body); diff --git a/core/src/physics_entity.h b/core/src/physics_entity.h index d33128a..9d2fb3c 100644 --- a/core/src/physics_entity.h +++ b/core/src/physics_entity.h @@ -1,20 +1,20 @@ #ifndef _fencer_collidable_h #define _fencer_collidable_h -#include "vmath.h" #include "typeclass_helpers.h" #include "list.h" -#include "shape.h" +#include "transformable.h" +typedef struct Collider Collider; typedef struct Collision Collision; typedef struct RigidBody RigidBody; + typedef struct PhysicsEntity PhysicsEntity; typedef struct IPhysicsEntity { RigidBody* (*const get_rigidbody)(void* self); - Shape* (*const get_shape)(void* self); void(*const on_collision)(void* self, Collision collision); - void(*const on_overlap)(void* self, PhysicsEntity other); + void(*const on_overlap)(void* self, Collider* other); } IPhysicsEntity; typedef struct PhysicsEntity { @@ -28,18 +28,15 @@ extern void physics_entity_solve_contacts(PhysicsEntity self, List* contacts); extern void physics_entity_update(PhysicsEntity self); -#define impl_PhysicsEntity_for(T, get_rigidbody_f, get_shape_f, on_collision_f, on_overlap_f)\ +#define impl_PhysicsEntity_for(T, get_rigidbody_f, on_collision_f, on_overlap_f)\ static inline PhysicsEntity T##_as_PhysicsEntity(T* x) {\ - TC_FN_TYPECHECK(Transformable, T##_as_Transformable, T*);\ TC_FN_TYPECHECK(RigidBody*, get_rigidbody_f, T*);\ - TC_FN_TYPECHECK(Shape*, get_shape_f, T*);\ TC_FN_TYPECHECK(void, on_collision_f, T*, Collision);\ - TC_FN_TYPECHECK(void, on_overlap_f, T*, PhysicsEntity);\ + TC_FN_TYPECHECK(void, on_overlap_f, T*, Collider*);\ static IPhysicsEntity const tc = {\ .get_rigidbody = (RigidBody*(*const)(void*)) get_rigidbody_f,\ - .get_shape = (Shape*(*const)(void*)) get_shape_f,\ .on_collision = (void(*const)(void*,Collision)) on_collision_f,\ - .on_overlap = (void(*const)(void*,PhysicsEntity)) on_overlap_f,\ + .on_overlap = (void(*const)(void*,Collider*)) on_overlap_f,\ };\ Transformable transformable = T##_as_Transformable(x);\ return (PhysicsEntity){.data = x, .tc = &tc, .transformable = transformable.tc};\ diff --git a/core/src/physics_world.c b/core/src/physics_world.c index 28a9c7e..2f03102 100644 --- a/core/src/physics_world.c +++ b/core/src/physics_world.c @@ -1,6 +1,7 @@ #include "physics_world.h" #include "debug.h" #include "collision.h" +#include "collider.h" #include "rigidbody.h" static List _world_bodies; @@ -29,30 +30,53 @@ void physics_world_remove_entity(PhysicsEntity entity) { ASSERT_RETURN(0,, "Physics entity with data at %p is not registered in physics world", entity.data); } -PhysicsEntity physics_world_query(PhysicsQuery query) { - list_foreach(PhysicsEntity*, entity, &_world_bodies) { - if(overlap_check(query, *entity)) - return *entity; +Collider* physics_world_query(PhysicsQuery query) { + list_foreach(RigidBody**, body, &_world_bodies) { + list_foreach(Collider**, collider, rigidbody_get_colliders(*body)) { + if(overlap_check(query, *collider)) + return *collider; + } + } + + return NULL; +} + +static inline +void _internal_physics_check_entities(PhysicsEntity left, PhysicsEntity right) { + RigidBody* rbleft = left.tc->get_rigidbody(left.data); + RigidBody* rbright = right.tc->get_rigidbody(right.data); + + Collision collision_left, collision_right; + int is_overlap = 0; + + list_foreach(Collider**, left_col, rigidbody_get_colliders(rbleft)) { + list_foreach(Collider**, right_col, rigidbody_get_colliders(rbright)) { + is_overlap = collider_is_overlap(*left_col) || collider_is_overlap(*right_col); + + if(collision_check(*left_col, *right_col, &collision_left, &collision_right)) { + if(is_overlap) { + left.tc->on_overlap(left.data, *right_col); + right.tc->on_overlap(right.data, *left_col); + } else { + rigidbody_add_contact(rbleft, collision_left); + rigidbody_add_contact(rbright, collision_right); + } + } + } } } static inline void _internal_physics_narrow_collision() { size_t half_end = _world_bodies.len/2; - Collision collision_left, collision_right; PhysicsEntity* right = NULL; list_foreach(PhysicsEntity*, left, &_world_bodies) { for(size_t right_index = 0; right_index < half_end; ++right_index) { right = list_at_as(PhysicsEntity, &_world_bodies, right_index); - if(left->data == right->data) continue; - if(collision_check(*left, *right, &collision_left, &collision_right)) { - left->tc->on_collision(left->data, collision_left); - right->tc->on_collision(right->data, collision_right); - rigidbody_add_contact(left->tc->get_rigidbody(left->data), collision_left); - rigidbody_add_contact(right->tc->get_rigidbody(right->data), collision_right); - } + if(left->data == right->data) continue; + _internal_physics_check_entities(*left, *right); } } } diff --git a/core/src/physics_world.h b/core/src/physics_world.h index e2aa674..b4ce2df 100644 --- a/core/src/physics_world.h +++ b/core/src/physics_world.h @@ -10,7 +10,7 @@ extern void physics_world_clean(); extern void physics_world_add_entity(PhysicsEntity entity); extern void physics_world_remove_entity(PhysicsEntity entity); -extern PhysicsEntity physics_world_query(PhysicsQuery query); +extern Collider* physics_world_query(PhysicsQuery query); extern void physics_world_tick(); diff --git a/core/src/rigidbody.c b/core/src/rigidbody.c index fed0d8b..93519b5 100644 --- a/core/src/rigidbody.c +++ b/core/src/rigidbody.c @@ -19,7 +19,8 @@ struct RigidBody { PhysicsMask layers; PhysicsMask collision_mask; - int overlap; + List colliders; + int is_static; List contacts; @@ -42,7 +43,7 @@ RigidBody* rigidbody_make(Transformable transform) { .layers = 0x1, .collision_mask = 0x1, - .overlap = 0, + .colliders = list_from_type(Collider*), .is_static = 0, @@ -158,14 +159,6 @@ void rigidbody_set_collision_mask(RigidBody* self, PhysicsMask mask) { self->collision_mask = mask; } -int rigidbody_get_overlap(RigidBody* self) { - return self->overlap; -} - -void rigidbody_set_overlap(RigidBody* self, int value) { - self->overlap = 1; -} - int rigidbody_is_static(RigidBody* self) { return self->is_static; } @@ -187,6 +180,23 @@ Vector rigidbody_get_force(RigidBody* self) { return self->next_linear_force; } +void rigidbody_add_collider(RigidBody *self, Collider* collider) { + list_add(&self->colliders, &collider); +} + +void rigidbody_remove_collider(RigidBody *self, Collider* collider) { + for(size_t i = 0; i < self->colliders.len; ++i) { + if(collider == *list_at_as(Collider*, &self->colliders, i)) { + list_erase(&self->colliders, i); + return; + } + } +} + +List* rigidbody_get_colliders(RigidBody* self) { + return &self->colliders; +} + void rigidbody_debug_draw_contacts(RigidBody* self) { list_foreach(Contact*, contact, &self->contacts) { _internal_debug_draw_collision_edge(self, contact); diff --git a/core/src/rigidbody.h b/core/src/rigidbody.h index d8f5a4e..fe9a055 100644 --- a/core/src/rigidbody.h +++ b/core/src/rigidbody.h @@ -4,12 +4,11 @@ #include "shape.h" #include "transformable.h" #include "list.h" -#include "collision.h" #include "stdint.h" +#include "physics.h" -struct Collision; typedef struct { - struct Collision hit; + Collision hit; float duration; } Contact; @@ -54,7 +53,12 @@ extern void rigidbody_set_velocity(RigidBody* self, Vector velocity); extern Vector rigidbody_get_force(RigidBody* self); +extern void rigidbody_add_collider(RigidBody* self, Collider* collider); +extern void rigidbody_remove_collider(RigidBody* self, Collider* collider); +extern List* rigidbody_get_colliders(RigidBody* self); + extern void rigidbody_debug_draw_contacts(RigidBody* self); + extern Transform* rigidbody_get_transform(RigidBody* self); impl_Transformable_for(RigidBody, diff --git a/game/src/Player.c b/game/src/Player.c index cb77117..28c50ad 100644 --- a/game/src/Player.c +++ b/game/src/Player.c @@ -27,12 +27,7 @@ Player* MakePlayer() { *self = (Player) { .transform = IdentityTransform, .rigidbody = NULL, - .collisionShape = shape_new((Vector[]){ - MakeVector(-0.15, -0.15), - MakeVector( 0.15, -0.15), - MakeVector( 0.15, 0.0), - MakeVector(-0.15, 0.0) - }, 4), + .physicsCollider = NULL, .playerInput = playerinput_new(self, -1), .moveInput = ZeroVector, .attackInput = 0, @@ -45,8 +40,14 @@ Player* MakePlayer() { }; self->rigidbody = rigidbody_make(Player_as_Transformable(self)); + self->physicsCollider = collider_new(self->rigidbody, shape_new((Vector[]){ + MakeVector(-0.15, -0.065), + MakeVector( 0.15, -0.065), + MakeVector( 0.15, 0.065), + MakeVector(-0.15, 0.065) + }, 4), 0, 0x1); - sprite_set_origin(self->sprite, MakeVector(0.45f, 1.f)); + sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f)); self->idle = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop); self->walk = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 5.f, LoopMode_Loop); @@ -70,8 +71,8 @@ Player* SpawnPlayer(Vector location) { } void DestroyPlayer(Player* self) { + collider_destroy(self->physicsCollider); rigidbody_destroy(self->rigidbody); - shape_destroy(self->collisionShape); playerinput_drop(self->playerInput); @@ -105,7 +106,7 @@ void PlayerUpdate(Player* self, float deltaTime) { void PlayerDraw(Player* self) { animation_sprite_draw(self->currentAnimation, &self->transform); - shape_draw(self->collisionShape, self->transform); + shape_draw(collider_get_shape(self->physicsCollider), self->transform); } Transform* PlayerGetTransform(Player* self) { @@ -116,9 +117,5 @@ RigidBody* PlayerGetRigidBody(Player* self) { return self->rigidbody; } -Shape* PlayerGetCollisionShape(Player* self) { - return self->collisionShape; -} - void PlayerOnCollision(Player* self, Collision collision) {} -void PlayerOnOverlap(Player* self, PhysicsEntity other) {} +void PlayerOnOverlap(Player* self, Collider* other) {} diff --git a/game/src/Player.h b/game/src/Player.h index fda0b33..14fb5d6 100644 --- a/game/src/Player.h +++ b/game/src/Player.h @@ -10,7 +10,7 @@ #include "transform.h" #include "player_input.h" #include "rigidbody.h" -#include "shape.h" +#include "collider.h" extern const Vector PLAYER_SPEED; @@ -18,7 +18,7 @@ typedef struct Player { Transform transform; RigidBody* rigidbody; - Shape* collisionShape; + Collider* physicsCollider; PlayerInput* playerInput; @@ -52,9 +52,8 @@ void PlayerDraw(Player* self); Transform* PlayerGetTransform(Player* self); RigidBody* PlayerGetRigidBody(Player* self); -Shape* PlayerGetCollisionShape(Player* self); void PlayerOnCollision(Player* self, Collision collision); -void PlayerOnOverlap(Player* self, PhysicsEntity other); +void PlayerOnOverlap(Player* self, Collider* other); static long PlayerGetDepth(Player* self) { return -(int)(self->transform.position.y * 1000); } @@ -75,7 +74,6 @@ impl_Transformable_for(Player, impl_PhysicsEntity_for(Player, PlayerGetRigidBody, - PlayerGetCollisionShape, PlayerOnCollision, PlayerOnOverlap ) diff --git a/game/src/Prop.c b/game/src/Prop.c index dc49cd1..ae3bd44 100644 --- a/game/src/Prop.c +++ b/game/src/Prop.c @@ -10,15 +10,16 @@ Prop* MakeProp(Sprite* sprite, Shape* shape) { .transform = IdentityTransform, .sprite = sprite, .rigidbody = NULL, - .collisionShape = shape + .collisionShape = NULL }; self->rigidbody = rigidbody_make(Prop_as_Transformable(self)); + self->collisionShape = collider_new(self->rigidbody, shape, 0, 0x1); rigidbody_set_static(self->rigidbody, 1); sprite_set_origin(self->sprite, MakeVector(0.5f, 1.0f)); return self; } -Prop* SpawnProp(Vector location, Sprite* sprite, Shape* shape) { +Prop* SpawnProp(Vector location, Sprite* sprite, Shape* shape, Vector origin) { Prop* self = MakeProp(sprite, shape); self->transform.position @@ -27,14 +28,16 @@ Prop* SpawnProp(Vector location, Sprite* sprite, Shape* shape) { game_world_add_entity(Prop_as_BehaviourEntity(self)); physics_world_add_entity(Prop_as_PhysicsEntity(self)); + + sprite_set_origin(self->sprite, origin); return self; } void DestroyProp(Prop* self) { sprite_destroy(self->sprite); + collider_destroy(self->collisionShape); rigidbody_destroy(self->rigidbody); - shape_destroy(self->collisionShape); free(self); } @@ -43,11 +46,11 @@ void PropUpdate(Prop* self, float deltaTime) {} void PropDraw(Prop* self) { sprite_draw(self->sprite, self->transform); - shape_draw(self->collisionShape, self->transform); + shape_draw(collider_get_shape(self->collisionShape), self->transform); } void PropOnCollision(Prop* self, Collision collision) {} -void PropOnOverlap(Prop* self, PhysicsEntity other) {} +void PropOnOverlap(Prop* self, Collider* other) {} Transform* PropGetTransform(Prop* self) { return &self->transform; @@ -56,7 +59,3 @@ Transform* PropGetTransform(Prop* self) { RigidBody* PropGetRigidBody(Prop* self) { return self->rigidbody; } - -Shape* PropGetCollisionShape(Prop* self) { - return self->collisionShape; -} diff --git a/game/src/Prop.h b/game/src/Prop.h index 2dd03a4..305ec64 100644 --- a/game/src/Prop.h +++ b/game/src/Prop.h @@ -8,17 +8,17 @@ #include "transform.h" #include "sprite.h" #include "rigidbody.h" -#include "shape.h" +#include "collider.h" typedef struct Prop { Transform transform; Sprite* sprite; RigidBody* rigidbody; - Shape* collisionShape; + Collider* collisionShape; } Prop; Prop* MakeProp(Sprite* sprite, Shape* shape); -Prop* SpawnProp(Vector location, Sprite* sprite, Shape* shape); +Prop* SpawnProp(Vector location, Sprite* sprite, Shape* shape, Vector origin); void DestroyProp(Prop* self); void PropStart(Prop* self); @@ -26,11 +26,10 @@ void PropUpdate(Prop* self, float deltaTime); void PropDraw(Prop* self); void PropOnCollision(Prop* self, Collision collision); -void PropOnOverlap(Prop* self, PhysicsEntity other); +void PropOnOverlap(Prop* self, Collider* other); Transform* PropGetTransform(Prop* self); RigidBody* PropGetRigidBody(Prop* self); -Shape* PropGetCollisionShape(Prop* self); static long PropGetDepth(Prop* self) { return -(int)(self->transform.position.y * 1000); } @@ -40,7 +39,6 @@ impl_Transformable_for(Prop, impl_PhysicsEntity_for(Prop, PropGetRigidBody, - PropGetCollisionShape, PropOnCollision, PropOnOverlap ) diff --git a/game/src/beat-em-up.c b/game/src/beat-em-up.c index e3b0d48..7a2bd91 100644 --- a/game/src/beat-em-up.c +++ b/game/src/beat-em-up.c @@ -8,11 +8,12 @@ void play() { SpawnProp(MakeVector(2.f, 0.f), sprite_from_spritesheet(spritesheet_load("assets/bag.png", IVectorFrom(512)), 0), shape_new((Vector[]){ - MakeVector(-0.25, -0.1), - MakeVector(0.25, -0.1), - MakeVector(0.25, 0.0), - MakeVector(-0.25, 0.0) - }, 4) + MakeVector(-0.2, -0.1), + MakeVector( 0.2, -0.1), + MakeVector( 0.2, 0.05), + MakeVector(-0.2, 0.05) + }, 4), + MakeVector(0.5f, .95f) ); SpawnPlayer(ZeroVector); }