package game import "core:math/rand" import "core:math" import rl "vendor:raylib" init_opponent :: proc() -> Entity { return Entity{ type = .Opponent, active = true, pos = rl.Vector2{0,0}, speed = 800, shape = .Rectangle, size = rl.Vector2{30, 150} } } update_opponent :: proc(self: ^Entity, ball: Entity, bounds: rl.Rectangle, dt: f32) { // determin y target first if ball.vel.x > 0 { // ball is approaching tick down the timer to react self.reaction_timer -= dt if self.reaction_timer <= 0 { // timeout so calc new target with small offset for error error_offset := rand.float32_range(-25.0, 25.0) // center of ball - center of paddle gives the target self.target_y = (ball.pos.y + (ball.size.y / 2)) - (self.size.y / 2) + error_offset self.reaction_timer = 0.20 } } else { // ball going away get back to middle of screen self.target_y = bounds.y + (bounds.height / 2) - (self.size.y / 2) } diff := self.target_y - self.pos.y deadzone : f32 = 8.0 // stops jittering if math.abs(diff) > deadzone { dir : f32 = diff > 0 ? 1.0 : -1.0 self.pos.y += dir * self.speed * dt } // clamp position within field bounds min_y := bounds.y + 3 // Padding offset inside border max_y := bounds.y + bounds.height - self.size.y - 3 self.pos.y = math.clamp(self.pos.y, min_y, max_y) } render_opponent :: proc(self: Entity, field_bounds: rl.Rectangle) { rl.DrawRectangleV(self.pos, self.size, rl.BLACK) }