Compare commits
1 Commits
main
...
more_effic
Author | SHA1 | Date | |
---|---|---|---|
1483af3177 |
@ -12,7 +12,7 @@
|
||||
#include "./sprite.h"
|
||||
#include "./vec.h"
|
||||
|
||||
#define NO_SCREEN_SPRITES 6
|
||||
#define NO_SCREEN_SPRITES 3
|
||||
|
||||
void init_gfx()
|
||||
{
|
||||
@ -35,12 +35,9 @@ void main(void)
|
||||
|
||||
|
||||
memcpy(&(screen_sprites[0]), &(sprites_info[2]), sizeof(Sprite));
|
||||
memcpy(&(screen_sprites[1]), &(sprites_info[0]), sizeof(Sprite));
|
||||
memcpy(&(screen_sprites[1]), &(sprites_info[1]), sizeof(Sprite));
|
||||
memcpy(&(screen_sprites[2]), &(sprites_info[0]), sizeof(Sprite));
|
||||
memcpy(&(screen_sprites[3]), &(sprites_info[0]), sizeof(Sprite));
|
||||
memcpy(&(screen_sprites[4]), &(sprites_info[0]), sizeof(Sprite));
|
||||
memcpy(&(screen_sprites[5]), &(sprites_info[0]), sizeof(Sprite));
|
||||
screen_sprites[1].has_joypad = 1;
|
||||
screen_sprites[0].has_joypad = 1;
|
||||
|
||||
for (i = 0; i < NO_SCREEN_SPRITES; i++) {
|
||||
screen_sprites[i].bitmap_index_prev = -1;
|
||||
|
144
src/sprite.c
144
src/sprite.c
@ -46,8 +46,6 @@ typedef struct Sprites {
|
||||
|
||||
int get_tile_index_by_coord(unsigned int x, unsigned int y);
|
||||
void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc);
|
||||
unsigned int sprite_internal_collision(Map *map, Sprite *sprite);
|
||||
unsigned int sprite_collision(Map *map, Sprite *sprite);
|
||||
void sprite_draw_to_screen(Sprite *sprite);
|
||||
void sprite_update_bitmap(Sprite *sprite);
|
||||
|
||||
@ -55,7 +53,12 @@ void sprite_update_bitmap(Sprite *sprite);
|
||||
// update a sprite for stuff that changes every frame
|
||||
void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc)
|
||||
{
|
||||
int c, collision_check_steps, absvelx = abs(sprite->vel.x), absvely = abs(sprite->vel.y);
|
||||
SpriteCorners sc;
|
||||
int c, collision_check_steps, sprite_internal_collision,
|
||||
absvelx = abs(sprite->vel.x), absvely = abs(sprite->vel.y);
|
||||
int b_right = joypad & J_RIGHT, b_left = joypad & J_LEFT, b_up = joypad & J_UP,
|
||||
b_down = joypad & J_DOWN, b_a = joypad & J_A, b_b = joypad & J_B;
|
||||
int tl, tr, bl, br, lt, lb, rt, rb;
|
||||
|
||||
// target displacement is sprite->vel but may collide, giving actual displacment
|
||||
Vec displacement = {.x = 0, .y = 0};
|
||||
@ -70,71 +73,91 @@ void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc)
|
||||
}
|
||||
|
||||
// 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;
|
||||
if ((joypad & b_right) && (sprite->vel.x < TERM_VELX)) sprite->acc.x = 1;
|
||||
else if ((joypad & b_left) && (sprite->vel.x > -TERM_VELX)) sprite->acc.x = -1;
|
||||
else sprite->acc.x = -sprite->vel.x/absvelx;
|
||||
sprite->vel.x += sprite->acc.x;
|
||||
|
||||
// player dash
|
||||
if ((joypad & J_B) && (sprite->frames_since_last_dash > DASH_TIMEOUT_FRAMES)) {
|
||||
if (b_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)) {
|
||||
if (b_left) {
|
||||
if (b_up) {
|
||||
sprite->vel.x = -DASH_VELD;
|
||||
sprite->vel.y = -DASH_VELD;
|
||||
} else if ((joypad & J_LEFT) && (joypad & J_DOWN)) {
|
||||
} else if (b_down) {
|
||||
sprite->vel.x = -DASH_VELD;
|
||||
sprite->vel.y = DASH_VELD;
|
||||
} else if ((joypad & J_RIGHT) && (joypad & J_DOWN)) {
|
||||
} else {
|
||||
sprite->vel.x = -DASH_VELL;
|
||||
}
|
||||
} else if (b_right) {
|
||||
if (b_up) {
|
||||
sprite->vel.x = DASH_VELD;
|
||||
sprite->vel.y = -DASH_VELD;
|
||||
} else if (b_down) {
|
||||
sprite->vel.x = DASH_VELD;
|
||||
sprite->vel.y = DASH_VELD;
|
||||
} else {
|
||||
sprite->vel.x = DASH_VELL;
|
||||
}
|
||||
}
|
||||
else if (b_up) sprite->vel.y = -DASH_VELL;
|
||||
else if (b_down) sprite->vel.y = DASH_VELL;
|
||||
// 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;
|
||||
}
|
||||
else 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 -= (absvely-TERM_VELY)/TERM_VELY_DIVISOR;
|
||||
//if (sprite->vel.y < -TERM_VELY) sprite->vel.y += (absvely-TERM_VELY)/TERM_VELY_DIVISOR;
|
||||
//if (sprite->vel.x > TERM_VELX) sprite->vel.x -= (absvelx-TERM_VELX)/TERM_VELX_DIVISOR;
|
||||
//if (sprite->vel.x < -TERM_VELX) sprite->vel.x += (absvelx-TERM_VELX)/TERM_VELX_DIVISOR;
|
||||
//
|
||||
//absvelx = abs(sprite->vel.x);
|
||||
//absvely = abs(sprite->vel.y);
|
||||
if (sprite->vel.y > TERM_VELY) sprite->vel.y -= (absvely-TERM_VELY)/TERM_VELY_DIVISOR;
|
||||
if (sprite->vel.y < -TERM_VELY) sprite->vel.y += (absvely-TERM_VELY)/TERM_VELY_DIVISOR;
|
||||
if (sprite->vel.x > TERM_VELX) sprite->vel.x -= (absvelx-TERM_VELX)/TERM_VELX_DIVISOR;
|
||||
if (sprite->vel.x < -TERM_VELX) sprite->vel.x += (absvelx-TERM_VELX)/TERM_VELX_DIVISOR;
|
||||
|
||||
absvelx = abs(sprite->vel.x);
|
||||
absvely = abs(sprite->vel.y);
|
||||
|
||||
// if sprite not moving, no more logic needs to be done --- right?
|
||||
if ((absvelx == 0) && (absvely == 0)) return;
|
||||
|
||||
c = sprite_collision(map, sprite);
|
||||
GET_SPRITE_CORNERS(sprite, sc);
|
||||
|
||||
// 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)) {
|
||||
if (sprite->vel.y > 0) {
|
||||
br = map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x, sc.ibl.y+1)];
|
||||
bl = map->data[GET_TILE_INDEX_BY_COORD(sc.ibr.x, sc.ibr.y+1)];
|
||||
|
||||
if (bl | br) {
|
||||
sprite->vel.y = 0;
|
||||
// player jump
|
||||
if ((joypad & J_A) && (sprite->frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) {
|
||||
if (b_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; }
|
||||
} else if (sprite->vel.y < 0) {
|
||||
tl = map->data[GET_TILE_INDEX_BY_COORD(sc.itl.x, sc.itl.y-1)];
|
||||
tr = map->data[GET_TILE_INDEX_BY_COORD(sc.itr.x, sc.itr.y-1)];
|
||||
if (tl | tr) sprite->vel.y = 0;
|
||||
}
|
||||
|
||||
if (sprite->vel.x > 0) {
|
||||
rt = map->data[GET_TILE_INDEX_BY_COORD(sc.itr.x+1, sc.itr.y)];
|
||||
rb = map->data[GET_TILE_INDEX_BY_COORD(sc.ibr.x+1, sc.ibr.y)];
|
||||
if (rt | rb) sprite->vel.x = 0;
|
||||
} else if (sprite->vel.x < 0) {
|
||||
lt = map->data[GET_TILE_INDEX_BY_COORD(sc.itl.x-1, sc.itl.y)];
|
||||
lb = map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x-1, sc.ibl.y)];
|
||||
if (lt | lb) sprite->vel.x = 0;
|
||||
}
|
||||
|
||||
absvelx = abs(sprite->vel.x);
|
||||
absvely = abs(sprite->vel.y);
|
||||
|
||||
collision_check_steps = (absvelx > absvely) ? absvelx : absvely;
|
||||
|
||||
@ -145,56 +168,23 @@ void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc)
|
||||
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;
|
||||
sprite_internal_collision = 0;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itl.x, sc.itl.y)]) sprite_internal_collision++;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itr.x, sc.itr.y)]) sprite_internal_collision++;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x, sc.ibl.y)]) sprite_internal_collision++;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibr.x, sc.ibr.y)]) sprite_internal_collision++;
|
||||
if (sprite_internal_collision == 0) break;
|
||||
}
|
||||
|
||||
sprite_update_bitmap(sprite);
|
||||
sprite_draw_to_screen(sprite);
|
||||
move_sprite(sprite->gb_sprite_index, sprite->pos.x, sprite->pos.y);
|
||||
}
|
||||
|
||||
|
||||
// calculate internal collisions
|
||||
unsigned int sprite_internal_collision(Map *map, Sprite *sprite)
|
||||
{
|
||||
unsigned int rv = 0;
|
||||
SpriteCorners sc;
|
||||
GET_SPRITE_CORNERS(sprite, sc);
|
||||
// (((y / PIXELS_PER_TILE) * 20) + (x / PIXELS_PER_TILE))
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itl.x, sc.itl.y)]) rv = rv | SC_ITL;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itr.x, sc.itr.y)]) rv = rv | SC_ITR;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x, sc.ibl.y)]) rv = rv | SC_IBL;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(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(Map *map, Sprite *sprite)
|
||||
{
|
||||
unsigned int rv = 0;
|
||||
SpriteCorners sc;
|
||||
GET_SPRITE_CORNERS(sprite, sc);
|
||||
|
||||
// check if corners are in a non 0 tile
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itl.x, sc.itl.y-1)]) rv = rv | SC_TL;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itr.x, sc.itr.y-1)]) rv = rv | SC_TR;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x, sc.ibl.y+1)]) rv = rv | SC_BL;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibr.x, sc.ibr.y+1)]) rv = rv | SC_BR;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itl.x-1, sc.itl.y )]) rv = rv | SC_LT;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x-1, sc.ibl.y )]) rv = rv | SC_LB;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.itr.x+1, sc.itr.y )]) rv = rv | SC_RT;
|
||||
if (map->data[GET_TILE_INDEX_BY_COORD(sc.ibr.x+1, sc.ibr.y )]) rv = rv | SC_RB;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// set new sprite bitmap
|
||||
void sprite_update_bitmap(Sprite *sprite)
|
||||
{
|
||||
|
||||
sprite->bitmap_index_prev = sprite->bitmap_index;
|
||||
|
||||
if ((sprite->vel.y > 0) && (sprite->vel.x > 0)) sprite->bitmap_index = SI_DOWN_RIGHT;
|
||||
else if ((sprite->vel.y < 0) && (sprite->vel.x > 0)) sprite->bitmap_index = SI_UP_RIGHT;
|
||||
else if ((sprite->vel.y > 0) && (sprite->vel.x < 0)) sprite->bitmap_index = SI_DOWN_LEFT;
|
||||
@ -208,6 +198,8 @@ void sprite_update_bitmap(Sprite *sprite)
|
||||
|
||||
void sprite_draw_to_screen(Sprite *sprite)
|
||||
{
|
||||
// only set sprite if sprite to be used has changed
|
||||
sprite_update_bitmap(sprite);
|
||||
if (sprite->bitmap_index_prev != sprite->bitmap_index) {
|
||||
set_sprite_tile(sprite->gb_sprite_index, sprite->bitmap_indexes[sprite->bitmap_index]);
|
||||
set_sprite_prop(sprite->gb_sprite_index, sprite->bitmap_prop[sprite->bitmap_index]);
|
||||
|
Loading…
Reference in New Issue
Block a user