fixed sand bias and added progressive flow
This commit is contained in:
parent
6c8dd16a97
commit
4ddb7e9efc
2 changed files with 87 additions and 27 deletions
79
src/main.zig
79
src/main.zig
|
|
@ -2,6 +2,8 @@ const std = @import("std");
|
||||||
|
|
||||||
const sand = @import("sand");
|
const sand = @import("sand");
|
||||||
|
|
||||||
|
const pow = std.math.pow;
|
||||||
|
|
||||||
const raylib = @import("raylib");
|
const raylib = @import("raylib");
|
||||||
const raygui = @import("raygui");
|
const raygui = @import("raygui");
|
||||||
|
|
||||||
|
|
@ -11,6 +13,8 @@ pub fn main(init: std.process.Init) !void {
|
||||||
|
|
||||||
var async: [screenHeight]std.Io.Future(void) = undefined;
|
var async: [screenHeight]std.Io.Future(void) = undefined;
|
||||||
|
|
||||||
|
var circleAsyncArray: ?[]std.Io.Future(void) = null;
|
||||||
|
|
||||||
var grid: sand.Grid = try .init(screenWidth, screenHeight, init.gpa);
|
var grid: sand.Grid = try .init(screenWidth, screenHeight, init.gpa);
|
||||||
defer grid.deinit(init.gpa);
|
defer grid.deinit(init.gpa);
|
||||||
// defer gridCopy.deinit(init.gpa);
|
// defer gridCopy.deinit(init.gpa);
|
||||||
|
|
@ -37,18 +41,25 @@ pub fn main(init: std.process.Init) !void {
|
||||||
raylib.initWindow(screenWidth, screenHeight, "sand");
|
raylib.initWindow(screenWidth, screenHeight, "sand");
|
||||||
defer raylib.closeWindow();
|
defer raylib.closeWindow();
|
||||||
|
|
||||||
raylib.setTargetFPS(144 * 3);
|
var IndicatorPosition: raylib.Vector2 = .init(-100, -100);
|
||||||
|
var IndicatorSize: f32 = 40;
|
||||||
|
var IndicatorSizeDelta: f32 = 0;
|
||||||
|
const scrollSpeed = -3;
|
||||||
|
|
||||||
|
var placeChace: u8 = 250;
|
||||||
|
|
||||||
|
raylib.setTargetFPS(50);
|
||||||
|
|
||||||
var timeForUpdate: u64 = 0;
|
var timeForUpdate: u64 = 0;
|
||||||
var timeForDraw: u64 = 0;
|
var timeForDraw: u64 = 0;
|
||||||
|
|
||||||
// init grid
|
// init grid
|
||||||
var random = std.Random.DefaultPrng.init(@bitCast(std.Io.Timestamp.now(init.io, .real).toMicroseconds()));
|
var random = std.Random.DefaultPrng.init(@bitCast(std.Io.Timestamp.now(init.io, .real).toMicroseconds()));
|
||||||
for (0..300) |y| {
|
// for (0..300) |y| {
|
||||||
for (y..(600 - y)) |x| {
|
// for (y..(600 - y)) |x| {
|
||||||
grid.arr[y][x] = .{ .alive = random.random().int(u8) > 179 };
|
// grid.arr[y][x] = .{ .alive = random.random().int(u8) > 179 };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
const texture: []raylib.Color = try init.gpa.alloc(raylib.Color, screenHeight * screenWidth);
|
const texture: []raylib.Color = try init.gpa.alloc(raylib.Color, screenHeight * screenWidth);
|
||||||
defer init.gpa.free(texture);
|
defer init.gpa.free(texture);
|
||||||
|
|
@ -62,14 +73,6 @@ pub fn main(init: std.process.Init) !void {
|
||||||
};
|
};
|
||||||
const screenTexture = try raylib.loadTextureFromImage(screenImage);
|
const screenTexture = try raylib.loadTextureFromImage(screenImage);
|
||||||
|
|
||||||
var fps: struct {
|
|
||||||
total: f64,
|
|
||||||
count: f64,
|
|
||||||
} = .{
|
|
||||||
.total = 0,
|
|
||||||
.count = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
while (!raylib.windowShouldClose()) {
|
while (!raylib.windowShouldClose()) {
|
||||||
const updateTimer = std.Io.Clock.now(.awake, init.io);
|
const updateTimer = std.Io.Clock.now(.awake, init.io);
|
||||||
try grid.updateAllConcurrent(init.gpa, init.io, &async);
|
try grid.updateAllConcurrent(init.gpa, init.io, &async);
|
||||||
|
|
@ -81,7 +84,10 @@ pub fn main(init: std.process.Init) !void {
|
||||||
const drawTimer = std.Io.Clock.now(.awake, init.io);
|
const drawTimer = std.Io.Clock.now(.awake, init.io);
|
||||||
for (grid.arr, 0..) |line, y| {
|
for (grid.arr, 0..) |line, y| {
|
||||||
for (line, 0..) |cell, x| {
|
for (line, 0..) |cell, x| {
|
||||||
texture[x + screenWidth * y] = if (cell.alive) .white else .black;
|
texture[x + screenWidth * y] = if (cell.alive)
|
||||||
|
.white
|
||||||
|
else
|
||||||
|
.black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
raylib.updateTexture(screenTexture, @ptrCast(texture));
|
raylib.updateTexture(screenTexture, @ptrCast(texture));
|
||||||
|
|
@ -89,11 +95,46 @@ pub fn main(init: std.process.Init) !void {
|
||||||
|
|
||||||
timeForDraw += @intCast(drawTimer.durationTo(.now(init.io, .awake)).toMicroseconds());
|
timeForDraw += @intCast(drawTimer.durationTo(.now(init.io, .awake)).toMicroseconds());
|
||||||
|
|
||||||
fps.count += 1;
|
IndicatorPosition = raylib.getMousePosition();
|
||||||
fps.total += @floatFromInt(raylib.getFPS());
|
IndicatorSizeDelta = 0;
|
||||||
std.log.info("fps: {}", .{raylib.getFPS()});
|
IndicatorSizeDelta -= raylib.getMouseWheelMove() * scrollSpeed;
|
||||||
|
IndicatorSize += IndicatorSizeDelta;
|
||||||
|
if (IndicatorSizeDelta > 0) {
|
||||||
|
if (circleAsyncArray) |*arr| {
|
||||||
|
arr.* = try init.gpa.realloc(arr.*, @trunc(IndicatorSize * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.drawCircleV(IndicatorPosition, IndicatorSize, .alpha(.gray, 0.5));
|
||||||
|
if (raylib.isMouseButtonDown(.left)) {
|
||||||
|
if (placeChace > 170) placeChace -= 1;
|
||||||
|
if (circleAsyncArray) |_| {} else circleAsyncArray = try init.gpa.alloc(std.Io.Future(void), (@as(usize, @trunc(IndicatorPosition.y)) + @as(usize, @trunc(IndicatorSize)) - (@as(usize, @trunc(IndicatorPosition.y)) - @as(usize, @trunc(IndicatorSize)))));
|
||||||
|
for (@as(usize, @trunc(IndicatorPosition.x)) - @as(usize, @trunc(IndicatorSize))..@as(usize, @trunc(IndicatorPosition.x)) + @as(usize, @trunc(IndicatorSize)), 0..) |x, i| {
|
||||||
|
circleAsyncArray.?[i] = init.io.async((struct {
|
||||||
|
pub fn l(IP: raylib.Vector2, IS: f32, fx: usize, rand: *std.Random.DefaultPrng, gr: sand.Grid, pc: u8) void {
|
||||||
|
for (@as(usize, @trunc(IP.y)) - @as(usize, @trunc(IS))..@as(usize, @trunc(IP.y)) + @as(usize, @trunc(IS))) |y| {
|
||||||
|
const dx = @as(f32, @floatFromInt(fx)) - IP.x;
|
||||||
|
const dy = @as(f32, @floatFromInt(y)) - IP.y;
|
||||||
|
if (fx >= screenWidth or fx < 0 or y >= screenHeight or y < 0) {} else if (pow(f32, dx, 2) + pow(f32, dy, 2) <= pow(f32, IS, 2) and rand.random().int(u8) > pc)
|
||||||
|
gr.arr[y][fx].alive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).l, .{ IndicatorPosition, IndicatorSize, x, &random, grid, placeChace });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (circleAsyncArray) |arr| {
|
||||||
|
for (arr) |*a| {
|
||||||
|
a.await(init.io);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (raylib.isMouseButtonReleased(.left)) {
|
||||||
|
placeChace = 250;
|
||||||
|
init.gpa.free(circleAsyncArray.?);
|
||||||
|
circleAsyncArray = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// std.log.info("fps: {}", .{raylib.getFPS()});
|
||||||
}
|
}
|
||||||
|
|
||||||
std.log.debug("time for draw: {}, time for update: {}", .{ timeForDraw, timeForUpdate });
|
std.log.debug("time for draw: {}, time for update: {}", .{ timeForDraw, timeForUpdate });
|
||||||
std.log.debug("median fps: {}", .{fps.total / fps.count});
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
35
src/root.zig
35
src/root.zig
|
|
@ -67,25 +67,44 @@ pub const Grid = struct {
|
||||||
update(.{ .y = @truncate(y), .x = @truncate(x) }, self.*, newGrid);
|
update(.{ .y = @truncate(y), .x = @truncate(x) }, self.*, newGrid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch (self.leaning) {
|
||||||
|
.Left => for (0..self.arr.len) |y| {
|
||||||
|
self.updateLineLeftBiased(newGrid, y);
|
||||||
|
},
|
||||||
|
.Right => for (0..self.arr.len) |y| {
|
||||||
|
self.updateLineRightBiased(newGrid, y);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
self.deinit(allocator);
|
self.deinit(allocator);
|
||||||
self.* = newGrid;
|
self.* = newGrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn updateLineRightBiased(s: Grid, ng: Grid, fy: usize) void {
|
||||||
|
for (0..s.arr[fy].len) |x| {
|
||||||
|
update(.{ .y = @truncate(fy), .x = @truncate(x) }, s, ng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn updateLineLeftBiased(s: Grid, ng: Grid, fy: usize) void {
|
||||||
|
for (0..s.arr[fy].len) |x| {
|
||||||
|
update(.{ .y = @truncate(fy), .x = @truncate((s.arr[fy].len - x) - 1) }, s, ng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn updateAllConcurrent(self: *Grid, allocator: std.mem.Allocator, io: std.Io, async: []std.Io.Future(void)) (std.mem.Allocator.Error || std.Io.ConcurrentError)!void {
|
pub fn updateAllConcurrent(self: *Grid, allocator: std.mem.Allocator, io: std.Io, async: []std.Io.Future(void)) (std.mem.Allocator.Error || std.Io.ConcurrentError)!void {
|
||||||
var newGrid: Grid = try .init(self.max.x + 1, self.max.y + 1, allocator);
|
var newGrid: Grid = try .init(self.max.x + 1, self.max.y + 1, allocator);
|
||||||
|
|
||||||
newGrid.leaning = self.leaning.opposite();
|
newGrid.leaning = self.leaning.opposite();
|
||||||
|
|
||||||
for (0..self.arr.len) |y| {
|
switch (self.leaning) {
|
||||||
async[y] = try io.concurrent((struct {
|
.Left => for (0..self.arr.len) |y| {
|
||||||
pub fn updateLine(s: Grid, ng: Grid, fy: usize) void {
|
async[y] = try io.concurrent(Grid.updateLineLeftBiased, .{ self.*, newGrid, y });
|
||||||
for (0..s.arr[fy].len) |x| {
|
},
|
||||||
update(.{ .y = @truncate(fy), .x = @truncate(x) }, s, ng);
|
.Right => for (0..self.arr.len) |y| {
|
||||||
}
|
async[y] = try io.concurrent(Grid.updateLineRightBiased, .{ self.*, newGrid, y });
|
||||||
}
|
},
|
||||||
}).updateLine, .{ self.*, newGrid, y });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (async) |*a| {
|
for (async) |*a| {
|
||||||
a.await(io);
|
a.await(io);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue