Compare commits
5 Commits
92b5fca3bb
...
a0e62c6d3a
| Author | SHA1 | Date |
|---|---|---|
|
|
a0e62c6d3a | 1 week ago |
|
|
957d3e962d | 1 week ago |
|
|
b01f37fea4 | 1 week ago |
|
|
42460a76fb | 1 week ago |
|
|
69ae279f76 | 1 week ago |
5 changed files with 214 additions and 61 deletions
|
After Width: | Height: | Size: 288 B |
@ -0,0 +1,39 @@ |
|||||||
|
use bevy::ecs::system::SystemParam; |
||||||
|
use bevy::prelude::*; |
||||||
|
|
||||||
|
#[derive(Component)] |
||||||
|
pub struct Block; |
||||||
|
|
||||||
|
#[derive(SystemParam)] |
||||||
|
pub struct Blocks<'w, 's> { |
||||||
|
commands: Commands<'w, 's>, |
||||||
|
block_resources: Res<'w, BlockResources>, |
||||||
|
} |
||||||
|
|
||||||
|
impl Blocks<'_, '_> { |
||||||
|
pub fn spawn(&mut self, pos: IVec3) { |
||||||
|
self.commands.spawn(( |
||||||
|
Block, |
||||||
|
Mesh3d(self.block_resources.mesh.clone()), |
||||||
|
MeshMaterial3d(self.block_resources.material.clone()), |
||||||
|
Transform::from_translation(pos.as_vec3() + Vec3::ONE / 2.), |
||||||
|
)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Resource)] |
||||||
|
pub struct BlockResources { |
||||||
|
mesh: Handle<Mesh>, |
||||||
|
material: Handle<StandardMaterial>, |
||||||
|
} |
||||||
|
|
||||||
|
pub fn setup_blocks( |
||||||
|
mut commands: Commands, |
||||||
|
mut meshes: ResMut<Assets<Mesh>>, |
||||||
|
mut materials: ResMut<Assets<StandardMaterial>>, |
||||||
|
) { |
||||||
|
commands.insert_resource(BlockResources { |
||||||
|
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)), |
||||||
|
material: materials.add(Color::srgb_u8(124, 144, 255)), |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,48 @@ |
|||||||
|
use bevy::prelude::*; |
||||||
|
use bevy::window::{CursorGrabMode, CursorOptions}; |
||||||
|
|
||||||
|
use crate::block::*; |
||||||
|
|
||||||
|
pub fn place_break_blocks( |
||||||
|
mut commands: Commands, |
||||||
|
mut blocks: Blocks, |
||||||
|
mut ray_cast: MeshRayCast, |
||||||
|
mouse_button_input: Res<ButtonInput<MouseButton>>, |
||||||
|
window: Single<(&Window, &CursorOptions)>, |
||||||
|
camera: Single<(&GlobalTransform, &Camera)>, |
||||||
|
block_lookup: Query<&Transform, With<Block>>, |
||||||
|
) { |
||||||
|
if !mouse_button_input.any_just_pressed([MouseButton::Left, MouseButton::Right]) { |
||||||
|
return; // only run this system when left or right mouse button is pressed
|
||||||
|
} |
||||||
|
|
||||||
|
let (window, cursor) = window.into_inner(); |
||||||
|
let (cam_transform, camera) = camera.into_inner(); |
||||||
|
|
||||||
|
let ray = if cursor.grab_mode == CursorGrabMode::Locked { |
||||||
|
Ray3d::new(cam_transform.translation(), cam_transform.forward()) |
||||||
|
} else if let Some(cursor_pos) = window.cursor_position() { |
||||||
|
camera.viewport_to_world(cam_transform, cursor_pos).unwrap() |
||||||
|
} else { |
||||||
|
return; // cursor outside window area
|
||||||
|
}; |
||||||
|
|
||||||
|
let settings = &MeshRayCastSettings::default(); |
||||||
|
let Some((block, hit)) = ray_cast.cast_ray(ray, settings).first() else { |
||||||
|
return; // ray didn't hit anything
|
||||||
|
}; |
||||||
|
let Ok(block_transform) = block_lookup.get(*block) else { |
||||||
|
return; // entity hit is not a block
|
||||||
|
}; |
||||||
|
|
||||||
|
if mouse_button_input.just_pressed(MouseButton::Left) { |
||||||
|
// Destroy the block clicked.
|
||||||
|
commands.entity(*block).despawn(); |
||||||
|
} else if mouse_button_input.just_pressed(MouseButton::Right) { |
||||||
|
// Create a new block next to the one that was just clicked.
|
||||||
|
let pos = block_transform.translation.floor().as_ivec3(); |
||||||
|
// FIXME: This only works for axis-aligned normals.
|
||||||
|
let offset = hit.normal.normalize().round().as_ivec3(); |
||||||
|
blocks.spawn(pos + offset); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue