hot entity on entity action

This commit is contained in:
2025-06-19 09:55:56 -05:00
parent 04158a1ad2
commit 78837b3212
14 changed files with 414 additions and 86 deletions

View File

@ -440,6 +440,24 @@
"template":"templates\/NPC.tx",
"x":6627,
"y":6828.33333333333
},
{
"id":8,
"template":"templates\/NPC.tx",
"x":6640,
"y":6817
},
{
"id":9,
"template":"templates\/NPC.tx",
"x":6639.66666666667,
"y":6839
},
{
"id":10,
"template":"templates\/NPC.tx",
"x":6653.66666666667,
"y":6832
}],
"opacity":1,
"type":"objectgroup",
@ -448,7 +466,7 @@
"y":0
}],
"nextlayerid":6,
"nextobjectid":8,
"nextobjectid":11,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.11.1",

View File

@ -25,5 +25,6 @@ target_sources(${DUSK_TARGET_NAME}
add_subdirectory(assert)
add_subdirectory(display)
add_subdirectory(entity)
add_subdirectory(physics)
add_subdirectory(util)
add_subdirectory(world)

View File

@ -8,6 +8,8 @@
#include "entity.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "world/world.h"
#include "physics/physics.h"
entity_t ENTITIES[ENTITY_COUNT_MAX] = {0};
@ -43,6 +45,50 @@ void entityUpdate(entity_t *entity) {
ENTITY_CALLBACKS[entity->type].update(entity);
entity->x += entity->vx;
entity->y += entity->vy;
if(
entity->vx == FIXED248(0, 0) &&
entity->vy == FIXED248(0, 0)
) return;
fixed248_t newX = entity->x + entity->vx;
fixed248_t newY = entity->y + entity->vy;
// Check for collisions with the world boundaries
// Check for collisions with tiles
// Check for collisions with other entities
fixed248_t halfTileW = FIXED248(TILE_WIDTH_HEIGHT / 2, 0);
fixed248_t halfTileH = FIXED248(TILE_WIDTH_HEIGHT / 2, 0);
fixed248_t selfCircR = halfTileW;
fixed248_t selfCircX = newX - halfTileW;
fixed248_t selfCircY = newY - halfTileH;
for(entity_t *otherEntity = ENTITIES; otherEntity < ENTITIES + ENTITY_COUNT_MAX; ++otherEntity) {
// Skip self and null entities
if(otherEntity == entity || otherEntity->type == ENTITY_TYPE_NULL) continue;
fixed248_t otherCircX = otherEntity->x - halfTileW;
fixed248_t otherCircY = otherEntity->y - halfTileH;
fixed248_t otherCircR = halfTileW;
collisionresult_t collision = physicsCheckCircleCircle(
selfCircX, selfCircY, selfCircR,
otherCircX, otherCircY, otherCircR
);
if(!collision.hit) continue;
// Collision with entity detected. Slide out of collision.
fixed248_t slideX = fx248Mulf32(collision.normalX, fx248Tof32(collision.depth));
fixed248_t slideY = fx248Mulf32(collision.normalY, fx248Tof32(collision.depth));
newX -= slideX;
newY -= slideY;
// Update selfCircX/Y for next collision check
selfCircX = newX - halfTileW;
selfCircY = newY - halfTileH;
}
entity->x = newX;
entity->y = newY;
}

View File

@ -10,6 +10,7 @@
#include "input.h"
#include "display/render.h"
#include "world/world.h"
#include "physics/physics.h"
void playerInit() {
entity_t *ent = &ENTITIES[0];

View File

@ -0,0 +1,10 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
physics.c
)

View File

@ -0,0 +1,52 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "physics.h"
collisionresult_t physicsCheckCircleCircle(
fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r,
fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r
) {
collisionresult_t result;
// Compute vector between centers
fixed248_t dx = fx248Subfx248(circle1x, circle0x);
fixed248_t dy = fx248Subfx248(circle1y, circle0y);
// Distance squared between centers
fixed248_t distSq = fx248Addfx248(
fx248Mulfx248(dx, dx),
fx248Mulfx248(dy, dy)
);
// Sum of radii
fixed248_t rSum = fx248Addfx248(circle0r, circle1r);
fixed248_t rSumSq = fx248Mulfx248(rSum, rSum);
if(distSq > rSumSq) {
// No collision
result.hit = false;
return result;
}
// Collision: calculate normal and penetration depth
fixed248_t dist = fx248Sqrt(distSq);
// If centers are the same, pick arbitrary normal (1,0)
if(dist == 0) {
result.normalX = FIXED248(1,0);
result.normalY = 0;
result.depth = rSum;
} else {
// Normalized direction from circle0 to circle1
result.normalX = fx248Divfx248(dx, dist);
result.normalY = fx248Divfx248(dy, dist);
// Penetration depth = sum of radii - distance
result.depth = fx248Subfx248(rSum, dist);
}
result.hit = true;
return result;
}

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "util/fixed.h"
typedef struct {
bool_t hit;
fixed248_t normalX, normalY;
fixed248_t depth;
} collisionresult_t;
/**
* Check for collision between two circles.
*
* @param circle0x X coordinate of the first circle's center.
* @param circle0y Y coordinate of the first circle's center.
* @param circle0r Radius of the first circle.
* @param circle1x X coordinate of the second circle's center.
* @param circle1y Y coordinate of the second circle's center.
* @param circle1r Radius of the second circle.
* @return A collisionresult_t structure containing collision information.
*/
collisionresult_t physicsCheckCircleCircle(
fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r,
fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r
);

View File

@ -6,59 +6,118 @@
*/
#include "fixed.h"
#include "assert/assert.h"
fixed248_t fx248Fromi32(const int32_t b) {
return (fixed248_t)b << FIXED248_FRACTION_BITS;
}
fixed248_t fx248Fromui32(const uint32_t b) {
return (fixed248_t)b << FIXED248_FRACTION_BITS;
fixed248_t fx248Fromu32(const uint32_t b) {
return (fixed248_t)((int32_t)b << FIXED248_FRACTION_BITS);
}
fixed248_t fx248Fromf32(const float_t b) {
return (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS));
}
int32_t fx248Toi32(const fixed248_t a) {
return (int32_t)(a >> FIXED248_FRACTION_BITS);
}
uint32_t fx248Tou32(const fixed248_t a) {
return (uint32_t)(a >> FIXED248_FRACTION_BITS);
return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF);
}
float_t fx248Tof32(const fixed248_t a) {
return (float_t)(a / (1 << FIXED248_FRACTION_BITS));
return (float_t)(a / (float_t)(1 << FIXED248_FRACTION_BITS));
}
void fx248Addfx248(fixed248_t *a, const fixed248_t b) {
*a += b;
fixed248_t fx248Addfx248(const fixed248_t a, const fixed248_t b) {
return a + b;
}
void fx248Addi32(fixed248_t *a, const int32_t b) {
*a += (fixed248_t)b << FIXED248_FRACTION_BITS;
fixed248_t fx248Addi32(const fixed248_t a, const int32_t b) {
return fx248Addfx248(a, fx248Fromi32(b));
}
void fx248Addui32(fixed248_t *a, const uint32_t b) {
*a += (fixed248_t)b << FIXED248_FRACTION_BITS;
fixed248_t fx248Addu32(const fixed248_t a, const uint32_t b) {
return fx248Addfx248(a, fx248Fromu32(b));
}
void fx248Subfx248(fixed248_t *a, const fixed248_t b) {
*a -= b;
fixed248_t fx248Addf32(const fixed248_t a, const float_t b) {
return fx248Addfx248(a, fx248Fromf32(b));
}
void fx248Subi32(fixed248_t *a, const int32_t b) {
*a -= (fixed248_t)b << FIXED248_FRACTION_BITS;
fixed248_t fx248Subfx248(const fixed248_t a, const fixed248_t b) {
return a - b;
}
void fx248Subui32(fixed248_t *a, const uint32_t b) {
*a -= (fixed248_t)b << FIXED248_FRACTION_BITS;
fixed248_t fx248Subi32(const fixed248_t a, const int32_t b) {
return fx248Subfx248(a, fx248Fromi32(b));
}
void fx248Subf32(fixed248_t *a, const float_t b) {
*a -= (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS));
fixed248_t fx248Subu32(const fixed248_t a, const uint32_t b) {
return fx248Subfx248(a, fx248Fromu32(b));
}
fixed248_t fx248Subf32(const fixed248_t a, const float_t b) {
return fx248Subfx248(a, fx248Fromf32(b));
}
fixed248_t fx248Mulfx248(const fixed248_t a, const fixed248_t b) {
return (fixed248_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS);
}
fixed248_t fx248Muli32(const fixed248_t a, const int32_t b) {
return (fixed248_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS);
}
fixed248_t fx248Mulu32(const fixed248_t a, const uint32_t b) {
return (fixed248_t)(
((int64_t)a * (int64_t)(int32_t)b
) >> FIXED248_FRACTION_BITS);
}
fixed248_t fx248Mulf32(const fixed248_t a, const float_t b) {
return (fixed248_t)((
(int64_t)a * (int64_t)(b * (1 << FIXED248_FRACTION_BITS))
) >> FIXED248_FRACTION_BITS);
}
fixed248_t fx248Divfx248(const fixed248_t a, const fixed248_t b) {
assertFalse(b == 0, "Division by zero in fx248Divfx248");
return (fixed248_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b);
}
fixed248_t fx248Divi32(const fixed248_t a, const int32_t b) {
assertFalse(b == 0, "Division by zero in fx248Divi32");
return (fixed248_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b);
}
fixed248_t fx248Divu32(const fixed248_t a, const uint32_t b) {
assertFalse(b == 0, "Division by zero in fx248Divu32");
return (fixed248_t)(
((int64_t)a << FIXED248_FRACTION_BITS
) / (int64_t)(int32_t)b);
}
fixed248_t fx248Divf32(const fixed248_t a, const float_t b) {
assertFalse(b == 0, "Division by zero in fx248Divf32");
return (fixed248_t)((
(int64_t)a << FIXED248_FRACTION_BITS
) / (int64_t)(b * (1 << FIXED248_FRACTION_BITS)));
}
int32_t fx248Floor(const fixed248_t a) {
return (int32_t)(a >> FIXED248_FRACTION_BITS);
}
@ -76,17 +135,27 @@ int32_t fx248Round(const fixed248_t a) {
}
uint32_t fx248Flooru32(const fixed248_t a) {
return (uint32_t)(a >> FIXED248_FRACTION_BITS);
return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF);
}
uint32_t fx248Ceilu32(const fixed248_t a) {
return (uint32_t)((
a + ((1 << FIXED248_FRACTION_BITS) - 1)
) >> FIXED248_FRACTION_BITS);
return (uint32_t)(((a + ((1 << FIXED248_FRACTION_BITS) - 1)) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF);
}
uint32_t fx248Roundu32(const fixed248_t a) {
return (uint32_t)(
(a + (1 << (FIXED248_FRACTION_BITS - 1))
) >> FIXED248_FRACTION_BITS);
return (uint32_t)(((a + (1 << (FIXED248_FRACTION_BITS - 1))) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF);
}
fixed248_t fx248Sqrt(const fixed248_t a) {
if(a == 0) return 0;
fixed248_t y = a > FIXED248(1, 0) ? a : FIXED248(1, 0);
fixed248_t last = 0;
int max_iter = 16;
while(y != last && max_iter-- > 0) {
last = y;
int32_t div = (int32_t)(((int64_t)a << FIXED248_FRACTION_BITS) / y);
y = (y + div) >> 1;
}
return y;
}

View File

@ -8,10 +8,12 @@
#pragma once
#include "dusk.h"
typedef uint32_t fixed248_t;
typedef int32_t fixed248_t;
#define FIXED248_FRACTION_BITS 8
#define FIXED248_HIGH_MULTIPLIER (1 << FIXED248_FRACTION_BITS)
#define FIXED248_MIN INT32_MIN
#define FIXED248_MAX INT32_MAX
#define FIXED248(i, f) ((fixed248_t)( \
((i) << FIXED248_FRACTION_BITS) + \
(((f) * FIXED248_HIGH_MULTIPLIER) / 100) \
@ -31,7 +33,7 @@ fixed248_t fx248Fromi32(const int32_t b);
* @param b The uint32_t value to convert.
* @return The converted fixed248_t value.
*/
fixed248_t fx248Fromui32(const uint32_t b);
fixed248_t fx248Fromu32(const uint32_t b);
/**
* Convert a float_t value to a fixed248_t value.
@ -41,6 +43,8 @@ fixed248_t fx248Fromui32(const uint32_t b);
*/
fixed248_t fx248Fromf32(const float_t b);
/**
* Convert a fixed248_t value to an int32_t value.
*
@ -65,69 +69,159 @@ uint32_t fx248Tou32(const fixed248_t a);
*/
float_t fx248Tof32(const fixed248_t a);
/**
* Add a fixed248_t value to another fixed248_t value.
*
* @param a Pointer to the first fixed248_t value (will be modified).
* @param b The fixed248_t value to add to the first value.
* @param a First fixed248_t value.
* @param b Second fixed248_t value to add to the first value.
* @return The result of the addition as a fixed248_t value.
*/
void fx248Addfx248(fixed248_t *a, const fixed248_t b);
fixed248_t fx248Addfx248(const fixed248_t a, const fixed248_t b);
/**
* Add an int32_t value to a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param a The fixed248_t value to which the int32_t will be added.
* @param b The int32_t value to add to the fixed248_t value.
* @return The result of the addition as a fixed248_t value.
*/
void fx248Addi32(fixed248_t *a, const int32_t b);
fixed248_t fx248Addi32(const fixed248_t a, const int32_t b);
/**
* Add a uint32_t value to a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param a The fixed248_t value to which the uint32_t will be added.
* @param b The uint32_t value to add to the fixed248_t value.
* @return The result of the addition as a fixed248_t value.
*/
void fx248Addui32(fixed248_t *a, const uint32_t b);
fixed248_t fx248Addu32(const fixed248_t a, const uint32_t b);
/**
* Add a float_t value to a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The float_t value to add to the fixed248_t value.
* @return The result of the addition as a fixed248_t value.
*/
void fx248Addf32(fixed248_t *a, const float_t b);
fixed248_t fx248Addf32(const fixed248_t a, const float_t b);
/**
* Subtract a fixed248_t value from another fixed248_t value.
*
* @param a Pointer to the first fixed248_t value (will be modified).
* @param a First fixed248_t value.
* @param b The fixed248_t value to subtract from the first value.
* @return The result of the subtraction as a fixed248_t value.
*/
void fx248Subfx248(fixed248_t *a, const fixed248_t b);
fixed248_t fx248Subfx248(const fixed248_t a, const fixed248_t b);
/**
* Subtract an int32_t value from a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param a The fixed248_t value from which the int32_t will be subtracted.
* @param b The int32_t value to subtract from the fixed248_t value.
* @return The result of the subtraction as a fixed248_t value.
*/
void fx248Subi32(fixed248_t *a, const int32_t b);
fixed248_t fx248Subi32(const fixed248_t a, const int32_t b);
/**
* Subtract a uint32_t value from a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param a The fixed248_t value from which the uint32_t will be subtracted.
* @param b The uint32_t value to subtract from the fixed248_t value.
* @return The result of the subtraction as a fixed248_t value.
*/
void fx248Subui32(fixed248_t *a, const uint32_t b);
fixed248_t fx248Subu32(const fixed248_t a, const uint32_t b);
/**
* Subtract a float_t value from a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param a The fixed248_t value from which the float_t will be subtracted.
* @param b The float_t value to subtract from the fixed248_t value.
* @return The result of the subtraction as a fixed248_t value.
*/
void fx248Subf32(fixed248_t *a, const float_t b);
fixed248_t fx248Subf32(const fixed248_t a, const float_t b);
/**
* Multiply two fixed248_t values.
*
* @param a First fixed248_t value.
* @param b Second fixed248_t value to multiply with the first value.
* @return The result of the multiplication as a fixed248_t value.
*/
fixed248_t fx248Mulfx248(const fixed248_t a, const fixed248_t b);
/**
* Multiply a fixed248_t value by an int32_t value.
*
* @param a The fixed248_t value to multiply.
* @param b The int32_t value to multiply with the fixed248_t value.
* @return The result of the multiplication as a fixed248_t value.
*/
fixed248_t fx248Muli32(const fixed248_t a, const int32_t b);
/**
* Multiply a fixed248_t value by a uint32_t value.
*
* @param a The fixed248_t value to multiply.
* @param b The uint32_t value to multiply with the fixed248_t value.
* @return The result of the multiplication as a fixed248_t value.
*/
fixed248_t fx248Mulu32(const fixed248_t a, const uint32_t b);
/**
* Multiply a fixed248_t value by a float_t value.
*
* @param a The fixed248_t value to multiply.
* @param b The float_t value to multiply with the fixed248_t value.
* @return The result of the multiplication as a fixed248_t value.
*/
fixed248_t fx248Mulf32(const fixed248_t a, const float_t b);
/**
* Divide two fixed248_t values.
*
* @param a The fixed248_t value to be divided.
* @param b The fixed248_t value to divide by.
* @return The result of the division as a fixed248_t value.
*/
fixed248_t fx248Divfx248(const fixed248_t a, const fixed248_t b);
/**
* Divide a fixed248_t value by an int32_t value.
*
* @param a The fixed248_t value to be divided.
* @param b The int32_t value to divide by.
* @return The result of the division as a fixed248_t value.
*/
fixed248_t fx248Divi32(const fixed248_t a, const int32_t b);
/**
* Divide a fixed248_t value by a uint32_t value.
*
* @param a The fixed248_t value to be divided.
* @param b The uint32_t value to divide by.
* @return The result of the division as a fixed248_t value.
*/
fixed248_t fx248Divu32(const fixed248_t a, const uint32_t b);
/**
* Divide a fixed248_t value by a float_t value.
*
* @param a The fixed248_t value to be divided.
* @param b The float_t value to divide by.
* @return The result of the division as a fixed248_t value.
*/
fixed248_t fx248Divf32(const fixed248_t a, const float_t b);
/**
* Convert a fixed248_t value to an int32_t value, rounding towards zero.
@ -179,4 +273,11 @@ uint32_t fx248Ceilu32(const fixed248_t a);
* @param a The fixed248_t value to convert.
* @return The converted uint32_t value.
*/
uint32_t fx248Roundu32(const fixed248_t a);
uint32_t fx248Roundu32(const fixed248_t a);
/**
* Returns the square root of a fixed248_t value.
*
* @param a The fixed248_t value to calculate the square root of.
*/
fixed248_t fx248Sqrt(const fixed248_t a);

View File

@ -248,8 +248,8 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) {
entity->id = data->id;
// Positions are chunk-relative.
entity->x = fx248Fromui32((chunk->x * CHUNK_WIDTH * TILE_WIDTH) + data->x);
entity->y = fx248Fromui32((chunk->y * CHUNK_HEIGHT * TILE_HEIGHT)+data->y);
entity->x = fx248Fromu32((chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT) + data->x);
entity->y = fx248Fromu32((chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT)+data->y);
// Next entity
data++;
@ -285,10 +285,10 @@ void chunkUnload(chunk_t *chunk) {
// If the entity is still within our chunk bounds, it's getting unloaded
if(
fx248Flooru32(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH &&
fx248Ceilu32(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH &&
fx248Flooru32(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_HEIGHT &&
fx248Ceilu32(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_HEIGHT
fx248Flooru32(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT &&
fx248Ceilu32(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT &&
fx248Flooru32(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT &&
fx248Ceilu32(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT
) {
shouldUnload = true;
} else {

View File

@ -52,20 +52,20 @@ void overworldUpdate() {
uint16_t x, y;
uint16_t halfWidth, halfHeight;
halfWidth = ((CHUNK_MAP_WIDTH - 1) * CHUNK_WIDTH * TILE_WIDTH) / 2;
halfHeight = ((CHUNK_MAP_HEIGHT - 1) * CHUNK_HEIGHT * TILE_HEIGHT) / 2;
halfWidth = ((CHUNK_MAP_WIDTH - 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT) / 2;
halfHeight = ((CHUNK_MAP_HEIGHT - 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT) / 2;
// Calculate the chunk map position based on the camera position.
if(OVERWORLD_CAMERA_X < halfWidth) {
x = 0;
} else {
x = (OVERWORLD_CAMERA_X - halfWidth) / (CHUNK_WIDTH*TILE_WIDTH);
x = (OVERWORLD_CAMERA_X - halfWidth) / (CHUNK_WIDTH*TILE_WIDTH_HEIGHT);
}
if(OVERWORLD_CAMERA_Y < halfHeight) {
y = 0;
} else {
y = (OVERWORLD_CAMERA_Y - halfHeight) / (CHUNK_HEIGHT*TILE_HEIGHT);
y = (OVERWORLD_CAMERA_Y - halfHeight) / (CHUNK_HEIGHT*TILE_WIDTH_HEIGHT);
}
chunkMapSetPosition(x, y);

View File

@ -8,7 +8,6 @@
#pragma once
#include "dusk.h"
#define TILE_WIDTH 16
#define TILE_HEIGHT 16
#define TILE_WIDTH_HEIGHT 16
typedef uint8_t tile_t;

View File

@ -55,18 +55,18 @@ void drawOverworldDraw(void) {
if(tile == 0) continue; // Skip empty tiles
uint32_t tilemapIndex = tile - 1; // Convert to zero-based index
uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH + (i % CHUNK_WIDTH) * TILE_WIDTH;
uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_HEIGHT + (i / CHUNK_WIDTH) * TILE_HEIGHT;
uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_WIDTH;
uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_HEIGHT;
uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT + (i % CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + (i / CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
DrawTextureRec(
RENDER_TILEMAP_TEXTURE,
(Rectangle){
tilemapX,
tilemapY,
TILE_WIDTH,
TILE_HEIGHT
TILE_WIDTH_HEIGHT,
TILE_WIDTH_HEIGHT
},
(Vector2){ x, y },
WHITE
@ -79,18 +79,18 @@ void drawOverworldDraw(void) {
if(tile == 0) continue; // Skip empty tiles
uint32_t tilemapIndex = tile - 1; // Convert to zero-based index
uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH + (i % CHUNK_WIDTH) * TILE_WIDTH;
uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_HEIGHT + (i / CHUNK_WIDTH) * TILE_HEIGHT;
uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_WIDTH;
uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_HEIGHT;
uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT + (i % CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + (i / CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
DrawTextureRec(
RENDER_TILEMAP_TEXTURE,
(Rectangle){
tilemapX,
tilemapY,
TILE_WIDTH,
TILE_HEIGHT
TILE_WIDTH_HEIGHT,
TILE_WIDTH_HEIGHT
},
(Vector2){ x, y },
WHITE
@ -123,10 +123,10 @@ void drawOverworldDrawEntity(const entity_t *entity) {
DrawTextureRec(
RENDER_ENTITIES_TEXTURE,
(Rectangle){
col * TILE_WIDTH,
row * TILE_HEIGHT,
TILE_WIDTH,
TILE_HEIGHT
col * TILE_WIDTH_HEIGHT,
row * TILE_WIDTH_HEIGHT,
TILE_WIDTH_HEIGHT,
TILE_WIDTH_HEIGHT
},
(Vector2){ x, y },
WHITE

View File

@ -9,8 +9,8 @@ CHUNK_WIDTH = 8
CHUNK_HEIGHT = 8
CHUNK_TILE_COUNT = CHUNK_WIDTH * CHUNK_HEIGHT
CHUNK_ENTITY_COUNT_MAX = 8
TILE_WIDTH = 16
TILE_HEIGHT = 16
TILE_WIDTH_HEIGHT = 16
TILE_WIDTH_HEIGHT = 16
ENTITY_TYPE_MAP = {
"npc": "ENTITY_TYPE_NPC",
@ -194,11 +194,11 @@ for obIndex, ob in enumerate(objectLayer['objects']):
print(f"Error: Object in object layer does not contain 'x' or 'y' key.")
sys.exit(1)
ob['x'] -= inputMapLowestX * TILE_WIDTH
ob['y'] -= inputMapLowestY * TILE_HEIGHT
ob['x'] -= inputMapLowestX * TILE_WIDTH_HEIGHT
ob['y'] -= inputMapLowestY * TILE_WIDTH_HEIGHT
# Objects are bottom aligned in tiled, so we need to adjust the Y coordinate.
ob['y'] -= TILE_HEIGHT
ob['y'] -= TILE_WIDTH_HEIGHT
# Round off the coordinates
ob['x'] = round(ob['x'])
@ -281,13 +281,13 @@ for chunkY in range(mapHeightInRealChunks):
sys.exit(1)
# Is this object within the chunk?
if ob['x'] < topLeftTileX * TILE_WIDTH:
if ob['x'] < topLeftTileX * TILE_WIDTH_HEIGHT:
continue
if ob['x'] >= (topLeftTileX + CHUNK_WIDTH) * TILE_WIDTH:
if ob['x'] >= (topLeftTileX + CHUNK_WIDTH) * TILE_WIDTH_HEIGHT:
continue
if ob['y'] < topLeftTileY * TILE_HEIGHT:
if ob['y'] < topLeftTileY * TILE_WIDTH_HEIGHT:
continue
if ob['y'] >= (topLeftTileY + CHUNK_HEIGHT) * TILE_HEIGHT:
if ob['y'] >= (topLeftTileY + CHUNK_HEIGHT) * TILE_WIDTH_HEIGHT:
continue
entities.append(ob)
@ -372,8 +372,8 @@ for chunkY in range(mapHeightInRealChunks):
f.write(f" .entities = {{\n")
for entity in entities:
# Entities are center aligned in tiled.
localX = round(entity['x'] - (topLeftTileX * TILE_WIDTH))
localY = round(entity['y'] - (topLeftTileY * TILE_HEIGHT))
localX = round(entity['x'] - (topLeftTileX * TILE_WIDTH_HEIGHT))
localY = round(entity['y'] - (topLeftTileY * TILE_WIDTH_HEIGHT))
if 'type' in entity and entity['type'] not in ENTITY_TYPE_MAP:
continue