#include #include "camera.h" #include "conf.h" #include "vec.h" #include "player.h" #include "level.h" void camera_step(Camera *camera) { /* lerp towards target */ vec_lerp(&camera->pos, *camera->target, camera->speed); /* put the camera in the right place */ vec_clamp(&camera->pos, camera->min, camera->max); /* calculate pixel offset */ Vec * const offset = &camera->offset; /* DRY */ vec_cpy(offset, camera->pos); vec_div(offset, VEC_PRECISION); vec_sub(offset, VEC_SCALED_DCENTER); } void camera_init(Camera *camera, Player *player, const Level *level) { /* initialize struct */ camera->pos = (Vec){ DWIDTH * VEC_PRECISION, DHEIGHT * VEC_PRECISION }; camera->target = &player->pos; camera->speed = 0.04; /* NOTE: This system doesn't totally works, but it's good enough * for now. TODO: Add informations about what isn't working * correctly and/or fix the issues. */ /* check level size */ const Vec level_dim = {level->width * (TILE_SIZE / VEC_PRECISION * SCALE), level->height * (TILE_SIZE / VEC_PRECISION * SCALE)}; if (level_dim.x > DWIDTH || level_dim.y > DHEIGHT) { /* level cannot be displayed on a single screen */ /* calculate min and max */ vec_cpy(&camera->min, VEC_SCALED_DCENTER); vec_mul(&camera->min, VEC_PRECISION); vec_cpy(&camera->max, (Vec){ 0, 0 }); vec_sub(&camera->max, VEC_SCALED_DCENTER); vec_mul(&camera->max, VEC_PRECISION); vec_add(&camera->max, (Vec){ TILE_SIZE * level->width, TILE_SIZE * level->height }); vec_cpy(&camera->pos, player->pos); } else { /* level is single screen */ /* We calculate the offset and setup the camera to center everything. */ const Vec screen_center_precise = {level->width * TILE_SIZE / 2, level->height * TILE_SIZE / 2}; vec_cpy(&camera->min, screen_center_precise); vec_cpy(&camera->max, screen_center_precise); } vec_clamp(&camera->pos, camera->min, camera->max); } void camera_draw_debug(Camera *camera) { dprint(0, 0, C_BLACK, "-x: %d, -y: %d", camera->min.x, camera->min.y); dprint(0, 10, C_BLACK, "+x: %d, +y: %d", camera->max.x, camera->max.y); dprint(0, 20, C_BLACK, "cx: %d, cy: %d", camera->pos.x, camera->pos.y); dprint(0, 30, C_BLACK, "px: %d, py: %d", camera->offset.x, camera->offset.y); }