game: add camera movement with left/right keys
This commit is contained in:
parent
f68e28df53
commit
d4db7d54d1
24
src/main.cpp
24
src/main.cpp
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
37
src/render.h
37
src/render.h
|
@ -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__ */
|
||||
|
|
Loading…
Reference in New Issue