-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworld.rs
118 lines (109 loc) · 3.8 KB
/
world.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use super::{sim::ConwayGol, CameraRotation, CubeInd, GameTimer, Paused, BOARD_SIZE, CUBE_SPACING};
use bevy::prelude::*;
/// Creates one-time world assets like the camera, sky, and sun.
pub fn setup_world(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let offset = BOARD_SIZE as f32;
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(8., 8., 0.).looking_at(Vec3::ZERO, Vec3::Y),
..Camera3dBundle::default()
},
CameraRotation::default(),
));
// A dome around the world to reflect back the sun
commands.spawn(PbrBundle {
mesh: meshes.add(Sphere::new(offset * 8.)),
material: materials.add(StandardMaterial {
base_color: Color::rgb(0.2, 0.2, 0.2),
perceptual_roughness: 0.08,
cull_mode: None,
double_sided: true,
..default()
}),
..default()
});
// The sun
commands.spawn(PointLightBundle {
point_light: PointLight {
color: Color::WHITE,
intensity: 12_000_000_000.,
range: offset * 8.,
..default()
},
transform: Transform::from_xyz(-offset, offset, -offset * 2.),
..default()
});
}
/// Builds the Game of Life simulation and sets up the geometries used
/// to render it.
pub fn init_conway_grid(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Oversize the board to make the edges look more alive
let gol = ConwayGol::build_rand(BOARD_SIZE * 2)
.expect("Conway grid must initialize in order to continue");
let cube_mesh = meshes.add(Cuboid::new(2., 2., 2.));
let cube_mat = materials.add(StandardMaterial {
base_color: Color::WHITE,
..default()
});
commands
.spawn_empty()
.insert(gol)
.insert(Paused(true))
.insert(GameTimer::default())
.insert(Transform::default())
.insert(GlobalTransform::default())
.insert(InheritedVisibility::default())
.with_children(|parent| {
let middle_cube = BOARD_SIZE as f32 / 2.;
let board_offset = BOARD_SIZE / 2;
let live_region = board_offset..(BOARD_SIZE + board_offset);
for row in live_region.clone() {
for col in live_region.clone() {
let x = CUBE_SPACING * (middle_cube - (row - board_offset) as f32);
let z = CUBE_SPACING * (middle_cube - (col - board_offset) as f32);
parent.spawn((
PbrBundle {
// resource handles have cheap clone
mesh: cube_mesh.clone(),
material: cube_mat.clone(),
transform: Transform::from_xyz(x, 0., z),
..Default::default()
},
CubeInd { row, col },
));
}
}
});
}
/// Every time the timer completes, computes the next Game of Life board
/// state and updates resources controlled by the simulation.
pub fn next_game_tick(
mut game_state: Query<(&mut ConwayGol, &Paused, &mut GameTimer)>,
mut cubes: Query<(&mut Visibility, &CubeInd)>,
time: Res<Time>,
) {
let (mut game_state, sim, mut timer) = game_state.single_mut();
if !timer.0.tick(time.delta()).finished() {
return;
}
if sim.is_paused() {
return;
}
game_state.tick();
let board = game_state.board();
for (mut vis, pos) in &mut cubes {
*vis = if board[pos.row][pos.col] {
Visibility::Visible
} else {
Visibility::Hidden
};
}
}