Clean up
parent
a06d7fb32b
commit
2b98bf7d78
|
@ -0,0 +1,39 @@
|
||||||
|
time: usize = 0,
|
||||||
|
currentOp: usize = 0,
|
||||||
|
delayUntil: usize = 0,
|
||||||
|
anim: []const Ops,
|
||||||
|
stopped: bool = false,
|
||||||
|
|
||||||
|
pub const Ops = union(enum) { Index: usize, Wait: usize, Stop };
|
||||||
|
|
||||||
|
pub fn play(this: *@This(), anim: []const Ops) void {
|
||||||
|
if (this.anim.ptr == anim.ptr) return;
|
||||||
|
this.anim = anim;
|
||||||
|
this.stopped = false;
|
||||||
|
this.currentOp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(this: *@This(), out: *usize) void {
|
||||||
|
this.time += 1;
|
||||||
|
while (!this.stopped and this.anim.len > 0 and this.time >= this.delayUntil) {
|
||||||
|
switch (this.anim[this.currentOp]) {
|
||||||
|
.Index => |index| out.* = index,
|
||||||
|
.Wait => |wait| this.delayUntil = this.time + wait,
|
||||||
|
.Stop => this.stopped = true,
|
||||||
|
}
|
||||||
|
this.currentOp = (this.currentOp + 1) % this.anim.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn simple(rate: usize, comptime arr: []const usize) [arr.len * 2]Ops {
|
||||||
|
var anim: [arr.len * 2]Ops = undefined;
|
||||||
|
inline for (arr) |item, i| {
|
||||||
|
anim[i * 2] = Ops{ .Index = item };
|
||||||
|
anim[i * 2 + 1] = Ops{ .Wait = rate };
|
||||||
|
}
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frame(comptime index: usize) [2]Ops {
|
||||||
|
return [_]Ops{ .{ .Index = index }, .Stop };
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ const Tuple = std.meta.Tuple;
|
||||||
pub fn World(comptime ComponentBase: type) type {
|
pub fn World(comptime ComponentBase: type) type {
|
||||||
// Build a component type at comptime based off of ComponentBase. It makes all the fields
|
// Build a component type at comptime based off of ComponentBase. It makes all the fields
|
||||||
// nullable so they are easy to pull out of the store.
|
// nullable so they are easy to pull out of the store.
|
||||||
const Component = componentConstructor: {
|
const ComponentCon = componentConstructor: {
|
||||||
var fields = std.meta.fields(ComponentBase);
|
var fields = std.meta.fields(ComponentBase);
|
||||||
var newFields: [fields.len]std.builtin.TypeInfo.StructField = undefined;
|
var newFields: [fields.len]std.builtin.TypeInfo.StructField = undefined;
|
||||||
inline for (fields) |field, i| {
|
inline for (fields) |field, i| {
|
||||||
|
@ -30,6 +30,7 @@ pub fn World(comptime ComponentBase: type) type {
|
||||||
components: ComponentPool,
|
components: ComponentPool,
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
pub const Query = ComponentQuery;
|
pub const Query = ComponentQuery;
|
||||||
|
pub const Component = ComponentCon;
|
||||||
|
|
||||||
const ComponentPool = std.MultiArrayList(Component);
|
const ComponentPool = std.MultiArrayList(Component);
|
||||||
const ComponentEnum = std.meta.FieldEnum(Component);
|
const ComponentEnum = std.meta.FieldEnum(Component);
|
||||||
|
|
127
src/main.zig
127
src/main.zig
|
@ -10,47 +10,7 @@ const Map = @import("map.zig");
|
||||||
const Vec2 = util.Vec2;
|
const Vec2 = util.Vec2;
|
||||||
const Vec2f = util.Vec2f;
|
const Vec2f = util.Vec2f;
|
||||||
const AABB = util.AABB;
|
const AABB = util.AABB;
|
||||||
const Anim = struct {
|
const Anim = @import("anim.zig");
|
||||||
time: usize = 0,
|
|
||||||
currentOp: usize = 0,
|
|
||||||
delayUntil: usize = 0,
|
|
||||||
anim: []const Ops,
|
|
||||||
stopped: bool = false,
|
|
||||||
|
|
||||||
pub const Ops = union(enum) { Index: usize, Wait: usize, Stop };
|
|
||||||
|
|
||||||
pub fn play(this: *@This(), anim: []const Ops) void {
|
|
||||||
if (this.anim.ptr == anim.ptr) return;
|
|
||||||
this.anim = anim;
|
|
||||||
this.stopped = false;
|
|
||||||
this.currentOp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(this: *@This(), out: *usize) void {
|
|
||||||
this.time += 1;
|
|
||||||
while (!this.stopped and this.anim.len > 0 and this.time >= this.delayUntil) {
|
|
||||||
switch (this.anim[this.currentOp]) {
|
|
||||||
.Index => |index| out.* = index,
|
|
||||||
.Wait => |wait| this.delayUntil = this.time + wait,
|
|
||||||
.Stop => this.stopped = true,
|
|
||||||
}
|
|
||||||
this.currentOp = (this.currentOp + 1) % this.anim.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn simple(rate: usize, comptime arr: []const usize) [arr.len * 2]Ops {
|
|
||||||
var anim: [arr.len * 2]Ops = undefined;
|
|
||||||
inline for (arr) |item, i| {
|
|
||||||
anim[i * 2] = Ops{ .Index = item };
|
|
||||||
anim[i * 2 + 1] = Ops{ .Wait = rate };
|
|
||||||
}
|
|
||||||
return anim;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame(comptime index: usize) [2]Ops {
|
|
||||||
return [_]Ops{ .{ .Index = index }, .Stop };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
const Pos = struct {
|
const Pos = struct {
|
||||||
|
@ -171,13 +131,9 @@ export fn start() void {
|
||||||
.wire = w,
|
.wire = w,
|
||||||
}) catch showErr("Adding wire entity");
|
}) catch showErr("Adding wire entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (assets.sources) |source| {
|
|
||||||
circuit.fill(source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var indicator: ?struct { pos: Vec2, t: enum { wire, plug } } = null;
|
var indicator: ?struct { pos: Vec2, t: enum { wire, plug, lever } } = null;
|
||||||
var time: usize = 0;
|
var time: usize = 0;
|
||||||
|
|
||||||
export fn update() void {
|
export fn update() void {
|
||||||
|
@ -186,8 +142,8 @@ export fn update() void {
|
||||||
|
|
||||||
world.process(1, &.{.pos}, velocityProcess);
|
world.process(1, &.{.pos}, velocityProcess);
|
||||||
world.process(1, &.{ .pos, .physics }, physicsProcess);
|
world.process(1, &.{ .pos, .physics }, physicsProcess);
|
||||||
world.processWithID(1, &.{ .pos, .control }, wireManipulationProcess);
|
world.process(1, &.{ .pos, .control }, wireManipulationProcess);
|
||||||
world.processWithID(1, &.{ .pos, .control }, circuitManipulationProcess);
|
world.process(1, &.{ .pos, .control }, circuitManipulationProcess);
|
||||||
world.process(1, &.{.wire}, wirePhysicsProcess);
|
world.process(1, &.{.wire}, wirePhysicsProcess);
|
||||||
world.process(1, &.{ .pos, .control, .physics, .kinematic }, controlProcess);
|
world.process(1, &.{ .pos, .control, .physics, .kinematic }, controlProcess);
|
||||||
world.process(1, &.{ .pos, .kinematic }, kinematicProcess);
|
world.process(1, &.{ .pos, .kinematic }, kinematicProcess);
|
||||||
|
@ -202,8 +158,8 @@ export fn update() void {
|
||||||
while (wireIter.next()) |wireID| {
|
while (wireIter.next()) |wireID| {
|
||||||
const e = world.get(wireID);
|
const e = world.get(wireID);
|
||||||
const nodes = e.wire.?.nodes.constSlice();
|
const nodes = e.wire.?.nodes.constSlice();
|
||||||
const cellBegin = world2cell(nodes[0].pos);
|
const cellBegin = util.world2cell(nodes[0].pos);
|
||||||
const cellEnd = world2cell(nodes[nodes.len - 1].pos);
|
const cellEnd = util.world2cell(nodes[nodes.len - 1].pos);
|
||||||
|
|
||||||
circuit.bridge(.{ cellBegin, cellEnd });
|
circuit.bridge(.{ cellBegin, cellEnd });
|
||||||
}
|
}
|
||||||
|
@ -242,6 +198,7 @@ export fn update() void {
|
||||||
switch (details.t) {
|
switch (details.t) {
|
||||||
.wire => w4.oval(pos - half, size),
|
.wire => w4.oval(pos - half, size),
|
||||||
.plug => w4.rect(pos - half, size),
|
.plug => w4.rect(pos - half, size),
|
||||||
|
.lever => w4.rect(pos - half, size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,21 +207,7 @@ export fn update() void {
|
||||||
time += 1;
|
time += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn world2cell(vec: Vec2f) Vec2 {
|
fn circuitManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
|
||||||
return vec2ftovec2(vec / @splat(2, @as(f32, 8)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pos should be in tile coordinates, not world coordinates
|
|
||||||
fn get_conduit(vec: Vec2) ?u8 {
|
|
||||||
const x = vec[0];
|
|
||||||
const y = vec[1];
|
|
||||||
if (x < 0 or x > 19 or y < 0 or y > 19) return null;
|
|
||||||
const i = x + y * 20;
|
|
||||||
return assets.conduit[@intCast(u32, i)];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn circuitManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) void {
|
|
||||||
_ = id;
|
|
||||||
var offset = switch (control.facing) {
|
var offset = switch (control.facing) {
|
||||||
.left => Vec2f{ -6, -4 },
|
.left => Vec2f{ -6, -4 },
|
||||||
.right => Vec2f{ 6, -4 },
|
.right => Vec2f{ 6, -4 },
|
||||||
|
@ -276,7 +219,7 @@ fn circuitManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) v
|
||||||
const cell = @divTrunc(mapPos, @splat(2, @as(i32, 8)));
|
const cell = @divTrunc(mapPos, @splat(2, @as(i32, 8)));
|
||||||
if (circuit.get_cell(cell)) |tile| {
|
if (circuit.get_cell(cell)) |tile| {
|
||||||
if (Circuit.is_switch(tile)) {
|
if (Circuit.is_switch(tile)) {
|
||||||
indicator = .{ .t = .plug, .pos = cell * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 } };
|
indicator = .{ .t = .lever, .pos = cell * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 } };
|
||||||
if (input.btnp(.one, .two)) {
|
if (input.btnp(.one, .two)) {
|
||||||
circuit.toggle(cell);
|
circuit.toggle(cell);
|
||||||
}
|
}
|
||||||
|
@ -285,18 +228,20 @@ fn circuitManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wireManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) void {
|
fn wireManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
|
||||||
var offset = switch (control.facing) {
|
var offset = switch (control.facing) {
|
||||||
.left => Vec2f{ -6, -4 },
|
.left => Vec2f{ -6, -4 },
|
||||||
.right => Vec2f{ 6, -4 },
|
.right => Vec2f{ 6, -4 },
|
||||||
.up => Vec2f{ 0, -12 },
|
.up => Vec2f{ 0, -12 },
|
||||||
.down => Vec2f{ 0, 4 },
|
.down => Vec2f{ 0, 4 },
|
||||||
};
|
};
|
||||||
|
var offsetPos = pos.pos + offset;
|
||||||
|
var entity: World.Component = undefined;
|
||||||
|
var mapPos = util.world2cell(offsetPos);
|
||||||
|
|
||||||
if (control.grabbing) |details| {
|
if (control.grabbing) |details| {
|
||||||
_ = details;
|
entity = world.get(details.id);
|
||||||
_ = id;
|
var wire = &entity.wire.?;
|
||||||
var e = world.get(details.id);
|
|
||||||
var wire = &e.wire.?;
|
|
||||||
var nodes = wire.nodes.slice();
|
var nodes = wire.nodes.slice();
|
||||||
|
|
||||||
var maxLength = wireMaxLength(wire);
|
var maxLength = wireMaxLength(wire);
|
||||||
|
@ -305,26 +250,25 @@ fn wireManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) void
|
||||||
if (length > maxLength * 1.5) {
|
if (length > maxLength * 1.5) {
|
||||||
nodes[details.which].pinned = false;
|
nodes[details.which].pinned = false;
|
||||||
control.grabbing = null;
|
control.grabbing = null;
|
||||||
world.set(details.id, e);
|
world.set(details.id, entity);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
nodes[details.which].pos = pos.pos + Vec2f{ 0, -4 };
|
nodes[details.which].pos = pos.pos + Vec2f{ 0, -4 };
|
||||||
}
|
}
|
||||||
|
|
||||||
var mapPos = vec2ftovec2((pos.pos + offset) / @splat(2, @as(f32, 8)));
|
|
||||||
if (Circuit.is_plug(circuit.get_cell(mapPos) orelse 0)) {
|
if (Circuit.is_plug(circuit.get_cell(mapPos) orelse 0)) {
|
||||||
indicator = .{ .t = .plug, .pos = mapPos * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 } };
|
indicator = .{ .t = .plug, .pos = mapPos * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 } };
|
||||||
if (input.btnp(.one, .two)) {
|
if (input.btnp(.one, .two)) {
|
||||||
e.wire.?.nodes.slice()[details.which].pinned = true;
|
nodes[details.which].pinned = true;
|
||||||
e.wire.?.nodes.slice()[details.which].pos = vec2tovec2f(indicator.?.pos);
|
nodes[details.which].pos = vec2tovec2f(indicator.?.pos);
|
||||||
e.wire.?.nodes.slice()[details.which].last = vec2tovec2f(indicator.?.pos);
|
nodes[details.which].last = vec2tovec2f(indicator.?.pos);
|
||||||
control.grabbing = null;
|
control.grabbing = null;
|
||||||
}
|
}
|
||||||
} else if (input.btnp(.one, .two)) {
|
} else if (input.btnp(.one, .two)) {
|
||||||
e.wire.?.nodes.slice()[details.which].pinned = false;
|
nodes[details.which].pinned = false;
|
||||||
control.grabbing = null;
|
control.grabbing = null;
|
||||||
}
|
}
|
||||||
world.set(details.id, e);
|
world.set(details.id, entity);
|
||||||
} else {
|
} else {
|
||||||
const interactDistance = 4;
|
const interactDistance = 4;
|
||||||
var minDistance: f32 = interactDistance;
|
var minDistance: f32 = interactDistance;
|
||||||
|
@ -333,19 +277,19 @@ fn wireManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) void
|
||||||
var interactWireID: ?usize = null;
|
var interactWireID: ?usize = null;
|
||||||
var which: usize = 0;
|
var which: usize = 0;
|
||||||
while (wireIter.next()) |entityID| {
|
while (wireIter.next()) |entityID| {
|
||||||
const entity = world.get(entityID);
|
entity = world.get(entityID);
|
||||||
const wire = entity.wire.?;
|
const wire = entity.wire.?;
|
||||||
const nodes = wire.nodes.constSlice();
|
const nodes = wire.nodes.constSlice();
|
||||||
const begin = nodes[0].pos;
|
const begin = nodes[0].pos;
|
||||||
const end = nodes[wire.nodes.len - 1].pos;
|
const end = nodes[wire.nodes.len - 1].pos;
|
||||||
var dist = util.distancef(begin, pos.pos + offset);
|
var dist = util.distancef(begin, offsetPos);
|
||||||
if (dist < minDistance) {
|
if (dist < minDistance) {
|
||||||
minDistance = dist;
|
minDistance = dist;
|
||||||
indicator = .{ .t = .wire, .pos = vec2ftovec2(begin) };
|
indicator = .{ .t = .wire, .pos = vec2ftovec2(begin) };
|
||||||
interactWireID = entityID;
|
interactWireID = entityID;
|
||||||
which = 0;
|
which = 0;
|
||||||
}
|
}
|
||||||
dist = util.distancef(end, pos.pos + offset);
|
dist = util.distancef(end, offsetPos);
|
||||||
if (dist < minDistance) {
|
if (dist < minDistance) {
|
||||||
minDistance = dist;
|
minDistance = dist;
|
||||||
indicator = .{ .t = .wire, .pos = vec2ftovec2(end) };
|
indicator = .{ .t = .wire, .pos = vec2ftovec2(end) };
|
||||||
|
@ -354,11 +298,9 @@ fn wireManipulationProcess(_: f32, id: usize, pos: *Pos, control: *Control) void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (interactWireID) |wireID| {
|
if (interactWireID) |wireID| {
|
||||||
_ = wireID;
|
entity = world.get(wireID);
|
||||||
var entity = world.get(wireID);
|
|
||||||
if (input.btnp(.one, .two)) {
|
if (input.btnp(.one, .two)) {
|
||||||
control.grabbing = .{ .id = wireID, .which = which };
|
control.grabbing = .{ .id = wireID, .which = which };
|
||||||
// entity.wire.?.nodes.slice()[which].pinned = true;
|
|
||||||
}
|
}
|
||||||
world.set(wireID, entity);
|
world.set(wireID, entity);
|
||||||
}
|
}
|
||||||
|
@ -422,15 +364,6 @@ fn wireLength(wire: *Wire) f32 {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tension(prevNode: *Pos, node: *Pos) f32 {
|
|
||||||
var dist = util.distancef(node.pos, prevNode.pos);
|
|
||||||
var difference: f32 = 0;
|
|
||||||
if (dist > 0) {
|
|
||||||
difference = (@minimum(dist, wireSegmentMaxLength) - dist) / dist;
|
|
||||||
}
|
|
||||||
return difference;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn constrainNodes(prevNode: *Pos, node: *Pos) void {
|
fn constrainNodes(prevNode: *Pos, node: *Pos) void {
|
||||||
var diff = prevNode.pos - node.pos;
|
var diff = prevNode.pos - node.pos;
|
||||||
var dist = util.distancef(node.pos, prevNode.pos);
|
var dist = util.distancef(node.pos, prevNode.pos);
|
||||||
|
@ -520,14 +453,6 @@ fn controlProcess(_: f32, pos: *Pos, control: *Control, physics: *Physics, kinem
|
||||||
pos.pos += move;
|
pos.pos += move;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getTile(cell: Vec2) ?u8 {
|
|
||||||
const x = cell[0];
|
|
||||||
const y = cell[1];
|
|
||||||
if (x < 0 or x > 19 or y < 0 or y > 19) return null;
|
|
||||||
const i = x + y * 20;
|
|
||||||
return assets.solid[@intCast(u32, i)];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn kinematicProcess(_: f32, pos: *Pos, kinematic: *Kinematic) void {
|
fn kinematicProcess(_: f32, pos: *Pos, kinematic: *Kinematic) void {
|
||||||
var next = pos.last;
|
var next = pos.last;
|
||||||
next[0] = pos.pos[0];
|
next[0] = pos.pos[0];
|
||||||
|
|
Loading…
Reference in New Issue