Reorganize source code
This commit is contained in:
parent
d54148e5db
commit
f4388e1626
10
src/defs.rs
10
src/defs.rs
@ -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,
|
|
||||||
}
|
|
216
src/main.rs
216
src/main.rs
@ -3,149 +3,16 @@
|
|||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
||||||
input::{mouse::{MouseMotion, MouseButtonInput}, ButtonState},
|
input::mouse::MouseMotion,
|
||||||
math::Vec4Swizzles,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::camera::RenderTarget,
|
|
||||||
};
|
};
|
||||||
use bevy_ecs_tilemap::prelude::*;
|
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] = [
|
mod pawns;
|
||||||
SurfaceDef {
|
mod terrain;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
commands.spawn(Camera2dBundle::default());
|
commands.spawn(Camera2dBundle::default());
|
||||||
@ -176,87 +43,14 @@ fn mouse_motion(
|
|||||||
buttons: Res<Input<MouseButton>>,
|
buttons: Res<Input<MouseButton>>,
|
||||||
mut query: Query<(&mut Transform, &mut OrthographicProjection), With<Camera>>,
|
mut query: Query<(&mut Transform, &mut OrthographicProjection), With<Camera>>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
for ev in motion_evr.iter() {
|
for ev in motion_evr.iter() {
|
||||||
if buttons.pressed(MouseButton::Middle) {
|
if buttons.pressed(MouseButton::Middle) {
|
||||||
for (mut transform, mut _ortho) in query.iter_mut() {
|
for (mut transform, mut _ortho) in query.iter_mut() {
|
||||||
let direction = Vec3::new(ev.delta.x, ev.delta.y * -1.0, 0.0);
|
let direction = Vec3::new(ev.delta.x, ev.delta.y * -1.0, 0.0);
|
||||||
transform.translation += direction;
|
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() {
|
fn main() {
|
||||||
|
130
src/pawns.rs
Normal file
130
src/pawns.rs
Normal 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
96
src/terrain.rs
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user