game: add camera movement with left/right keys

This commit is contained in:
Lephenixnoir 2022-08-20 23:08:30 +02:00
parent f68e28df53
commit d4db7d54d1
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
3 changed files with 85 additions and 16 deletions

View File

@ -44,6 +44,9 @@ int main(void)
struct camera camera;
camera.pos = vec3(0, RENDER_CAMERA_DEPTH, 0);
camera.platform = 0;
camera.rot_direction = 0;
camera.rot_t = 0;
bool game_run = true;
while(game_run) {
@ -56,7 +59,7 @@ int main(void)
prof_enter_norec(perf_frame);
level_update(&level);
camera_set_angle(&camera, t / 2);
camera_set_angle(&camera, camera_compute_platform_angle(&camera));
//---
// Rendering
@ -137,6 +140,14 @@ int main(void)
level = level_create(3);
level_update(&level);
}
if(ev.key == KEY_LEFT && !camera.rot_direction) {
camera.rot_direction = -1;
camera.rot_t = 0;
}
if(ev.key == KEY_RIGHT && !camera.rot_direction) {
camera.rot_direction = 1;
camera.rot_t = 0;
}
}
if(!game_run) break;
@ -153,6 +164,17 @@ int main(void)
sections_passed++;
}
if(camera.rot_direction != 0) {
camera.rot_t += dt;
if(camera.rot_t > CAMERA_ROTATION_DURATION) {
int p = camera.platform + camera.rot_direction;
p = (p + PLATFORM_COUNT) % PLATFORM_COUNT;
camera.platform = p;
camera.rot_direction = 0;
camera.rot_t = 0;
}
}
//---
prof_leave_norec(perf_frame);

View File

@ -5,7 +5,7 @@
#include <azur/gint/render.h>
/* Angle span for a platform in the level cylinder */
static float get_alpha(void)
num render_platform_arc(void)
{
return 2 * 3.14159 / PLATFORM_COUNT;
}
@ -46,10 +46,10 @@ static vec2 alpha_rotations[PLATFORM_COUNT];
computed values. */
void render_init(void)
{
float alpha = get_alpha();
num alpha = render_platform_arc();
for(int i = 0; i < PLATFORM_COUNT; i++) {
num angle = num(-alpha * i + (alpha / 2));
num angle = -alpha * i + (alpha / 2);
alpha_rotations[i] = vec2(num_cos(angle), num_sin(angle));
}
}
@ -114,10 +114,10 @@ void camera_project_prect(struct camera *camera, struct prect *p,
? (int)half_screen.x
: (int)half_screen.y;
p->nl = vec_rotate_around_z(p->nl, camera->angle_rotation) - camera->pos;
p->nr = vec_rotate_around_z(p->nr, camera->angle_rotation) - camera->pos;
p->fl = vec_rotate_around_z(p->fl, camera->angle_rotation) - camera->pos;
p->fr = vec_rotate_around_z(p->fr, camera->angle_rotation) - camera->pos;
p->nl = vec_rotate_around_z(p->nl, camera->_angle_rotation) - camera->pos;
p->nr = vec_rotate_around_z(p->nr, camera->_angle_rotation) - camera->pos;
p->fl = vec_rotate_around_z(p->fl, camera->_angle_rotation) - camera->pos;
p->fr = vec_rotate_around_z(p->fr, camera->_angle_rotation) - camera->pos;
/* We assume nl/nr have the same z, and so do fl/fr */
num f = near_plane * screen;
@ -132,8 +132,30 @@ void camera_project_prect(struct camera *camera, struct prect *p,
void camera_set_angle(struct camera *camera, num angle)
{
camera->angle = angle;
camera->angle_rotation = vec2(num_cos(angle), num_sin(angle));
camera->_angle = angle;
camera->_angle_rotation = vec2(num_cos(angle), num_sin(angle));
}
static num cubic(num t)
{
if(t <= 0.5) {
return 4 * t * t * t;
}
else {
t = num(1) - t;
return num(1) - 4 * t * t * t;
}
}
num camera_compute_platform_angle(struct camera *camera)
{
num arc = render_platform_arc();
num a = camera->platform * arc;
if(camera->rot_direction) {
num t = camera->rot_t / CAMERA_ROTATION_DURATION;
a += camera->rot_direction * arc * t;
}
return a;
}
void render_triangle(vec3 *p1, vec3 *p2, vec3 *p3, int color)

View File

@ -16,32 +16,57 @@ using namespace libnum;
#define RENDER_SECTION_LENGTH num(4.0)
/* Number of sections visible in advance */
#define RENDER_SECTION_DISTANCE 8
/* Duration of a camera rotation by one platform */
#define CAMERA_ROTATION_DURATION num(0.1)
struct prect {
vec3 nl, nr; /* Near left and near right points */
vec3 fl, fr; /* Far left and far right points */
};
/* We assume the camera is looking towards (0,0,z) */
struct camera {
/* Position in space - we assume looking towards (0,0,z) */
vec3 pos;
/* Current platform (or, when rotating, platform we just left) */
int platform;
/* Viewing angle and associated rotation vector */
num angle;
vec2 angle_rotation;
/* Current direction of rotation (-1, 0, or +1) */
int rot_direction;
/* How much of the movement in rot_direction has been accomplished yet
(between 0 and CAMERA_ROTATION_DURATION) */
num rot_t;
/* Viewing angle and associated rotation vector. Both of these fields are
computed from the previous. */
num _angle;
vec2 _angle_rotation;
};
/* Initialize the render module. */
void render_init(void);
struct prect render_platform_position(int platform_id, num z);
/* Angle, in radians, of a platform arc (2π / PLATFORM_COUNT) */
num render_platform_arc(void);
/* Position, in world units, of a flat platform in the specified platform slot
(0..PLATFORM_COUNT-1) that has its near side at the specified depth z. */
struct prect render_platform_position(int platform_slot, num z);
/* Project a point from world units to screen units viewed through the provided
camera. screen_size holds sizes in pixels as num values. */
vec3 camera_project(struct camera *camera, vec3 u, vec2 screen_size);
/* Optimized camera_project() that projects an entire prect in-place. */
void camera_project_prect(struct camera *camera, struct prect *p,
vec2 screen_size);
/* Set the camera's viewing angle and recompute its rotation vector. */
void camera_set_angle(struct camera *camera, num angle);
/* Compute the camera's viewing angle based on its platform position. */
num camera_compute_platform_angle(struct camera *camera);
/* Queue an Azur command to render the triangle defined by p1/p2/p3. Only the
x/y coordinates are used, z is ignored. */
void render_triangle(vec3 *p1, vec3 *p2, vec3 *p3, int color);
#endif /* __RENDERH__ */