convert ant into slime with trail

This commit is contained in:
Felix Ableitner 2021-10-06 02:56:06 +02:00
parent b7101f46c6
commit 813d03adbb
4 changed files with 45 additions and 28 deletions

View file

@ -1,4 +1,6 @@
use crate::constants::{ANT_SPEED, FLOOR_COLOR}; use crate::constants::ANT_SPEED;
use crate::constants::MAP_HEIGHT;
use crate::constants::MAP_WIDTH;
use crate::Drawable; use crate::Drawable;
use macroquad::prelude::*; use macroquad::prelude::*;
use macroquad::rand::RandomRange; use macroquad::rand::RandomRange;
@ -15,27 +17,31 @@ impl Ant {
(0..num) (0..num)
.into_iter() .into_iter()
.map(|n| Ant { .map(|n| Ant {
pos: Vec2::new(400., 200.), pos: Vec2::new((MAP_WIDTH / 2) as f32, (MAP_HEIGHT / 2) as f32),
dir: n as f32 * dir_steps, dir: n as f32 * dir_steps,
}) })
.collect() .collect()
} }
pub(crate) fn walk(&mut self, map_data: &Image) { pub(crate) fn walk(&mut self, frame_time: f32, trail_map: &mut Image) {
let new_dir = PI / 8. * RandomRange::gen_range(-2, 2) as f32; let new_dir = PI / 8. * RandomRange::gen_range(-2, 2) as f32;
self.dir += new_dir; self.dir += new_dir;
self.dir = self.dir.clamp(0., PI * 2.); if self.dir > 2. * PI {
self.dir -= 2. * PI;
}
let acceleration = Vec2::new(self.dir.sin(), -self.dir.cos()); let acceleration = Vec2::new(self.dir.sin(), -self.dir.cos());
let new_pos = self.pos + acceleration * ANT_SPEED * get_frame_time(); self.pos += acceleration * ANT_SPEED * frame_time;
let dest_pixel = map_data.get_pixel(new_pos.x as u32, new_pos.y as u32); // TODO: this is not fixing out of bounds write
if dest_pixel == FLOOR_COLOR { self.pos.x = self.pos.x.clamp(0., MAP_WIDTH as f32);
self.pos = new_pos; self.pos.y = self.pos.y.clamp(0., MAP_HEIGHT as f32);
}
// TODO: change color over time
trail_map.set_pixel(self.pos.x as u32, self.pos.y as u32, RED);
} }
} }
impl Drawable for Ant { impl Drawable for Ant {
fn draw(&self) { fn draw(&self) {
draw_circle(self.pos.x, self.pos.y, 1., BLACK); draw_circle(self.pos.x, self.pos.y, 1., WHITE);
} }
} }

View file

@ -1,6 +1,3 @@
use macroquad::color::Color;
pub static ANT_SPEED: f32 = 20.; pub static ANT_SPEED: f32 = 20.;
pub static FLOOR_COLOR: Color = Color::new(0.46666667, 0.38431373, 0.3019608, 1.); pub const MAP_WIDTH: u32 = 1280;
pub static SCREEN_WIDTH: i32 = 1280; pub const MAP_HEIGHT: u32 = 720;
pub static SCREEN_HEIGHT: i32 = 720;

View file

@ -7,6 +7,7 @@ pub(crate) struct Food {
pos: Vec2, pos: Vec2,
} }
#[allow(dead_code)]
impl Food { impl Food {
pub(crate) fn new(pos: Vec2) -> Self { pub(crate) fn new(pos: Vec2) -> Self {
Food { pos } Food { pos }

View file

@ -1,18 +1,19 @@
extern crate macroquad;
mod ant; mod ant;
mod constants; mod constants;
mod food; mod food;
use crate::ant::Ant; use crate::ant::Ant;
use crate::constants::{SCREEN_HEIGHT, SCREEN_WIDTH}; use constants::{MAP_HEIGHT, MAP_WIDTH};
use crate::food::Food;
use macroquad::prelude::*; use macroquad::prelude::*;
fn window_conf() -> Conf { fn window_conf() -> Conf {
Conf { Conf {
window_title: "Ants".to_string(), window_title: "Ants".to_string(),
fullscreen: false, fullscreen: false,
window_width: SCREEN_WIDTH, window_width: MAP_WIDTH as i32,
window_height: SCREEN_HEIGHT, window_height: MAP_HEIGHT as i32,
..Default::default() ..Default::default()
} }
} }
@ -23,27 +24,39 @@ trait Drawable {
#[macroquad::main(window_conf)] #[macroquad::main(window_conf)]
async fn main() { async fn main() {
let map = load_texture("map_scaled.png").await.unwrap(); //let map = load_texture("map_scaled.png").await.unwrap();
let map_data = map.get_texture_data(); let mut trail_map = Image::gen_image_color(MAP_WIDTH as u16, MAP_HEIGHT as u16, BLACK);
let mut ants = Ant::init(16); let mut ants = Ant::init(1024);
let mut food = Food::init();
loop { loop {
// fade trails (doesnt really work)
let frame_time = get_frame_time();
for x in 0..MAP_WIDTH {
for y in 0..MAP_HEIGHT {
let mut current_pixel = trail_map.get_pixel(x, y);
current_pixel.r -= 0.1 * frame_time;
current_pixel.g -= 0.1 * frame_time;
current_pixel.b -= 0.1 * frame_time;
trail_map.set_pixel(x, y, current_pixel);
}
}
// actions // actions
ants.iter_mut().for_each(|ant| ant.walk(&map_data)); ants.iter_mut()
.for_each(|ant| ant.walk(frame_time, &mut trail_map));
if is_key_down(KeyCode::Escape) || is_quit_requested() { if is_key_down(KeyCode::Escape) || is_quit_requested() {
return; return;
} }
if is_mouse_button_down(MouseButton::Left) { if is_mouse_button_down(MouseButton::Left) {
let mouse = mouse_position(); let mouse = mouse_position();
food.push(Food::new(Vec2::new(mouse.0, mouse.1))); dbg!(&mouse);
//food.push(Food::new(Vec2::new(mouse.0, mouse.1)));
} }
// render // render
clear_background(BEIGE); clear_background(BLACK);
draw_texture(map, 0., 0., WHITE); let texture = Texture2D::from_image(&trail_map);
draw_texture(texture, 0., 0., WHITE);
ants.iter().for_each(|ant| ant.draw()); ants.iter().for_each(|ant| ant.draw());
food.iter().for_each(|food| food.draw());
next_frame().await next_frame().await
} }