Reorganize source code

This commit is contained in:
Gender Shrapnel 2022-12-24 21:32:47 +01:00
parent d54148e5db
commit f4388e1626
Signed by: modzero
GPG Key ID: 4E11A06C6D1E5213
4 changed files with 231 additions and 221 deletions

View File

@ -1,10 +0,0 @@
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct SurfaceDef<'a> {
pub label: &'a str,
pub name: &'a str,
pub description: &'a str,
pub texture_index: u32,
pub support: f32,
}

View File

@ -3,149 +3,16 @@
use bevy::{
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
input::{mouse::{MouseMotion, MouseButtonInput}, ButtonState},
math::Vec4Swizzles,
input::mouse::MouseMotion,
prelude::*,
render::camera::RenderTarget,
};
use bevy_ecs_tilemap::prelude::*;
use defs::SurfaceDef;
mod defs;
use pawns::{make_pawn, pawn_control, pawn_motion};
use terrain::make_ground_layer;
const TERRAINS: [SurfaceDef; 3] = [
SurfaceDef {
label: "Mud",
name: "mud",
description: "Soil saturated with water.",
texture_index: 13,
support: 20.0,
},
SurfaceDef {
label: "Grass",
name: "grass",
description: "Green. Try to touch it.",
texture_index: 14,
support: 40.0,
},
SurfaceDef {
label: "Sand",
name: "sand",
description: "Gets everywhere, ruins vanilla sex fantasies.",
texture_index: 15,
support: 20.0,
},
];
#[derive(Component)]
struct PlayerCharacter {}
#[derive(Component, Clone)]
struct TileTerrain {
terrain_id: usize,
}
impl TileTerrain {
fn def(&self) -> &SurfaceDef {
&TERRAINS[self.terrain_id]
}
}
#[derive(Component, Default, Clone, Copy, Debug)]
pub struct PawnPos {
pub x: u32,
pub y: u32,
}
#[derive(Component, Default, Clone, Copy, Debug)]
pub struct PawnDest {
pub x: u32,
pub y: u32,
}
#[derive(Bundle, Default)]
struct PawnBundle {
position: PawnPos,
sprite: Sprite,
transform: Transform,
global_transform: GlobalTransform,
texture: Handle<Image>,
visibility: Visibility,
computed_visibility: ComputedVisibility,
}
fn make_ground_layer(
commands: &mut Commands,
tilemap_size: TilemapSize,
texture_handle: Handle<Image>,
tile_size: TilemapTileSize,
) -> Entity {
let mut tile_storage = TileStorage::empty(tilemap_size);
let tilemap_entity = commands.spawn_empty().id();
for x in 0..tilemap_size.x {
for y in 0..tilemap_size.y {
let tile_pos = TilePos { x, y };
let tile_terrain = TileTerrain { terrain_id: 1 };
let tile_entity = commands
.spawn((
tile_terrain.clone(),
TileBundle {
position: tile_pos,
tilemap_id: TilemapId(tilemap_entity),
texture_index: TileTextureIndex(tile_terrain.def().texture_index),
..Default::default()
},
))
.id();
tile_storage.set(&tile_pos, tile_entity);
}
}
let grid_size = tile_size.into();
let map_type = TilemapType::default();
commands.entity(tilemap_entity).insert(TilemapBundle {
grid_size,
map_type,
size: tilemap_size,
storage: tile_storage.clone(),
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: get_tilemap_center_transform(&tilemap_size, &grid_size, &map_type, 0.0),
..Default::default()
});
tilemap_entity
}
fn make_pawn(
commands: &mut Commands,
tilemap_entity: Entity,
texture_handle: Handle<Image>,
tile_size: &TilemapTileSize,
map_size: &TilemapSize,
) {
let pos = PawnPos {
x: map_size.x / 2,
y: map_size.y / 2,
};
commands
.spawn(PawnBundle {
position: pos,
transform: Transform::from_xyz(
(pos.x as f32) * tile_size.x,
(pos.y as f32) * tile_size.y,
1.0,
),
texture: texture_handle,
visibility: Visibility { is_visible: true },
..Default::default()
})
.insert(PlayerCharacter {})
.set_parent(tilemap_entity);
info!("Pawn at {:?}", pos);
}
mod pawns;
mod terrain;
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default());
@ -176,87 +43,14 @@ fn mouse_motion(
buttons: Res<Input<MouseButton>>,
mut query: Query<(&mut Transform, &mut OrthographicProjection), With<Camera>>,
) {
for ev in motion_evr.iter() {
if buttons.pressed(MouseButton::Middle) {
for (mut transform, mut _ortho) in query.iter_mut() {
let direction = Vec3::new(ev.delta.x, ev.delta.y * -1.0, 0.0);
transform.translation += direction;
}
}
}
}
fn pawn_control(
mut commands: Commands,
wnds: Res<Windows>,
query: Query<Entity, With<PlayerCharacter>>,
mut buttons_evr: EventReader<MouseButtonInput>,
camera_q: Query<(&GlobalTransform, &Camera)>,
tilemap_q: Query<(&TilemapSize, &TilemapGridSize, &TilemapType, &Transform)>,
) {
for ev in buttons_evr.iter() {
if (ev.button == MouseButton::Right) && (ev.state == ButtonState::Released) {
let (cam_gt, cam) = camera_q.single();
let wnd = if let RenderTarget::Window(id) = cam.target {
wnds.get(id).unwrap()
} else {
wnds.get_primary().unwrap()
};
if let Some(screen_pos) = wnd.cursor_position() {
query.for_each(|entity| {
if let Some(world_ray) = cam.viewport_to_world(cam_gt, screen_pos) {
let (map_size, map_grid_size, map_type, map_t) = tilemap_q.single();
let tilemap_pos = (map_t.compute_matrix().inverse()
* Vec4::from((world_ray.origin, 1.0)))
.xy();
info!("WP {:?} {:?}", world_ray.origin, tilemap_pos);
if let Some(tile_pos) =
TilePos::from_world_pos(&tilemap_pos, map_size, map_grid_size, map_type)
{
info!("{:?}", tile_pos);
commands.entity(entity).insert(PawnDest {
x: tile_pos.x,
y: tile_pos.y,
});
}
}
});
}
}
}
}
type ChangedPawns = Or<(Changed<PawnPos>, With<PawnDest>)>;
fn pawn_motion(
mut commands: Commands,
mut pawn_q: Query<(Entity, &mut PawnPos, &mut Transform, Option<&PawnDest>), ChangedPawns>,
tilemap_q: Query<&TilemapTileSize>,
) {
let map_tile_size = tilemap_q.single();
pawn_q.for_each_mut(|(entity, mut pos, mut transform, dest)| match dest {
Some(d) => {
pos.x = d.x;
pos.y = d.y;
transform.translation = Vec3::from((
(pos.x as f32) * map_tile_size.x,
(pos.y as f32) * map_tile_size.y,
1.0,
));
commands.entity(entity).remove::<PawnDest>();
}
None => {
transform.translation = Vec3::from((
(pos.x as f32) * map_tile_size.x,
(pos.y as f32) * map_tile_size.y,
1.0,
));
}
})
}
fn main() {

130
src/pawns.rs Normal file
View File

@ -0,0 +1,130 @@
use bevy::{
input::{mouse::MouseButtonInput, ButtonState},
math::Vec4Swizzles,
prelude::*,
render::camera::RenderTarget,
};
use bevy_ecs_tilemap::prelude::*;
#[derive(Component)]
pub struct PlayerCharacter {}
#[derive(Component, Default, Clone, Copy, Debug)]
pub struct PawnPos {
pub x: u32,
pub y: u32,
}
#[derive(Component, Default, Clone, Copy, Debug)]
pub struct PawnDest {
pub x: u32,
pub y: u32,
}
#[derive(Bundle, Default)]
struct PawnBundle {
position: PawnPos,
sprite: Sprite,
transform: Transform,
global_transform: GlobalTransform,
texture: Handle<Image>,
visibility: Visibility,
computed_visibility: ComputedVisibility,
}
pub fn make_pawn(
commands: &mut Commands,
tilemap_entity: Entity,
texture_handle: Handle<Image>,
tile_size: &TilemapTileSize,
map_size: &TilemapSize,
) {
let pos = PawnPos {
x: map_size.x / 2,
y: map_size.y / 2,
};
commands
.spawn(PawnBundle {
position: pos,
transform: Transform::from_xyz(
(pos.x as f32) * tile_size.x,
(pos.y as f32) * tile_size.y,
1.0,
),
texture: texture_handle,
visibility: Visibility { is_visible: true },
..Default::default()
})
.insert(PlayerCharacter {})
.set_parent(tilemap_entity);
info!("Pawn at {:?}", pos);
}
pub fn pawn_control(
mut commands: Commands,
wnds: Res<Windows>,
query: Query<Entity, With<PlayerCharacter>>,
mut buttons_evr: EventReader<MouseButtonInput>,
camera_q: Query<(&GlobalTransform, &Camera)>,
tilemap_q: Query<(&TilemapSize, &TilemapGridSize, &TilemapType, &Transform)>,
) {
for ev in buttons_evr.iter() {
if (ev.button == MouseButton::Right) && (ev.state == ButtonState::Released) {
let (cam_gt, cam) = camera_q.single();
let wnd = if let RenderTarget::Window(id) = cam.target {
wnds.get(id).unwrap()
} else {
wnds.get_primary().unwrap()
};
if let Some(screen_pos) = wnd.cursor_position() {
query.for_each(|entity| {
if let Some(world_ray) = cam.viewport_to_world(cam_gt, screen_pos) {
let (map_size, map_grid_size, map_type, map_t) = tilemap_q.single();
let tilemap_pos = (map_t.compute_matrix().inverse()
* Vec4::from((world_ray.origin, 1.0)))
.xy();
if let Some(tile_pos) =
TilePos::from_world_pos(&tilemap_pos, map_size, map_grid_size, map_type)
{
commands.entity(entity).insert(PawnDest {
x: tile_pos.x,
y: tile_pos.y,
});
}
}
});
}
}
}
}
type ChangedPawns = Or<(Changed<PawnPos>, With<PawnDest>)>;
pub fn pawn_motion(
mut commands: Commands,
mut pawn_q: Query<(Entity, &mut PawnPos, &mut Transform, Option<&PawnDest>), ChangedPawns>,
tilemap_q: Query<&TilemapTileSize>,
) {
let map_tile_size = tilemap_q.single();
pawn_q.for_each_mut(|(entity, mut pos, mut transform, dest)| match dest {
Some(d) => {
pos.x = d.x;
pos.y = d.y;
transform.translation = Vec3::from((
(pos.x as f32) * map_tile_size.x,
(pos.y as f32) * map_tile_size.y,
1.0,
));
commands.entity(entity).remove::<PawnDest>();
}
None => {
transform.translation = Vec3::from((
(pos.x as f32) * map_tile_size.x,
(pos.y as f32) * map_tile_size.y,
1.0,
));
}
})
}

96
src/terrain.rs Normal file
View File

@ -0,0 +1,96 @@
// Copyright 2022 ModZero.
// SPDX-License-Identifier: AGPL-3.0-or-later
use bevy::prelude::*;
use bevy_ecs_tilemap::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct SurfaceDef<'a> {
pub label: &'a str,
pub name: &'a str,
pub description: &'a str,
pub texture_index: u32,
pub support: f32,
}
#[derive(Component, Clone)]
struct TileTerrain {
terrain_id: usize,
}
impl TileTerrain {
fn def(&self) -> &SurfaceDef {
&TERRAINS[self.terrain_id]
}
}
const TERRAINS: [SurfaceDef; 3] = [
SurfaceDef {
label: "Mud",
name: "mud",
description: "Soil saturated with water.",
texture_index: 13,
support: 20.0,
},
SurfaceDef {
label: "Grass",
name: "grass",
description: "Green. Try to touch it.",
texture_index: 14,
support: 40.0,
},
SurfaceDef {
label: "Sand",
name: "sand",
description: "Gets everywhere, ruins vanilla sex fantasies.",
texture_index: 15,
support: 20.0,
},
];
pub fn make_ground_layer(
commands: &mut Commands,
tilemap_size: TilemapSize,
texture_handle: Handle<Image>,
tile_size: TilemapTileSize,
) -> Entity {
let mut tile_storage = TileStorage::empty(tilemap_size);
let tilemap_entity = commands.spawn_empty().id();
for x in 0..tilemap_size.x {
for y in 0..tilemap_size.y {
let tile_pos = TilePos { x, y };
let tile_terrain = TileTerrain { terrain_id: 1 };
let tile_entity = commands
.spawn((
tile_terrain.clone(),
TileBundle {
position: tile_pos,
tilemap_id: TilemapId(tilemap_entity),
texture_index: TileTextureIndex(tile_terrain.def().texture_index),
..Default::default()
},
))
.id();
tile_storage.set(&tile_pos, tile_entity);
}
}
let grid_size = tile_size.into();
let map_type = TilemapType::default();
commands.entity(tilemap_entity).insert(TilemapBundle {
grid_size,
map_type,
size: tilemap_size,
storage: tile_storage.clone(),
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: get_tilemap_center_transform(&tilemap_size, &grid_size, &map_type, 0.0),
..Default::default()
});
tilemap_entity
}