Enabled tile randomization.
This commit is contained in:
parent
e66908ca71
commit
7a51415e5e
@ -3,6 +3,7 @@ const assets = @import("engine/assets.zig");
|
||||
pub const Fonts = assets.Fonts;
|
||||
pub const FPS = @import("engine/fps.zig").FPS;
|
||||
pub const Keys = @import("engine/keys.zig").Keys;
|
||||
pub const Object = @import("engine/object.zig").Object;
|
||||
pub const OpaquePtr = @import("engine/opaque_ptr.zig").OpaquePtr;
|
||||
pub const Point = @import("engine/point.zig").Point;
|
||||
pub const PointF = @import("engine/point_f.zig").PointF;
|
||||
|
19
src/engine/object.zig
Normal file
19
src/engine/object.zig
Normal file
@ -0,0 +1,19 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn Object(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
ptr: *T,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !Self {
|
||||
const ptr = try allocator.create(T);
|
||||
return Self{ .allocator = allocator, .ptr = ptr };
|
||||
}
|
||||
|
||||
pub fn destroy(self: Self) void {
|
||||
self.allocator.destroy(self.ptr);
|
||||
}
|
||||
};
|
||||
}
|
@ -2,8 +2,9 @@ const std = @import("std");
|
||||
const allegro = @import("allegro");
|
||||
const engine = @import("../engine.zig");
|
||||
const Animation = @import("animation.zig").Animation;
|
||||
const Renderer = @import("../renderer.zig").Renderer;
|
||||
const Level = @import("level.zig").Level;
|
||||
const Renderer = @import("../renderer.zig").Renderer;
|
||||
const TileMap = @import("tile_map.zig").TileMap;
|
||||
|
||||
pub const Game = struct {
|
||||
pub const Direction = enum {
|
||||
@ -13,6 +14,8 @@ pub const Game = struct {
|
||||
|
||||
pub const TileSize = 32;
|
||||
|
||||
prng: std.rand.DefaultPrng = std.rand.DefaultPrng.init(0),
|
||||
|
||||
level: Level,
|
||||
health: i64 = 4,
|
||||
|
||||
@ -25,10 +28,11 @@ pub const Game = struct {
|
||||
starAnimation: Animation,
|
||||
|
||||
renderer: *Renderer,
|
||||
randomTile: TileMap(usize),
|
||||
// current viewport translated to tiles.
|
||||
boundsInTiles: engine.RectangleF,
|
||||
|
||||
pub fn init(level: Level, renderer: *Renderer) Game {
|
||||
pub fn init(allocator: std.mem.Allocator, level: Level, renderer: *Renderer) Game {
|
||||
const playerPosition = level.character.float();
|
||||
return Game{
|
||||
.level = level,
|
||||
@ -39,10 +43,16 @@ pub const Game = struct {
|
||||
.isPlayerWalking = false,
|
||||
.starAnimation = Animation.init(renderer.sprites.get("item_star_32").?, 0.15),
|
||||
.renderer = renderer,
|
||||
.randomTile = TileMap(usize).init(allocator),
|
||||
.boundsInTiles = Game.calculateBoundsInTiles(playerPosition),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Game) void {
|
||||
self.level.deinit();
|
||||
self.randomTile.deinit();
|
||||
}
|
||||
|
||||
fn calculateBoundsInTiles(position: engine.PointF) engine.RectangleF {
|
||||
return engine.RectangleF.initRelative(
|
||||
position.x - 15,
|
||||
@ -77,6 +87,15 @@ pub const Game = struct {
|
||||
self.boundsInTiles = Game.calculateBoundsInTiles(self.playerPosition);
|
||||
}
|
||||
|
||||
pub fn randomTileOffset(self: *Game, x: i64, y: i64, maxOffset: usize) usize {
|
||||
if (self.randomTile.get(x, y)) |offset| {
|
||||
return offset;
|
||||
}
|
||||
const offset = self.prng.random().intRangeLessThan(usize, 0, maxOffset);
|
||||
self.randomTile.set(x, y, offset) catch {};
|
||||
return offset;
|
||||
}
|
||||
|
||||
// return values are in view coordinates
|
||||
pub fn tile(self: Game, x: f32, y: f32) engine.PointF {
|
||||
return self.tileP(engine.PointF.init(x, y));
|
||||
|
@ -15,7 +15,7 @@ pub const Level = struct {
|
||||
tiles: TileMap(Tile),
|
||||
collectables: TileMap(Collectable),
|
||||
|
||||
pub fn load(allocator: std.mem.Allocator, path: []const u8) !Level {
|
||||
pub fn init(allocator: std.mem.Allocator, path: []const u8) !Level {
|
||||
const path_ = try std.fs.realpathAlloc(allocator, path);
|
||||
defer allocator.free(path_);
|
||||
|
||||
@ -25,10 +25,10 @@ pub const Level = struct {
|
||||
const data = try file.readToEndAlloc(allocator, 1024 * 1024);
|
||||
defer allocator.free(data);
|
||||
|
||||
return try Level.loadFromMemory(allocator, data);
|
||||
return try Level.initFromMemory(allocator, data);
|
||||
}
|
||||
|
||||
pub fn loadFromMemory(allocator: std.mem.Allocator, data: []const u8) !Level {
|
||||
pub fn initFromMemory(allocator: std.mem.Allocator, data: []const u8) !Level {
|
||||
const n = std.mem.count(u8, data, "\n");
|
||||
_ = n;
|
||||
|
||||
@ -41,9 +41,6 @@ pub const Level = struct {
|
||||
while (lines.next()) |line| {
|
||||
defer y += 1;
|
||||
|
||||
try tiles.ensureColumns(line.len);
|
||||
try collectables.ensureColumns(line.len);
|
||||
|
||||
for (line, 0..) |tile, column| {
|
||||
var x = @intCast(i64, column);
|
||||
switch (tile) {
|
||||
@ -61,4 +58,9 @@ pub const Level = struct {
|
||||
.collectables = collectables,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Level) void {
|
||||
self.tiles.deinit();
|
||||
self.collectables.deinit();
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const Object = @import("../engine/object.zig").Object;
|
||||
|
||||
pub fn TileMap(comptime Value: type) type {
|
||||
return struct {
|
||||
@ -13,7 +14,7 @@ pub fn TileMap(comptime Value: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Column) void {
|
||||
pub fn deinit(self: *Column) void {
|
||||
self.values.deinit();
|
||||
}
|
||||
|
||||
@ -27,35 +28,45 @@ pub fn TileMap(comptime Value: type) type {
|
||||
};
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
columns: std.ArrayList(Column),
|
||||
columns: std.AutoHashMap(i64, Column),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) Self {
|
||||
return Self{
|
||||
.allocator = allocator,
|
||||
.columns = std.ArrayList(Column).init(allocator),
|
||||
.columns = std.AutoHashMap(i64, Column).init(allocator),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Self) void {
|
||||
for (self.columns.items) |item| {
|
||||
item.deinit();
|
||||
pub fn deinit(self: *Self) void {
|
||||
var columns = self.columns.valueIterator();
|
||||
while (columns.next()) |c| {
|
||||
c.deinit();
|
||||
}
|
||||
self.columns.deinit();
|
||||
}
|
||||
|
||||
pub fn column(self: Self, i: i64) *Column {
|
||||
return &self.columns.items[@intCast(usize, i)];
|
||||
pub fn column(self: Self, x: i64) *Column {
|
||||
return self.columns.getPtr(x).?;
|
||||
}
|
||||
|
||||
pub fn ensureColumns(self: *Self, n: usize) !void {
|
||||
while (self.columns.items.len < n) {
|
||||
try self.columns.append(Column.init(self.allocator));
|
||||
pub fn ensureColumn(self: *Self, x: i64) !*Column {
|
||||
if (self.columns.getPtr(x)) |c| {
|
||||
return c;
|
||||
}
|
||||
try self.columns.put(x, Column.init(self.allocator));
|
||||
return self.columns.getPtr(x).?;
|
||||
}
|
||||
|
||||
pub fn set(self: *Self, c: i64, r: i64, value: Value) !void {
|
||||
try self.ensureColumns(@intCast(usize, c) + 1);
|
||||
try self.column(c).set(r, value);
|
||||
pub fn get(self: Self, x: i64, y: i64) ?Value {
|
||||
if (self.columns.get(x)) |c| {
|
||||
return c.get(y);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn set(self: *Self, x: i64, y: i64, value: Value) !void {
|
||||
const c = try self.ensureColumn(x);
|
||||
try c.set(y, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ pub const GameScene = struct {
|
||||
game: game.Game = undefined,
|
||||
|
||||
pub fn enter(self: *GameScene, ctx: *Context) void {
|
||||
const level = game.Level.load(ctx.allocator, paths.AssetsDir ++ "/levels/level1.txt") catch unreachable;
|
||||
self.game = game.Game.init(level, &ctx.renderer);
|
||||
const level = game.Level.init(ctx.allocator, paths.AssetsDir ++ "/levels/level1.txt") catch unreachable;
|
||||
self.game = game.Game.init(ctx.allocator, level, &ctx.renderer);
|
||||
}
|
||||
|
||||
pub fn exit(self: *GameScene, ctx: *Context) void {
|
||||
self.game.deinit();
|
||||
_ = ctx;
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn handle(self: *GameScene, ctx: *Context, event: *allegro.Event) !void {
|
||||
@ -68,20 +68,22 @@ pub const GameScene = struct {
|
||||
|
||||
var x = tileBounds.min.x;
|
||||
while (x < tileBounds.max.x) : (x += 1) {
|
||||
self.game.drawSpriteFrame("tiles_dirt_32", 0, x, 19);
|
||||
self.game.drawSpriteFrame("tiles_dirt_32", 3, x, 20);
|
||||
const randomDirtOffset = self.game.randomTileOffset(x, 99, 3);
|
||||
self.game.drawSpriteFrame("tiles_dirt_32", 0 + randomDirtOffset, x, 19);
|
||||
self.game.drawSpriteFrame("tiles_dirt_32", 3 + randomDirtOffset, x, 20);
|
||||
|
||||
if (x < 0) continue;
|
||||
|
||||
const tiles = self.game.level.tiles.column(x);
|
||||
const collectables = self.game.level.collectables.column(x);
|
||||
const tiles = self.game.level.tiles.ensureColumn(x) catch continue;
|
||||
const collectables = self.game.level.collectables.ensureColumn(x) catch continue;
|
||||
var y = tileBounds.min.y;
|
||||
while (y < tileBounds.max.y) : (y += 1) {
|
||||
if (tiles.get(y)) |tile| {
|
||||
switch (tile) {
|
||||
game.Level.Tile.Grass => {
|
||||
self.game.drawSpriteFrame("tiles_grass_32", 1, x, y - 1);
|
||||
self.game.drawSpriteFrame("tiles_grass_32", 5, x, y);
|
||||
const randomOffset = self.game.randomTileOffset(x, y, 2);
|
||||
self.game.drawSpriteFrame("tiles_grass_32", 1 + randomOffset, x, y - 1);
|
||||
self.game.drawSpriteFrame("tiles_grass_32", 5 + randomOffset, x, y);
|
||||
},
|
||||
// else => {},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user