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() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, add_texture) .add_systems(Startup, add_texture)
.add_systems(Update, rotate_mesh.run_if(|keys: Res<ButtonInput<KeyCode>>| -> bool { .add_systems(
keys.pressed(KeyCode::Space) Update,
})) rotate_mesh
.run_if(|keys: Res<ButtonInput<KeyCode>>| -> bool { keys.pressed(KeyCode::Space) }),
)
.run(); .run();
} }
@ -83,30 +85,32 @@ fn add_texture(
["Up", "Down", "Left", "Right", "Top", "Bottom"] ["Up", "Down", "Left", "Right", "Top", "Bottom"]
.into_iter() .into_iter()
.for_each(|text| { .for_each(|text| {
parent.spawn(NodeBundle { parent
style: Style { .spawn(NodeBundle {
height: Val::Percent(100.0 / 6.0), style: Style {
width: Val::Percent(100.0), height: Val::Percent(100.0 / 6.0),
justify_content: JustifyContent::Center, width: Val::Percent(100.0),
justify_items: JustifyItems::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, justify_items: JustifyItems::Center,
align_content: AlignContent::Center, align_items: AlignItems::Center,
..default() 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() ..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 { let material = materials.add(StandardMaterial {
base_color_texture: Some(image_handle), base_color_texture: Some(image_handle),
..default() ..default()
@ -178,13 +157,10 @@ fn add_texture(
} }
} }
fn rotate_mesh( fn rotate_mesh(mut query: Query<&mut Transform, With<Handle<Mesh>>>, time: Res<Time>) {
mut query: Query<&mut Transform, With<Handle<Mesh>>>,
time: Res<Time>,
) {
query.iter_mut().for_each(|mut t| { query.iter_mut().for_each(|mut t| {
t.rotate_x(time.delta_seconds() * 0.5); t.rotate_x(time.delta_seconds() * 0.5);
t.rotate_y(time.delta_seconds() * 0.5); t.rotate_y(time.delta_seconds() * 0.5);
t.rotate_z(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) { fn build(&self, app: &mut App) {
app.add_event::<DiceAction>(); app.add_event::<DiceAction>();
app.add_systems(Startup, init_dice_ui); 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(Startup, init_dice);
app.add_systems( app.add_systems(
Update, Update,
button_emit_event::<DiceAction>.run_if(any_component_changed::<Interaction>), 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, roll_die.run_if(on_event::<DiceAction>()));
app.add_systems(Update, move_die.run_if(on_event::<KeyboardInput>())); app.add_systems(Update, move_die.run_if(on_event::<KeyboardInput>()));
} }
@ -23,6 +23,36 @@ enum DiceAction {
Roll, 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 /// Create UI for the Dice game at startup
fn init_dice_ui(mut commands: Commands) { fn init_dice_ui(mut commands: Commands) {
commands commands
@ -68,8 +98,6 @@ fn init_dice_ui(mut commands: Commands) {
} }
fn init_dice( fn init_dice(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut commands: Commands, mut commands: Commands,
) { ) {
[ [
@ -84,41 +112,13 @@ fn init_dice(
.spawn(( .spawn((
GameChoice::Dice, GameChoice::Dice,
MenuState::Closed, MenuState::Closed,
Die::new(set),
PickableBundle { ..default() }, PickableBundle { ..default() },
On::<Pointer<Drag>>::target_component_mut::<Transform>(|m, transform| { On::<Pointer<Drag>>::target_component_mut::<Transform>(|m, transform| {
transform.translation.x += m.delta.x; transform.translation.x += m.delta.x;
transform.translation.y -= m.delta.y; transform.translation.y -= m.delta.y;
}), }),
)) ))
.insert(MaterialMesh2dBundle { .add(Die::new(set));
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());
}); });
} }
@ -175,6 +175,120 @@ struct Die {
top: usize, 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 { impl Die {
/// Initialize all dice values /// Initialize all dice values
fn new(sides: [&'static str; 6]) -> Die { fn new(sides: [&'static str; 6]) -> Die {

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

@ -1,10 +1,14 @@
pub(crate) use std::fmt::Debug; pub(crate) use std::fmt::Debug;
/// Bevy imports
pub(crate) use bevy::ecs::system::EntityCommand; pub(crate) use bevy::ecs::system::EntityCommand;
pub(crate) use bevy::input::keyboard::KeyboardInput; pub(crate) use bevy::input::keyboard::KeyboardInput;
pub(crate) use bevy::input::ButtonState; pub(crate) use bevy::input::ButtonState;
/// Bevy imports
pub(crate) use bevy::prelude::*; 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; pub(crate) use bevy::sprite::MaterialMesh2dBundle;
/// Bevy Plugins /// Bevy Plugins

Loading…
Cancel
Save