119 lines
3.5 KiB
Zig
119 lines
3.5 KiB
Zig
const std = @import("std");
|
|
const sdl = @import("sdl");
|
|
const Game = @import("game.zig");
|
|
const Graphics = @import("graphics.zig");
|
|
const Time = @import("time.zig");
|
|
const World = @import("world.zig");
|
|
const math = @import("math.zig");
|
|
|
|
position: @Vector(2, i32),
|
|
player: bool = false,
|
|
enemy: bool = false,
|
|
controller: Controller = .{},
|
|
next_update: Time = Time.ZERO,
|
|
|
|
const Controller = struct {
|
|
const Action = union(enum) {
|
|
move: @Vector(2, i32),
|
|
};
|
|
wanted_action: ?Action = null,
|
|
move_units: f32 = 0.125,
|
|
};
|
|
|
|
const Self = @This();
|
|
pub fn update(self: *Self) void {
|
|
if (!World.time.past(self.next_update)) return;
|
|
|
|
if (self.player) self.updatePlayer();
|
|
if (self.enemy) self.updateEnemy();
|
|
self.updateController();
|
|
}
|
|
|
|
pub fn updatePlayer(self: *Self) void {
|
|
var delta: @Vector(2, i32) = .{ 0, 0 };
|
|
if (Game.keyboard.keys.is_pressed(sdl.SCANCODE_UP)) {
|
|
delta[1] += 1;
|
|
}
|
|
if (Game.keyboard.keys.is_pressed(sdl.SCANCODE_DOWN)) {
|
|
delta[1] -= 1;
|
|
}
|
|
if (Game.keyboard.keys.is_pressed(sdl.SCANCODE_RIGHT)) {
|
|
delta[0] += 1;
|
|
}
|
|
if (Game.keyboard.keys.is_pressed(sdl.SCANCODE_LEFT)) {
|
|
delta[0] -= 1;
|
|
}
|
|
if (@reduce(.Or, delta != @Vector(2, i32){ 0, 0 }))
|
|
self.controller.wanted_action = .{ .move = delta }
|
|
else
|
|
self.controller.wanted_action = null;
|
|
}
|
|
|
|
fn updateEnemy(self: *Self) void {
|
|
if (World.getPlayer()) |player| {
|
|
var delta = player.position - self.position;
|
|
if (@reduce(.And, @abs(delta) <= @Vector(2, i64){ 1, 1 })) {
|
|
self.controller.wanted_action = null;
|
|
} else {
|
|
delta[0] = @max(-1, @min(1, delta[0]));
|
|
delta[1] = @max(-1, @min(1, delta[1]));
|
|
self.controller.wanted_action = .{ .move = delta };
|
|
}
|
|
}
|
|
}
|
|
|
|
fn updateController(self: *Self) void {
|
|
if (self.controller.wanted_action) |action| {
|
|
switch (action) {
|
|
.move => |delta| {
|
|
const target = self.position + delta;
|
|
if (World.isFree(target)) {
|
|
self.next_update = World.time.offset(self.controller.move_units * math.lengthInt(delta));
|
|
self.position[0] += delta[0];
|
|
self.position[1] += delta[1];
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn draw(self: *Self, delta: f32) void {
|
|
const transform = Graphics.Transform{
|
|
.position = .{
|
|
@floatFromInt(self.position[0]),
|
|
@floatFromInt(self.position[1]),
|
|
0.5,
|
|
},
|
|
};
|
|
Graphics.drawMesh(World.cube_mesh, World.texture, transform);
|
|
|
|
if (!self.player) return;
|
|
|
|
Graphics.camera.transform.position = math.lerpTimeLn(
|
|
Graphics.camera.transform.position,
|
|
transform.position + @Vector(3, f32){ 0.0, -2.0, 5.0 },
|
|
delta,
|
|
-25,
|
|
);
|
|
|
|
const ORIGIN_DIR = @Vector(3, f32){ 0.0, 0.0, -1.0 };
|
|
const INIT_ROTATION = Graphics.Transform.rotationByAxis(.{ 1.0, 0.0, 0.0 }, std.math.pi * 0.5);
|
|
|
|
const ROTATED_DIR = Graphics.Transform.rotateVector(ORIGIN_DIR, INIT_ROTATION);
|
|
|
|
const target_rotation = Graphics.Transform.combineRotations(
|
|
INIT_ROTATION,
|
|
Graphics.Transform.rotationToward(
|
|
ROTATED_DIR,
|
|
transform.position - Graphics.camera.transform.position,
|
|
.{ .normalize_to = true },
|
|
),
|
|
);
|
|
Graphics.camera.transform.rotation = Graphics.Transform.normalizeRotation(math.slerpTimeLn(
|
|
Graphics.camera.transform.rotation,
|
|
target_rotation,
|
|
delta,
|
|
-2,
|
|
));
|
|
}
|