Compare commits

...

4 Commits

Author SHA1 Message Date
1483af3177 i think this is less code maybe but also it doesn't work 2022-06-21 19:08:36 +01:00
565f7eebbd optimisation? 2022-06-19 16:42:21 +01:00
9239a34256 add mike character 2022-06-12 22:48:10 +01:00
b02543c848 fix arrow sprite metadata 2022-06-12 19:42:01 +01:00
6 changed files with 278 additions and 122 deletions

View File

@@ -16,3 +16,10 @@ make all
``` ```
the gameboy rom will be output to `obj/untitled2dshooter.gb` the gameboy rom will be output to `obj/untitled2dshooter.gb`
## credits
### art
a cool guy named louie - drew mike

View File

@@ -23,10 +23,10 @@ Sprite sprites_info[] = {
}, },
.bitmap_indexes[SI_DOWN] = 12, .bitmap_prop[SI_DOWN] = S_FLIPY, .bitmap_indexes[SI_DOWN] = 12, .bitmap_prop[SI_DOWN] = S_FLIPY,
.collision_offset[SI_DOWN] = { .collision_offset[SI_DOWN] = {
.itl = { .x = 8, .y = 8}, .itl = { .x = 3, .y = 8},
.itr = { .x = 5, .y = 8}, .itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1}, .ibl = { .x = 3, .y = 1},
.ibr = { .x = 5, .y = 1}, .ibr = { .x = 1, .y = 1},
}, },
.bitmap_indexes[SI_LEFT] = 11, .bitmap_prop[SI_LEFT] = 0, .bitmap_indexes[SI_LEFT] = 11, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = { .collision_offset[SI_LEFT] = {
@@ -70,5 +70,141 @@ Sprite sprites_info[] = {
.ibl = { .x = 7, .y = 1}, .ibl = { .x = 7, .y = 1},
.ibr = { .x = 1, .y = 1}, .ibr = { .x = 1, .y = 1},
} }
},
{
.frames_since_last_dash = 0,
.frames_since_last_jump = 0,
.name = "dodgy_hat_guy",
.has_diag_sprites = 0,
.bitmap_index = SI_LEFT,
.has_joypad = 0,
.pos = { .x = 0, .y = 0},
.vel = { .x = 0, .y = 0},
.acc = { .x = 0, .y = 0},
.bitmap_indexes[SI_UP] = 14, .bitmap_prop[SI_UP] = 0,
.collision_offset[SI_UP] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN] = 15, .bitmap_prop[SI_DOWN] = 0,
.collision_offset[SI_DOWN] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_LEFT] = 14, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_RIGHT] = 14, .bitmap_prop[SI_RIGHT] = S_FLIPX,
.collision_offset[SI_RIGHT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_UP_RIGHT] = 14, .bitmap_prop[SI_UP_RIGHT] = 0,
.collision_offset[SI_UP_RIGHT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_UP_LEFT] = 14, .bitmap_prop[SI_UP_LEFT] = S_FLIPX,
.collision_offset[SI_UP_LEFT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN_LEFT] = 15, .bitmap_prop[SI_DOWN_LEFT] = 0,
.collision_offset[SI_DOWN_LEFT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN_RIGHT] = 15, .bitmap_prop[SI_DOWN_RIGHT] = S_FLIPX,
.collision_offset[SI_DOWN_RIGHT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
}
},
{
.frames_since_last_dash = 0,
.frames_since_last_jump = 0,
.name = "mike",
.has_diag_sprites = 0,
.bitmap_index = SI_LEFT,
.has_joypad = 0,
.pos = { .x = 0, .y = 0},
.vel = { .x = 0, .y = 0},
.acc = { .x = 0, .y = 0},
.bitmap_indexes[SI_UP] = 25, .bitmap_prop[SI_UP] = 0,
.collision_offset[SI_UP] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN] = 22, .bitmap_prop[SI_DOWN] = 0,
.collision_offset[SI_DOWN] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_LEFT] = 21, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = {
.itl = { .x = 8, .y = 5},
.itr = { .x = 1, .y = 5},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_RIGHT] = 21, .bitmap_prop[SI_RIGHT] = S_FLIPX,
.collision_offset[SI_RIGHT] = {
.itl = { .x = 8, .y = 5},
.itr = { .x = 1, .y = 5},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_UP_RIGHT] = 23, .bitmap_prop[SI_UP_RIGHT] = 0,
.collision_offset[SI_UP_RIGHT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_UP_LEFT] = 23, .bitmap_prop[SI_UP_LEFT] = S_FLIPX,
.collision_offset[SI_UP_LEFT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN_LEFT] = 24, .bitmap_prop[SI_DOWN_LEFT] = S_FLIPX,
.collision_offset[SI_DOWN_LEFT] = {
.itl = { .x = 8, .y = 7},
.itr = { .x = 1, .y = 7},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN_RIGHT] = 24, .bitmap_prop[SI_DOWN_RIGHT] = 0,
.collision_offset[SI_DOWN_RIGHT] = {
.itl = { .x = 8, .y = 7},
.itr = { .x = 1, .y = 7},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
}
} }
}; };

View File

@@ -10,7 +10,7 @@
Compression : None. Compression : None.
Counter : None. Counter : None.
Tile size : 8 x 8 Tile size : 8 x 8
Tiles : 0 to 13 Tiles : 0 to 25
Palette colors : None. Palette colors : None.
SGB Palette : None. SGB Palette : None.
@@ -52,7 +52,31 @@ unsigned char sprites[] =
0x00,0x02,0x00,0x07,0x02,0x00,0x02,0x00, 0x00,0x02,0x00,0x07,0x02,0x00,0x02,0x00,
0x02,0x00,0x00,0x02,0x00,0x07,0x00,0x05, 0x02,0x00,0x00,0x02,0x00,0x07,0x00,0x05,
0x00,0x03,0x02,0x01,0x04,0x00,0x08,0x00, 0x00,0x03,0x02,0x01,0x04,0x00,0x08,0x00,
0x00,0x30,0x00,0x50,0x00,0x20,0x00,0x00 0x00,0x30,0x00,0x50,0x00,0x20,0x00,0x00,
0x38,0x38,0x7C,0x7C,0x7C,0x44,0x38,0x00,
0x18,0x00,0x18,0x18,0xBD,0xBD,0xBD,0xBD,
0x38,0x38,0x7C,0x7C,0x7C,0x44,0x39,0x01,
0x99,0x81,0x98,0x98,0x3C,0x3C,0x3C,0x3C,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,
0x25,0xFE,0x18,0xE7,0x7E,0xFF,0x00,0xDB,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,
0x38,0xEE,0x52,0xAD,0x7C,0xFF,0x01,0xD7,
0x00,0x38,0x10,0x6E,0x2C,0x77,0x22,0xDD,
0x7E,0xFF,0x12,0xC9,0x18,0xE7,0x00,0x7E,
0x00,0x38,0x10,0x6C,0x3C,0xC6,0x60,0xBF,
0x0E,0xFF,0x78,0xF3,0x00,0xDE,0x00,0x70,
0x00,0x00,0x30,0x4C,0x70,0x9E,0x06,0xFB,
0x7C,0xF3,0x0E,0x5F,0x00,0x7B,0x00,0x1E,
0x00,0x7E,0x18,0xE7,0x36,0xED,0x02,0xFD,
0x7E,0xFF,0x08,0x53,0x10,0x6E,0x00,0x38
}; };
/* End of SPRITES.C */ /* End of SPRITES.C */

View File

@@ -10,7 +10,7 @@
Compression : None. Compression : None.
Counter : None. Counter : None.
Tile size : 8 x 8 Tile size : 8 x 8
Tiles : 0 to 13 Tiles : 0 to 25
Palette colors : None. Palette colors : None.
SGB Palette : None. SGB Palette : None.

View File

@@ -12,14 +12,14 @@
#include "./sprite.h" #include "./sprite.h"
#include "./vec.h" #include "./vec.h"
#define NO_SCREEN_SPRITES 2 #define NO_SCREEN_SPRITES 3
void init_gfx() void init_gfx()
{ {
// Load Background tiles and then map // Load Background tiles and then map
set_bkg_data(0, 23, tiles); set_bkg_data(0, 23, tiles);
set_bkg_tiles(0, 0, map.width, map.height, map.data); set_bkg_tiles(0, 0, map.width, map.height, map.data);
set_sprite_data(0, 14, sprites); set_sprite_data(0, 26, sprites);
// Turn the background map on to make it visible // Turn the background map on to make it visible
SHOW_BKG; SHOW_BKG;
@@ -34,10 +34,10 @@ void main(void)
struct Sprites screen_sprites[NO_SCREEN_SPRITES]; struct Sprites screen_sprites[NO_SCREEN_SPRITES];
memcpy(&(screen_sprites[0]), &(sprites_info[0]), sizeof(Sprite)); 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));
screen_sprites[0].has_joypad = 1; screen_sprites[0].has_joypad = 1;
screen_sprites[1].bitmap_index = SI_UP;
for (i = 0; i < NO_SCREEN_SPRITES; i++) { for (i = 0; i < NO_SCREEN_SPRITES; i++) {
screen_sprites[i].bitmap_index_prev = -1; screen_sprites[i].bitmap_index_prev = -1;
@@ -54,7 +54,6 @@ void main(void)
jp = joypad(); jp = joypad();
for (i = 0; i < NO_SCREEN_SPRITES; i++) { for (i = 0; i < NO_SCREEN_SPRITES; i++) {
sprite_iter_frame(&(screen_sprites[i]), &map, screen_sprites[i].has_joypad ? jp : 0, &fc); sprite_iter_frame(&(screen_sprites[i]), &map, screen_sprites[i].has_joypad ? jp : 0, &fc);
//gprintf("x: %d y: %d\n", sprites[i].pos.x, sprites[i].pos.y);
} }
// Done processing, yield CPU and wait for start of next frame // Done processing, yield CPU and wait for start of next frame

View File

@@ -5,6 +5,18 @@
#include "./flags.h" #include "./flags.h"
#include "./map.h" #include "./map.h"
#define GET_TILE_INDEX_BY_COORD(x, y) ((((y) / PIXELS_PER_TILE) * 20) + ((x) / PIXELS_PER_TILE))
#define GET_SPRITE_CORNERS(sprite, sc) \
sc.itl.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].itl.x; \
sc.itl.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].itl.y - 8; \
sc.itr.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].itr.x; \
sc.itr.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].itr.y - 8; \
sc.ibl.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].ibl.x; \
sc.ibl.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].ibl.y - 8; \
sc.ibr.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].ibr.x; \
sc.ibr.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].ibr.y - 8;
typedef struct SpriteCorners { typedef struct SpriteCorners {
UVec itl; UVec itl;
@@ -33,37 +45,20 @@ typedef struct Sprites {
int get_tile_index_by_coord(unsigned int x, unsigned int y); int get_tile_index_by_coord(unsigned int x, unsigned int y);
void get_sprite_corners(Sprite *sprite, SpriteCorners *r);
void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc); 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_draw_to_screen(Sprite *sprite);
void sprite_update_bitmap(Sprite *sprite); void sprite_update_bitmap(Sprite *sprite);
int get_tile_index_by_coord(unsigned int x, unsigned int y)
{
return ((y / PIXELS_PER_TILE) * 20) + (x / PIXELS_PER_TILE);
}
void get_sprite_corners(Sprite *sprite, SpriteCorners *sc)
{
sc->itl.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].itl.x;
sc->itl.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].itl.y - 8;
sc->itr.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].itr.x;
sc->itr.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].itr.y - 8;
sc->ibl.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].ibl.x;
sc->ibl.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].ibl.y - 8;
sc->ibr.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].ibr.x;
sc->ibr.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].ibr.y - 8;
}
// update a sprite for stuff that changes every frame // update a sprite for stuff that changes every frame
void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc) void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc)
{ {
int c, collision_check_steps; 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 // target displacement is sprite->vel but may collide, giving actual displacment
Vec displacement = {.x = 0, .y = 0}; Vec displacement = {.x = 0, .y = 0};
@@ -78,68 +73,92 @@ void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc)
} }
// player move left/right // player move left/right
if ((joypad & J_RIGHT) && (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 & J_LEFT) && (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/abs(sprite->vel.x); else sprite->acc.x = -sprite->vel.x/absvelx;
sprite->vel.x += sprite->acc.x; sprite->vel.x += sprite->acc.x;
// player dash // 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; int frames_since_last_dash_copy = sprite->frames_since_last_dash;
sprite->frames_since_last_dash = 0; sprite->frames_since_last_dash = 0;
if ((joypad & J_LEFT) && !(joypad & (J_UP | J_RIGHT | J_DOWN))) { if (b_left) {
sprite->vel.x = -DASH_VELL; if (b_up) {
} else if ((joypad & J_RIGHT) && !(joypad & (J_UP | J_LEFT | J_DOWN))) { sprite->vel.x = -DASH_VELD;
sprite->vel.x = DASH_VELL; sprite->vel.y = -DASH_VELD;
} else if ((joypad & J_UP) && !(joypad & (J_RIGHT | J_LEFT | J_DOWN))) { } else if (b_down) {
sprite->vel.y = -DASH_VELL; sprite->vel.x = -DASH_VELD;
} else if ((joypad & J_DOWN) && !(joypad & (J_UP | J_LEFT | J_RIGHT))) { sprite->vel.y = DASH_VELD;
sprite->vel.y = DASH_VELL; } else {
} else if ((joypad & J_RIGHT) && (joypad & J_UP)) { sprite->vel.x = -DASH_VELL;
sprite->vel.x = DASH_VELD; }
sprite->vel.y = -DASH_VELD; } else if (b_right) {
} else if ((joypad & J_LEFT) && (joypad & J_UP)) { if (b_up) {
sprite->vel.x = -DASH_VELD; sprite->vel.x = DASH_VELD;
sprite->vel.y = -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.x = DASH_VELD;
sprite->vel.y = DASH_VELD; sprite->vel.y = DASH_VELD;
} else if ((joypad & J_RIGHT) && (joypad & J_DOWN)) { } else {
sprite->vel.x = DASH_VELD; sprite->vel.x = DASH_VELL;
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;
} }
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
else sprite->frames_since_last_dash = frames_since_last_dash_copy;
} }
// slow down sprite in kind of realistic way // slow down sprite in kind of realistic way
// (in real life i think it's drag is proportional to sprite->vel square but not // (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) // 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 -= (absvely-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.y < -TERM_VELY) sprite->vel.y += (absvely-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 -= (absvelx-TERM_VELX)/TERM_VELX_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 += (absvelx-TERM_VELX)/TERM_VELX_DIVISOR;
c = sprite_collision(map, sprite); 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;
GET_SPRITE_CORNERS(sprite, sc);
// don't let player move in a direction which they are already touching something // 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 (sprite->vel.y > 0) {
if (((c & SC_BL) | (c & SC_BR)) && (sprite->vel.y > 0)) { br = map->data[GET_TILE_INDEX_BY_COORD(sc.ibl.x, sc.ibl.y+1)];
// player jump bl = map->data[GET_TILE_INDEX_BY_COORD(sc.ibr.x, sc.ibr.y+1)];
if ((joypad & J_A) && (sprite->frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) {
sprite->vel.y = -JUMP_VEL; if (bl | br) {
sprite->frames_since_last_jump = 0; sprite->vel.y = 0;
} // player jump
else sprite->vel.y = 0; if (b_a && (sprite->frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) {
} sprite->vel.y = -JUMP_VEL;
if (((c & SC_RT) | (c & SC_RB)) && (sprite->vel.x > 0)) { sprite->vel.x = 0; } sprite->frames_since_last_jump = 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);
int absvelx = abs(sprite->vel.x);
int absvely = abs(sprite->vel.y);
collision_check_steps = (absvelx > absvely) ? absvelx : absvely; collision_check_steps = (absvelx > absvely) ? absvelx : absvely;
original_position.x = sprite->pos.x; original_position.x = sprite->pos.x;
@@ -149,55 +168,24 @@ 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.x = original_position.x + ((step * sprite->vel.x)/collision_check_steps);
sprite->pos.y = original_position.y + ((step * sprite->vel.y)/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); sprite_draw_to_screen(sprite);
move_sprite(sprite->gb_sprite_index, sprite->pos.x, sprite->pos.y);
} }
// calculate internal collisions // set new sprite bitmap
unsigned int sprite_internal_collision(Map *map, Sprite *sprite)
{
unsigned int rv = 0;
SpriteCorners sc;
get_sprite_corners(sprite, &sc);
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;
}
void sprite_update_bitmap(Sprite *sprite) void sprite_update_bitmap(Sprite *sprite)
{ {
sprite->bitmap_index_prev = sprite->bitmap_index; sprite->bitmap_index_prev = sprite->bitmap_index;
if ((sprite->vel.y > 0) && (sprite->vel.x > 0)) sprite->bitmap_index = SI_DOWN_RIGHT;
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_UP_RIGHT;
else if ((sprite->vel.y > 0) && (sprite->vel.x < 0)) sprite->bitmap_index = SI_DOWN_LEFT; else if ((sprite->vel.y > 0) && (sprite->vel.x < 0)) sprite->bitmap_index = SI_DOWN_LEFT;
else if ((sprite->vel.y < 0) && (sprite->vel.x < 0)) sprite->bitmap_index = SI_UP_LEFT; else if ((sprite->vel.y < 0) && (sprite->vel.x < 0)) sprite->bitmap_index = SI_UP_LEFT;
@@ -210,6 +198,8 @@ void sprite_update_bitmap(Sprite *sprite)
void sprite_draw_to_screen(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) { if (sprite->bitmap_index_prev != sprite->bitmap_index) {
set_sprite_tile(sprite->gb_sprite_index, sprite->bitmap_indexes[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]); set_sprite_prop(sprite->gb_sprite_index, sprite->bitmap_prop[sprite->bitmap_index]);