Setup
- Raylib Version: 5.5
- Zig Version: 0.15.2
Overview:
I am new to game development overall so, excuse my ignorance, but I am trying to make a game using Raylib Library using ZIG lang, but when I was trying to pass a loaded texture in an array item through a function using the pointer parameter to the Entity object, the texture is not loaded correctly, I was able to make this work only to pass the loaded texture to the Entity instead of pass just a pointer.
NOTE: I want to use the array to store textures, then use them everywhere to save memory.
Code
This is the whole Code which not working properly.
const std = @import("std");
const rl = @cImport({
@cInclude("raylib.h");
});
const Entity = struct {
position: rl.Vector2,
texture: ?*rl.Texture2D,
fn Init(pos: rl.Vector2, texture: ?*rl.Texture2D) Entity {
return .{
.position = pos,
.texture = texture,
};
}
fn Draw(self: *Entity) void {
if (self.texture) |texture| {
rl.DrawTexture(
texture.*,
@intFromFloat(self.position.x),
@intFromFloat(self.position.y),
rl.WHITE,
);
} else {
rl.DrawRectangle(
@intFromFloat(self.position.x),
@intFromFloat(self.position.y),
100,
100,
rl.ORANGE,
);
}
}
};
const Map = struct {
tileset: [3]rl.Texture2D,
entities: [5]?Entity,
fn Init() Map {
var map: Map = undefined;
map.tileset[0] = rl.LoadTexture("./res/imgs/red.png");
map.tileset[1] = rl.LoadTexture("./res/imgs/ground.png");
map.tileset[2] = rl.LoadTexture("./res/imgs/blue.png");
const layer: [5]u8 = .{ 1, 2, 0, 3, 1 };
for (layer, 0..) |item, index| {
if (item != 0) {
map.entities[index] = Entity.Init(
.{ .x = 30 + 100 * @as(f32, @floatFromInt(index)), .y = 3 },
&map.tileset[item - 1],
);
} else {
map.entities[index] = null;
}
}
return map;
}
fn DeInit(self: *Map) void {
rl.UnloadTexture(self.tileset[0]);
rl.UnloadTexture(self.tileset[1]);
rl.UnloadTexture(self.tileset[2]);
}
fn Draw(self: *Map) void {
for (&self.entities) |*entity_nl| {
if (entity_nl.*) |*entity| {
entity.Draw();
}
}
}
};
pub fn main() !void {
rl.InitWindow(1920, 1080, "Texture Pointer");
defer rl.CloseWindow();
rl.SetTargetFPS(60);
var map = Map.Init();
defer map.DeInit();
while (!rl.WindowShouldClose()) {
rl.BeginDrawing();
defer rl.EndDrawing();
rl.ClearBackground(rl.BEIGE);
map.Draw();
}
}
Result:
Working Code:
See the Change comments:
const std = @import("std");
const rl = @cImport({
@cInclude("raylib.h");
});
// Entity Object
const Entity = struct {
position: rl.Vector2,
// Change #1: Here I am Removing The Pointer
texture: ?rl.Texture2D,
// Change #2: Here I am Removing The Pointer also from texture
fn Init(pos: rl.Vector2, texture: ?rl.Texture2D) Entity {
return .{
.position = pos,
.texture = texture,
};
}
fn Draw(self: *Entity) void {
if (self.texture) |texture| {
// Change #3: Here I am Removing The dereferencing from texture
rl.DrawTexture(
texture,
@intFromFloat(self.position.x),
@intFromFloat(self.position.y),
rl.WHITE,
);
} else {
rl.DrawRectangle(
@intFromFloat(self.position.x),
@intFromFloat(self.position.y),
100,
100,
rl.ORANGE,
);
}
}
};
const Map = struct {
tileset: [3]rl.Texture2D,
entities: [5]?Entity,
fn Init() Map {
var map: Map = undefined;
map.tileset[0] = rl.LoadTexture("./res/imgs/red.png");
map.tileset[1] = rl.LoadTexture("./res/imgs/ground.png");
map.tileset[2] = rl.LoadTexture("./res/imgs/blue.png");
const layer: [5]u8 = .{ 1, 2, 0, 3, 1 };
for (layer, 0..) |item, index| {
if (item != 0) {
map.entities[index] = Entity.Init(
.{ .x = 30 + 100 * @as(f32, @floatFromInt(index)), .y = 3 },
// Change #4: Here I am removing the &
map.tileset[item - 1],
);
} else {
map.entities[index] = null;
}
}
return map;
}
fn DeInit(self: *Map) void {
rl.UnloadTexture(self.tileset[0]);
rl.UnloadTexture(self.tileset[1]);
rl.UnloadTexture(self.tileset[2]);
}
fn Draw(self: *Map) void {
for (&self.entities) |*entity_nl| {
if (entity_nl.*) |*entity| {
entity.Draw();
}
}
}
};
pub fn main() !void {
rl.InitWindow(1920, 1080, "Texture Pointer");
defer rl.CloseWindow();
rl.SetTargetFPS(60);
var map = Map.Init();
defer map.DeInit();
while (!rl.WindowShouldClose()) {
rl.BeginDrawing();
defer rl.EndDrawing();
rl.ClearBackground(rl.BEIGE);
map.Draw();
}
}
I hope my explanation is to the point.

