Skip to content
Snippets Groups Projects
Commit db1e4f01 authored by Arian's avatar Arian
Browse files

Fin du vaisseau

parent 4871a68a
No related branches found
No related tags found
No related merge requests found
use oort_api::prelude::*;
// Ship
pub enum Ship {
Fighter(Fighter),
Missile(Missile),
}
impl Ship {
pub fn new() -> Ship {
match class() {
Class::Fighter => Ship::Fighter(Fighter::new()),
Class::Missile => Ship::Missile(Missile::new()),
_ => unreachable!(),
}
}
pub fn tick(&mut self) {
match self {
Ship::Fighter(fighter) => fighter.tick(),
Ship::Missile(missile) => missile.tick(),
}
}
}
// Fighters
pub struct Fighter {}
impl Fighter {
pub fn new() -> Self {
Self {}
}
pub fn tick(&mut self) {
set_radio_channel(2);
set_radar_width(TAU / 128.0);
stay_within_bounds(position());
fire_missile();
if let Some(contact) = scan().filter(|c| [Class::Missile, Class::Fighter].contains(&c.class)) {
if contact.class == Class::Missile {
dodge(position(), contact.position);
fire_guns(contact);
} else if contact.class == Class::Fighter {
send([contact.position.x, contact.position.y, contact.velocity.x, contact.velocity.y]);
}
} else {
set_radar_heading(radar_heading() + radar_width());
}
}
}
pub fn stay_within_bounds(pos: Vec2){
let move_speed = 800.0;
if pos.y > 0.6e4{
accelerate( vec2(0.0,-1.0).normalize() * move_speed);
}else{
accelerate( vec2(0.0,1.0).normalize() * move_speed);
}
}
pub fn dodge(position: Vec2, missile_position: Vec2) {
let dp = position - missile_position;
let distance = dp.length();
// Define the boundaries of the map
let boundary_limit = 0.6e4;
let min_dodge_speed = 300.0;
let max_dodge_speed = 800.0;
// Dodge direction based on the proximity to the edges:
let mut dodge_direction = vec2(0.0, 1.0);
// Check vertical (y-axis) boundaries
if position.y > boundary_limit {
dodge_direction.y = -1.0;
} else if position.y < -boundary_limit {
dodge_direction.y = 1.0;
}
// Check horizontal (x-axis) boundaries
if position.x > boundary_limit {
dodge_direction.x = -1.0;
} else if position.x < -boundary_limit {
dodge_direction.x = 1.0;
} else {
dodge_direction.x = 0.0;
}
let dodge_speed = min_dodge_speed + (max_dodge_speed - min_dodge_speed) * (1.0 / (1.0 + distance / 1e4));
let dodge_vector = dodge_direction.normalize() * dodge_speed;
accelerate(dodge_vector);
}
pub fn fire_guns(target: ScanResult){
let dp = target.position - position();
let missile_angle = dp.angle();
turn_to(missile_angle);
let angle_diff = angle_diff(heading(), missile_angle);
if angle_diff.abs() < 0.2 && dp.length() < 1e4 {
fire(0);
}
}
// Missiles
pub struct Missile {
target_position: Vec2,
target_velocity: Vec2,
last_velocity: Vec2,
last_tick: u32,
}
impl Missile {
pub fn new() -> Self {
Self {
target_position: vec2(0.0, 0.0),
target_velocity: vec2(0.0, 0.0),
last_velocity: vec2(0.0, 0.0),
last_tick: current_tick(),
}
}
pub fn tick(&mut self) {
set_radar_max_distance(10e4);
set_radar_width(TAU / 64.0);
set_radio_channel(2);
debug!("Velocity : {:?}", velocity());
if let Some(contact) = scan().filter(|c| [Class::Fighter].contains(&c.class)) {
// Handle detected fighter from the radar
let target_position = contact.position;
let target_velocity = contact.velocity;
self.update_and_chase(target_position, target_velocity, current_tick() - self.last_tick);
self.last_tick = current_tick(); // Update the last_tick after processing
set_radar_heading((target_position - position()).angle());
draw_line(position(), self.target_position, 0xFF0000);
} else if let Some(msg) = receive() {
// Handle the message from the radio
let target_position = vec2(msg[0], msg[1]);
let target_velocity = vec2(msg[2], msg[3]);
self.update_and_chase(target_position, target_velocity, current_tick() - self.last_tick);
self.last_tick = current_tick(); // Update the last_tick after processing
set_radar_heading((target_position - position()).angle());
draw_line(position(), self.target_position, 0xFF0000);
} else {
sweep();
chase(self.target_position);
}
if (self.target_position - position()).length() < 100.0 {
explode();
}
}
fn update_and_chase(&mut self, target_position: Vec2, target_velocity: Vec2, dt: u32) {
let estimated_acceleration = (target_velocity - self.last_velocity) / dt as f64;
let predicted_position = self.predict_target_position_with_acceleration(
target_position,
target_velocity,
estimated_acceleration,
dt
);
// Update target and last velocity
self.target_position = predicted_position;
self.last_velocity = target_velocity; // Save current velocity for the next tick
chase(self.target_position);
}
fn predict_target_position_with_acceleration(&self, target_position: Vec2, target_velocity: Vec2, estimated_acceleration: Vec2, dt: u32) -> Vec2 {
let time = dt as f64; // Use the actual time difference (in ticks)
// Predict future position using the formula:
// future_position = target_position + target_velocity * time + 0.5 * estimated_acceleration * time^2
target_position + target_velocity * time + 0.5 * estimated_acceleration * time.powi(2)
}
}
pub fn chase(target_position: Vec2) {
let dp = target_position - position();
let distance = dp.length();
// Determine speed based on distance to target
let speed_factor = if distance < 500.0 { 0.5 } else { 1.0 };
let max_speed = 1600.0 * speed_factor;
let desired_direction = dp.normalize();
let desired_velocity = desired_direction * max_speed;
let steering = desired_velocity - velocity();
// Limit the steering to a maximum acceleration to prevent instant changes
let max_acceleration = 400.0;
let steering_length = steering.length();
let acceleration = if steering_length > max_acceleration {
steering.normalize() * max_acceleration
} else {
steering
};
// Apply the calculated acceleration
accelerate(acceleration);
// Turn towards the desired direction smoothly
let target_angle = dp.angle();
let current_angle = velocity().angle();
let angle_difference = angle_diff(current_angle, target_angle);
// Use a factor to determine how quickly to turn
let turn_factor = 0.1; // Adjust this for smoother turning
let turning_rate = angle_difference * turn_factor;
turn_to(current_angle + turning_rate);
debug!("Fuel level: {}, Speed: {}", fuel(), max_speed);
}
pub fn sweep() {
set_radar_width(TAU / 64.0);
set_radar_heading(radar_heading() + radar_width() / 2.0);
}
fn turn_to(target_heading: f64) {
let heading_error = angle_diff(heading(), target_heading);
turn(60.0 * heading_error);
}
fn fire_missile(){
if reload_ticks(1) == 0 {
fire(1);
}
}
\ No newline at end of file
use oort_api::prelude::*;
const BULLET_SPEED: f64 = 1000.0; // meter per second
const TICKRATE: f64 = 60.0; // hertz
pub struct Ship {
}
impl Ship {
pub fn new() -> Ship {
Ship {
}
}
pub fn tick(&mut self) {
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment