Basic Input/Output

We played some optimization tennis with the WASD code, its was stupid.

I still don't know what I'm doing with this repo, maybe I should just make a game about unfinished game projects ... "The minds of Indie Developers"

Regardless though I want some input and some result of that input to appear on screen. I mean that's 99% of the game done at that point isn't it?

So some typing later ...

/* Data Types */

struct transform {
        float position[3];
};

struct input_device {
        float move_axis[2];
};

struct time {
        float delta;
};

struct player {
        struct transform tform;
};

struct ground {
        struct transform tform; 
};

struct game {
        /* Platform */
        struct input_device input_device;
        struct time time;
        /* World */
        struct player player;
        struct ground ground;
};

/* Game loopy functions */

void update_platform(struct game *game);
void update_player(struct game *game);
void update_render(struct game *game);

Now to hook some Raylib so we can get some input, my nice simple wasd controls

void
update_platform(
        struct game *game)
{
        /* Input Device 
         */

        uint8_t kw = IsKeyDown(KEY_W);
        uint8_t ka = IsKeyDown(KEY_A);
        uint8_t ks = IsKeyDown(KEY_S);
        uint8_t kd = IsKeyDown(KEY_D);

        int8_t mx = kd - ka;
        int8_t my = kw - ks;
        uint8_t ml = (mx & my) & 1;

        /* 1 or (sqrt(2) / 2), we do this so that we dont move faster
         * when going diagonal, this is what you'd get if you
         * normalized the vector {1, 0, 1}, then asked for its
         * length.
         */
        float len_rcp = (float[2]) { 1.f, 0.70710678118f }[ml];

        float kb_x = mx * len_rcp;
        float kb_y = my * len_rcp;

        game->input_device = (struct input_device) {
                .move_axis = { kb_x, kb_y },
        };

        /* Timer
         */

        game->time = (struct time) {
                .delta = GetFrameTime(),
        };
}
Look ma no branches

Sooooo. maybe not as 'simple' as it could be, I should provide some context, some time ago a friend and myself were making a prototype game and for whatever reason we played some optimization tennis with the WASD code, its was stupid, it was fun. (Maybe not a surprise but we never started making the game, let alone finish the prototype).

We got rid of all the branches and the vector normalization code, in a weird way I actually think its a nice example of how to approach optimization, we went from logic to data. And we pushed vector normalization code back in time.

I do personally have a grudge with the seemingly default approach of endless fucking branches that folk seem to have, but that is a rant for another day.

We also need to store the accumulation of the input, with some time logic so it can handle any inconsistent frame times.

void
update_player(
        struct game *game)
{
        /* Update player based on input 
         */

        float dt = game->time.delta;
        float sp = 10.f; 
        float ds = dt * sp;

        game->player.tform.position[0] += ds * game->input_device.move_axis[0];
        game->player.tform.position[2] += ds * game->input_device.move_axis[1];
}
Move based on delta time.

Woo! Now that we have all that, we can reach back into Raylib to render this.

void
update_render(
        struct game *game)
{
        BeginDrawing();
        ClearBackground(RAYWHITE);

        Camera3D camera = { 0 };
        camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
        camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
        camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
        camera.fovy = 45.0f;
        camera.projection = CAMERA_PERSPECTIVE;

        BeginMode3D(camera);

        Vector3 cubePosition = {
                game->player.tform.position[0],
                game->player.tform.position[1],
                game->player.tform.position[2]
        };
        DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
        DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);

        DrawGrid(10, 1.0f);

        EndMode3D();
        EndDrawing();
}

Yesh! (Said Sir Sean), it moves!

Early Access incoming.

Shoulda made a Gif then you'd see the sheer amazing level of gameplay.

Subscribe to Republic Of Almost

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe