feat: Basic NPC wandering
This commit is contained in:
27
code/first.c
27
code/first.c
@@ -4,11 +4,15 @@
|
|||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
|
#include "game/npc.h"
|
||||||
#include "os/core.h"
|
#include "os/core.h"
|
||||||
|
|
||||||
#include "vulkan/core.h"
|
#include "vulkan/core.h"
|
||||||
|
|
||||||
#include "game/impl/player.c"
|
#include "game/impl/player.c"
|
||||||
|
#include "game/world.h"
|
||||||
|
#include "game/impl/npc.c"
|
||||||
|
#include "game/testnavmesh.h"
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -34,6 +38,28 @@ int main(int argc, char **argv)
|
|||||||
Player player;
|
Player player;
|
||||||
player.pos.x = 0;
|
player.pos.x = 0;
|
||||||
player.pos.y = 0;
|
player.pos.y = 0;
|
||||||
|
World world = {
|
||||||
|
.npcCount = 2,
|
||||||
|
.npcs = {
|
||||||
|
{
|
||||||
|
.collision = {{10, 10}, {10, 10}},
|
||||||
|
.name = S("Matt"),
|
||||||
|
.mode = NPC_ACTION_WAITING,
|
||||||
|
.waitTime = 0,
|
||||||
|
.maxWaitTime = 5,
|
||||||
|
.currentNavNode = 87
|
||||||
|
},{
|
||||||
|
.collision = {{15, 15}, {10, 10}},
|
||||||
|
.name = S("James"),
|
||||||
|
.mode = NPC_ACTION_WAITING,
|
||||||
|
.waitTime = 0,
|
||||||
|
.maxWaitTime = 10,
|
||||||
|
.currentNavNode = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.navMesh = TestNavMesh,
|
||||||
|
.npcPOI = {100}
|
||||||
|
};
|
||||||
while (running)
|
while (running)
|
||||||
{
|
{
|
||||||
SDL_Event e;
|
SDL_Event e;
|
||||||
@@ -45,6 +71,7 @@ int main(int argc, char **argv)
|
|||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdateNPCs(1.0/60.0, &world);
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#if !defined(LD_GAME_AABB_H_)
|
#if !defined(LD_GAME_AABB_H_)
|
||||||
#define LD_GAME_AABB_H_
|
#define LD_GAME_AABB_H_
|
||||||
#include "types.h"
|
#include "../core/types.h"
|
||||||
#include "../core/macros.h"
|
#include "../core/macros.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
50
code/game/impl/npc.c
Normal file
50
code/game/impl/npc.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include "../npc.h"
|
||||||
|
#include "../world.h"
|
||||||
|
#include "../../core/types.h"
|
||||||
|
#include "nav.c"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void updateNPC(F32 delta, NPC *npc, World *world) {
|
||||||
|
switch (npc->mode) {
|
||||||
|
case NPC_ACTION_WAITING:
|
||||||
|
npc->waitTime+=delta;
|
||||||
|
if(npc->waitTime > npc->maxWaitTime) {
|
||||||
|
npc->mode = NPC_ACTION_WALKING;
|
||||||
|
U32 next = npc->targetNavNode == 100 ? 20 : 100;
|
||||||
|
npc->targetNavNode = next; // TODO RANDOM
|
||||||
|
printf("Starting to nav path\n");
|
||||||
|
npc->path = Nav_Path(world->navMesh, npc->currentNavNode, npc->targetNavNode);
|
||||||
|
printf("done\n");
|
||||||
|
npc->walkTimer = 0;
|
||||||
|
printf("%*.s started walking to %d\n", Sv(npc->name), npc->targetNavNode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NPC_ACTION_WALKING:
|
||||||
|
npc->walkTimer+=delta;
|
||||||
|
if(npc->walkTimer >= NPC_SPEED){
|
||||||
|
npc->walkTimer = 0;
|
||||||
|
if(npc->path.nodeCount == npc->pathIndex+1){
|
||||||
|
printf("Finished! so I'm waiting");
|
||||||
|
npc->mode = NPC_ACTION_WAITING;
|
||||||
|
npc->maxWaitTime = 20; // TODO RANDOM
|
||||||
|
npc->waitTime = 0;
|
||||||
|
npc->pathIndex = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
npc->pathIndex+=1;
|
||||||
|
npc->currentNavNode = npc->path.indexes[npc->pathIndex];
|
||||||
|
}
|
||||||
|
NavNode cNav = world->navMesh.nodes[npc->currentNavNode];
|
||||||
|
NavNode tNav = world->navMesh.nodes[npc->pathIndex];
|
||||||
|
npc->collision.pos.x = cNav.pos.x * (1 - npc->walkTimer/NPC_SPEED) + tNav.pos.x * npc->walkTimer/NPC_SPEED;
|
||||||
|
npc->collision.pos.y = cNav.pos.y * (1 - npc->walkTimer/NPC_SPEED) + tNav.pos.y * npc->walkTimer/NPC_SPEED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateNPCs(F32 delta, World *world) {
|
||||||
|
for(int i = 0; i < world->npcCount; i++) {
|
||||||
|
updateNPC(delta, &world->npcs[i], world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,31 @@
|
|||||||
#if !defined(LD_GAME_NPC_H_)
|
#if !defined(LD_GAME_NPC_H_)
|
||||||
#define LD_GAME_NPC_H_
|
#define LD_GAME_NPC_H_
|
||||||
#include "aabb.h"
|
#include "aabb.h"
|
||||||
|
#include "nav.h"
|
||||||
|
#include "../core/types.h"
|
||||||
|
|
||||||
|
#define NPC_SPEED 0.2
|
||||||
|
|
||||||
|
typedef enum NPC_ACTION NPC_ACTION;
|
||||||
|
enum NPC_ACTION {
|
||||||
|
// Waiting can be at any point of interest
|
||||||
|
NPC_ACTION_WAITING,
|
||||||
|
// Walking is when they are actively moving somewhere
|
||||||
|
NPC_ACTION_WALKING,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct NPC NPC;
|
typedef struct NPC NPC;
|
||||||
struct NPC {
|
struct NPC {
|
||||||
AABB collision;
|
AABB collision;
|
||||||
|
Str8 name;
|
||||||
|
NPC_ACTION mode;
|
||||||
|
F32 waitTime;
|
||||||
|
F32 maxWaitTime;
|
||||||
|
NavPath path;
|
||||||
|
U32 currentNavNode;
|
||||||
|
U32 pathIndex;
|
||||||
|
U32 targetNavNode;
|
||||||
|
F32 walkTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LD_GAME_NPC_H_
|
#endif // LD_GAME_NPC_H_
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "core/types.h"
|
#include "../core/types.h"
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
#include "../core/macros.h"
|
#include "../core/macros.h"
|
||||||
|
|
||||||
@@ -8,4 +8,4 @@ struct Player
|
|||||||
V2f pos;
|
V2f pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
function void PlayerUpdate(SDL_Event *event, Player *player);
|
function void PlayerUpdate(SDL_Event *event, Player *player);
|
||||||
|
|||||||
35012
code/game/testnavmesh.h
Normal file
35012
code/game/testnavmesh.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,24 @@
|
|||||||
#if !defined(LD_GAME_WORLD_H_)
|
#if !defined(LD_GAME_WORLD_H_)
|
||||||
#define LD_GAME_WORLD_H_
|
#define LD_GAME_WORLD_H_
|
||||||
|
#include "player.h"
|
||||||
|
#include "npc.h"
|
||||||
|
|
||||||
|
// Areas are which
|
||||||
|
enum AREA {
|
||||||
|
WORLD_AREA_OUTSIDE = 1,
|
||||||
|
WORLD_AREA_SALOON = 1 << 1,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct World World;
|
typedef struct World World;
|
||||||
struct World {
|
struct World {
|
||||||
NPC[128] npcs;
|
U32 npcCount;
|
||||||
u32 npcCount;
|
NPC npcs[128];
|
||||||
|
NavMesh navMesh;
|
||||||
|
// NPC points of interest, places to walk to.
|
||||||
|
U32 npcPOI[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function void updateWorld(F32 delta, World *world);
|
||||||
|
function void UpdateNPCs(F32 delta, World *world);
|
||||||
|
|
||||||
#endif // LD_GAME_WORLD_H_
|
#endif // LD_GAME_WORLD_H_
|
||||||
|
|||||||
Reference in New Issue
Block a user