Images of plates creating and drawing

This commit is contained in:
2026-07-03 10:16:36 +03:00
parent 9372c1ae56
commit bee1573e3d
6 changed files with 175 additions and 60 deletions
+146 -36
View File
@@ -1,13 +1,12 @@
use crate::collision_world::{CollisionBody, CollisionWorld};
use crate::hex_table::HexTable;
use crate::table::{IntoImage, Table};
use crate::SeededRng;
use bevy::asset::Assets;
use crate::{Moving, SeededRng};
use bevy::asset::{Assets, RenderAssetUsages};
use bevy::image::Image;
use bevy::input::ButtonInput;
use bevy::prelude::{
Commands, Component, Entity, KeyCode, Query, Res, ResMut, Single, Sprite,
With,
};
use bevy::prelude::*;
use bevy::render::render_resource::{Extent3d, TextureDimension, TextureFormat};
use rand::RngExt;
use rand_chacha::ChaCha8Rng;
use std::collections::HashMap;
@@ -22,7 +21,6 @@ pub fn update_automation_view(
let (sprite, automation) = query.into_inner();
let image = automation.world.get_image_data();
// images.remove(sprite.image.id());
images.insert(sprite.image.id(), image).unwrap();
commands.entity(request.into_inner().1).despawn();
@@ -30,35 +28,33 @@ pub fn update_automation_view(
pub fn update_automation(
query: Single<(&mut SubPlateAutomation, Entity)>,
hex_query: Single<&mut HexMatrixBuild>,
mut hex_query: Single<&mut HexMatrixBuild>,
mut seeded_rng: ResMut<SeededRng>,
keys: Res<ButtonInput<KeyCode>>,
mut commands: Commands,
mut images: ResMut<Assets<Image>>,
) {
let (mut automation, _entity) = query.into_inner();
let (mut automation, entity) = query.into_inner();
if keys.just_pressed(KeyCode::Space) || keys.all_pressed([KeyCode::Space, KeyCode::ShiftLeft]) {
let random = &mut seeded_rng.0;
automation.next(random);
commands.spawn(ViewRedrawRequest);
}
if keys.just_pressed(KeyCode::AltLeft) {
let random = &mut seeded_rng.0;
for _ in 0..16 {
automation.seed(random);
for i in 1..=16 {
automation.seed(random, i * 8);
}
commands.spawn(ViewRedrawRequest);
}
if keys.just_pressed(KeyCode::AltRight) {
automation.smooth();
commands.spawn(ViewRedrawRequest);
}
if keys.just_pressed(KeyCode::KeyS) {
@@ -66,9 +62,130 @@ pub fn update_automation(
}
if keys.just_pressed(KeyCode::KeyF) {
automation.calculate_front_lines(&mut commands, hex_query, &automation);
automation.calculate_front_lines(&mut commands, &mut hex_query, &automation);
}
if keys.just_pressed(KeyCode::Enter) {
// commands.entity(entity).despawn();
create_collision_world(commands, &automation, &hex_query, images);
}
}
fn create_collision_world(
mut commands: Commands,
query: &Mut<SubPlateAutomation>,
hex_query: &Single<&mut HexMatrixBuild>,
mut images: ResMut<Assets<Image>>,
) {
println!("Switching to CollisionAutomation");
let mut colors = query.world.data.clone();
colors.sort();
colors.dedup();
colors.remove(0);
let mut territories = vec![Vec::<(usize, usize)>::new(); colors.len()];
let mut borders = vec![Vec::<Vec2>::new(); colors.len()];
for x in 0..query.world.side {
for y in 0..query.world.side {
let color = *query.world.get_dim(x, y);
if color == 0 {
continue;
}
let index = colors.iter().position(|v| *v == color).unwrap();
territories[index].push((x, y));
}
}
for x in 0..hex_query.hex_matrix.dimensions.0 {
for y in 0..hex_query.hex_matrix.dimensions.1 {
let color = *query.world.get_dim(x, y);
if color == 0 {
continue;
}
let index = colors.iter().position(|v| *v == color).unwrap();
let coordinates = hex_query.hex_matrix.get_offset_of(x, y);
borders[index].push(Vec2::new(coordinates.0, coordinates.1));
}
}
let plates_data = territories
.iter()
.map(|v| {
let center = v
.iter()
.map(|(x, y)| Vec2::new(*x as f32, *y as f32))
.collect::<Vec<_>>()
.into_iter()
.sum::<Vec2>()
/ v.len() as f32;
let xs = v.iter().map(|(x, y)| *x).collect::<Vec<_>>();
let ys = v.iter().map(|(x, y)| *y).collect::<Vec<_>>();
let max_x = *xs.iter().max().unwrap();
let max_y = *ys.iter().max().unwrap();
let min_x = *xs.iter().min().unwrap();
let min_y = *ys.iter().min().unwrap();
let mut image = Image::new_fill(
Extent3d {
width: (max_x - min_x) as u32 + 1,
height: (max_y - min_y) as u32 + 1,
depth_or_array_layers: 1,
},
TextureDimension::D2,
&[0, 0, 0, 0],
TextureFormat::Rgba8UnormSrgb,
RenderAssetUsages::default(),
);
let size = image.size();
v.into_iter().for_each(|(x, y)| {
let position = ((*x - min_x) as u32, (*y - min_y) as u32);
image
.set_color_at(position.0, position.1, Color::WHITE)
.unwrap();
});
let image_offset = Vec2::new(min_x as f32, min_y as f32);
(v.len(), image_offset, image, Vec2::ZERO)
})
.collect::<Vec<_>>();
let mut world = CollisionWorld { bodies: vec![] };
let mut parts = Vec::with_capacity(plates_data.len());
for index in 0..plates_data.len() {
let (mass, center, image, offset) = plates_data.get(index).unwrap();
let image_handle = images.add(image.clone());
let view = commands
.spawn((
Transform::from_xyz(offset.x, offset.y, 0.0),
Sprite::from_image(image_handle),
))
.id();
let size = image.size();
let mut entity = commands.spawn((Transform::from_xyz(center.x + size.x as f32 / 2.0, -center.y - size.y as f32 / 2.0, 0.0),));
entity.add_child(view);
let entity_id = entity.id();
parts.push(entity_id);
let col_body = CollisionBody {
value: colors[index],
position: *center,
border: borders[index].clone(),
forces: vec![],
mass: *mass as f32,
};
world.bodies.push(col_body);
}
commands.spawn((Transform::default(), Moving)).add_children(parts.as_slice());
}
#[derive(Component)]
@@ -80,7 +197,6 @@ impl SubPlateAutomation {
fn next(&mut self, rng: &mut ChaCha8Rng) {
let time = Instant::now();
for index in 0..self.world.side * self.world.side {
let current_color = *self.world.get(index);
if current_color == 0 || current_color != u8::MAX {
@@ -129,7 +245,7 @@ impl SubPlateAutomation {
}
}
fn seed(&mut self, rng: &mut ChaCha8Rng) {
fn seed(&mut self, rng: &mut ChaCha8Rng, value: u8) {
let len = (self.world.side * self.world.side) as f32;
loop {
let index = (rng.random::<f32>() * len) as usize;
@@ -137,7 +253,7 @@ impl SubPlateAutomation {
continue;
}
self.world.set(index, rng.random::<u8>());
self.world.set(index, value);
break;
}
}
@@ -145,7 +261,7 @@ impl SubPlateAutomation {
fn calculate_front_lines(
&self,
commands: &mut Commands,
mut hex_query: Single<&mut HexMatrixBuild>,
mut hex_query: &mut Single<&mut HexMatrixBuild>,
automation: &SubPlateAutomation,
) {
let table = &mut hex_query.hex_matrix;
@@ -161,15 +277,14 @@ impl SubPlateAutomation {
for x in 0..table.dimensions.0 {
for y in 0..table.dimensions.1 {
let color = table.get_dim(x, y);
if *color == 0 { continue; }
if *color == 0 {
continue;
}
let around = table.around(x, y);
if around.iter().all(|x1| *x1 == around[0]) {
table_copy.set_dim(x, y, 0);
}else {
let new_color = (color).overflowing_add(128_u8).0;
table_copy.set_dim(x, y, new_color);
} else {
table_copy.set_dim(x, y, *color);
}
}
}
@@ -205,28 +320,24 @@ pub fn setup_hex_matrix(
mut commands: Commands,
mut images: ResMut<Assets<Image>>,
) {
let entity = request_query.into_inner().1;
let automation = automation_query.into_inner();
commands.entity(entity).despawn();
println!("Seed hex matrix");
let resolution = automation.world.side / 2;
let resolution = automation.world.side / 4;
let hex_table = HexTable::new(resolution, 0, 2.0);
let hex_table = HexTable::new(resolution, 0, 4.0);
let image = hex_table.get_image_data();
let sprite = view_query.into_inner();
// images.remove(sprite.image.id());
images.insert(sprite.image.id(), image).unwrap();
commands.spawn(
HexMatrixBuild {
hex_matrix: hex_table,
},
);
commands.spawn(HexMatrixBuild {
hex_matrix: hex_table,
});
}
pub fn update_hex_matrix_view(
@@ -244,7 +355,6 @@ pub fn update_hex_matrix_view(
let sprite = view_query.into_inner();
// images.remove(sprite.image.id());
images.insert(sprite.image.id(), image).unwrap();
}
#[derive(Component)]