HOLD ON, I'VE PUT AN OBSOLETE CODE. I'VE UPDATED IT
i've been using GRRLIB for a while, and i figured out on how to make basic rectangular collision, and even managed to get it working with OriginX/Y, and left, right, top and bottom properties, so i can set where the collision starts specifically. However, something that i still couldn't figure out is pixel perfect / alpha based collision.
you see, i'm trying to implment it this way: i currently have 2 types of collision, which are "RECTANGLE" and "PRECISE" (one being the simple collision i've mentioned before and the other being the pixel perfect one). I want to make two conditions:
if ObjectA's Type = RECTANGLE && ObjectB's Type = PRECISE (or viceversa), and other being if both ObjectA's and B's Type = PRECISE.
I for the life of me couldn't get to implement this type of collision.
someone recomended me this tutorial, although idk if the library he's using handles pixels differently: Pixel Perfect Collision Detection in C
here's my code btw:
Sprite Handling:
Object Handling;
My collision code, which has a messy logic for RECTANGLE && PRECISE Types:
The function that's being used:
Any help will be appreciated.
i've been using GRRLIB for a while, and i figured out on how to make basic rectangular collision, and even managed to get it working with OriginX/Y, and left, right, top and bottom properties, so i can set where the collision starts specifically. However, something that i still couldn't figure out is pixel perfect / alpha based collision.
you see, i'm trying to implment it this way: i currently have 2 types of collision, which are "RECTANGLE" and "PRECISE" (one being the simple collision i've mentioned before and the other being the pixel perfect one). I want to make two conditions:
if ObjectA's Type = RECTANGLE && ObjectB's Type = PRECISE (or viceversa), and other being if both ObjectA's and B's Type = PRECISE.
I for the life of me couldn't get to implement this type of collision.
someone recomended me this tutorial, although idk if the library he's using handles pixels differently: Pixel Perfect Collision Detection in C
here's my code btw:
Sprite Handling:
C:
typedef struct {
const unsigned char *spriteData;
int spriteSize;
int left;
int right;
int top;
int bottom;
int originX;
int originY;
int Type;
CollisionMap Map;
} SpriteWithCollision;
extern SpriteWithCollision* currentSprite;
Object Handling;
C:
typedef struct {
int id;
float x;
float y;
float width;
float height;
int depth;
SpriteWithCollision collision_mask;
Layer layer;
GRRLIB_texImg* texture;
bool persistent;
//struct GameList* parent;
struct ObjectList* descendant; //User doesn't change it's value, it's the program who does the dirty work
} GameObject;
extern GameObject* currentObject; //Global Pointer to an array of GameObject pointers
typedef struct {
GameObject* objects[MAX_OBJECTS];
int numObjects;
bool initialized; // flag to track initialization status
} ObjectList;
typedef struct {
ObjectList* Descen;
ObjectList* Parent;
} ParObj;
My collision code, which has a messy logic for RECTANGLE && PRECISE Types:
C:
bool place_meeting(float x, float y, ObjectList *obj_list) {
if (currentObject == NULL || obj_list == NULL) {
return false; // No collision possible without valid input
}
SpriteWithCollision *currentSprite = ¤tObject->collision_mask;
// Calculate the current object's boundaries based on the given position
float objLeft = x + currentSprite->left - currentSprite->originX;
float objRight = x + currentObject->width + currentSprite->right - currentSprite->originX;
float objTop = y + currentSprite->top - currentSprite->originY;
float objBottom = y + currentObject->height + currentSprite->bottom - currentSprite->originY;
// Iterate through the target object list
for (int i = 0; i < obj_list->numObjects; ++i) {
GameObject *otherObject = obj_list->objects[i];
if (otherObject == NULL || otherObject == currentObject) {
continue; // Skip null or self-collision
}
SpriteWithCollision *otherSprite = &otherObject->collision_mask;
// Calculate the other object's boundaries
float otherLeft = otherObject->x + otherSprite->left - otherSprite->originX;
float otherRight = otherObject->x + otherObject->width + otherSprite->right - otherSprite->originX;
float otherTop = otherObject->y + otherSprite->top - otherSprite->originY;
float otherBottom = otherObject->y + otherObject->height + otherSprite->bottom - otherSprite->originY;
bool isColliding = (objRight >= otherLeft && objLeft <= otherRight && objBottom >= otherTop && objTop <= otherBottom);
// Handle collision types
if (currentSprite->Type == RECTANGLE && otherSprite->Type == RECTANGLE) {
if (isColliding){ return true; } // Simple bounding box collision
}
if ((currentSprite->Type == RECTANGLE && otherSprite->Type == PRECISE) ||
(currentSprite->Type == PRECISE && otherSprite->Type == RECTANGLE)) {
// Determine RECTANGLE and PRECISE objects
SpriteWithCollision *rectSprite = (currentSprite->Type == RECTANGLE) ? currentSprite : otherSprite;
SpriteWithCollision *preciseSprite = (currentSprite->Type == PRECISE) ? currentSprite : otherSprite;
const GRRLIB_texImg *preciseTexture = (currentSprite->Type == PRECISE)
? currentObject->texture
: otherObject->texture;
// Determine positions for the PRECISE object
float preciseX = (preciseSprite == currentSprite) ? currentObject->x : otherObject->x;
float preciseY = (preciseSprite == currentSprite) ? currentObject->y : otherObject->y;
// Calculate the scale factors for the PRECISE object
float scaleX = (preciseSprite == currentSprite)
? (currentObject->width / (preciseSprite->right - preciseSprite->left))
: (otherObject->width / (preciseSprite->right - preciseSprite->left));
float scaleY = (preciseSprite == currentSprite)
? (currentObject->height / (preciseSprite->bottom - preciseSprite->top))
: (otherObject->height / (preciseSprite->bottom - preciseSprite->top));
// Calculate RECTANGLE bounds
float rectLeft = (rectSprite == currentSprite) ? objLeft : otherLeft;
float rectRight = (rectSprite == currentSprite) ? objRight : otherRight;
float rectTop = (rectSprite == currentSprite) ? objTop : otherTop;
float rectBottom = (rectSprite == currentSprite) ? objBottom : otherBottom;
// Perform precise collision detection
isColliding = CheckRectangleVsPrecise(
rectLeft, rectTop, rectRight, rectBottom,
preciseTexture, preciseSprite,
preciseX, preciseY, scaleX, scaleY
);
if (isColliding) {
return true;
}
}
if (currentSprite->Type == PRECISE && otherSprite->Type == PRECISE) {
if (isColliding){ return true; } // Simple bounding box collision
}
return false;
}
The function that's being used:
C:
bool CheckRectangleVsPrecise(float rectLeft, float rectTop, float rectRight, float rectBottom,
const GRRLIB_texImg *texture, const SpriteWithCollision *sprite,
float preciseX, float preciseY, float scaleX, float scaleY) {
if (!texture || !sprite) {
printf("Error: Invalid texture or sprite provided.\n");
return false;
}
// Compute the scaled bounds of the precise sprite
float preciseLeft = preciseX + (sprite->left - sprite->originX) * scaleX;
float preciseRight = preciseLeft + (sprite->right - sprite->left) * scaleX;
float preciseTop = preciseY + (sprite->top - sprite->originY) * scaleY;
float preciseBottom = preciseTop + (sprite->bottom - sprite->top) * scaleY;
// Early exit if there is no overlap
if (rectRight < preciseLeft || rectLeft > preciseRight || rectBottom < preciseTop || rectTop > preciseBottom) {
return false;
}
// Iterate over the overlapping region
for (int y = MAX(rectTop, preciseTop); y < MIN(rectBottom, preciseBottom); ++y) {
for (int x = MAX(rectLeft, preciseLeft); x < MIN(rectRight, preciseRight); ++x) {
// Map world coordinates to the texture space
int texX = (x - preciseLeft) / scaleX + sprite->left;
int texY = (y - preciseTop) / scaleY + sprite->top;
// Ensure the coordinates are within bounds
if (texX < 0 || texX >= texture->w || texY < 0 || texY >= texture->h) {
continue;
}
// Check if the pixel is non-transparent
u32 pixelColor = GRRLIB_GetPixelFromtexImg(texX, texY, texture);
if (A(pixelColor) > 0) {
return true; // Collision detected
}
}
}
return false; // No collision found
}
Any help will be appreciated.
Last edited by FoxFore32x,







