Following my passion #2: position vector and learning more Zig
Source: Dev.to
Introduction
I spent a work night coding a small project. After a busy day debugging Kafka, I returned to a Raylib bootstrap that was only drawing a square. The goal for today was to make the square move, which I managed to accomplish.
I’m not new to game development—I previously attempted a C++ game in 2024—but I’m fairly new to Zig, so this was an interesting challenge.
Player struct
const Player = struct {
x: usize,
y: usize,
width: usize,
height: usize,
};
This struct defines the position and size of the square on the screen.
Constructor
In Zig, constructors are regular functions placed inside the struct’s namespace. By convention we use an init function:
pub fn init() Player {
return Player{
// initializations go here
};
}
You can also alias the struct type with const Self = @This();, but I chose not to use that here.
Draw function
pub fn draw(self: Player) void {
const origin = rl.Vector2{
.x = 0,
.y = 0,
};
const rec = rl.Rectangle{
.x = self.x,
.y = self.y,
.height = self.height,
.width = self.width,
};
rl.drawRectanglePro(rec, origin, @as(f32, @floatFromInt(0)), .white);
}
rl is an alias for the Raylib library. The function builds a Rectangle from the player’s fields and draws it.
Update function
Initially the update method was defined as:
pub fn update(self: Player) void {
self.x += 1;
}
This didn’t work because self was immutable. The fix is to pass a pointer so the struct can be mutated:
pub fn update(self: *Player) void {
self.x += 1;
}
Centering the square
To start the square roughly in the middle of the screen I tried:
return Player{
.x = rl.getScreenHeight() / 2,
.y = rl.getScreenWidth() / 2,
.height = 10,
.width = 10,
};
Since rl.getScreenHeight() and rl.getScreenWidth() return i32 while Raylib drawing functions expect f32, I converted the values:
return Player{
.x = @as(f32, @floatFromInt(rl.getScreenHeight())) / 2,
.y = @as(f32, @floatFromInt(rl.getScreenWidth())) / 2,
.height = 10,
.width = 10,
};
The conversion satisfies the compiler, though the precision isn’t perfect yet.
Main loop and input handling
if (rl.isKeyDown(.d)) {
player.update();
player.draw();
}
rl.beginDrawing();
defer rl.endDrawing();
rl.clearBackground(.dark_gray);
player.draw();
Pressing the D key moves the square to the right.
Conclusion
Today I learned more about Zig than about game development. Tomorrow I plan to draw additional squares and explore collision detection so my square can interact with them.