Fixed rotation completely?

This commit is contained in:
Carlos Sanchez 2024-08-21 17:48:58 -04:00
parent 819f7e7f76
commit 29c5ece6da
4 changed files with 1376 additions and 40 deletions

4
ecs2.h
View File

@ -5,7 +5,7 @@
#ifndef __HALOO3D_ECS2_H #ifndef __HALOO3D_ECS2_H
#define __HALOO3D_ECS2_H #define __HALOO3D_ECS2_H
#include <stdint.h> #include <string.h>
#ifndef ECS_MAXENTITIES #ifndef ECS_MAXENTITIES
#define ECS_MAXENTITIES 1024 #define ECS_MAXENTITIES 1024
@ -13,7 +13,7 @@
#define ECS_MAXCTYPES 63 // uint64 bits minus one #define ECS_MAXCTYPES 63 // uint64 bits minus one
typedef uint64_t ecs_cid; typedef unsigned long long ecs_cid;
typedef int ecs_eid; typedef int ecs_eid;
#define ECS_START(name) \ #define ECS_START(name) \

@ -1 +1 @@
Subproject commit 92fd1294cb6b910f7de2817d60b536738a2ecc7a Subproject commit 8d814bd4abae2fb0113e5675f838ed2caa4e938f

70
maze.c
View File

@ -17,8 +17,8 @@
// INteresting flags for performance comparisons // INteresting flags for performance comparisons
#define FASTFILL #define FASTFILL
#define WIDTH 480 #define WIDTH 320
#define HEIGHT 300 #define HEIGHT 200
#define ASPECT ((float)WIDTH / HEIGHT) #define ASPECT ((float)WIDTH / HEIGHT)
#define SCREENSCALE 2 #define SCREENSCALE 2
#define SWIDTH (WIDTH * SCREENSCALE) #define SWIDTH (WIDTH * SCREENSCALE)
@ -29,7 +29,7 @@
#define AVGWEIGHT 0.85 #define AVGWEIGHT 0.85
// Game options // Game options
#define MAZESIZE 5 #define MAZESIZE 15
#define HSCALE 1.5 #define HSCALE 1.5
// Maze grows in the positive direction // Maze grows in the positive direction
@ -444,18 +444,30 @@ enum {
// State for tracking a smart ai moving through the maze. // State for tracking a smart ai moving through the maze.
typedef struct { typedef struct {
uint8_t state; uint8_t state;
uint8_t rotstate; // uint8_t rotstate;
uint8_t dir; uint8_t dir;
uint32_t timer; uint32_t timer;
mfloat_t rotchange;
struct vec2i mpos; struct vec2i mpos;
worldstate *ws; worldstate *ws;
haloo3d_obj_instance *startmarker; haloo3d_obj_instance *startmarker;
} ecs_smartai; } ecs_smartai;
int smartai_mazeend(ecs_smartai *smartai) {
if (smartai->mpos.x == smartai->ws->end.x &&
smartai->mpos.y == smartai->ws->end.y) {
eprintf("YOU WIN\n");
smartai->ws->state = WSTATE_GAMEOVER;
smartai->state = SAI_INIT;
return 1;
}
return 0;
}
static void sys_smartai(ecs_smartai *smartai, ecs_placement *p, static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
ecs_autonav *anav, ecs_autorotate *arot) { ecs_autonav *anav, ecs_autorotate *arot) {
const int actiontime = smartai->ws->fps / (2 * speed); const int actiontime = smartai->ws->fps / (2 * speed);
const int rotdelaytime = 2 * actiontime / 5; const int rotdelaytime = actiontime / 2; // 2 * actiontime / 5;
switch (smartai->state) { switch (smartai->state) {
case SAI_INIT: case SAI_INIT:
// Here, we wait until the world state is spinup, in which // Here, we wait until the world state is spinup, in which
@ -498,32 +510,19 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
// a tile. I instead calculate that in the middle of the tile. It doesn't // a tile. I instead calculate that in the middle of the tile. It doesn't
// really line up like it does on the windows screensaver but it's // really line up like it does on the windows screensaver but it's
// close enough for me. // close enough for me.
if (smartai->timer == 0) { if (smartai->timer == 0 && smartai->rotchange) {
if (smartai->rotstate == 1) { eprintf("TURNING BY %f\n", smartai->rotchange);
eprintf("TURNING RIGHT\n"); arot->dest.x += smartai->rotchange;
arot->dest.x += MPI_2; smartai->rotchange = 0;
arot->timer = actiontime; arot->timer = actiontime;
smartai->dir = TURNRIGHT(smartai->dir);
smartai->rotstate = 0;
} else if (smartai->rotstate == 2) {
eprintf("TURNING LEFT\n");
arot->dest.x -= MPI_2;
arot->timer = actiontime;
smartai->dir = TURNLEFT(smartai->dir);
smartai->rotstate = 0;
}
} }
// Only decide to do things if you're not moving anymore. Movement is the // Only decide to do things if you're not moving anymore. Movement is the
// most important thing // most important thing
if (anav->timer == 0) { if (anav->timer == 0) {
eprintf("SMARTAI: %d TIMER: %d DIR: %d POS: (%f, %f)\n", eprintf("SMARTAI: %f TIMER: %d DIR: %d POS: (%f, %f)\n",
smartai->rotstate, smartai->timer, smartai->dir, p->pos.x, smartai->rotchange, smartai->timer, smartai->dir, p->pos.x,
p->pos.z); p->pos.z);
if (smartai->mpos.x == smartai->ws->end.x && if (smartai_mazeend(smartai)) {
smartai->mpos.y == smartai->ws->end.y) {
eprintf("YOU WIN\n");
smartai->ws->state = WSTATE_GAMEOVER;
smartai->state = SAI_INIT;
return; return;
} }
// Player can only move forward if there's nothing in front of them // Player can only move forward if there's nothing in front of them
@ -535,10 +534,9 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
anav->timer = actiontime; anav->timer = actiontime;
anav->dest.x = p->pos.x + smartai->ws->cellsize * movement.x; anav->dest.x = p->pos.x + smartai->ws->cellsize * movement.x;
anav->dest.z = p->pos.z + smartai->ws->cellsize * movement.y; anav->dest.z = p->pos.z + smartai->ws->cellsize * movement.y;
smartai->rotstate = 0;
} }
// Figure out if a rotation should be scheduled // Figure out if a rotation should be scheduled
if (smartai->timer <= 0 && !(smartai->mpos.x == smartai->ws->end.x && if (!(smartai->mpos.x == smartai->ws->end.x &&
smartai->mpos.y == smartai->ws->end.y)) { smartai->mpos.y == smartai->ws->end.y)) {
// Ok we might be moving, we might not be. Let's go ahead and calculate // Ok we might be moving, we might not be. Let's go ahead and calculate
// rotation based on the FUTURE direction we want to turn. // rotation based on the FUTURE direction we want to turn.
@ -547,18 +545,26 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y, if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
MAZESIZE, rightdir)) { MAZESIZE, rightdir)) {
// Always choose right over left // Always choose right over left
smartai->rotstate = 1; smartai->rotchange += MPI_2;
smartai->timer = rotdelaytime; smartai->timer = rotdelaytime;
smartai->dir = TURNRIGHT(smartai->dir);
eprintf("WILL TURN RIGHT TO: %d\n", rightdir); eprintf("WILL TURN RIGHT TO: %d\n", rightdir);
} else if (!maze_connected(smartai->ws->maze, smartai->mpos.x, } else {
// This while loop lets us turn around if necessary, so reaching a
// dead end isn't super painful waiting for two rotations
while (!maze_connected(smartai->ws->maze, smartai->mpos.x,
smartai->mpos.y, MAZESIZE, smartai->dir)) { smartai->mpos.y, MAZESIZE, smartai->dir)) {
// We only move left if the player can't move forward or right // We seem to have reached a wall. Do we need to turn ALL the way
smartai->rotstate = 2; // around? We only move left if the player can't move forward or
// right
smartai->rotchange -= MPI_2;
smartai->timer = rotdelaytime; smartai->timer = rotdelaytime;
smartai->dir = TURNLEFT(smartai->dir);
eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir); eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir);
} }
} }
} }
}
break; break;
} }
@ -850,7 +856,7 @@ int main() { // int argc, char **argv) {
ECS_SETCOMPONENT(&ecs, playerid, ecs_autorotate){.timer = 0}; ECS_SETCOMPONENT(&ecs, playerid, ecs_autorotate){.timer = 0};
ECS_SETCOMPONENT(&ecs, playerid, ecs_smartai){.state = SAI_INIT, ECS_SETCOMPONENT(&ecs, playerid, ecs_smartai){.state = SAI_INIT,
.ws = &wstate, .ws = &wstate,
.rotstate = 0, .rotchange = 0,
.timer = 0, .timer = 0,
.startmarker = starti}; .startmarker = starti};

1330
resources/specwall.ppm Normal file

File diff suppressed because one or more lines are too long