Compare commits

9 Commits

Author SHA1 Message Date
6e1690ceea faster collisions
Squashed commit of the following:

commit 053c06ea29702728e2605899a2b47edac647c459
Author: Alvie Rahman <alvierahman90@gmail.com>
Date:   Sat Dec 3 16:09:51 2022 +0000

    begin documentation on codebase: sprite metadata

commit 435f0c62743112818594f4b1a902d90d1f60823a
Author: Alvie Rahman <alvierahman90@gmail.com>
Date:   Sat Dec 3 16:05:37 2022 +0000

    formatting, mostly

commit f338476aaf4c33081969b18b2a6d13a3639571cd
Author: Alvie Rahman <alvierahman90@gmail.com>
Date:   Fri Dec 2 23:18:27 2022 +0000

    way faster collisions
2022-12-03 16:13:44 +00:00
ea60bdeede add mike source 2022-12-03 16:07:39 +00: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
3eb6cc58ef move screen drawing logic outside of main.c 2022-06-12 19:31:27 +01:00
0615ab5073 all collision information is stored with sprites, support multiple sprites 2022-06-10 23:07:14 +01:00
776cf354f8 add arrow sprite 2022-06-09 16:07:21 +01:00
3b186a3d75 define sprite collision boxes in res, use in src/sprite.c 2022-06-09 15:51:27 +01:00
14 changed files with 375 additions and 113 deletions

View File

@@ -0,0 +1,9 @@
sprite.c:
struct Sprites
collision_offset = {
quad1x1, quad1y1, quad1x2, quad1y2,
quad2x1, quad2y1, quad2x2, quad2y2,
quad3x1, quad3y1, quad3x2, quad3y2
}

View File

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

186
res/sprite_metadata.c Normal file
View File

@@ -0,0 +1,186 @@
#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] = {
3, 8, 1, 7,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN] = 12, .bitmap_prop[SI_DOWN] = S_FLIPY,
.collision_offset[SI_DOWN] = {
3, 2, 1, 1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_LEFT] = 11, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = {
8, 3, 7, 1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_RIGHT] = 11, .bitmap_prop[SI_RIGHT] = S_FLIPX,
.collision_offset[SI_RIGHT] = {
2, 3, 1, 1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_UP_RIGHT] = 13, .bitmap_prop[SI_UP_RIGHT] = 0,
.collision_offset[SI_UP_RIGHT] = {
2, 8, 1, 7,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_UP_LEFT] = 13, .bitmap_prop[SI_UP_LEFT] = S_FLIPX,
.collision_offset[SI_UP_LEFT] = {
8, 8, 7, 7,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN_LEFT] = 13, .bitmap_prop[SI_DOWN_LEFT] = S_FLIPX | S_FLIPY,
.collision_offset[SI_DOWN_LEFT] = {
8, 2, 7, 1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN_RIGHT] = 13, .bitmap_prop[SI_DOWN_RIGHT] = S_FLIPY,
.collision_offset[SI_DOWN_RIGHT] = {
2, 2, 1, 1,
255, 255, 255, 255,
255, 255, 255, 255
}
},
{
.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] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN] = 15, .bitmap_prop[SI_DOWN] = 0,
.collision_offset[SI_DOWN] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_LEFT] = 14, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_RIGHT] = 14, .bitmap_prop[SI_RIGHT] = S_FLIPX,
.collision_offset[SI_RIGHT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_UP_RIGHT] = 14, .bitmap_prop[SI_UP_RIGHT] = 0,
.collision_offset[SI_UP_RIGHT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_UP_LEFT] = 14, .bitmap_prop[SI_UP_LEFT] = S_FLIPX,
.collision_offset[SI_UP_LEFT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN_LEFT] = 15, .bitmap_prop[SI_DOWN_LEFT] = 0,
.collision_offset[SI_DOWN_LEFT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN_RIGHT] = 15, .bitmap_prop[SI_DOWN_RIGHT] = S_FLIPX,
.collision_offset[SI_DOWN_RIGHT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
}
},
{
.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] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN] = 22, .bitmap_prop[SI_DOWN] = 0,
.collision_offset[SI_DOWN] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_LEFT] = 21, .bitmap_prop[SI_LEFT] = 0,
.collision_offset[SI_LEFT] = {
8,5, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_RIGHT] = 21, .bitmap_prop[SI_RIGHT] = S_FLIPX,
.collision_offset[SI_RIGHT] = {
8,5, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_UP_RIGHT] = 23, .bitmap_prop[SI_UP_RIGHT] = 0,
.collision_offset[SI_UP_RIGHT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_UP_LEFT] = 23, .bitmap_prop[SI_UP_LEFT] = S_FLIPX,
.collision_offset[SI_UP_LEFT] = {
8,8, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN_LEFT] = 24, .bitmap_prop[SI_DOWN_LEFT] = S_FLIPX,
.collision_offset[SI_DOWN_LEFT] = {
8,7, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
},
.bitmap_indexes[SI_DOWN_RIGHT] = 24, .bitmap_prop[SI_DOWN_RIGHT] = 0,
.collision_offset[SI_DOWN_RIGHT] = {
8,7, 1,1,
255, 255, 255, 255,
255, 255, 255, 255
}
}
};

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

Binary file not shown.

View File

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

View File

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

@@ -4,15 +4,15 @@
#define MAX_PLAYER_COUNT 1
#define GRAV_ACC 1
#define TERM_VELY 3
#define TERM_VELY 2
#define TERM_VELX 2
#define TERM_VELY_DIVISOR 3
#define TERM_VELY_DIVISOR 5
#define TERM_VELX_DIVISOR 3
#define JUMP_VEL 4
#define JUMP_TIMEOUT_FRAMES 18
#define DASH_VELL 7
#define DASH_VELL 4
// mfw when pythagoras irl :scream_cat:
#define DASH_VELD 5
#define DASH_TIMEOUT_FRAMES 30

View File

@@ -24,6 +24,15 @@
#define SC_IBL 0b0010
#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:
* x TL LT x
* ------------

View File

@@ -1,22 +1,25 @@
#include <gb/gb.h>
#include <gb/drawing.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../res/tiles.h"
#include "../res/map.h"
#include"../res/sprites.h"
#include"../res/sprite_metadata.h"
#include "./flags.h"
#include "./constants.h"
#include "./sprite.h"
#include "./vec.h"
#define NO_SCREEN_SPRITES 6
void init_gfx()
{
// Load Background tiles and then map
set_bkg_data(0, 23, tiles);
set_bkg_tiles(0, 0, map.width, map.height, map.data);
set_sprite_data(0, 11, sprites);
set_sprite_tile(0, 2);
set_sprite_prop(0, 0);
set_sprite_data(0, 26, sprites);
// Turn the background map on to make it visible
SHOW_BKG;
@@ -25,25 +28,34 @@ void init_gfx()
void main(void)
{
unsigned int fc = 0;
struct Sprites sprite;
init_gfx();
sprite.pos.x = 72;
sprite.pos.y = 36;
sprite.vel.x = 0;
sprite.vel.y = 0;
sprite.acc.x = 0;
sprite.acc.y = 0;
move_sprite(0, sprite.pos.x, sprite.pos.y);
unsigned int i, jp, fc = 0;
struct Sprites screen_sprites[NO_SCREEN_SPRITES];
memcpy(&(screen_sprites[0]), &(sprites_info[2]), sizeof(Sprite));
memcpy(&(screen_sprites[1]), &(sprites_info[1]), sizeof(Sprite));
for (i = 2; i < NO_SCREEN_SPRITES; i++) memcpy(&(screen_sprites[i]), &(sprites_info[0]), sizeof(Sprite));
screen_sprites[4].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
while(1) {
fc++;
sprite_iter_frame(&sprite, &map, joypad(), &fc);
move_sprite(0, sprite.pos.x, sprite.pos.y);
jp = joypad();
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
wait_vbl_done();

View File

@@ -1,63 +1,45 @@
#include <gb/gb.h>
#include <stdlib.h>
#include <stdio.h>
#include "./vec.h"
#include "./constants.h"
#include "./flags.h"
#include "./map.h"
#define LYO 8
#define GET_TILE_INDEX_BY_COORD(x, y) ((((y) / PIXELS_PER_TILE) * 20) + ((x) / PIXELS_PER_TILE))
typedef struct Sprites {
int gb_sprite_index;
int frames_since_last_dash;
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];
int collision_offset[8][12];
UVec pos;
Vec vel;
Vec acc;
} Sprite;
typedef struct SpriteCorners {
UVec itl;
UVec itr;
UVec ibl;
UVec ibr;
} SpriteCorners;
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);
unsigned int sprite_internal_collision(Map *map, Sprite *sprite);
unsigned int sprite_collision(Map *map, 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;
}
void sprite_draw_to_screen(Sprite *sprite);
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;
unsigned int colx, coly;
UVec original_position;
// 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++;
@@ -108,74 +90,84 @@ void sprite_iter_frame(Sprite *sprite, Map *map, int joypad, unsigned int *fc)
// 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 = TERM_VELY;
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
int *offsets = sprite->collision_offset[sprite->bitmap_index];
// jump if on platform
if ((joypad & J_A) && (sprite->frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) {
coly = map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[0], sprite->pos.y - offsets[3]-LYO+1)];
if (!coly) coly += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[2], sprite->pos.y - offsets[3]-LYO+1)];
if(coly) {
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;
// if no velocity component, pretend sprite has already collided
colx = sprite->vel.x == 0;
coly = sprite->vel.y == 0;
//for (int step = collision_check_steps; step >= 0; step--) {
if(sprite->vel.y != 0){
sprite->pos.y = original_position.y + sprite->vel.y;
if (sprite->vel.y < 0) {
coly += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[0], sprite->pos.y - offsets[1]-LYO)];
if (!coly) coly += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[2], sprite->pos.y - offsets[1]-LYO)];
} else if (sprite->vel.y > 0) {
coly += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[0], sprite->pos.y - offsets[3]-LYO)];
if (!coly) coly += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[2], sprite->pos.y - offsets[3]-LYO)];
}
if (coly) sprite->pos.y = original_position.y;
}
if(sprite->vel.x != 0) {
sprite->pos.x = original_position.x + sprite->vel.x;
if (sprite->vel.x < 0) {
colx += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[0], sprite->pos.y - offsets[1]-LYO)];
if(!colx) colx += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[0], sprite->pos.y - offsets[3]-LYO)];
} else if (sprite->vel.x > 0) {
colx += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[2], sprite->pos.y - offsets[1]-LYO)];
if(!colx) colx += map->data[GET_TILE_INDEX_BY_COORD(sprite->pos.x - offsets[2], sprite->pos.y - offsets[3]-LYO)];
}
if (colx) sprite->pos.x = original_position.x;
}
sprite_update_bitmap(sprite);
sprite_draw_to_screen(sprite);
}
// calculate internal collisions
unsigned int sprite_internal_collision(Map *map, Sprite *sprite)
void sprite_update_bitmap(Sprite *sprite)
{
unsigned int rv = 0;
SpriteCorners sc;
getSpriteCorners(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;
sprite->bitmap_index_prev = sprite->bitmap_index;
return rv;
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;
else if ((sprite->vel.y < 0) && (sprite->vel.x < 0)) sprite->bitmap_index = SI_UP_LEFT;
else if ( sprite->vel.y < 0) sprite->bitmap_index = SI_UP;
else if ( sprite->vel.y > 0) sprite->bitmap_index = SI_DOWN;
else if ( sprite->vel.x > 0) sprite->bitmap_index = SI_RIGHT;
else if ( sprite->vel.x < 0) sprite->bitmap_index = SI_LEFT;
}
// check for external collisions (if rectangle is at least touchign something)
unsigned int sprite_collision(Map *map, Sprite *sprite)
void sprite_draw_to_screen(Sprite *sprite)
{
unsigned int rv = 0;
SpriteCorners sc;
getSpriteCorners(sprite, &sc);
int bmi = sprite->bitmap_index;
// 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;
if (sprite->bitmap_index_prev != bmi) {
set_sprite_tile(sprite->gb_sprite_index, sprite->bitmap_indexes[bmi]);
set_sprite_prop(sprite->gb_sprite_index, sprite->bitmap_prop[bmi]);
}
move_sprite(sprite->gb_sprite_index, sprite->pos.x, sprite->pos.y);
}

View File

@@ -4,17 +4,31 @@
#include "./vec.h"
#include "./map.h"
typedef struct SpriteCorners {
UVec itl;
UVec itr;
UVec ibl;
UVec ibr;
} SpriteCorners;
typedef struct Sprites {
int gb_sprite_index;
int frames_since_last_dash;
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];
int collision_offset[8][12];
UVec pos;
Vec vel;
Vec acc;
} Sprite;
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);
#endif