144 lines
2.9 KiB
C
144 lines
2.9 KiB
C
#include <gint/display.h>
|
|
|
|
#include "player.h"
|
|
|
|
int
|
|
sign(int n)
|
|
{
|
|
/* I do not know well C lmao */
|
|
|
|
if (n > 0) {
|
|
return 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
Vec2
|
|
search(tile_t x, Level level)
|
|
{
|
|
/* Search for x in a given matrix. */
|
|
/* If x is found, return it coordinates */
|
|
Vec2 coordinates = {0, 0};
|
|
for (int m = 0; m < level.width; ++m) {
|
|
for (int n = 0; n < level.height; ++n) {
|
|
if (level.data[m + n * level.width] == x) {
|
|
coordinates.x = m * TILE_S;
|
|
coordinates.y = n * TILE_S;
|
|
return coordinates;
|
|
}
|
|
}
|
|
}
|
|
return coordinates;
|
|
}
|
|
|
|
int
|
|
convert_all(tile_t x, tile_t y, Level level)
|
|
{
|
|
/* convert all instance of a tile */
|
|
for (int i = 0; i < level.width * level.height; ++i) {
|
|
if (level.data[i] == x) {
|
|
level.data[i] = y;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
collide_pixel(Vec2 pos, tile_t obj, Level level)
|
|
{
|
|
/* Check if there's something in (x, y) */
|
|
const int position = pos.x / TILE_S + pos.y / TILE_S * level.width;
|
|
const int uwu = level.data[position];
|
|
|
|
/* debug */
|
|
drect(pos.x / TILE_S * 8, pos.y / TILE_S * 8, pos.x / TILE_S * 8 + 8,
|
|
pos.y / TILE_S * 8 + 8, C_BLUE);
|
|
|
|
if (position < 0 || position > level.width * level.height || uwu == 0) {
|
|
return 0;
|
|
}
|
|
|
|
/* others */
|
|
if (obj != 1) {
|
|
if (uwu == obj) {
|
|
return position;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* solids */
|
|
if ((uwu - 1) % TILESET_W <= 6) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int
|
|
collide(Vec2 pos, int h, tile_t obj, Level level)
|
|
{
|
|
/* tl = top left */
|
|
/* br = bottom right */
|
|
const Vec2 pos_tl = (Vec2){pos.x + h, pos.y + h};
|
|
const Vec2 pos_br =
|
|
(Vec2){pos.x + PLAYER_SIZE - h - 1, pos.y + PLAYER_SIZE - h - 1};
|
|
/* Check if there's something in */
|
|
/* the square (x, y, x + 15, y + 15) */
|
|
/* The size of the hitbox changes with h */
|
|
|
|
/* debug */
|
|
drect(pos_tl.x, pos_tl.y, pos_br.x, pos_br.y, C_RED);
|
|
|
|
if (collide_pixel(pos_tl, obj, level) ||
|
|
collide_pixel(pos_br, obj, level) ||
|
|
collide_pixel((Vec2){pos_tl.x, pos_br.y}, obj, level) ||
|
|
collide_pixel((Vec2){pos_br.x, pos_tl.y}, obj, level)) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Res_Mov
|
|
move(Player player, Level level)
|
|
{
|
|
/* move the player */
|
|
Vec2 moved = {0, 0};
|
|
|
|
if (player.spd.x == 0 && player.spd.y == 0) {
|
|
return (Res_Mov){player, moved};
|
|
}
|
|
|
|
int Ispd_x = player.spd.x;
|
|
player.pos.x += Ispd_x;
|
|
if (collide(player.pos, 0, 1, level)) {
|
|
float sign_x = sign(player.spd.x);
|
|
while (collide(player.pos, 0, 1, level) == 1) {
|
|
player.pos.x -= sign_x;
|
|
}
|
|
moved.x = 1;
|
|
}
|
|
|
|
int Ispd_y = player.spd.y;
|
|
player.pos.y += Ispd_y;
|
|
if (collide(player.pos, 0, 1, level)) {
|
|
float sign_y = sign(player.spd.y);
|
|
while (collide(player.pos, 0, 1, level) == 1) {
|
|
player.pos.y -= sign_y;
|
|
}
|
|
moved.y = 1;
|
|
}
|
|
return (Res_Mov){player, moved};
|
|
}
|
|
|
|
Player
|
|
player_reset(Player player, Level level)
|
|
{
|
|
/* reset the level */
|
|
player.spawn = search(52, level);
|
|
player.pos = player.spawn;
|
|
player.spd = (FVec2){0, 0};
|
|
return player;
|
|
}
|