Skip to content
Snippets Groups Projects
Commit d553505d authored by Finn Bear's avatar Finn Bear
Browse files

Conway progress.

parent 51c5f2f8
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,7 @@ macro_rules! img {
#[macro_export]
macro_rules! ctx_img {
($ctx: expr, $name: literal) => {{
$ctx.load_texture($name, img!($name))
$ctx.load_texture($name, crate::img!($name))
}};
}
......
src/image/conway_portrait.png

57.4 KiB

use crate::egui::Align2;
use crate::slide::Slide;
use crate::{ctx_img, img, Margin};
use eframe::egui;
use eframe::egui::{Frame, Ui, Vec2, Window};
use crate::{ctx_img, Margin};
use eframe::egui::{Frame, TextureHandle, Ui, Vec2, Window};
/// The first slide in the cartoon.
#[derive(Default)]
pub struct Title {
examples: Vec<egui::TextureHandle>,
examples: Vec<TextureHandle>,
}
impl Slide for Title {
......
use crate::color::set_alpha;
use crate::component::arrow::Arrow;
use crate::component::grid::Grid;
use crate::egui::Context;
use crate::fade_in::fade_in_manual;
use crate::ctx_img;
use crate::egui::{Align2, Context, TextureHandle, Vec2, Window};
use crate::fade_in::{fade_in, fade_in_manual};
use crate::governor::Governor;
use crate::slide::Slide;
use eframe::egui::style::Margin;
......@@ -18,6 +19,8 @@ pub struct Automata {
state: AutomataState,
/// For knowing when to advance the simulation.
governor: Governor,
/// John Conway portrait, loaded lazily.
conway_portrait: Option<TextureHandle>,
}
#[derive(Default)]
......@@ -31,6 +34,8 @@ enum AutomataState {
alive: Option<f64>,
/// When started fading in "alive" arrow.
dead: Option<f64>,
/// When rules started fading in.
rules: Option<f64>,
},
/// Simulation.
Life,
......@@ -65,6 +70,7 @@ impl Default for Automata {
life,
state: AutomataState::default(),
governor: Governor::default(),
conway_portrait: None,
}
}
}
......@@ -76,6 +82,7 @@ impl Slide for Automata {
self.state = AutomataState::Static {
alive: None,
dead: None,
rules: None,
};
let mut rng = ChaCha8Rng::seed_from_u64(123456789876543216);
......@@ -89,12 +96,14 @@ impl Slide for Automata {
}
}
}
AutomataState::Static { alive, dead } => {
// Enable arrows one by one.
AutomataState::Static { alive, dead, rules } => {
// Enable arrows/text one by one.
if alive.is_none() {
*alive = Some(ctx.input().time);
} else if dead.is_none() {
*dead = Some(ctx.input().time);
} else if rules.is_none() {
*rules = Some(ctx.input().time)
} else {
self.state = AutomataState::Life;
}
......@@ -111,22 +120,66 @@ impl Slide for Automata {
});
});
// TODO: Fade/move/position as appropriate.
Window::new("portrait")
.title_bar(false)
.resizable(false)
.frame(Frame::window(&ui.style()).margin(Margin::same(5.0)))
.show(ui.ctx(), |ui| {
ui.image(
self.conway_portrait
.get_or_insert_with(|| ctx_img!(ui.ctx(), "conway_portrait.png")),
Vec2::splat(128.0),
);
});
// Need to continuously animate the grid, or at least poll the governor.
ui.ctx().request_repaint();
// If [`None`], don't show rules. If [`Some`], fade in rules as if they started fading in
// at this time.
let mut rules_fade: Option<f64> = None;
// How much grid goes left and rules go right.
const HORIZONTAL_OFFSET: f32 = 250.0;
match &self.state {
AutomataState::Empty => {}
AutomataState::Static { .. } => {}
AutomataState::Static { rules, .. } => {
if let &Some(rules) = rules {
let elapsed = ui.ctx().input().time - rules;
self.life.offset_x = (elapsed as f32 * -400.0).max(-HORIZONTAL_OFFSET);
rules_fade = Some(rules);
}
}
AutomataState::Life => {
// Iterate grid ~5 times a second.
if self.governor.ready(ui.ctx().input().time, 0.2) {
self.life = conways_game_of_life(&self.life);
}
// Kludge to render rules with full opacity.
rules_fade = Some(0.0);
}
}
if let Some(rules_fade) = rules_fade {
fade_in(ui, rules_fade, |ui| {
Window::new("conway_rules")
.frame(Frame::window(&ui.ctx().style()))
.anchor(Align2::CENTER_CENTER, Vec2::new(HORIZONTAL_OFFSET, 0.0))
.title_bar(false)
.resizable(false)
.show(ui.ctx(), |ui| {
ui.label(" ⏵ Cells with fewer than two neighbors die");
ui.label(" ⏵ Cells with more than three neighbors die");
ui.label(" ⏵ Cells with three neighbors become alive");
});
});
}
self.life.show_with_overlays(ui.ctx(), |ui, to_screen| {
if let &AutomataState::Static { alive, dead } = &self.state {
if let &AutomataState::Static { alive, dead, .. } = &self.state {
if let Some(alive) = alive {
fade_in_manual(ui, alive, |ui, alpha| {
let color = set_alpha(Color32::GREEN, alpha);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment