Use image size instead of screen size

This commit is contained in:
Joseph Ferano 2024-08-18 15:34:54 +07:00
parent 633ddb73c1
commit 52a0002eb0

View File

@ -6,15 +6,22 @@
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 800
#define IMG_W SCREEN_WIDTH
#define IMG_H SCREEN_HEIGHT
#define IMG_SIZE SCREEN_WIDTH * SCREEN_HEIGHT
#define IMG_W 500
#define IMG_H 400
#define IMG_SIZE IMG_W * IMG_H
#define TARGET_FPS 120
const int maxRadius = 25;
const int paintTankMax = 250;
const Color playerColor = { 0, 121, 241, 255 };
typedef enum Direction {
NORTH,
WEST,
EAST,
SOUTH,
} Direction;
typedef struct Pixel {
int x;
int y;
@ -40,8 +47,9 @@ typedef struct GameState {
int fillCount;
} GameState;
int PixelToIndex(Pixel p) {return p.y * SCREEN_WIDTH + p.x;}
Pixel IndexToPixel(int idx) {return (Pixel) {idx % SCREEN_WIDTH, (int)(idx / SCREEN_WIDTH) }; }
int PixelToIndex(Pixel p) {return p.y * IMG_W + p.x;}
Pixel IndexToPixel(int idx) {return (Pixel) {idx % IMG_W, (int)(idx / IMG_W) }; }
Pixel IsInBounds(int idx, Direction direction) {return (Pixel) {idx % IMG_W, (int)(idx / IMG_W) }; }
GameState *Init() {
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Flood Fill");
@ -59,7 +67,7 @@ GameState *Init() {
.fill = RL_CALLOC(IMG_SIZE, sizeof(Pixel)),
};
int r = 150;
int r = IMG_W * 0.2f;
ImageDrawCircle(&state.imageBuffer, 0, 0, r, playerColor);
ImageDrawCircle(&state.imageBuffer, IMG_W, 0, r, GREEN);
ImageDrawCircle(&state.imageBuffer, 0, IMG_H, r, VIOLET);
@ -88,7 +96,7 @@ void Update(GameState *S) {
Vector2 joystickDelta = Vector2Normalize(dist);
Vector2 dir = Vector2Normalize(joystickDelta);
S->playerDir = Vector2Lerp(S->playerDir, dir, S->dt * 5.0f);
S->playerPos = Vector2Add(S->playerPos, Vector2Scale(S->playerDir, 180.0f * S->dt));
S->playerPos = Vector2Add(S->playerPos, Vector2Scale(S->playerDir, 100.0f * S->dt));
Vector2 minBounds = (Vector2){25.0f, 25.0f};
Vector2 maxBounds = (Vector2){SCREEN_WIDTH - 25.0f, SCREEN_HEIGHT - 25.0f};
S->playerPos = Vector2Clamp(S->playerPos, minBounds, maxBounds);
@ -106,7 +114,7 @@ void Update(GameState *S) {
S->paintTank += 4;
S->paintTank = S->paintTank > paintTankMax ? paintTankMax : S->paintTank;
} else {
S->paintTank -= 4;
S->paintTank -= 1;
S->paintTank = S->paintTank < 0 ? 0 : S->paintTank;
}
if (S->paintTank > 0 && !sameColor) {
@ -124,6 +132,7 @@ void Update(GameState *S) {
Pixel pixel = IndexToPixel(i);
Color color = GetImageColor(S->imageBuffer, pixel.x, pixel.y);
bool sameColor = ColorIsEqual(color, playerColor);
// printf("X: %d Y: %d - C: %d IDX: %d \n", pixel.x, pixel.y, sameColor, S->bfsBuffer[i]);
if (S->bfsBuffer[i] != 0 || sameColor) {
continue;
}
@ -134,15 +143,18 @@ void Update(GameState *S) {
Pixel pixel = S->queue[S->q_head++];
int idx = PixelToIndex(pixel);
int left = pixel.y * IMG_W - idx - 1 >= 0 ? idx - 1 : -1;
int right = pixel.y * IMG_W - idx + 1 < IMG_W ? idx + 1 : IMG_W;
int left = abs(pixel.y * IMG_W - idx) - 1 >= 0 ? idx - 1 : -1;
int right = abs(pixel.y * IMG_W - idx) + 1 < IMG_W ? idx + 1 : IMG_W;
int top = idx - IMG_W;
int bottom = idx + IMG_W;
int directions[] = { left, right, top, bottom };
printf("=========================\n");
for (int i = 0; i < 4; i++) {
int j = directions[i];
if (j >= 0 && j < IMG_W) {
// printf("IDX: %d ||| %d %d %d %d \n", idx, left, right, top, bottom);
if ((i < 2 && j >= 0 && j < IMG_W) || (i >= 2 && j >= 0 && j < IMG_SIZE)) {
Pixel pixel = IndexToPixel(j);
printf("PX: %d PY: %d\n", pixel.x, pixel.y);
Color c = GetImageColor(S->imageBuffer, pixel.x, pixel.y);
if (S->bfsBuffer[j] == 0 && !ColorIsEqual(playerColor, c)) {
S->queue[S->q_tail++] = pixel;
@ -158,6 +170,7 @@ void Update(GameState *S) {
S->fill[S->fillCount++] = pixel;
}
}
printf("------------------\n");
// Fill that sucker
if (!edgeDetected) {
for (int i = 0; i < S->fillCount; i++) {
@ -173,7 +186,9 @@ void Update(GameState *S) {
}
void Draw2D(const GameState *S) {
DrawTexture(S->displayTexture, 0, 0, WHITE);
Rectangle source = {0, 0, IMG_W, IMG_H};
Rectangle dest = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
DrawTexturePro(S->displayTexture, source, dest, (Vector2){0,0}, 0, WHITE);
DrawCircleV(S->playerPos, 20, BLACK);
Vector2 lookPos = Vector2Scale(S->playerDir, 50.0f);
lookPos = Vector2Add(S->playerPos, lookPos);