Compare commits

...

8 Commits

12 changed files with 444 additions and 131 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

210
res/sprite_metadata.c Normal file
View File

@@ -0,0 +1,210 @@
#include <gb/gb.h>
#include "../src/sprite.h"
#include "../src/flags.h"
Sprite sprites_info[] = {
{
.frames_since_last_dash = 0,
.frames_since_last_jump = 0,
.name = "arrow",
.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] = 12, .bitmap_prop[SI_UP] = 0,
.collision_offset[SI_UP] = {
.itl = { .x = 3, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 3, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_DOWN] = 12, .bitmap_prop[SI_DOWN] = S_FLIPY,
.collision_offset[SI_DOWN] = {
.itl = { .x = 3, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 3, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_LEFT] = 11, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = {
.itl = { .x = 8, .y = 3},
.itr = { .x = 1, .y = 3},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_RIGHT] = 11, .bitmap_prop[SI_RIGHT] = S_FLIPX,
.collision_offset[SI_RIGHT] = {
.itl = { .x = 8, .y = 3},
.itr = { .x = 1, .y = 3},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 1, .y = 1},
},
.bitmap_indexes[SI_UP_RIGHT] = 13, .bitmap_prop[SI_UP_RIGHT] = 0,
.collision_offset[SI_UP_RIGHT] = {
.itl = { .x = 7, .y = 8},
.itr = { .x = 1, .y = 8},
.ibl = { .x = 7, .y = 2},
.ibr = { .x = 1, .y = 2},
},
.bitmap_indexes[SI_UP_LEFT] = 13, .bitmap_prop[SI_UP_LEFT] = S_FLIPX,
.collision_offset[SI_UP_LEFT] = {
.itl = { .x = 8, .y = 8},
.itr = { .x = 2, .y = 8},
.ibl = { .x = 8, .y = 2},
.ibr = { .x = 2, .y = 2},
},
.bitmap_indexes[SI_DOWN_LEFT] = 13, .bitmap_prop[SI_DOWN_LEFT] = S_FLIPX | S_FLIPY,
.collision_offset[SI_DOWN_LEFT] = {
.itl = { .x = 8, .y = 7},
.itr = { .x = 2, .y = 7},
.ibl = { .x = 8, .y = 1},
.ibr = { .x = 2, .y = 1},
},
.bitmap_indexes[SI_DOWN_RIGHT] = 13, .bitmap_prop[SI_DOWN_RIGHT] = S_FLIPY,
.collision_offset[SI_DOWN_RIGHT] = {
.itl = { .x = 7, .y = 7},
.itr = { .x = 1, .y = 7},
.ibl = { .x = 7, .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},
}
}
};

3
res/sprite_metadata.h Normal file
View File

@@ -0,0 +1,3 @@
#include "../src/sprite.h"
extern Sprite sprites_info[];

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 10 Tiles : 0 to 25
Palette colors : None. Palette colors : None.
SGB Palette : None. SGB Palette : None.
@@ -25,8 +25,8 @@
/* Start of tile array. */ /* Start of tile array. */
unsigned char sprites[] = unsigned char sprites[] =
{ {
0xF7,0x08,0xED,0x12,0xFE,0x11,0xFF,0x38, 0xFF,0x19,0xEF,0x17,0xFF,0x11,0xFF,0x3B,
0xFE,0x39,0xFE,0x39,0xFF,0x7E,0xFF,0x6E, 0xFE,0x3F,0xFE,0x3D,0xFF,0x7E,0xFF,0x6E,
0xFF,0x00,0xC3,0x42,0x81,0x00,0x81,0x00, 0xFF,0x00,0xC3,0x42,0x81,0x00,0x81,0x00,
0x81,0x00,0x81,0x00,0xC3,0x42,0xFF,0x00, 0x81,0x00,0x81,0x00,0xC3,0x42,0xFF,0x00,
0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, 0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E,
@@ -46,7 +46,37 @@ unsigned char sprites[] =
0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, 0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E,
0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x42,0xC3, 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x42,0xC3,
0x43,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, 0x43,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E,
0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x43,0xC3 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x43,0xC3,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x43,0x38,0xC6,0x00,0x43,
0x00,0x02,0x00,0x07,0x02,0x00,0x02,0x00,
0x02,0x00,0x00,0x02,0x00,0x07,0x00,0x05,
0x00,0x03,0x02,0x01,0x04,0x00,0x08,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 */

Binary file not shown.

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 10 Tiles : 0 to 25
Palette colors : None. Palette colors : None.
SGB Palette : None. SGB Palette : None.

View File

@@ -25,8 +25,8 @@
/* Start of tile array. */ /* Start of tile array. */
unsigned char tiles[] = unsigned char tiles[] =
{ {
0x10,0x00,0x00,0x00,0x08,0x00,0x10,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x30,0x00,0x20,0x00,0x60,0x00,0x50,0x20, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0xFF, 0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0xFF,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,

Binary file not shown.

View File

@@ -24,6 +24,15 @@
#define SC_IBL 0b0010 #define SC_IBL 0b0010
#define SC_IBR 0b0001 #define SC_IBR 0b0001
#define SI_UP 0
#define SI_DOWN 1
#define SI_LEFT 2
#define SI_RIGHT 3
#define SI_UP_RIGHT 4
#define SI_DOWN_RIGHT 5
#define SI_UP_LEFT 6
#define SI_DOWN_LEFT 7
/* Sprite Collision point diagram: /* Sprite Collision point diagram:
* x TL LT x * x TL LT x
* ------------ * ------------

View File

@@ -1,22 +1,25 @@
#include <gb/gb.h> #include <gb/gb.h>
#include <gb/drawing.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../res/tiles.h" #include "../res/tiles.h"
#include "../res/map.h" #include "../res/map.h"
#include"../res/sprites.h" #include"../res/sprites.h"
#include"../res/sprite_metadata.h"
#include "./flags.h" #include "./flags.h"
#include "./constants.h" #include "./constants.h"
#include "./sprite.h" #include "./sprite.h"
#include "./vec.h" #include "./vec.h"
#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, 26, sprites);
set_sprite_data(0, 11, sprites);
set_sprite_tile(0, 2);
set_sprite_prop(0, 0);
// Turn the background map on to make it visible // Turn the background map on to make it visible
SHOW_BKG; SHOW_BKG;
@@ -25,25 +28,33 @@ void init_gfx()
void main(void) void main(void)
{ {
unsigned int fc = 0;
struct Sprites sprite;
init_gfx(); init_gfx();
sprite.pos.x = 72; unsigned int i, jp, fc = 0;
sprite.pos.y = 36; struct Sprites screen_sprites[NO_SCREEN_SPRITES];
sprite.vel.x = 0;
sprite.vel.y = 0;
sprite.acc.x = 0; memcpy(&(screen_sprites[0]), &(sprites_info[2]), sizeof(Sprite));
sprite.acc.y = 0; memcpy(&(screen_sprites[1]), &(sprites_info[1]), sizeof(Sprite));
move_sprite(0, sprite.pos.x, sprite.pos.y); memcpy(&(screen_sprites[2]), &(sprites_info[0]), sizeof(Sprite));
screen_sprites[0].has_joypad = 1;
for (i = 0; i < NO_SCREEN_SPRITES; i++) {
screen_sprites[i].bitmap_index_prev = -1;
screen_sprites[i].gb_sprite_index = i;
screen_sprites[i].pos.x = 72+(8*i);
screen_sprites[i].pos.y = 36+(8*i);
sprite_draw_to_screen(&(screen_sprites[i]));
}
// Loop forever // Loop forever
while(1) { while(1) {
fc++; fc++;
sprite_iter_frame(&sprite, &map, joypad(), &fc); jp = joypad();
move_sprite(0, sprite.pos.x, sprite.pos.y); for (i = 0; i < NO_SCREEN_SPRITES; i++) {
sprite_iter_frame(&(screen_sprites[i]), &map, screen_sprites[i].has_joypad ? jp : 0, &fc);
}
// 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();

View File

@@ -5,15 +5,17 @@
#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))
typedef struct Sprites { #define GET_SPRITE_CORNERS(sprite, sc) \
int frames_since_last_dash; sc.itl.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].itl.x; \
int frames_since_last_jump; sc.itl.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].itl.y - 8; \
int size; sc.itr.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].itr.x; \
UVec pos; sc.itr.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].itr.y - 8; \
Vec vel; sc.ibl.x = sprite->pos.x - sprite->collision_offset[sprite->bitmap_index].ibl.x; \
Vec acc; sc.ibl.y = sprite->pos.y - sprite->collision_offset[sprite->bitmap_index].ibl.y - 8; \
} Sprite; 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 {
@@ -24,36 +26,39 @@ typedef struct SpriteCorners {
} SpriteCorners; } SpriteCorners;
typedef struct Sprites {
int gb_sprite_index;
int frames_since_last_dash;
int frames_since_last_jump;
int bitmap_index_prev;
int bitmap_index;
int bitmap_indexes[8];
int bitmap_prop[8];
int has_diag_sprites;
int has_joypad;
char name[20];
SpriteCorners collision_offset[8];
UVec pos;
Vec vel;
Vec acc;
} Sprite;
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 getSpriteCorners(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); void sprite_draw_to_screen(Sprite *sprite);
unsigned int sprite_collision(Map *map, 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 getSpriteCorners(Sprite *sprite, SpriteCorners *sc)
{
sc->itl.x = sprite->pos.x-8;
sc->itl.y = sprite->pos.y-16;
sc->itr.x = sprite->pos.x-1;
sc->itr.y = sprite->pos.y-16;
sc->ibl.x = sprite->pos.x-8;
sc->ibl.y = sprite->pos.y-9 ;
sc->ibr.x = sprite->pos.x-1;
sc->ibr.y = sprite->pos.y-9;
}
// 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};
@@ -68,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;
absvelx = abs(sprite->vel.x);
absvely = abs(sprite->vel.y);
c = sprite_collision(map, sprite); // 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;
@@ -139,43 +168,41 @@ 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_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) void sprite_update_bitmap(Sprite *sprite)
{ {
unsigned int rv = 0; sprite->bitmap_index_prev = sprite->bitmap_index;
SpriteCorners sc; if ((sprite->vel.y > 0) && (sprite->vel.x > 0)) sprite->bitmap_index = SI_DOWN_RIGHT;
getSpriteCorners(sprite, &sc); 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_UP_LEFT;
if (map->data[get_tile_index_by_coord(sc.itl.x, sc.itl.y)]) rv = rv | SC_ITL; else if ( sprite->vel.y < 0) sprite->bitmap_index = SI_UP;
if (map->data[get_tile_index_by_coord(sc.itr.x, sc.itr.y)]) rv = rv | SC_ITR; else if ( sprite->vel.y > 0) sprite->bitmap_index = SI_DOWN;
if (map->data[get_tile_index_by_coord(sc.ibl.x, sc.ibl.y)]) rv = rv | SC_IBL; else if ( sprite->vel.x > 0) sprite->bitmap_index = SI_RIGHT;
if (map->data[get_tile_index_by_coord(sc.ibr.x, sc.ibr.y)]) rv = rv | SC_IBR; else if ( sprite->vel.x < 0) sprite->bitmap_index = SI_LEFT;
return rv;
} }
void sprite_draw_to_screen(Sprite *sprite)
// check for external collisions (if rectangle is at least touchign something)
unsigned int sprite_collision(Map *map, Sprite *sprite)
{ {
unsigned int rv = 0; // only set sprite if sprite to be used has changed
SpriteCorners sc; sprite_update_bitmap(sprite);
getSpriteCorners(sprite, &sc); if (sprite->bitmap_index_prev != sprite->bitmap_index) {
set_sprite_tile(sprite->gb_sprite_index, sprite->bitmap_indexes[sprite->bitmap_index]);
// check if corners are in a non 0 tile set_sprite_prop(sprite->gb_sprite_index, sprite->bitmap_prop[sprite->bitmap_index]);
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; move_sprite(sprite->gb_sprite_index, sprite->pos.x, sprite->pos.y);
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;
} }

View File

@@ -4,10 +4,25 @@
#include "./vec.h" #include "./vec.h"
#include "./map.h" #include "./map.h"
typedef struct SpriteCorners {
UVec itl;
UVec itr;
UVec ibl;
UVec ibr;
} SpriteCorners;
typedef struct Sprites { typedef struct Sprites {
int gb_sprite_index;
int frames_since_last_dash; int frames_since_last_dash;
int frames_since_last_jump; int frames_since_last_jump;
int size; int bitmap_index_prev;
int bitmap_index;
int bitmap_indexes[8];
int bitmap_prop[8];
int has_diag_sprites;
int has_joypad;
char name[20];
SpriteCorners collision_offset[8];
UVec pos; UVec pos;
Vec vel; Vec vel;
Vec acc; Vec acc;
@@ -16,5 +31,6 @@ typedef struct Sprites {
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_internal_collision(Map *map, Sprite *sprite);
unsigned int sprite_collision(Map *map, Sprite *sprite); unsigned int sprite_collision(Map *map, Sprite *sprite);
void sprite_draw_to_screen(Sprite *sprite);
#endif #endif