Nature of Code 之 6 - Autonomous Agents Vehicle’s Wander .
改用VLANG
module sobj
import vector2
import rand
/*
Vehcle behavior is seek a target then movie toward it.
*/
pub struct Vehicle {
pub mut:
location vector2.Vec2
velocity vector2.Vec2
acceleration vector2.Vec2
r f32
max_speed f32
max_force f32
direction f32
wander_theta f32
}
pub fn new_vehicle(x f32, y f32) &Vehicle {
vehicle := &Vehicle{
location: vector2.Vec2{x, y}
velocity: vector2.Vec2{0, 0}
acceleration: vector2.Vec2{0, 0}
r: 3.0
max_speed: 4.0
max_force: 0.05
direction: 0
wander_theta:0
}
return vehicle
}
// update position
pub fn (mut v Vehicle) update() {
head := v.location.clone()
v.velocity = vector2.add(v.velocity, v.acceleration)
v.velocity.limit(v.max_speed)
v.location = vector2.add(v.location,v.velocity)
v.acceleration.zero()
v.direction = vector2.angle(head,v.location)
}
pub fn (mut v Vehicle) wander() {
wander_r := f32(25.0)
wander_d := f32(80.0)
change := f32(0.1)
v.wander_theta += rand.f32_in_range(-change, change)
mut circle_pos := v.velocity.clone()
circle_pos.normalize()
circle_pos.scale(wander_d)
circle_pos = vector2.add(circle_pos,v.location)
mut circle_offset := circle_pos.clone()
circle_offset.rotate(v.wander_theta)
circle_offset.scale(wander_r)
target :=vector2.add(circle_pos,circle_offset)
v.seek(target)
}
pub fn(mut v Vehicle)border(width f32,height f32) {
if v.location.x < -v.r {v.location.x = width + v.r}
if v.location.y < -v.r {v.location.y = height + v.r}
if v.location.x > width + v.r {v.location.x = -v.r}
if v.location.y > height +v.r {v.location.y = -v.r}
}
pub fn (mut v Vehicle) apply_force(force vector2.Vec2) {
// add mass here if we want A = F / M
v.acceleration =vector2.add(v.acceleration,force)
}
// calculates a steering force rowards a target
// STEER = DESIRED MINUS VELOCITY
pub fn (mut v Vehicle) seek(target vector2.Vec2) {
mut desired :=vector2.sub(target,v.location)
desired.normalize()
desired.scale(v.max_speed)
mut steer :=vector2.sub(desired,v.velocity)
steer.limit(v.max_force)
v.apply_force(steer)
}