sprite-better-collision #1
@ -1,6 +1,8 @@
|
|||||||
#ifndef CONSTANTS_LOADED
|
#ifndef CONSTANTS_LOADED
|
||||||
#define CONSTANTS_LOADED
|
#define CONSTANTS_LOADED
|
||||||
|
|
||||||
|
#define MAX_PLAYER_COUNT 1
|
||||||
|
|
||||||
#define GRAV_ACC 1
|
#define GRAV_ACC 1
|
||||||
#define TERM_VELY 3
|
#define TERM_VELY 3
|
||||||
#define TERM_VELX 2
|
#define TERM_VELX 2
|
||||||
@ -11,6 +13,7 @@
|
|||||||
#define JUMP_TIMEOUT_FRAMES 18
|
#define JUMP_TIMEOUT_FRAMES 18
|
||||||
|
|
||||||
#define DASH_VELL 7
|
#define DASH_VELL 7
|
||||||
|
// mfw when pythagoras irl :scream_cat:
|
||||||
#define DASH_VELD 5
|
#define DASH_VELD 5
|
||||||
#define DASH_TIMEOUT_FRAMES 30
|
#define DASH_TIMEOUT_FRAMES 30
|
||||||
|
|
||||||
|
201
src/main.c
201
src/main.c
@ -5,60 +5,8 @@
|
|||||||
#include"../res/sprites.h"
|
#include"../res/sprites.h"
|
||||||
#include "./flags.h"
|
#include "./flags.h"
|
||||||
#include "./constants.h"
|
#include "./constants.h"
|
||||||
#include "./vec.c"
|
#include "./sprite.h"
|
||||||
|
#include "./vec.h"
|
||||||
int getTileIndexByCoord(unsigned int x, unsigned int y)
|
|
||||||
{
|
|
||||||
return ((y / PIXELS_PER_TILE) * 20) + (x / PIXELS_PER_TILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for external collisions (if rectangle is at least touchign something)
|
|
||||||
unsigned int collision(unsigned char map[], struct UVec *sprite_pos, struct UVec *sprite_size)
|
|
||||||
{
|
|
||||||
unsigned int rv = 0;
|
|
||||||
struct UVec itl, itr, ibl, ibr;
|
|
||||||
|
|
||||||
itl.x = sprite_pos->x-8; itl.y = sprite_pos->y-16;
|
|
||||||
itr.x = sprite_pos->x-1; itr.y = sprite_pos->y-16;
|
|
||||||
ibl.x = sprite_pos->x-8; ibl.y = sprite_pos->y-9;
|
|
||||||
ibr.x = sprite_pos->x-1; ibr.y = sprite_pos->y-9;
|
|
||||||
|
|
||||||
// check if corners are in a non 0 tile
|
|
||||||
if (map[getTileIndexByCoord(itl.x, itl.y-1)]) rv = rv | SC_TL;
|
|
||||||
if (map[getTileIndexByCoord(itr.x, itr.y-1)]) rv = rv | SC_TR;
|
|
||||||
|
|
||||||
if (map[getTileIndexByCoord(ibl.x, ibl.y+1)]) rv = rv | SC_BL;
|
|
||||||
if (map[getTileIndexByCoord(ibr.x, ibr.y+1)]) rv = rv | SC_BR;
|
|
||||||
|
|
||||||
if (map[getTileIndexByCoord(itl.x-1, itl.y)]) rv = rv | SC_LT;
|
|
||||||
if (map[getTileIndexByCoord(ibl.x-1, ibl.y)]) rv = rv | SC_LB;
|
|
||||||
|
|
||||||
if (map[getTileIndexByCoord(itr.x+1, itr.y)]) rv = rv | SC_RT;
|
|
||||||
if (map[getTileIndexByCoord(ibr.x+1, ibr.y)]) rv = rv | SC_RB;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// calculate internal collisions from external collisions
|
|
||||||
unsigned int icollision(unsigned char map[], struct UVec *sprite_pos, struct UVec *sprite_size)
|
|
||||||
{
|
|
||||||
unsigned int c, rv = 0;
|
|
||||||
struct UVec itl, itr, ibl, ibr;
|
|
||||||
|
|
||||||
itl.x = sprite_pos->x-8; itl.y = sprite_pos->y-16;
|
|
||||||
itr.x = sprite_pos->x-1; itr.y = sprite_pos->y-16;
|
|
||||||
ibl.x = sprite_pos->x-8; ibl.y = sprite_pos->y-9;
|
|
||||||
ibr.x = sprite_pos->x-1; ibr.y = sprite_pos->y-9;
|
|
||||||
|
|
||||||
if (map[getTileIndexByCoord(itl.x, itl.y)]) rv = rv | SC_ITL;
|
|
||||||
if (map[getTileIndexByCoord(itr.x, itr.y)]) rv = rv | SC_ITR;
|
|
||||||
if (map[getTileIndexByCoord(ibl.x, ibl.y)]) rv = rv | SC_IBL;
|
|
||||||
if (map[getTileIndexByCoord(ibr.x, ibr.y)]) rv = rv | SC_IBR;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void init_gfx()
|
void init_gfx()
|
||||||
{
|
{
|
||||||
@ -77,146 +25,25 @@ void init_gfx()
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
unsigned int c, search_found, frames_since_last_jump, frames_since_last_dash, fc = 0;
|
unsigned int fc = 0;
|
||||||
int xsearch, ysearch;
|
struct Sprites sprite;
|
||||||
struct UVec sprite_pos, search_pos, sprite_size;
|
|
||||||
struct Vec velocity, acceleration;
|
|
||||||
|
|
||||||
init_gfx();
|
init_gfx();
|
||||||
|
|
||||||
sprite_pos.x = 72;
|
sprite.pos.x = 72;
|
||||||
sprite_pos.y = 35;
|
sprite.pos.y = 36;
|
||||||
sprite_size.x = 8;
|
sprite.vel.x = 0;
|
||||||
sprite_size.y = 8;
|
sprite.vel.y = 0;
|
||||||
frames_since_last_jump = JUMP_TIMEOUT_FRAMES;
|
sprite.acc.x = 0;
|
||||||
frames_since_last_dash = DASH_TIMEOUT_FRAMES;
|
sprite.acc.y = 0;
|
||||||
velocity.x = 0;
|
move_sprite(0, sprite.pos.x, sprite.pos.y);
|
||||||
velocity.y = 0;
|
|
||||||
acceleration.x = 0;
|
|
||||||
acceleration.y = 0;
|
|
||||||
|
|
||||||
move_sprite(0, sprite_pos.x, sprite_pos.y);
|
|
||||||
|
|
||||||
// Loop forever
|
// Loop forever
|
||||||
while(1) {
|
while(1) {
|
||||||
// the gameboy simulates physics too quickly to have good control over the speeds of things
|
fc++;
|
||||||
// so draw them less often and move them more
|
sprite_iter_frame(&sprite, map, joypad(), &fc);
|
||||||
if (frames_since_last_jump <= JUMP_TIMEOUT_FRAMES) frames_since_last_jump++;
|
move_sprite(0, sprite.pos.x, sprite.pos.y);
|
||||||
if (frames_since_last_dash <= DASH_TIMEOUT_FRAMES) frames_since_last_dash++;
|
|
||||||
|
|
||||||
if (++fc % 2 == 0) {
|
|
||||||
velocity.y += GRAV_ACC;
|
|
||||||
fc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// player move left/right
|
|
||||||
if ((joypad() & J_RIGHT) && (velocity.x < TERM_VELX)) acceleration.x = 1;
|
|
||||||
else if ((joypad() & J_LEFT) && (velocity.x > -TERM_VELX)) acceleration.x = -1;
|
|
||||||
else acceleration.x = -velocity.x/abs(velocity.x);
|
|
||||||
velocity.x += acceleration.x;
|
|
||||||
|
|
||||||
// player dash
|
|
||||||
if ((joypad() & J_B) && (frames_since_last_dash > DASH_TIMEOUT_FRAMES)) {
|
|
||||||
int frames_since_last_dash_copy = frames_since_last_dash;
|
|
||||||
frames_since_last_dash = 0;
|
|
||||||
|
|
||||||
if ((joypad() & J_LEFT) && !(joypad() & (J_UP | J_RIGHT | J_DOWN))) {
|
|
||||||
velocity.x = -DASH_VELL;
|
|
||||||
} else if ((joypad() & J_RIGHT) && !(joypad() & (J_UP | J_LEFT | J_DOWN))) {
|
|
||||||
velocity.x = DASH_VELL;
|
|
||||||
} else if ((joypad() & J_UP) && !(joypad() & (J_RIGHT | J_LEFT | J_DOWN))) {
|
|
||||||
velocity.y = -DASH_VELL;
|
|
||||||
} else if ((joypad() & J_DOWN) && !(joypad() & (J_UP | J_LEFT | J_RIGHT))) {
|
|
||||||
velocity.y = DASH_VELL;
|
|
||||||
} else if ((joypad() & J_RIGHT) && (joypad() & J_UP)) {
|
|
||||||
velocity.x = DASH_VELD;
|
|
||||||
velocity.y = -DASH_VELD;
|
|
||||||
} else if ((joypad() & J_LEFT) && (joypad() & J_UP)) {
|
|
||||||
velocity.x = -DASH_VELD;
|
|
||||||
velocity.y = -DASH_VELD;
|
|
||||||
} else if ((joypad() & J_LEFT) && (joypad() & J_DOWN)) {
|
|
||||||
velocity.x = -DASH_VELD;
|
|
||||||
velocity.y = DASH_VELD;
|
|
||||||
} else if ((joypad() & J_RIGHT) && (joypad() & J_DOWN)) {
|
|
||||||
velocity.x = DASH_VELD;
|
|
||||||
velocity.y = DASH_VELD;
|
|
||||||
} else {
|
|
||||||
// if player doesn't hold the right buttons to dash, don't dash and set the
|
|
||||||
// frames_since_last_dash counter back to what it was before
|
|
||||||
frames_since_last_dash = frames_since_last_dash_copy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// slow down sprite in kind of realistic way
|
|
||||||
// (in real life i think it's drag is proportional to velocity square but not
|
|
||||||
// sure if that is worth the compute yet)
|
|
||||||
if (velocity.y > TERM_VELY) velocity.y -= (abs(velocity.y)-TERM_VELY)/TERM_VELY_DIVISOR;
|
|
||||||
if (velocity.y < -TERM_VELY) velocity.y += (abs(velocity.y)-TERM_VELY)/TERM_VELY_DIVISOR;
|
|
||||||
if (velocity.x > TERM_VELX) velocity.x -= (abs(velocity.x)-TERM_VELX)/TERM_VELX_DIVISOR;
|
|
||||||
if (velocity.x < -TERM_VELX) velocity.x += (abs(velocity.x)-TERM_VELX)/TERM_VELX_DIVISOR;
|
|
||||||
|
|
||||||
// don't let player move in a direction which they are already touching something
|
|
||||||
if (((c & SC_TL) | (c & SC_TR)) && (velocity.y < 0)) { velocity.y = 0; }
|
|
||||||
if (((c & SC_BL) | (c & SC_BR)) && (velocity.y > 0)) {
|
|
||||||
// player jump
|
|
||||||
if ((joypad() & J_A) && (frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) {
|
|
||||||
velocity.y = -JUMP_VEL;
|
|
||||||
frames_since_last_jump = 0;
|
|
||||||
}
|
|
||||||
else velocity.y = 0;
|
|
||||||
}
|
|
||||||
if (((c & SC_RT) | (c & SC_RB)) && (velocity.x > 0)) { velocity.x = 0; }
|
|
||||||
if (((c & SC_LT) | (c & SC_LB)) && (velocity.x < 0)) { velocity.x = 0; }
|
|
||||||
|
|
||||||
sprite_pos.x += velocity.x;
|
|
||||||
sprite_pos.y += velocity.y;
|
|
||||||
|
|
||||||
c = collision(map, &sprite_pos, &sprite_size);
|
|
||||||
|
|
||||||
// move player out of tiles by brute force searching :eyes:
|
|
||||||
// TODO this is really stupid and bad and i think it will have to be changed when there
|
|
||||||
// are more players moving around
|
|
||||||
search_found = 0;
|
|
||||||
for (ysearch = 0; ysearch <= SPRITE_HEIGHT; ysearch++) {
|
|
||||||
for (xsearch = 0; xsearch <= SPRITE_WIDTH; xsearch++) {
|
|
||||||
search_pos.x = sprite_pos.x + xsearch;
|
|
||||||
search_pos.y = sprite_pos.y + ysearch;
|
|
||||||
if(icollision(map, &search_pos, &sprite_size) == 0) {
|
|
||||||
sprite_pos.x = search_pos.x;
|
|
||||||
sprite_pos.y = search_pos.y;
|
|
||||||
search_found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
search_pos.x = sprite_pos.x - xsearch;
|
|
||||||
search_pos.y = sprite_pos.y + ysearch;
|
|
||||||
if(icollision(map, &search_pos, &sprite_size) == 0) {
|
|
||||||
sprite_pos.x = search_pos.x;
|
|
||||||
sprite_pos.y = search_pos.y;
|
|
||||||
search_found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
search_pos.x = sprite_pos.x - xsearch;
|
|
||||||
search_pos.y = sprite_pos.y - ysearch;
|
|
||||||
if(icollision(map, &search_pos, &sprite_size) == 0) {
|
|
||||||
sprite_pos.x = search_pos.x;
|
|
||||||
sprite_pos.y = search_pos.y;
|
|
||||||
search_found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
search_pos.x = sprite_pos.x + xsearch;
|
|
||||||
search_pos.y = sprite_pos.y - ysearch;
|
|
||||||
if(icollision(map, &search_pos, &sprite_size) == 0) {
|
|
||||||
sprite_pos.x = search_pos.x;
|
|
||||||
sprite_pos.y = search_pos.y;
|
|
||||||
search_found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (search_found) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally move the sprite
|
|
||||||
move_sprite(0, sprite_pos.x, sprite_pos.y);
|
|
||||||
|
|
||||||
// Done processing, yield CPU and wait for start of next frame
|
// Done processing, yield CPU and wait for start of next frame
|
||||||
wait_vbl_done();
|
wait_vbl_done();
|
||||||
|
179
src/sprite.c
Normal file
179
src/sprite.c
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#include <gb/gb.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "./vec.h"
|
||||||
|
#include "./constants.h"
|
||||||
|
#include "./flags.h"
|
||||||
|
|
||||||
|
typedef struct Sprites {
|
||||||
|
int frames_since_last_dash;
|
||||||
|
int frames_since_last_jump;
|
||||||
|
int size;
|
||||||
|
UVec pos;
|
||||||
|
Vec vel;
|
||||||
|
Vec acc;
|
||||||
|
} Sprite;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SpriteCorners {
|
||||||
|
UVec itl;
|
||||||
|
UVec itr;
|
||||||
|
UVec ibl;
|
||||||
|
UVec ibr;
|
||||||
|
} SpriteCorners;
|
||||||
|
|
||||||
|
|
||||||
|
void sprite_iter_frame(Sprite *sprite, unsigned char map[], int joypad, unsigned int *fc);
|
||||||
|
int getTileIndexByCoord(unsigned int x, unsigned int y);
|
||||||
|
unsigned int sprite_internal_collision(unsigned char map[], Sprite *sprite);
|
||||||
|
unsigned int sprite_collision(unsigned char map[], Sprite *sprite);
|
||||||
|
void sprite_decollide(unsigned char map[], Sprite *sprite);
|
||||||
|
|
||||||
|
// update a sprite for stuff that changes every frame
|
||||||
|
void sprite_iter_frame(Sprite *sprite, unsigned char map[], int joypad, unsigned int *fc)
|
||||||
|
{
|
||||||
|
int c, collision_check_steps;
|
||||||
|
|
||||||
|
// target displacement is sprite->vel but may collide, giving actual displacment
|
||||||
|
Vec displacement = {.x = 0, .y = 0};
|
||||||
|
UVec original_position;
|
||||||
|
|
||||||
|
if (sprite->frames_since_last_jump <= JUMP_TIMEOUT_FRAMES) sprite->frames_since_last_jump++;
|
||||||
|
if (sprite->frames_since_last_dash <= DASH_TIMEOUT_FRAMES) sprite->frames_since_last_dash++;
|
||||||
|
|
||||||
|
if (*fc % 2 == 0) {
|
||||||
|
sprite->vel.y += GRAV_ACC;
|
||||||
|
*fc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// player move left/right
|
||||||
|
if ((joypad & J_RIGHT) && (sprite->vel.x < TERM_VELX)) sprite->acc.x = 1;
|
||||||
|
else if ((joypad & J_LEFT) && (sprite->vel.x > -TERM_VELX)) sprite->acc.x = -1;
|
||||||
|
else sprite->acc.x = -sprite->vel.x/abs(sprite->vel.x);
|
||||||
|
sprite->vel.x += sprite->acc.x;
|
||||||
|
|
||||||
|
// player dash
|
||||||
|
if ((joypad & J_B) && (sprite->frames_since_last_dash > DASH_TIMEOUT_FRAMES)) {
|
||||||
|
int frames_since_last_dash_copy = sprite->frames_since_last_dash;
|
||||||
|
sprite->frames_since_last_dash = 0;
|
||||||
|
|
||||||
|
if ((joypad & J_LEFT) && !(joypad & (J_UP | J_RIGHT | J_DOWN))) {
|
||||||
|
sprite->vel.x = -DASH_VELL;
|
||||||
|
} else if ((joypad & J_RIGHT) && !(joypad & (J_UP | J_LEFT | J_DOWN))) {
|
||||||
|
sprite->vel.x = DASH_VELL;
|
||||||
|
} else if ((joypad & J_UP) && !(joypad & (J_RIGHT | J_LEFT | J_DOWN))) {
|
||||||
|
sprite->vel.y = -DASH_VELL;
|
||||||
|
} else if ((joypad & J_DOWN) && !(joypad & (J_UP | J_LEFT | J_RIGHT))) {
|
||||||
|
sprite->vel.y = DASH_VELL;
|
||||||
|
} else if ((joypad & J_RIGHT) && (joypad & J_UP)) {
|
||||||
|
sprite->vel.x = DASH_VELD;
|
||||||
|
sprite->vel.y = -DASH_VELD;
|
||||||
|
} else if ((joypad & J_LEFT) && (joypad & J_UP)) {
|
||||||
|
sprite->vel.x = -DASH_VELD;
|
||||||
|
sprite->vel.y = -DASH_VELD;
|
||||||
|
} else if ((joypad & J_LEFT) && (joypad & J_DOWN)) {
|
||||||
|
sprite->vel.x = -DASH_VELD;
|
||||||
|
sprite->vel.y = DASH_VELD;
|
||||||
|
} else if ((joypad & J_RIGHT) && (joypad & J_DOWN)) {
|
||||||
|
sprite->vel.x = DASH_VELD;
|
||||||
|
sprite->vel.y = DASH_VELD;
|
||||||
|
} else {
|
||||||
|
// if player doesn't hold the right buttons to dash, don't dash and set the
|
||||||
|
// frames_since_last_dash counter back to what it was before
|
||||||
|
sprite->frames_since_last_dash = frames_since_last_dash_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// slow down sprite in kind of realistic way
|
||||||
|
// (in real life i think it's drag is proportional to sprite->vel square but not
|
||||||
|
// sure if that is worth the compute yet cause everythign else is shit)
|
||||||
|
if (sprite->vel.y > TERM_VELY) sprite->vel.y -= (abs(sprite->vel.y)-TERM_VELY)/TERM_VELY_DIVISOR;
|
||||||
|
if (sprite->vel.y < -TERM_VELY) sprite->vel.y += (abs(sprite->vel.y)-TERM_VELY)/TERM_VELY_DIVISOR;
|
||||||
|
if (sprite->vel.x > TERM_VELX) sprite->vel.x -= (abs(sprite->vel.x)-TERM_VELX)/TERM_VELX_DIVISOR;
|
||||||
|
if (sprite->vel.x < -TERM_VELX) sprite->vel.x += (abs(sprite->vel.x)-TERM_VELX)/TERM_VELX_DIVISOR;
|
||||||
|
|
||||||
|
c = sprite_collision(map, sprite);
|
||||||
|
|
||||||
|
// don't let player move in a direction which they are already touching something
|
||||||
|
if (((c & SC_TL) | (c & SC_TR)) && (sprite->vel.y < 0)) { sprite->vel.y = 0; }
|
||||||
|
if (((c & SC_BL) | (c & SC_BR)) && (sprite->vel.y > 0)) {
|
||||||
|
// player jump
|
||||||
|
if ((joypad & J_A) && (sprite->frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) {
|
||||||
|
sprite->vel.y = -JUMP_VEL;
|
||||||
|
sprite->frames_since_last_jump = 0;
|
||||||
|
}
|
||||||
|
else sprite->vel.y = 0;
|
||||||
|
}
|
||||||
|
if (((c & SC_RT) | (c & SC_RB)) && (sprite->vel.x > 0)) { sprite->vel.x = 0; }
|
||||||
|
if (((c & SC_LT) | (c & SC_LB)) && (sprite->vel.x < 0)) { sprite->vel.x = 0; }
|
||||||
|
|
||||||
|
int absvelx = abs(sprite->vel.x);
|
||||||
|
int absvely = abs(sprite->vel.y);
|
||||||
|
collision_check_steps = (absvelx > absvely) ? absvelx : absvely;
|
||||||
|
|
||||||
|
original_position.x = sprite->pos.x;
|
||||||
|
original_position.y = sprite->pos.y;
|
||||||
|
// check if following the path by the velocity will lead to a collision
|
||||||
|
for (int step = collision_check_steps; step >= 0; step--) {
|
||||||
|
sprite->pos.x = original_position.x + ((step * sprite->vel.x)/collision_check_steps);
|
||||||
|
sprite->pos.y = original_position.y + ((step * sprite->vel.y)/collision_check_steps);
|
||||||
|
|
||||||
|
if (!sprite_internal_collision(map, sprite)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// holy shit it's so crunchy
|
||||||
|
//sprite_decollide(map, sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int getTileIndexByCoord(unsigned int x, unsigned int y)
|
||||||
|
{
|
||||||
|
return ((y / PIXELS_PER_TILE) * 20) + (x / PIXELS_PER_TILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SpriteCorners *getSpriteCorners(Sprite *sprite)
|
||||||
|
{
|
||||||
|
SpriteCorners r = {
|
||||||
|
.itl = { .x = sprite->pos.x-8, .y = sprite->pos.y-16 },
|
||||||
|
.itr = { .x = sprite->pos.x-1, .y = sprite->pos.y-16 },
|
||||||
|
.ibl = { .x = sprite->pos.x-8, .y = sprite->pos.y-9 },
|
||||||
|
.ibr = { .x = sprite->pos.x-1, .y = sprite->pos.y-9 }
|
||||||
|
};
|
||||||
|
return &r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// calculate internal collisions
|
||||||
|
unsigned int sprite_internal_collision(unsigned char map[], Sprite *sprite)
|
||||||
|
{
|
||||||
|
unsigned int rv = 0;
|
||||||
|
SpriteCorners *sc = getSpriteCorners(sprite);
|
||||||
|
|
||||||
|
if (map[getTileIndexByCoord(sc->itl.x, sc->itl.y)]) rv = rv | SC_ITL;
|
||||||
|
if (map[getTileIndexByCoord(sc->itr.x, sc->itr.y)]) rv = rv | SC_ITR;
|
||||||
|
if (map[getTileIndexByCoord(sc->ibl.x, sc->ibl.y)]) rv = rv | SC_IBL;
|
||||||
|
if (map[getTileIndexByCoord(sc->ibr.x, sc->ibr.y)]) rv = rv | SC_IBR;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check for external collisions (if rectangle is at least touchign something)
|
||||||
|
unsigned int sprite_collision(unsigned char map[], Sprite *sprite)
|
||||||
|
{
|
||||||
|
unsigned int rv = 0;
|
||||||
|
SpriteCorners *sc = getSpriteCorners(sprite);
|
||||||
|
|
||||||
|
// check if corners are in a non 0 tile
|
||||||
|
if (map[getTileIndexByCoord(sc->itl.x, sc->itl.y-1)]) rv = rv | SC_TL;
|
||||||
|
if (map[getTileIndexByCoord(sc->itr.x, sc->itr.y-1)]) rv = rv | SC_TR;
|
||||||
|
if (map[getTileIndexByCoord(sc->ibl.x, sc->ibl.y+1)]) rv = rv | SC_BL;
|
||||||
|
if (map[getTileIndexByCoord(sc->ibr.x, sc->ibr.y+1)]) rv = rv | SC_BR;
|
||||||
|
if (map[getTileIndexByCoord(sc->itl.x-1, sc->itl.y)]) rv = rv | SC_LT;
|
||||||
|
if (map[getTileIndexByCoord(sc->ibl.x-1, sc->ibl.y)]) rv = rv | SC_LB;
|
||||||
|
if (map[getTileIndexByCoord(sc->itr.x+1, sc->itr.y)]) rv = rv | SC_RT;
|
||||||
|
if (map[getTileIndexByCoord(sc->ibr.x+1, sc->ibr.y)]) rv = rv | SC_RB;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
22
src/sprite.h
Normal file
22
src/sprite.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef SPRITE_H_
|
||||||
|
#define SPRITE_H_
|
||||||
|
|
||||||
|
#include "./vec.h"
|
||||||
|
|
||||||
|
typedef struct Sprites {
|
||||||
|
int frames_since_last_dash;
|
||||||
|
int frames_since_last_jump;
|
||||||
|
int size;
|
||||||
|
UVec pos;
|
||||||
|
Vec vel;
|
||||||
|
Vec acc;
|
||||||
|
} Sprite;
|
||||||
|
|
||||||
|
void sprite_iter_frame(Sprite *sprite, unsigned char map[], int joypad, unsigned int *fc);
|
||||||
|
int getTileIndexByCoord(unsigned int x, unsigned int y);
|
||||||
|
unsigned int sprite_internal_collision(unsigned char map[], Sprite *sprite);
|
||||||
|
unsigned int sprite_collision(unsigned char map[], Sprite *sprite);
|
||||||
|
void sprite_decollide(unsigned char map[], Sprite *sprite);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -1,9 +0,0 @@
|
|||||||
struct UVec {
|
|
||||||
unsigned int x;
|
|
||||||
unsigned int y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vec {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user