We lost the die, but I think we're close!

main
Elijah C. Voigt 1 year ago
parent ba19b6342e
commit df02314be2

@ -14,9 +14,11 @@ fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, add_texture)
.add_systems(Update, rotate_mesh.run_if(|keys: Res<ButtonInput<KeyCode>>| -> bool {
keys.pressed(KeyCode::Space)
}))
.add_systems(
Update,
rotate_mesh
.run_if(|keys: Res<ButtonInput<KeyCode>>| -> bool { keys.pressed(KeyCode::Space) }),
)
.run();
}
@ -83,30 +85,32 @@ fn add_texture(
["Up", "Down", "Left", "Right", "Top", "Bottom"]
.into_iter()
.for_each(|text| {
parent.spawn(NodeBundle {
style: Style {
height: Val::Percent(100.0 / 6.0),
width: Val::Percent(100.0),
justify_content: JustifyContent::Center,
justify_items: JustifyItems::Center,
align_items: AlignItems::Center,
align_content: AlignContent::Center,
..default()
},
..default()
}).with_children(|parent| {
parent.spawn(TextBundle {
text: Text::from_section(
text,
TextStyle {
color: Color::BLACK,
font_size: 64.0,
..default()
},
),
parent
.spawn(NodeBundle {
style: Style {
height: Val::Percent(100.0 / 6.0),
width: Val::Percent(100.0),
justify_content: JustifyContent::Center,
justify_items: JustifyItems::Center,
align_items: AlignItems::Center,
align_content: AlignContent::Center,
..default()
},
..default()
})
.with_children(|parent| {
parent.spawn(TextBundle {
text: Text::from_section(
text,
TextStyle {
color: Color::BLACK,
font_size: 64.0,
..default()
},
),
..default()
});
});
});
});
});
@ -130,31 +134,6 @@ fn add_texture(
}
{
let cube_size = 4.0;
let a = 1.0 / 6.0;
let b = 2.0 * a;
let c = 3.0 * a;
let d = 4.0 * a;
let e = 5.0 * a;
let f = 1.0;
let cuboid = Mesh::from(Cuboid::new(cube_size, cube_size, cube_size))
.with_inserted_attribute(
Mesh::ATTRIBUTE_UV_0,
vec![
// Top side
[1.0, 0.0], [0.0, 0.0], [0.0, a], [1.0, a],
// Bottom side
[1.0, a], [0.0, a], [0.0, b], [1.0, b],
// Right side
[1.0, b], [0.0, b], [0.0, c], [1.0, c],
// Left side
[1.0, c], [0.0, c], [0.0, d], [1.0, d],
// Back side
[1.0, d], [0.0, d], [0.0, e], [1.0, e],
// Front side
[1.0, e], [0.0, e], [0.0, f], [1.0, f],
]);
let mesh = meshes.add(cuboid);
let material = materials.add(StandardMaterial {
base_color_texture: Some(image_handle),
..default()
@ -178,13 +157,10 @@ fn add_texture(
}
}
fn rotate_mesh(
mut query: Query<&mut Transform, With<Handle<Mesh>>>,
time: Res<Time>,
) {
fn rotate_mesh(mut query: Query<&mut Transform, With<Handle<Mesh>>>, time: Res<Time>) {
query.iter_mut().for_each(|mut t| {
t.rotate_x(time.delta_seconds() * 0.5);
t.rotate_y(time.delta_seconds() * 0.5);
t.rotate_z(time.delta_seconds() * 0.5);
});
}
}

@ -7,12 +7,12 @@ impl Plugin for DicePlugin {
fn build(&self, app: &mut App) {
app.add_event::<DiceAction>();
app.add_systems(Startup, init_dice_ui);
app.add_systems(Startup, init_dice_cuboid.before(init_dice));
app.add_systems(Startup, init_dice);
app.add_systems(
Update,
button_emit_event::<DiceAction>.run_if(any_component_changed::<Interaction>),
);
app.add_systems(Update, draw_die.run_if(any_component_changed::<Die>));
app.add_systems(Update, roll_die.run_if(on_event::<DiceAction>()));
app.add_systems(Update, move_die.run_if(on_event::<KeyboardInput>()));
}
@ -23,6 +23,36 @@ enum DiceAction {
Roll,
}
#[rustfmt::skip]
fn init_dice_cuboid(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
// Store handle to mesh for later use
let cube_size = 1.0;
let a = 1.0 / 6.0;
let b = 2.0 * a;
let c = 3.0 * a;
let d = 4.0 * a;
let e = 5.0 * a;
let f = 1.0;
let cuboid = Mesh::from(Cuboid::new(cube_size, cube_size, cube_size)).with_inserted_attribute(
Mesh::ATTRIBUTE_UV_0,
vec![
// Top side
[1.0, 0.0], [0.0, 0.0], [0.0, a], [1.0, a],
// Bottom side
[1.0, a], [0.0, a], [0.0, b], [1.0, b],
// Right side
[1.0, b], [0.0, b], [0.0, c], [1.0, c],
// Left side
[1.0, c], [0.0, c], [0.0, d], [1.0, d],
// Back side
[1.0, d], [0.0, d], [0.0, e], [1.0, e],
// Front side
[1.0, e], [0.0, e], [0.0, f], [1.0, f],
],
);
commands.insert_resource(DiceCuboid { mesh: meshes.add(cuboid) });
}
/// Create UI for the Dice game at startup
fn init_dice_ui(mut commands: Commands) {
commands
@ -68,8 +98,6 @@ fn init_dice_ui(mut commands: Commands) {
}
fn init_dice(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut commands: Commands,
) {
[
@ -84,41 +112,13 @@ fn init_dice(
.spawn((
GameChoice::Dice,
MenuState::Closed,
Die::new(set),
PickableBundle { ..default() },
On::<Pointer<Drag>>::target_component_mut::<Transform>(|m, transform| {
transform.translation.x += m.delta.x;
transform.translation.y -= m.delta.y;
}),
))
.insert(MaterialMesh2dBundle {
mesh: meshes
.add(Rectangle {
half_size: Vec2::splat(32.0),
})
.into(),
material: materials.add(Color::PINK),
..default()
})
.insert(Text2dBundle {
text: Text::from_section(
"",
TextStyle {
color: Color::BLACK,
font_size: 32.0,
..default()
},
),
..default()
})
.insert(Transform::from_xyz(idx as f32 * 100.0, 100.0, 0.0));
});
}
fn draw_die(mut q: Query<(&Die, &mut Text), Changed<Die>>) {
q.iter_mut().for_each(|(d, mut t)| {
info!("Dice currently reads {:?}", d.get());
t.sections[0].value.replace_range(.., d.get());
.add(Die::new(set));
});
}
@ -175,6 +175,120 @@ struct Die {
top: usize,
}
#[derive(Resource)]
struct DiceCuboid {
mesh: Handle<Mesh>,
}
impl EntityCommand for Die {
fn apply(self, id: Entity, world: &mut World) {
info!("Applying entity command for die");
// Image we will render our texture to
let image = {
let size = Extent3d {
width: 256,
height: 256 * 6,
..default()
};
let mut image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size,
dimension: TextureDimension::D2,
format: TextureFormat::Bgra8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::TEXTURE_BINDING
| TextureUsages::COPY_DST
| TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
},
..default()
};
image.resize(size);
image
};
// Create image
let image_handle = world.resource_mut::<Assets<Image>>().add(image);
// Camera capturing a hidden scene rendered to a texture
let texture_camera = world
.spawn(Camera2dBundle {
camera: Camera {
order: -1,
target: RenderTarget::Image(image_handle.clone()),
..default()
},
..default()
})
.id();
// Scene being rendered to a texture
world.spawn((
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..default()
},
background_color: BackgroundColor(Color::GOLD),
..default()
},
TargetCamera(texture_camera),
))
.with_children(|parent| {
self.sides.iter().for_each(|text| {
parent
.spawn(NodeBundle {
style: Style {
height: Val::Percent(100.0 / 6.0),
width: Val::Percent(100.0),
justify_content: JustifyContent::Center,
justify_items: JustifyItems::Center,
align_items: AlignItems::Center,
align_content: AlignContent::Center,
..default()
},
..default()
})
.with_children(|parent| {
parent.spawn(TextBundle {
text: Text::from_section(
*text,
TextStyle {
color: Color::BLACK,
font_size: 64.0,
..default()
},
),
..default()
});
});
});
});
// Material used for this object
let this_material = world.resource_mut::<Assets<StandardMaterial>>().add(StandardMaterial {
base_color_texture: Some(image_handle),
..default()
});
let pbr_bundle = PbrBundle {
mesh: world.resource::<DiceCuboid>().mesh.clone(),
material: this_material,
..default()
};
world.entity_mut(id).insert((self, pbr_bundle));
}
}
impl Die {
/// Initialize all dice values
fn new(sides: [&'static str; 6]) -> Die {

@ -31,11 +31,12 @@ pub(crate) enum GameChoice {
/// Main game camera
fn init_camera(mut commands: Commands) {
commands.spawn(Camera2dBundle {
commands.spawn(Camera3dBundle {
camera: Camera {
clear_color: ClearColorConfig::Custom(Color::WHITE),
..default()
},
transform: Transform::from_xyz(10.0, 10.0, 10.0),
..default()
});
}

@ -1,10 +1,14 @@
pub(crate) use std::fmt::Debug;
/// Bevy imports
pub(crate) use bevy::ecs::system::EntityCommand;
pub(crate) use bevy::input::keyboard::KeyboardInput;
pub(crate) use bevy::input::ButtonState;
/// Bevy imports
pub(crate) use bevy::prelude::*;
pub(crate) use bevy::render::camera::RenderTarget;
pub(crate) use bevy::render::render_resource::{
Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
};
pub(crate) use bevy::sprite::MaterialMesh2dBundle;
/// Bevy Plugins

Loading…
Cancel
Save