player collision code

This commit is contained in:
KikooDX 2021-11-10 08:08:29 +01:00
parent 6e8041a926
commit c0c4630095
10 changed files with 155 additions and 49 deletions

View File

@ -16,6 +16,7 @@ set(SOURCES
src/input.c
src/level.c
src/player.c
src/util.c
)
set(LEVELS

View File

@ -17,7 +17,11 @@ struct Level {
char *data;
};
struct Level level_load(struct LevelBin *restrict);
void level_free(struct Level *restrict);
void level_draw(struct Level *restrict);
struct Vec level_find(struct Level *restrict, enum Tile);
void level_load(struct LevelBin *);
void level_free(void);
void level_draw(void);
struct Vec level_find(enum Tile);
enum Tile level_get(int x, int y);
enum Tile level_get_px(int x, int y);
void level_set(int x, int y, enum Tile v);
void level_set_px(int x, int y, enum Tile v);

View File

@ -7,6 +7,9 @@ struct Player {
struct VecF rem;
};
struct Player player_new(struct Vec pos);
void player_update(struct Player *restrict);
void player_draw(struct Player *restrict);
void player_init(struct Vec pos);
void player_update(void);
void player_draw(void);
/* return truncated speed */
struct Vec player_update_rem(void);
void player_move(struct Vec spd);

View File

@ -1,3 +1,3 @@
#pragma once
enum Tile { TILE_VOID, TILE_SOLID };
enum Tile { TILE_VOID, TILE_SOLID, TILE_OOB = TILE_SOLID };

4
inc/util.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
int sign(int);
float signf(float);

View File

@ -16,4 +16,4 @@ struct VecF {
#define VECF(x, y) \
(struct VecF) { x, y }
#define VECFZ VECF(0.0, 0.0)
#define VECFZ VECF(0.0f, 0.0f)

View File

@ -5,29 +5,29 @@
#include <gint/display.h>
#include <stdlib.h>
struct Level
level_load(struct LevelBin *restrict s)
static struct Level self;
void
level_load(struct LevelBin *s)
{
struct Level level;
int i = s->width * s->height;
level.width = s->width;
level.height = s->height;
level.size = i;
level.data = malloc(i);
self.width = s->width;
self.height = s->height;
self.size = i;
self.data = malloc(i);
while (i-- > 0) {
level.data[i] = s->data[i];
self.data[i] = s->data[i];
}
return level;
}
void
level_free(struct Level *restrict s)
level_free(void)
{
free(s->data);
free(self.data);
}
void
level_draw(struct Level *restrict s)
level_draw(void)
{
extern bopti_image_t bimg_tileset;
const int tileset_width = bimg_tileset.width / TILE_SIZE;
@ -35,17 +35,17 @@ level_draw(struct Level *restrict s)
int x = 0;
int y = 0;
for (i = 0; i < s->size; i++) {
for (i = 0; i < self.size; i++) {
const int sx = x * TILE_SIZE;
const int sy = y * TILE_SIZE;
const int tile = s->data[i];
const int tile = self.data[i];
const int rx = tile % tileset_width * TILE_SIZE;
const int ry = tile / tileset_width * TILE_SIZE;
dsubimage(sx, sy, &bimg_tileset, rx, ry, TILE_SIZE, TILE_SIZE,
DIMAGE_NONE);
if (++x >= s->width) {
if (++x >= self.width) {
x = 0;
y++;
}
@ -53,15 +53,43 @@ level_draw(struct Level *restrict s)
}
struct Vec
level_find(struct Level *restrict s, enum Tile seek)
level_find(enum Tile seek)
{
int i;
for (i = 0; i < s->size; i++) {
const enum Tile tile = s->data[i];
for (i = 0; i < self.size; i++) {
const enum Tile tile = self.data[i];
if (tile == seek) {
return VEC(i % s->width * TILE_SIZE,
(int)(i / s->height) * TILE_SIZE);
return VEC(i % self.width * TILE_SIZE,
(int)(i / self.height) * TILE_SIZE);
}
}
return VEC(0, 0);
}
enum Tile
level_get(int x, int y)
{
if (x < 0 || y < 0 || x >= self.width || y >= self.height)
return TILE_OOB;
return self.data[x + y * self.width];
}
enum Tile
level_get_px(int x, int y)
{
return level_get(x / TILE_SIZE, y / TILE_SIZE);
}
void
level_set(int x, int y, enum Tile v)
{
if (x < 0 || y < 0 || x >= self.width || y >= self.height)
return;
self.data[x + y * self.size] = v;
}
void
level_set_px(int x, int y, enum Tile v)
{
level_set(x / TILE_SIZE, y / TILE_SIZE, v);
}

View File

@ -8,7 +8,6 @@
#include <gint/timer.h>
extern struct LevelBin lvl_test;
struct Level level;
struct Player player;
static void update(void);
@ -26,8 +25,8 @@ main(void)
GINT_CALL(callback, &has_ticked));
timer_start(timer);
input_init();
level = level_load(&lvl_test);
player = player_new(VECZ);
level_load(&lvl_test);
player_init(level_find(TILE_VOID));
while (!input_pressed(K_EXIT)) {
int i;
@ -45,7 +44,7 @@ main(void)
}
timer_stop(timer);
level_free(&level);
level_free();
return 1;
}
@ -53,15 +52,15 @@ static void
update(void)
{
input_update();
player_update(&player);
player_update();
}
static void
draw(void)
{
dclear(C_BLACK);
level_draw(&level);
player_draw(&player);
level_draw();
player_draw();
dupdate();
}

View File

@ -1,28 +1,82 @@
#include "player.h"
#include "conf.h"
#include "level.h"
#include "util.h"
#include "vec.h"
#include <gint/display.h>
struct Player
player_new(struct Vec pos)
static struct Player self;
static int collide_solid(int x, int y);
void
player_init(struct Vec pos)
{
struct Player p;
p.pos = pos;
p.spd = VECFZ;
p.rem = VECFZ;
return p;
self.pos = pos;
self.spd = VECFZ;
self.rem = VECFZ;
}
void
player_update(struct Player *restrict p)
player_update(void)
{
p->pos.x++;
self.spd.x = 0.9f;
player_move(player_update_rem());
}
void
player_draw(struct Player *restrict p)
player_draw(void)
{
const int x2 = p->pos.x + PLAYER_WIDTH - 1;
const int y2 = p->pos.y + PLAYER_HEIGHT - 1;
drect(p->pos.x, p->pos.y, x2, y2, C_BLUE);
const int x2 = self.pos.x + PLAYER_WIDTH - 1;
const int y2 = self.pos.y + PLAYER_HEIGHT - 1;
drect(self.pos.x, self.pos.y, x2, y2, C_BLUE);
}
struct Vec
player_update_rem(void)
{
struct VecF spd_n_rem = {self.spd.x + self.rem.x,
self.spd.y + self.rem.y};
struct Vec spd_trunc = {spd_n_rem.x, spd_n_rem.y};
self.rem.x = spd_n_rem.x - (float)spd_trunc.x;
self.rem.y = spd_n_rem.y - (float)spd_trunc.y;
return spd_trunc;
}
void
player_move(struct Vec spd)
{
float sign_x = signf(spd.x);
const float sign_y = signf(spd.y);
if (!sign_x && !sign_y)
sign_x = 1.0f;
self.pos.x += spd.x;
if (collide_solid(self.pos.x, self.pos.y)) {
self.spd.x = 0.0f;
self.rem.x = 0.0f;
}
while (collide_solid(self.pos.x, self.pos.y)) {
self.pos.x -= sign_x;
}
self.pos.y += spd.y;
if (collide_solid(self.pos.x, self.pos.y)) {
self.spd.y = 0.0f;
self.rem.y = 0.0f;
}
while (collide_solid(self.pos.x, self.pos.y)) {
self.pos.y -= sign_y;
}
}
static int
collide_solid(int x, int y)
{
const int x2 = x + PLAYER_WIDTH - 1;
const int y2 = y + PLAYER_HEIGHT - 1;
return level_get_px(x, y) == TILE_SOLID ||
level_get_px(x, y2) == TILE_SOLID ||
level_get_px(x2, y) == TILE_SOLID ||
level_get_px(x2, y2) == TILE_SOLID;
}

13
src/util.c Normal file
View File

@ -0,0 +1,13 @@
#include "util.h"
int
sign(int n)
{
return (n > 0) - (n < 0);
}
float
signf(float n)
{
return (n > 0.0) - (n < 0.0);
}