diff --git a/src/main-scene.zig b/src/main-scene.zig index a619988..fecbc88 100644 --- a/src/main-scene.zig +++ b/src/main-scene.zig @@ -16,7 +16,7 @@ const Player = struct { position: rl.Vector2, velocity: rl.Vector2 = rl.Vector2.zero(), acceleration: rl.Vector2 = rl.Vector2.zero(), - handDirection: rl.Vector2 = rl.Vector2{ .x = 1, .y = 0 } + handDirection: rl.Vector2 = rl.Vector2{ .x = 1, .y = 0 }, }; const Rope = struct { @@ -100,7 +100,9 @@ const Rope = struct { const offset = offsets.get(i); vel.* = vel.add(acc.scale(dt)); vel.* = vel.scale(1 - self.friction); - pos.* = pos.add(vel.scale(dt*10000)); + + const amplifier = @as(f32, @floatFromInt(i-1))/@as(f32, @floatFromInt(node_count-2)); + pos.* = pos.add(vel.scale(dt*10000 + amplifier*5)); pos.* = pos.add(offset.scale(0.01)); } } @@ -116,10 +118,12 @@ enemies: std.ArrayList(Enemy), player: Player, rope: Rope, +camera: rl.Camera2D, + const Self = @This(); pub fn init(allocator: Allocator) Self { - var playerPosition = rl.Vector2{ .x = 400, .y = 400 }; + var playerPosition = rl.Vector2{ .x = 0, .y = 0 }; var ropeSize: f32 = 200; var handPosition = playerPosition.add(rl.Vector2{ .x = handDistance, .y = 0}); @@ -128,7 +132,8 @@ pub fn init(allocator: Allocator) Self { .prng = std.rand.DefaultPrng.init(@bitCast(std.time.timestamp())), .enemies = std.ArrayList(Enemy).init(allocator), .player = .{ .position = playerPosition }, - .rope = Rope.init(handPosition, handPosition.add(.{ .x = ropeSize, .y = 0.002 }), 10) + .rope = Rope.init(handPosition, handPosition.add(.{ .x = ropeSize, .y = 0.002 }), 10), + .camera = .{ .target = playerPosition } }; } @@ -144,6 +149,14 @@ pub fn deinit(self: Self) void { pub fn tick(self: *Self) !void { rl.ClearBackground(rl.BLACK); + const screenWidth: f32 = @floatFromInt(rl.GetScreenWidth()); + const screenHeight: f32 = @floatFromInt(rl.GetScreenHeight()); + const mouseDelta = rl.GetMouseDelta(); + + self.camera.offset.x = screenWidth/2; + self.camera.offset.y = screenHeight/2; + self.camera.target = self.player.position; + const dt = rl.GetFrameTime(); var rng = self.prng.random(); var player = &self.player; @@ -156,7 +169,7 @@ pub fn tick(self: *Self) !void { self.enemyTimer = 0.5 + rng.float(f32) * 2; self.spawnedEnemiesCount += 1; try enemies.append(Enemy{ - .position = rl.Vector2.randomOnUnitCircle(rng).scale(100) + .position = rl.Vector2.randomOnUnitCircle(rng).scale(400) }); } @@ -175,16 +188,16 @@ pub fn tick(self: *Self) !void { moveDx += 1; } - var handDx: f32 = 0; - var handDy: f32 = 0; + var handDx: f32 = mouseDelta.x; + var handDy: f32 = mouseDelta.y; var gamepad: i32 = 0; if (rl.IsGamepadAvailable(gamepad)) { - moveDx += rl.GetGamepadAxisMovement(gamepad, rl.GamepadAxis.GAMEPAD_AXIS_LEFT_X); - moveDy += rl.GetGamepadAxisMovement(gamepad, rl.GamepadAxis.GAMEPAD_AXIS_LEFT_Y); + moveDx += rl.GetGamepadAxisMovement(gamepad, .GAMEPAD_AXIS_LEFT_X); + moveDy += rl.GetGamepadAxisMovement(gamepad, .GAMEPAD_AXIS_LEFT_Y); - handDx = rl.GetGamepadAxisMovement(gamepad, rl.GamepadAxis.GAMEPAD_AXIS_RIGHT_X); - handDy = rl.GetGamepadAxisMovement(gamepad, rl.GamepadAxis.GAMEPAD_AXIS_RIGHT_Y); + handDx += rl.GetGamepadAxisMovement(gamepad, .GAMEPAD_AXIS_RIGHT_X); + handDy += rl.GetGamepadAxisMovement(gamepad, .GAMEPAD_AXIS_RIGHT_Y); } var moveDir = rl.Vector2{ .x = moveDx, .y = moveDy }; @@ -221,86 +234,18 @@ pub fn tick(self: *Self) !void { const directionToPlayer = toPlayer.normalize(); enemy.position = enemy.position.add(directionToPlayer.scale(enemySpeed * dt)); - rl.DrawCircle( - @intFromFloat(enemy.position.x), - @intFromFloat(enemy.position.y), - enemySize, - rl.RED - ); } const handPosition = player.position.add(player.handDirection.scale(handDistance)); - const enemyCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.spawnedEnemiesCount}); - defer allocator.free(enemyCountText); - rl.DrawText(enemyCountText, 10, 10, 24, rl.RED); - - const killCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.killCount}); - defer allocator.free(killCountText); - rl.DrawText(killCountText, 10, 30, 24, rl.GREEN); - - rl.DrawCircle( - @intFromFloat(player.position.x), - @intFromFloat(player.position.y), - playerSize, - rl.RAYWHITE - ); - rl.DrawCircle( - @intFromFloat(handPosition.x), - @intFromFloat(handPosition.y), - 5, - rl.RAYWHITE - ); - rl.DrawLine( - @intFromFloat(player.position.x), - @intFromFloat(player.position.y), - @intFromFloat(player.position.x + player.velocity.x), - @intFromFloat(player.position.y + player.velocity.y), - rl.GREEN - ); - - rl.DrawCircle( - @intFromFloat(player.position.x + moveDir.x * maxSpeed), - @intFromFloat(player.position.y + moveDir.y * maxSpeed), - 5, - rl.GREEN - ); - - rope.nodePositions.set(0, handPosition); + const rope_root_node: rl.Vector2 = rope.nodePositions.get(0); + rope.nodePositions.set(0, rope_root_node.lerp(handPosition, 0.25)); + // rope.nodePositions.set(0, handPosition); rope.update(dt); - const rope_color = rl.PURPLE; - for (0..(rope.nodePositions.len-1)) |i| { - var node1: rl.Vector2 = rope.nodePositions.get(i); - var node2: rl.Vector2 = rope.nodePositions.get(i+1); - rl.DrawLine( - @intFromFloat(node1.x), - @intFromFloat(node1.y), - @intFromFloat(node2.x), - @intFromFloat(node2.y), - rope_color - ); - } - - for (rope.nodePositions.slice()) |node| { - rl.DrawCircle( - @intFromFloat(node.x), - @intFromFloat(node.y), - 5, - rope_color - ); - } - const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1); - rl.DrawCircle( - @intFromFloat(deathBallPosition.x), - @intFromFloat(deathBallPosition.y), - deathBallSize, - rl.RED - ); - { var i: usize = 0; while (i < enemies.items.len) { @@ -314,4 +259,85 @@ pub fn tick(self: *Self) !void { i += 1; } } + + { // UI + const enemyCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.spawnedEnemiesCount}); + defer allocator.free(enemyCountText); + rl.DrawText(enemyCountText, 10, 10, 24, rl.RED); + + const killCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.killCount}); + defer allocator.free(killCountText); + rl.DrawText(killCountText, 10, 30, 24, rl.GREEN); + } + + rl.BeginMode2D(self.camera); + { + rl.DrawCircle(0, 0, 5, rl.GOLD); + + rl.DrawCircle( + @intFromFloat(player.position.x), + @intFromFloat(player.position.y), + playerSize, + rl.RAYWHITE + ); + rl.DrawCircle( + @intFromFloat(handPosition.x), + @intFromFloat(handPosition.y), + 5, + rl.RAYWHITE + ); + rl.DrawLine( + @intFromFloat(player.position.x), + @intFromFloat(player.position.y), + @intFromFloat(player.position.x + player.velocity.x), + @intFromFloat(player.position.y + player.velocity.y), + rl.GREEN + ); + + rl.DrawCircle( + @intFromFloat(player.position.x + moveDir.x * maxSpeed), + @intFromFloat(player.position.y + moveDir.y * maxSpeed), + 5, + rl.GREEN + ); + + for (enemies.items) |*enemy| { + rl.DrawCircle( + @intFromFloat(enemy.position.x), + @intFromFloat(enemy.position.y), + enemySize, + rl.RED + ); + } + + const rope_color = rl.PURPLE; + for (0..(rope.nodePositions.len-1)) |i| { + var node1: rl.Vector2 = rope.nodePositions.get(i); + var node2: rl.Vector2 = rope.nodePositions.get(i+1); + rl.DrawLine( + @intFromFloat(node1.x), + @intFromFloat(node1.y), + @intFromFloat(node2.x), + @intFromFloat(node2.y), + rope_color + ); + } + + for (rope.nodePositions.slice()) |node| { + rl.DrawCircle( + @intFromFloat(node.x), + @intFromFloat(node.y), + 5, + rope_color + ); + } + + rl.DrawCircle( + @intFromFloat(deathBallPosition.x), + @intFromFloat(deathBallPosition.y), + deathBallSize, + rl.RED + ); + } + rl.EndMode2D(); } diff --git a/src/main.zig b/src/main.zig index 9ed0a0b..af31981 100644 --- a/src/main.zig +++ b/src/main.zig @@ -9,7 +9,8 @@ pub fn main() !void { defer _ = gpa.deinit(); rl.SetTargetFPS(60); - rl.InitWindow(800, 800, "Step kill"); + rl.InitWindow(1200, 1200, "Step kill"); + rl.DisableCursor(); defer rl.CloseWindow(); var scene = MainScene.init(allocator);