diff options
author | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-20 03:08:57 -0600 |
---|---|---|
committer | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-20 03:08:57 -0600 |
commit | 43e31b6e124da754ef928d22fbb9a1d7640aab4b (patch) | |
tree | 698f723866bd99982a6c606c63cfa0387863e2db /src | |
parent | f3f5fedbf591c10fa675a32103bab9480b42abe8 (diff) |
New bullet system
Diffstat (limited to 'src')
-rw-r--r-- | src/bullets.c | 181 | ||||
-rw-r--r-- | src/bullets.h | 29 | ||||
-rw-r--r-- | src/entities/antifaShip.c | 22 | ||||
-rw-r--r-- | src/entity.c | 28 | ||||
-rw-r--r-- | src/entity.h | 16 | ||||
-rw-r--r-- | src/game.c | 13 | ||||
-rw-r--r-- | src/game.h | 1 | ||||
-rw-r--r-- | src/gameScreen.c | 31 | ||||
-rw-r--r-- | src/playerCamera.c | 27 | ||||
-rw-r--r-- | src/playerCamera.h | 2 | ||||
-rw-r--r-- | src/world.c | 54 |
11 files changed, 217 insertions, 187 deletions
diff --git a/src/bullets.c b/src/bullets.c index 10116c2..ea913c7 100644 --- a/src/bullets.c +++ b/src/bullets.c @@ -1,138 +1,59 @@ #include "bullets.h" #include "game.h" -Bullet createBullet(Entity entity, Vector3 direction, Vector3 offset, float damage) { - Bullet bullet = (Bullet){ - .hit = false, +Bullet createBulletFromEntity(Entity entity, float damage) { + return (Bullet){ .ray = (Ray){ - .position = Vector3Add(entity.position, offset), - .direction = direction, + entity.position, + Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, entity.rotation) }, .fromId = entity.id, .fromFingerprint = entity.fingerprint, .damage = damage }; - - return bullet; -} - -void initBullets(Bullets * bullets) { - bullets->bullets = NULL; - bullets->bulletsCount = 0; -} - -void freeBullets(Bullets * bullets) { - if (bullets->bullets != NULL) - KF_FREE(bullets->bullets); -} - -KfError addBullet(Bullets * bullets, Bullet bullet) { - // Not allocated yet. - if (bullets->bullets == NULL) { - bullets->bullets = (Bullet*)KF_CALLOC(1, sizeof(Bullet)); - - if (bullets->bullets == NULL) { - ALLOCATION_ERROR; - return KFERROR; - } - - bullets->bulletsCount = 1; - bullets->bullets[0] = bullet; - return KFSUCCESS; - } - - ++bullets->bulletsCount; - - // Reallocate. - bullets->bullets = (Bullet*)KF_REALLOCARRAY( - bullets->bullets, - bullets->bulletsCount, - sizeof(Bullet) - ); - - if (bullets->bullets == NULL) { - ALLOCATION_ERROR; - return KFERROR; - } - - bullets->bullets[bullets->bulletsCount - 1] = bullet; - return KFSUCCESS; -} - -KfError popBackBullets(Bullets * bullets) { - if (bullets->bullets == NULL) - return KFSUCCESS; - - // At one. - if (bullets->bulletsCount == 1) { - KF_FREE(bullets->bullets); - bullets->bullets = NULL; - bullets->bulletsCount = 0; - return KFSUCCESS; - } - - --bullets->bulletsCount; - - // Reallocate. - bullets->bullets = (Bullet*)KF_REALLOCARRAY( - bullets->bullets, - bullets->bulletsCount, - sizeof(Bullet) - ); - - if (bullets->bullets == NULL) { - ALLOCATION_ERROR; - return KFERROR; - } - - return KFSUCCESS; } -void updateBullets(Game * game, Bullets * bullets) { - int i; - Bullet * last = NULL; - - if (bullets->bullets == NULL) - return; - - // Update each bullet. - for (i = 0; i < bullets->bulletsCount; ++i) - updateBullet(game, &bullets->bullets[i]); - - // Remove end if hit or out of bounds. - last = &bullets->bullets[bullets->bulletsCount - 1]; +BulletHitInfo handleBulletHit(Entity * entity, Bullet bullet) { + // Handle health. + entity->health -= bullet.damage; + entity->health = Clamp(entity->health, ENTITY_MIN_HEALTH, ENTITY_MAX_HEALTH); + + // Check hit info. + BulletHitInfo hitInfo = (BulletHitInfo){ + .hit = true, + .killed = entity->health == 0.0, + .hitId = entity->id, + .hitFingerprint = entity->fingerprint + }; - if (last->hit) - popBackBullets(bullets); - else if (Vector3Length(last->ray.position) >= GAME_BOUNDS) - popBackBullets(bullets); + return hitInfo; } -void updateBullet(Game * game, Bullet * bullet) { +BulletHitInfo shootBullet(World * world, Bullet bullet) { int i, j; RayCollision collision; - Ray ray; Entity * currentEntity; - - // Already hit. - if (bullet->hit) - return; + Ray ray; // Set direction. - ray.direction = bullet->ray.direction; + ray.direction = bullet.ray.direction; + + // Stores all the hits so we can find closest one. + int hits[world->entitiesCount]; + size_t hitsSize = 0; - // Check collision. - for (i = 0; i < game->world.entitiesCount; ++i) { - currentEntity = &game->world.entities[i]; + // Loop through entities. + for (i = 0; i < world->entitiesCount; ++i) { + currentEntity = &world->entities[i]; // This was the entity that shot it. - if (currentEntity->fingerprint == bullet->fromFingerprint) + if (currentEntity->fingerprint == bullet.fromFingerprint) continue; else if (currentEntity->model == NULL) // Null model indeed. continue; // Set position relative to entity. - ray.position = Vector3Subtract(bullet->ray.position, currentEntity->position); + ray.position = Vector3Subtract(bullet.ray.position, currentEntity->position); // Loop through meshes. for (j = 0; j < currentEntity->model->meshCount; ++j) { @@ -143,23 +64,37 @@ void updateBullet(Game * game, Bullet * bullet) { ); // Did hit. - if (!collision.hit) - continue; - - currentEntity->health -= bullet->damage; - bullet->hit = true; - goto afterCollisionCheck; + if (collision.hit) { + hits[hitsSize] = i; + ++hitsSize; + break; + } } } -afterCollisionCheck: - - // Update position. - bullet->ray.position = Vector3Add( - bullet->ray.position, - bullet->ray.direction - ); + // No hits. + if (hitsSize == 0) + return (BulletHitInfo){ + .hit = false, + .killed = false, + .hitId = ENTITY_NONE, + }; + + float dis = Vector3Distance(world->entities[hits[0]].position, bullet.ray.position); + float closest = dis; + int closestNum = 0; + + // Find closest. + for (i = 0; i < hitsSize; ++i) { + dis = Vector3Distance(world->entities[hits[i]].position, bullet.ray.position); + + // This fucker is closer. + if (dis < closest) { + closest = dis; + closestNum = i; + } + } - // Debug ray (: - //DrawRay(bullet->ray, BLUE); + // Handle closest bullet. + return handleBulletHit(&world->entities[hits[closestNum]], bullet); } diff --git a/src/bullets.h b/src/bullets.h index a01a967..eb6c15c 100644 --- a/src/bullets.h +++ b/src/bullets.h @@ -1,34 +1,29 @@ #include "gameCommon.h" #include "entity.h" +#include "world.h" #ifndef BULLET_H #define BULLET_H // Just a simple, deadly, bullet. typedef struct Bullet { - bool hit; Ray ray; EntityId fromId; - EntityFingerprint fromFingerprint; // Shooter gets shot before bullet hits object hehe. + EntityFingerprint fromFingerprint; float damage; } Bullet; -// All the simple, deadly, bullets. -typedef struct Bullets { - Bullet * bullets; - size_t bulletsCount; -} Bullets; - -// Create the simple, deadly, bullet. offset is the bullet offset from the entity. -Bullet createBullet(Entity entity, Vector3 direction, Vector3 offset, float damage); - -void initBullets(Bullets * bullets); -void freeBullets(Bullets * bullets); +typedef struct BulletHitInfo { + bool hit; + bool killed; + EntityId hitId; + EntityFingerprint hitFingerprint; +} BulletHitInfo; -KfError addBullet(Bullets * bullets, Bullet bullet); -KfError popBackBullets(Bullets * bullets); +// Uses entity postion and direction to create bullet ray. +Bullet createBulletFromEntity(Entity entity, float damage); -void updateBullets(Game * game, Bullets * bullets); -void updateBullet(Game * game, Bullet * bullet); +// Shoot this fucker. +BulletHitInfo shootBullet(World * world, Bullet bullet); #endif diff --git a/src/entities/antifaShip.c b/src/entities/antifaShip.c index 2d58510..1b90ea7 100644 --- a/src/entities/antifaShip.c +++ b/src/entities/antifaShip.c @@ -44,19 +44,15 @@ void controlAntifaShipJoystick(Game * game, Entity * entity) { // Shoot button. if (IsGamepadButtonPressed(gamePadNum, 8)) { - Vector3 dir = Vector3Normalize(Vector3Subtract( - getEntityFromWorld(game->world, 1)->position, - entity->position - )); - - Bullet bullet = createBullet( - *entity, - dir, - Vector3Zero(), - 0.1 - ); - - addBullet(&game->bullets, bullet); + Bullet bullet = createBulletFromEntity(*entity, 1.0); + BulletHitInfo info = shootBullet(&game->world, bullet); + + if (info.hit) { + Entity * hitEntity = getEntityFromWorld(game->world, info.hitId); + printVector3(hitEntity->position); + } else { + puts("no stink"); + } } Vector3 stick = (Vector3){ diff --git a/src/entity.c b/src/entity.c index 285744d..9c6e5e3 100644 --- a/src/entity.c +++ b/src/entity.c @@ -60,7 +60,8 @@ Entity createEntity(EntityType type, Game * game) { .useAcceleration = false, .updateCb = info.updateCb, .drawCb = info.drawCb, - .health = 1.0, + .health = ENTITY_MAX_HEALTH, + .collision.hit = false, .data = NULL }; @@ -74,6 +75,28 @@ void closeEntity(Entity * entity) { entityTypeInfo[entity->type].closeCb(entity); } +bool entitiesCollide(Entity entity1, Entity entity2) { + int i; + Vector3 triangle[3]; + + /* + for (i = 0; i < mesh.triangleCount; ++i) { + + for (j = 0; j < 3; ++j) + triangle[j] = (Vector3){ + mesh.vertices[(i * 9) + (j * 3)], + mesh.vertices[(i * 9) + (j * 3) + 1], + mesh.vertices[(i * 9) + (j * 3) + 2], + }; + + DrawLine3D(triangle[0], triangle[1], BLUE); + DrawLine3D(triangle[1], triangle[2], BLUE); + DrawLine3D(triangle[2], triangle[0], BLUE); + } + */ + return false; +} + // Basic wireframe drawing. void entityDraw(Entity * entity) { entity->model->transform = QuaternionToMatrix(entity->rotation); @@ -81,7 +104,7 @@ void entityDraw(Entity * entity) { DrawModelWires( *entity->model, entity->position, - 1, + 1.0, GREEN ); } @@ -107,6 +130,7 @@ void entityUpdateRotation(Entity * entity) { ); entity->rotation = QuaternionMultiply(entity->rotation, angularRotation); + entity->rotation = QuaternionNormalize(entity->rotation); } void entityJoystickControl(Entity * entity, Vector3 stick, float speed) { diff --git a/src/entity.h b/src/entity.h index dc6be72..844386c 100644 --- a/src/entity.h +++ b/src/entity.h @@ -45,11 +45,23 @@ typedef struct EntityVelocity { EntityVelocity entityVelocityIdentity(); +// This fucker hit something. +typedef struct EntityCollision { + bool hit; + EntityId fromId; + EntityFingerprint fromFingerprint; +} EntityCollision; + +// Health stuff. +#define ENTITY_MIN_HEALTH 0.0 +#define ENTITY_MAX_HEALTH 1.0 + // This fucker is a entity. typedef struct Entity { EntityId id; EntityFingerprint fingerprint; EntityType type; + Model * model; Vector3 position; @@ -67,6 +79,8 @@ typedef struct Entity { // Health is a percent from 1.0 to 0.0. float health; + EntityCollision collision; + // Used for whatever. void * data; } Entity; @@ -88,6 +102,8 @@ const extern EntityTypeInfo entityTypeInfo[ENTITY_TYPE_COUNT]; Entity createEntity(EntityType type, Game * game); void closeEntity(Entity * entity); +bool entitiesCollide(Entity entity1, Entity entity2); + // Helper functions for updating and drawing. void entityDraw(Entity * entity); void entityUpdatePosition(Entity * entity); @@ -19,19 +19,19 @@ void initGame(Game * game) { // Camera. initPlayerCamera(&game->playerCamera); - - // Bullets. - initBullets(&game->bullets); // World. initWorld(&game->world); // Debug. - WorldEntry entries[] = { - (WorldEntry){ENTITY_ANTIFA, Vector3Zero(), QuaternionIdentity()}, - (WorldEntry){ENTITY_SOLDATO, (Vector3){0.0, 0.0, 10.0}, QuaternionIdentity()} + WorldEntry entries[101] = { + (WorldEntry){ENTITY_ANTIFA, Vector3Zero(), QuaternionIdentity()}, }; + for (int i = 1; i < 101; ++i) { + entries[i] = (WorldEntry){ENTITY_CAPORALE, (Vector3){0.0, 0.0, i*10}, QuaternionIdentity()}; + } + addEntriesToWorld( &game->world, game, @@ -42,7 +42,6 @@ void initGame(Game * game) { void closeGame(Game * game) { unloadAssets(&game->assets); - freeBullets(&game->bullets); freeWorld(&game->world); // Close window last. @@ -24,7 +24,6 @@ typedef struct Game { Assets assets; World world; Settings settings; - Bullets bullets; } Game; void initGame(Game * game); diff --git a/src/gameScreen.c b/src/gameScreen.c index 286a026..65b020c 100644 --- a/src/gameScreen.c +++ b/src/gameScreen.c @@ -3,27 +3,46 @@ #include "world.h" #include "bullets.h" +void drawCrossHair(float size, float thick, Color color) { + Vector3 center = (Vector3){GetScreenWidth() / 2.0, GetScreenHeight() / 2.0}; + + // Left to right. + DrawLineEx( + (Vector2){center.x - size, center.y}, + (Vector2){center.x + size, center.y}, + thick, + color + ); + + // Top to bottom. + DrawLineEx( + (Vector2){center.x, center.y - size}, + (Vector2){center.x, center.y + size}, + thick, + color + ); +} + void updateGameScreen(Game * game) { + ClearBackground(BLACK); + + // Draw cross hair. + drawCrossHair(10.0, 2.0, BLUE); // Update world. updateWorld(&game->world, game); - ClearBackground(BLACK); - // Camera. updatePlayerCamera(&game->playerCamera, game); + // Draw. BeginMode3D(game->playerCamera); DrawGrid(50, 25.0); - //DrawSphereWires(Vector3Zero(), GAME_BOUNDS, 32, 32, WHITE); - // Draw world. drawWorld(&game->world, game); - updateBullets(game, &game->bullets); - EndMode3D(); } diff --git a/src/playerCamera.c b/src/playerCamera.c index ded59b7..6b165f3 100644 --- a/src/playerCamera.c +++ b/src/playerCamera.c @@ -12,25 +12,18 @@ void initPlayerCamera(Camera3D * camera) { void updatePlayerCamera(Camera3D * camera, Game * game) { Entity * player = getEntityFromWorld(game->world, 0); - camera->target = player->position; + Vector3 direction = Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, player->rotation); - Matrix m = QuaternionToMatrix(QuaternionInvert(player->rotation)); - Vector3 pos = (Vector3){0.0, CAMERA_DIS/2, -CAMERA_DIS}; + // Position. + camera->position = Vector3Add(player->position, Vector3Scale(direction, CAMERA_DIS)); - camera->position = (Vector3){ - m.m0 * pos.x + m.m1 * pos.y + m.m2 * pos.z, - m.m4 * pos.x + m.m5 * pos.y + m.m6 * pos.z, - m.m8 * pos.x + m.m9 * pos.y + m.m10 * pos.z - }; - - camera->position = Vector3Add(camera->position, player->position); + // Target. + camera->target = Vector3Add(camera->position, direction); - camera->up = (Vector3){ - m.m1 + m.m2, - m.m5 + m.m6, - m.m9 + m.m10 - }; + // Up. + camera->up = Vector3RotateByQuaternion((Vector3){0.0, 1.0, 0.0}, player->rotation); - camera->position = (Vector3){20.0, 20.0, 20.0}; - camera->up = (Vector3){0.0, 1.0, 0.0}; + //camera->target = player->position; + //camera->position = (Vector3){10.0, 10.0, 10.0}; + //camera->up = (Vector3){0.0, 1.0, 0.0}; } diff --git a/src/playerCamera.h b/src/playerCamera.h index 960c30d..87663d4 100644 --- a/src/playerCamera.h +++ b/src/playerCamera.h @@ -3,7 +3,7 @@ #ifndef PLAYER_CAMERA_H #define PLAYER_CAMERA_H -#define CAMERA_DIS 10.0 +#define CAMERA_DIS 5.0 void initPlayerCamera(Camera3D * camera); void updatePlayerCamera(Camera3D * camera, Game * game); diff --git a/src/world.c b/src/world.c index 3bc02cd..553f2ed 100644 --- a/src/world.c +++ b/src/world.c @@ -225,17 +225,69 @@ KfError removeEntityFromWorld(World * world, EntityId id) { return KFSUCCESS; } +void checkCollisionWithWorld(World * world, Entity * entity) { + int i, j; + Entity * entity2; + BoundingBox box1, box2; + + Mesh mesh = entity->model->meshes[0]; + + Vector3 triangle[3]; + + for (i = 0; i < mesh.triangleCount; ++i) { + + for (j = 0; j < 3; ++j) + triangle[j] = (Vector3){ + mesh.vertices[(i * 9) + (j * 3)], + mesh.vertices[(i * 9) + (j * 3) + 1], + mesh.vertices[(i * 9) + (j * 3) + 2], + }; + + DrawLine3D(triangle[0], triangle[1], BLUE); + DrawLine3D(triangle[1], triangle[2], BLUE); + DrawLine3D(triangle[2], triangle[0], BLUE); + } + + // Check for collision. + //for (i = 0; i < world->entitiesCount; ++i) { + // entity2 = &world->entities[i]; + + // if (entity->fingerprint == entity2->fingerprint) + // continue; + + // // These fuckers collided. + // if (CheckCollisionBoxes(box1, box2)) { + // printf("hi %ld\n", clock()); + // break; + // } + //} +} + void updateWorld(World * world, Game * game) { int i; Entity * entity; + // People are fucking dying. + EntityId kills[world->entitiesCount]; + size_t killCount = 0; + for (i = 0; i < world->entitiesCount; ++i) { entity = &world->entities[i]; // Call update callback. if (entity->updateCb != NULL) entity->updateCb(game, entity); + + // It fucking died. + if (entity->health <= 0.0) { + kills[killCount] = entity->id; + ++killCount; + } } + + // "bring out your dead!" + for (i = 0; i < killCount; ++i) + removeEntityFromWorld(world, kills[i]); } void drawWorld(World * world, Game * game) { @@ -245,6 +297,8 @@ void drawWorld(World * world, Game * game) { for (i = 0; i < world->entitiesCount; ++i) { entity = &world->entities[i]; + //checkCollisionWithWorld(world, entity); + // Call draw callback. if (entity->drawCb != NULL) entity->drawCb(game, entity); |