PVG
4. Basic Left Right Movement — Program Video Games

4. Basic Left Right Movement

[[programvideogames]]To move sideways, we won't update the player.pos directly each frame.

Instead, we'll add a veloctiy field to the player and use that for calcluations.

This will make things easier when we add other mechanics like jumping.

Player :: struct {
    // Allows us to use .x, .y, .width and .height directly
    // e.g. player.x += 10, same as player.collider.rect += 10
    using collider: Rect,
    vel:            Vec2,
    move_speed:     f32,
}

Down where we initialised our Player, we want to add the new move speed field.

player: Player = {
    x          = 100,
    y          = 100,
    width      = 16,
    height     = 38,
    move_speed = 280,
}

This movement code should go at the start of the game loop.

We'll be reorganising code as we go.

    for !rl.WindowShouldClose() {
    // starting here ...
        dt := rl.GetFrameTime()

        input_x: f32
        if rl.IsKeyDown(.D) do input_x += 1
        if rl.IsKeyDown(.A) do input_x -= 1

        player.vel.x = input_x * player.move_speed

        player.x += player.vel.x * dt

    // ...

That's it! Short and sweet.

In the next one we'll look at gravity and terminal velocity.

package main

import "core:os"
import rl "vendor:raylib"

Vec2 :: rl.Vector2
Rect :: rl.Rectangle

Player :: struct {
    // Allows us to use .x, .y, .width and .height directly
    // e.g. player.x += 10, same as player.collider.rect += 10
    using collider: Rect,
    vel:            Vec2,
    move_speed:     f32,
}

WINDOW_WIDTH :: 1280
WINDOW_HEIGHT :: 720
TILE_SIZE :: 16
ZOOM :: 2
BG_COLOR :: rl.BLACK

main :: proc() {
    rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Program Video Games!")

    camera := rl.Camera2D {
        zoom = ZOOM,
    }

    // Allocated using the context's allocator
    // unless otherwise specified
    solid_tiles: [dynamic]rl.Rectangle
    {
        level_data, ok := os.read_entire_file("data/simple_level.dat")
        assert(ok, "Failed to load level data")

        x, y: f32
        for v in level_data {
            if v == '
' {
                y += TILE_SIZE
                x = 0
                continue
            }
            if v == '#' {
                append(&solid_tiles, rl.Rectangle{x, y, TILE_SIZE, TILE_SIZE})
            }
            x += TILE_SIZE
        }
    }

    player: Player = {
        x          = 100,
        y          = 100,
        width      = 16,
        height     = 38,
        move_speed = 280,
    }

    for !rl.WindowShouldClose() {
        dt := rl.GetFrameTime()

        input_x: f32
        if rl.IsKeyDown(.D) do input_x += 1
        if rl.IsKeyDown(.A) do input_x -= 1

        player.vel.x = input_x * player.move_speed

        player.x += player.vel.x * dt

        rl.BeginDrawing()
        rl.BeginMode2D(camera)
        rl.ClearBackground(BG_COLOR)

        for rect in solid_tiles {
            rl.DrawRectangleRec(rect, rl.WHITE)
            rl.DrawRectangleLinesEx(rect, 1, rl.GRAY)
        }

        rl.DrawRectangleLinesEx(player.collider, 1, rl.GREEN)

        rl.EndMode2D()
        rl.EndDrawing()
    }
}