diff --git a/assets/PublicPixel.ttf b/assets/PublicPixel.ttf new file mode 100644 index 0000000..f6c69fe Binary files /dev/null and b/assets/PublicPixel.ttf differ diff --git a/items/item.c b/items/item.c index 58230c2..72d8bd6 100644 --- a/items/item.c +++ b/items/item.c @@ -6,6 +6,7 @@ #include "../tiles/tile.h" #include "../util/util.h" #include "../player/player.h" +#include "../util/font.h" #include Item ItemRegistry[ITEMREGISTRY_SIZE]; @@ -13,61 +14,84 @@ Item ItemRegistry[ITEMREGISTRY_SIZE]; uint16_t itemRegistryIndex = 0; void updateItems() { + const int dirDx[8] = {-1, -1, -1, 0, 1, 1, 1, 0}; + const int dirDy[8] = {1, 0, -1, -1, -1, 0, 1, 1}; + + const float speed = 0.002f; // fraction of tile per tick + const float epsilon = 0.999f; // if we can't move, back it off just below 1 + for (int y = 0; y < MAP_HEIGHT; y++) { for (int x = 0; x < MAP_WIDTH; x++) { Tile *t = &tileMap[y][x]; + if (t->type != TYPE_BELT) continue; + int dir = t->direction; + + bool horz = (dir == ORIENT_LEFT || dir == ORIENT_RIGHT); + bool vert = (dir == ORIENT_UP || dir == ORIENT_DOWN); + for (uint8_t lane = 0; lane < 2; lane++) { - for (uint8_t itemIndex = 0; itemIndex < 2; itemIndex++) { - if (t->type != TYPE_BELT || !t->items[lane][itemIndex].active) continue; + for (uint8_t slot = 0; slot < 2; slot++) { + ItemOnBelt *itm = &t->items[lane][slot]; + if (!itm->active) continue; - if ( - (t->items[lane][itemIndex].x < -0.5 && t->direction == ORIENT_LEFT) || - (t->items[lane][itemIndex].x > 1 && t->direction == ORIENT_RIGHT) || - (t->items[lane][itemIndex].y < -0.5 && t->direction == ORIENT_UP) || - (t->items[lane][itemIndex].y > 1 && t->direction == ORIENT_DOWN) - ) { - int nx = x, ny = y; - if (t->direction == ORIENT_LEFT) nx--; - if (t->direction == ORIENT_RIGHT) nx++; - if (t->direction == ORIENT_UP) ny--; - if (t->direction == ORIENT_DOWN) ny++; - if (nx >= 0 && nx < MAP_WIDTH && ny >= 0 && ny < MAP_HEIGHT) { - Tile *next = &tileMap[ny][nx]; - if (next->type == TYPE_BELT && !next->items[lane][itemIndex].active) { - memcpy(&next->items[lane][itemIndex], &t->items[lane][itemIndex], sizeof(ItemOnBelt)); - printf("Moved to X=%d, Y=%d\n", nx, ny); - next->items[lane][itemIndex].tileX = nx; - next->items[lane][itemIndex].tileY = ny; - if (t->direction == ORIENT_LEFT) next->items[lane][itemIndex].x = 0.5f; - if (t->direction == ORIENT_RIGHT) next->items[lane][itemIndex].x = 0; - if (t->direction == ORIENT_UP) next->items[lane][itemIndex].y = 0.5f; - if (t->direction == ORIENT_DOWN) next->items[lane][itemIndex].y = 0; - next->items[lane][itemIndex].active = true; - t->items[lane][itemIndex].active = false; - } else { - continue; - } - } else { - t->items[lane][itemIndex].active = false; + // 1) Advance + itm->offset += speed; + + // 2) Time to hop? + if (itm->offset >= 0.5f) { + itm->offset -= 1.0f; + + // target coords + int nx = x + dirDx[dir]; + int ny = y + dirDy[dir]; + + // bounds & belt? + if (nx < 0 || nx >= MAP_WIDTH || ny < 0 || ny >= MAP_HEIGHT) { + itm->active = false; + continue; + } + Tile *next = &tileMap[ny][nx]; + if (next->type != TYPE_BELT) { + itm->active = false; + continue; } - } - float speed = 0.002f; - switch (t->direction) { - case ORIENT_LEFT: - t->items[lane][itemIndex].x -= speed; - break; - case ORIENT_RIGHT: - t->items[lane][itemIndex].x += speed; - break; - case ORIENT_UP: - t->items[lane][itemIndex].y -= speed; - break; - case ORIENT_DOWN: - t->items[lane][itemIndex].y += speed; - break; - default: - break; + // Decide new lane + int newLane = lane; + int newDir = next->direction; + bool nH = (newDir == ORIENT_LEFT || newDir == ORIENT_RIGHT); + bool nV = (newDir == ORIENT_UP || newDir == ORIENT_DOWN); + + if ((horz && nH) || (vert && nV)) { + // same axis → keep lane + } else if (horz && nV) { + // came off a horizontal: lane0=top→vertical.left, lane1=bottom→vertical.right + newLane = (dir == ORIENT_LEFT ? 1 : 0); + } else if (vert && nH) { + // came off vertical: lane0=left→horizontal.top, lane1=right→horizontal.bottom + newLane = (dir == ORIENT_UP ? 0 : 1); + } + // (diagonals fall back to same-lane) + + // Find a free slot in newLane + int destSlot = -1; + if (!next->items[newLane][0].active) destSlot = 0; + else if (!next->items[newLane][1].active) destSlot = 1; + + if (destSlot >= 0) { + // MOVE it + ItemOnBelt moved = *itm; + moved.tileX = nx; + moved.tileY = ny; + next->items[newLane][destSlot] = moved; + next->items[newLane][destSlot].active = true; + + // clear this one + itm->active = false; + } else { + // both slots full → wait at end + itm->offset = epsilon; + } } } } @@ -75,6 +99,7 @@ void updateItems() { } } + void registerItem(char name[20], SDL_Renderer *renderer) { const char *dot = strchr(name, '.'); memcpy(ItemRegistry[itemRegistryIndex].name, name, dot - name); @@ -90,14 +115,96 @@ void registerItem(char name[20], SDL_Renderer *renderer) { itemRegistryIndex++; } -void renderItem(ItemOnBelt item, SDL_Renderer *renderer) { +void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane) { SDL_Rect rect = {0}; - rect.x = (item.tileX * TILE_SIZE) + (item.x * TILE_SIZE); - rect.y = (item.tileY * TILE_SIZE) + (item.y * TILE_SIZE); + rect.x = item.tileX * TILE_SIZE; + rect.y = item.tileY * TILE_SIZE; + + int dir = tileMap[item.tileY][item.tileX].direction; + int offset = item.offset * TILE_SIZE; + + int dx = 0, dy = 0; // Direction vector + switch (dir) { + case ORIENT_LEFT_DOWN: + dx = -1; + dy = 1; + break; + case ORIENT_LEFT: + dx = -1; + dy = 0; + break; + case ORIENT_LEFT_UP: + dx = -1; + dy = -1; + break; + case ORIENT_UP: + dx = 0; + dy = -1; + break; + case ORIENT_RIGHT_UP: + dx = 1; + dy = -1; + break; + case ORIENT_RIGHT: + dx = 1; + dy = 0; + break; + case ORIENT_RIGHT_DOWN: + dx = 1; + dy = 1; + break; + case ORIENT_DOWN: + dx = 0; + dy = 1; + break; + default: + break; + } + + // Main offset along belt direction + int xOffset = (offset * dx) % TILE_SIZE; + int yOffset = (offset * dy) % TILE_SIZE; + + // Perpendicular vector: (dy, -dx) + + float perpX = dy; + float perpY = -dx; + + float length = sqrtf(perpX * perpX + perpY * perpY); + if (length != 0) { + perpX /= length; + perpY /= length; + } + + // Lane offset distance + float laneOffset = (lane == 1 ? 1.0f : -1.0f); + + xOffset += (int) (perpX * laneOffset * (TILE_SIZE / 2)); + yOffset += (int) (perpY * laneOffset * (TILE_SIZE / 2)); + + rect.x += xOffset; + rect.y += yOffset; + rect.w = TILE_SIZE / 2; rect.h = TILE_SIZE / 2; + adjustRect(&rect); + SDL_Rect rectA = {0}; + rectA.x = item.tileX * TILE_SIZE; + rectA.y = item.tileY * TILE_SIZE; + rectA.w = TILE_SIZE; + rectA.h = TILE_SIZE; + char tempStr[20]; + sprintf(tempStr, "L%d\n%f\n%d\n%d", lane, item.offset, xOffset, yOffset); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 32); + adjustRect(&rectA); + SDL_RenderFillRect(renderer, &rectA); SDL_RenderCopy(renderer, ItemRegistry[item.type].textureOnBelt, NULL, &rect); + SDL_Texture *oldRenderTarget = SDL_GetRenderTarget(renderer); + SDL_SetRenderTarget(renderer, NULL); + renderText(renderer, fonts[3], tempStr, rectA.x, rectA.y); + SDL_SetRenderTarget(renderer, oldRenderTarget); } void renderBeltItems(SDL_Renderer *renderer) { @@ -106,12 +213,7 @@ void renderBeltItems(SDL_Renderer *renderer) { void putItem(int x, int y, uint16_t itemType, uint8_t lane, uint8_t itemIndex) { tileMap[y][x].items[lane][itemIndex].type = itemType; - tileMap[y][x].items[lane][itemIndex].x = 0.25f; - tileMap[y][x].items[lane][itemIndex].y = 0.25f; - if (tileMap[y][x].direction == ORIENT_LEFT) tileMap[y][x].items[lane][itemIndex].x = 0.5f; - if (tileMap[y][x].direction == ORIENT_RIGHT) tileMap[y][x].items[lane][itemIndex].x = 0.25f; - if (tileMap[y][x].direction == ORIENT_UP) tileMap[y][x].items[lane][itemIndex].y = 0.5f; - if (tileMap[y][x].direction == ORIENT_DOWN) tileMap[y][x].items[lane][itemIndex].y = 0.25f; + tileMap[y][x].items[lane][itemIndex].offset = 0; tileMap[y][x].items[lane][itemIndex].active = true; tileMap[y][x].items[lane][itemIndex].tileX = x; tileMap[y][x].items[lane][itemIndex].tileY = y; diff --git a/items/item.h b/items/item.h index 56e8160..978ca0d 100644 --- a/items/item.h +++ b/items/item.h @@ -19,18 +19,17 @@ typedef struct { extern Item ItemRegistry[ITEMREGISTRY_SIZE]; typedef struct { - float x, y; // local position in tile (0.0–1.0) + float offset; int tileX, tileY; bool active; uint16_t type; - uint8_t place; } ItemOnBelt; void updateItems(); void loadItems(SDL_Renderer *renderer); -void renderItem(ItemOnBelt item, SDL_Renderer *renderer); +void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane); void putItem(int x, int y, uint16_t itemType, uint8_t lane, uint8_t itemIndex); #endif //FACTORYGAME_ITEM_H diff --git a/main.c b/main.c index 5134b52..67427f2 100644 --- a/main.c +++ b/main.c @@ -25,10 +25,8 @@ SDL_Renderer *renderer = NULL; #define biggerFont fonts[0] #define smallFont fonts[1] #define smallerFont fonts[2] +#define smallestFont fonts[3] -#define fontCount 3 - -BitmapFont fonts[fontCount]; unsigned long frames = 0; bool cursor = true; @@ -110,9 +108,10 @@ int init() { SDL_RenderSetViewport(renderer, &viewport); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - biggerFont = prepText(renderer, 16, "PublicPixel.ttf", 255, 255, 255, 255); - smallFont = prepText(renderer, 12, "PublicPixel.ttf", 255, 255, 255, 255); - smallerFont = prepText(renderer, 8, "PublicPixel.ttf", 255, 255, 255, 255); + biggerFont = prepText(renderer, 16, "assets/PublicPixel.ttf", 255, 255, 255, 255); + smallFont = prepText(renderer, 12, "assets/PublicPixel.ttf", 255, 255, 255, 255); + smallerFont = prepText(renderer, 8, "assets/PublicPixel.ttf", 255, 255, 255, 255); + smallestFont = prepText(renderer, 4, "assets/PublicPixel.ttf", 255, 255, 255, 255); SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); generateTestMap(); diff --git a/tiles/belt.c b/tiles/belt.c index e9daaf8..db6d0ad 100644 --- a/tiles/belt.c +++ b/tiles/belt.c @@ -90,7 +90,7 @@ void renderAllBelts(SDL_Renderer *renderer) { for (uint8_t lane = 0; lane < 2; lane++) { for (uint8_t itemIndex = 0; itemIndex < 2; itemIndex++) { if (t.items[lane][itemIndex].active) { - renderItem(t.items[lane][itemIndex], renderer); + renderItem(t.items[lane][itemIndex], renderer, lane); } } } diff --git a/util/font.c b/util/font.c index b8371a4..8b526f8 100644 --- a/util/font.c +++ b/util/font.c @@ -4,6 +4,9 @@ #include "font.h" +BitmapFont fonts[fontCount]; + + BitmapFont prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { TTF_Font *gFont = TTF_OpenFont(file, pxSize); diff --git a/util/font.h b/util/font.h index 98272a2..e1f119b 100644 --- a/util/font.h +++ b/util/font.h @@ -9,6 +9,8 @@ #include #include +#define fontCount 4 + typedef struct { SDL_Texture *texture[256]; SDL_Surface *surface[256]; @@ -16,6 +18,8 @@ typedef struct { SDL_Color color; } BitmapFont; +extern BitmapFont fonts[fontCount]; + BitmapFont prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file, uint8_t r, uint8_t g, uint8_t b, uint8_t a);