Add board to state with hovering
This commit is contained in:
+195
-47
@@ -13,6 +13,27 @@ const V2 = struct {
|
|||||||
const max = V2{ .x = std.math.floatMax(f32), .y = std.math.floatMax(f32) };
|
const max = V2{ .x = std.math.floatMax(f32), .y = std.math.floatMax(f32) };
|
||||||
const zero = V2{ .x = 0.0, .y = 0.0 };
|
const zero = V2{ .x = 0.0, .y = 0.0 };
|
||||||
|
|
||||||
|
fn init(x: f32, y: f32) V2 {
|
||||||
|
return .{
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_int(x: i32, y: i32) V2 {
|
||||||
|
return .{
|
||||||
|
.x = @floatFromInt(x),
|
||||||
|
.y = @floatFromInt(y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_usize(x: usize, y: usize) V2 {
|
||||||
|
return .{
|
||||||
|
.x = @floatFromInt(x),
|
||||||
|
.y = @floatFromInt(y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn add(self: V2, other: V2) V2 {
|
fn add(self: V2, other: V2) V2 {
|
||||||
return .{
|
return .{
|
||||||
.x = self.x + other.x,
|
.x = self.x + other.x,
|
||||||
@@ -26,6 +47,27 @@ const V2 = struct {
|
|||||||
.y = self.y - other.y,
|
.y = self.y - other.y,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mul(self: V2, s: f32) V2 {
|
||||||
|
return .{
|
||||||
|
.x = self.x * s,
|
||||||
|
.y = self.y * s,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(self: V2, other: V2) f32 {
|
||||||
|
const result = self.x * other.x + self.y * other.y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hadamard(self: V2, other: V2) V2 {
|
||||||
|
var result = V2.zero;
|
||||||
|
|
||||||
|
result.x = self.x * other.x;
|
||||||
|
result.y = self.y * other.y;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const BBox = struct {
|
const BBox = struct {
|
||||||
@@ -39,6 +81,31 @@ const Camera = struct {
|
|||||||
offset: V2,
|
offset: V2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const BoardTile = struct {
|
||||||
|
blocked: bool,
|
||||||
|
taken: bool,
|
||||||
|
hovering: bool,
|
||||||
|
label: []const u8,
|
||||||
|
|
||||||
|
fn init(label: []const u8, blocked: bool) BoardTile {
|
||||||
|
const result: BoardTile = .{
|
||||||
|
.blocked = blocked,
|
||||||
|
.taken = false,
|
||||||
|
.hovering = false,
|
||||||
|
.label = label,
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Board = struct {
|
||||||
|
pos: V2,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
tiles: [7][7]BoardTile,
|
||||||
|
};
|
||||||
|
|
||||||
const Brick = struct {
|
const Brick = struct {
|
||||||
rotating: bool,
|
rotating: bool,
|
||||||
pos: V2,
|
pos: V2,
|
||||||
@@ -87,8 +154,10 @@ const State = struct {
|
|||||||
frame_count: i32,
|
frame_count: i32,
|
||||||
mouse_pos: V2,
|
mouse_pos: V2,
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
|
draw_bounding_rects: bool,
|
||||||
grabbed_brick_index: ?usize,
|
grabbed_brick_index: ?usize,
|
||||||
bricks: [8]Brick,
|
bricks: [8]Brick,
|
||||||
|
board: Board,
|
||||||
};
|
};
|
||||||
|
|
||||||
const tile_size = V2{
|
const tile_size = V2{
|
||||||
@@ -96,6 +165,13 @@ const tile_size = V2{
|
|||||||
.y = TILE_SIZE,
|
.y = TILE_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn getTilePos(i: usize, j: usize) V2 {
|
||||||
|
return V2{
|
||||||
|
.x = @floatFromInt(j * TILE_SIZE),
|
||||||
|
.y = @floatFromInt(i * TILE_SIZE),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn pointInsideRect(p: V2, rect_start: V2, rect_size: V2) bool {
|
fn pointInsideRect(p: V2, rect_start: V2, rect_size: V2) bool {
|
||||||
var result: bool = false;
|
var result: bool = false;
|
||||||
|
|
||||||
@@ -109,16 +185,31 @@ fn pointInsideRect(p: V2, rect_start: V2, rect_size: V2) bool {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tilesIntersects(r1: V2, r2: V2) bool {
|
||||||
|
var result = false;
|
||||||
|
|
||||||
|
const r2a: V2 = V2.init(r2.x, r2.y);
|
||||||
|
const r2b: V2 = V2.init(r2.x, r2.y + tile_size.y);
|
||||||
|
const r2c: V2 = V2.init(r2.x + tile_size.x, r2.y);
|
||||||
|
const r2d: V2 = V2.init(r2.x + tile_size.x, r2.y + tile_size.y);
|
||||||
|
|
||||||
|
const a = pointInsideRect(r2a, r1, tile_size);
|
||||||
|
const b = pointInsideRect(r2b, r1, tile_size);
|
||||||
|
const c = pointInsideRect(r2c, r1, tile_size);
|
||||||
|
const d = pointInsideRect(r2d, r1, tile_size);
|
||||||
|
|
||||||
|
result = a or b or c or d;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
fn findBrickBoundingBox(brick: *const Brick) BBox {
|
fn findBrickBoundingBox(brick: *const Brick) BBox {
|
||||||
var result = BBox{ .min = V2.max, .max = V2.zero, .center = V2.zero };
|
var result = BBox{ .min = V2.max, .max = V2.zero, .center = V2.zero };
|
||||||
|
|
||||||
for (brick.tiles, 0..) |row, i| {
|
for (brick.tiles, 0..) |row, i| {
|
||||||
for (row, 0..) |tile, j| {
|
for (row, 0..) |tile, j| {
|
||||||
if (tile > 0) {
|
if (tile > 0) {
|
||||||
const tile_start = V2{
|
const tile_start = getTilePos(i, j);
|
||||||
.x = @floatFromInt(j * TILE_SIZE),
|
|
||||||
.y = @floatFromInt(i * TILE_SIZE),
|
|
||||||
};
|
|
||||||
const tile_end = tile_start.add(tile_size);
|
const tile_end = tile_start.add(tile_size);
|
||||||
|
|
||||||
const start = brick.pos.add(tile_start);
|
const start = brick.pos.add(tile_start);
|
||||||
@@ -345,6 +436,35 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const tile_names = [7][7]?[]const u8{
|
||||||
|
.{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", null },
|
||||||
|
.{ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", null },
|
||||||
|
.{ "1", "2", "3", "4", "5", "6", "7" },
|
||||||
|
.{ "8", "9", "10", "11", "12", "13", "14" },
|
||||||
|
.{ "15", "16", "17", "18", "19", "20", "21" },
|
||||||
|
.{ "22", "23", "24", "25", "26", "27", "28" },
|
||||||
|
.{ "29", "30", "31", null, null, null, null },
|
||||||
|
};
|
||||||
|
|
||||||
|
var tiles: [7][7]BoardTile = undefined;
|
||||||
|
|
||||||
|
for (tile_names, 0..) |row, i| {
|
||||||
|
for (row, 0..) |opt, j| {
|
||||||
|
if (opt) |tile| {
|
||||||
|
tiles[i][j] = BoardTile.init(tile, false);
|
||||||
|
} else {
|
||||||
|
tiles[i][j] = BoardTile.init("", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state.board = .{
|
||||||
|
.pos = mid,
|
||||||
|
.width = 7,
|
||||||
|
.height = 7,
|
||||||
|
.tiles = tiles,
|
||||||
|
};
|
||||||
|
|
||||||
memory.initialized = true;
|
memory.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,10 +473,20 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
|||||||
|
|
||||||
const mouse_world_pos = mouse_pos.sub(state.camera.pos);
|
const mouse_world_pos = mouse_pos.sub(state.camera.pos);
|
||||||
|
|
||||||
|
if (keyPressed(&input.key.f1)) {
|
||||||
|
state.draw_bounding_rects = !state.draw_bounding_rects;
|
||||||
|
}
|
||||||
|
|
||||||
if (!input.mouse_left_down) {
|
if (!input.mouse_left_down) {
|
||||||
state.grabbed_brick_index = null;
|
state.grabbed_brick_index = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (&state.board.tiles) |*board_row| {
|
||||||
|
for (board_row) |*board_tile| {
|
||||||
|
board_tile.hovering = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (&state.bricks, 0..) |*brick, brick_index| {
|
for (&state.bricks, 0..) |*brick, brick_index| {
|
||||||
if (brick.rotating) {
|
if (brick.rotating) {
|
||||||
brick.rotating_time += input.delta_time;
|
brick.rotating_time += input.delta_time;
|
||||||
@@ -369,20 +499,25 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
|||||||
for (brick.tiles, 0..) |row, i| {
|
for (brick.tiles, 0..) |row, i| {
|
||||||
for (row, 0..) |tile, j| {
|
for (row, 0..) |tile, j| {
|
||||||
if (tile > 0) {
|
if (tile > 0) {
|
||||||
const tile_pos = V2{
|
const pos = getTilePos(i, j).add(brick.pos);
|
||||||
.x = @floatFromInt(j * TILE_SIZE),
|
|
||||||
.y = @floatFromInt(i * TILE_SIZE),
|
|
||||||
};
|
|
||||||
const pos = tile_pos.add(brick.pos);
|
|
||||||
|
|
||||||
const camera_pos = pos.add(state.camera.pos);
|
|
||||||
if (input.mouse_left_down) {
|
if (input.mouse_left_down) {
|
||||||
if (pointInsideRect(state.mouse_pos, camera_pos, tile_size)) {
|
if (pointInsideRect(mouse_world_pos, pos, tile_size)) {
|
||||||
if (state.grabbed_brick_index == null) {
|
if (state.grabbed_brick_index == null) {
|
||||||
state.grabbed_brick_index = brick_index;
|
state.grabbed_brick_index = brick_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (&state.board.tiles, 0..) |*board_row, k| {
|
||||||
|
for (board_row, 0..) |*board_tile, l| {
|
||||||
|
const board_tile_pos = getTilePos(k, l).add(state.board.pos);
|
||||||
|
|
||||||
|
if (!board_tile.hovering) {
|
||||||
|
board_tile.hovering = tilesIntersects(board_tile_pos, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,22 +559,36 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
|||||||
// Render
|
// Render
|
||||||
fillRect(buffer, 0, 0, buffer.width, buffer.height, 0xFFFFFFFF);
|
fillRect(buffer, 0, 0, buffer.width, buffer.height, 0xFFFFFFFF);
|
||||||
|
|
||||||
const board_pos = mid;
|
{
|
||||||
for (0..7) |i| {
|
const board = state.board;
|
||||||
for (0..7) |j| {
|
// const board_size = V2.init_int(
|
||||||
if (i == 0 and j == 6) continue;
|
// @intCast(board.width * TILE_SIZE),
|
||||||
if (i == 1 and j == 6) continue;
|
// @intCast(board.height * TILE_SIZE),
|
||||||
if (i == 6 and j == 3) continue;
|
// );
|
||||||
if (i == 6 and j == 4) continue;
|
// const half = board_size.mul(0.5);
|
||||||
if (i == 6 and j == 5) continue;
|
|
||||||
if (i == 6 and j == 6) continue;
|
|
||||||
|
|
||||||
const tile_pos = V2{
|
const board_camera_pos = board.pos.add(state.camera.pos);
|
||||||
.x = @floatFromInt(j * TILE_SIZE),
|
|
||||||
.y = @floatFromInt(i * TILE_SIZE),
|
for (board.tiles, 0..) |row, i| {
|
||||||
};
|
for (row, 0..) |tile, j| {
|
||||||
const camera_pos = board_pos.add(tile_pos).add(state.camera.pos);
|
const tile_pos = V2{
|
||||||
fillSquare(buffer, @intFromFloat(camera_pos.x), @intFromFloat(camera_pos.y), 30, 0xFF000000);
|
.x = @floatFromInt(j * TILE_SIZE),
|
||||||
|
.y = @floatFromInt(i * TILE_SIZE),
|
||||||
|
};
|
||||||
|
const camera_pos = board_camera_pos.add(tile_pos);
|
||||||
|
const pos_x: i32 = @intFromFloat(camera_pos.x);
|
||||||
|
const pos_y: i32 = @intFromFloat(camera_pos.y);
|
||||||
|
|
||||||
|
var color: u32 = 0xFF000000;
|
||||||
|
if (tile.blocked) {
|
||||||
|
color = 0xFFFFFFFF;
|
||||||
|
} else if (tile.hovering) {
|
||||||
|
color = 0xFF00FF00;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillSquare(buffer, pos_x, pos_y, TILE_SIZE, color);
|
||||||
|
drawRect(buffer, camera_pos, tile_size, 0xFFFFFFFF, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,11 +598,8 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
|||||||
for (brick.tiles, 0..) |row, i| {
|
for (brick.tiles, 0..) |row, i| {
|
||||||
for (row, 0..) |tile, j| {
|
for (row, 0..) |tile, j| {
|
||||||
if (tile > 0) {
|
if (tile > 0) {
|
||||||
const pos = V2{
|
const pos = getTilePos(i, j).add(brick.pos);
|
||||||
.x = @floatFromInt(j * TILE_SIZE),
|
const camera_pos = pos.add(state.camera.pos);
|
||||||
.y = @floatFromInt(i * TILE_SIZE),
|
|
||||||
};
|
|
||||||
const camera_pos = brick.pos.add(pos).add(state.camera.pos);
|
|
||||||
fillSquare(
|
fillSquare(
|
||||||
buffer,
|
buffer,
|
||||||
@intFromFloat(camera_pos.x),
|
@intFromFloat(camera_pos.x),
|
||||||
@@ -466,25 +612,27 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (comptime builtin.mode == std.builtin.OptimizeMode.Debug) {
|
if (comptime builtin.mode == std.builtin.OptimizeMode.Debug) {
|
||||||
{
|
if (state.draw_bounding_rects) {
|
||||||
const camera_pos = brick.pos.add(state.camera.pos);
|
{
|
||||||
drawRect(buffer, camera_pos, .{ .x = 4 * TILE_SIZE, .y = 4 * TILE_SIZE }, 0xFFFF0000, 1);
|
const camera_pos = brick.pos.add(state.camera.pos);
|
||||||
}
|
drawRect(buffer, camera_pos, .{ .x = 4 * TILE_SIZE, .y = 4 * TILE_SIZE }, 0xFFFF0000, 1);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const bbox_size = bounding_box.max.sub(bounding_box.min);
|
const bbox_size = bounding_box.max.sub(bounding_box.min);
|
||||||
const camera_pos = bounding_box.min.add(state.camera.pos);
|
const camera_pos = bounding_box.min.add(state.camera.pos);
|
||||||
|
|
||||||
drawRect(buffer, camera_pos, bbox_size, 0xFFFF0000, 1);
|
drawRect(buffer, camera_pos, bbox_size, 0xFFFF0000, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const size = 8;
|
const size = 8;
|
||||||
const half = @divTrunc(size, 2);
|
const half = @divTrunc(size, 2);
|
||||||
const camera_pos = bounding_box.center.add(state.camera.pos);
|
const camera_pos = bounding_box.center.add(state.camera.pos);
|
||||||
const x: i32 = @intFromFloat(camera_pos.x);
|
const x: i32 = @intFromFloat(camera_pos.x);
|
||||||
const y: i32 = @intFromFloat(camera_pos.y);
|
const y: i32 = @intFromFloat(camera_pos.y);
|
||||||
fillSquare(buffer, x - half, y - half, 8, 0xFFFF0000);
|
fillSquare(buffer, x - half, y - half, 8, 0xFFFF0000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user