Compare commits

...

5 Commits

Author SHA1 Message Date
annieversary 9731315e98 subtitled #14: doom fire 2021-09-07 23:07:18 +02:00
annieversary 858ed70ab4 updated 13 to not show ants 2021-09-04 21:45:10 +02:00
annieversary d333c9c9d6 subtitled #13: goop eating ants 2021-09-03 18:59:19 +02:00
annieversary 45fbe5a37f subtitled #12 2021-09-01 20:01:22 +02:00
annieversary 7506d4907f m 11 2021-09-01 20:00:54 +02:00
14 changed files with 406 additions and 6 deletions

42
Cargo.lock generated
View File

@ -1188,6 +1188,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "libm"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
name = "line_drawing"
version = "0.7.0"
@ -1649,6 +1655,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
"libm",
]
[[package]]
@ -2027,6 +2034,16 @@ dependencies = [
"getrandom 0.2.3",
]
[[package]]
name = "rand_distr"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "051b398806e42b9cd04ad9ec8f81e355d0a382c543ac6672c62f5a5b452ef142"
dependencies = [
"num-traits",
"rand 0.8.4",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
@ -2364,6 +2381,31 @@ dependencies = [
"utils",
]
[[package]]
name = "subtitled12"
version = "0.1.0"
dependencies = [
"nannou",
"rand_distr",
"utils",
]
[[package]]
name = "subtitled13"
version = "0.1.0"
dependencies = [
"nannou",
"utils",
]
[[package]]
name = "subtitled14"
version = "0.1.0"
dependencies = [
"nannou",
"utils",
]
[[package]]
name = "subtitled2"
version = "0.1.0"

BIN
assets/images/blahaj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

BIN
assets/images/dowom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/images/goop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
assets/images/uwu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -109,16 +109,20 @@ fn view(app: &App, model: &Model, frame: Frame) {
// rotate
let v = rot(t) * v;
// project onto xz plane cause it's the coolest one
100.0 * vec2(v.x, v.z)
50.0 * vec2(v.x + v.y, v.z + v.w)
})
.collect::<Vec<_>>();
// make all pairs of points
let p = p
for (i, (&a, &b)) in p
.iter()
.enumerate()
.flat_map(|(i, a)| p[i + 1..].iter().map(move |b| (a, b)));
for (&a, &b) in p {
draw.line().points(a, b).color(BLACK);
// make all pairs of points
.flat_map(|(i, a)| p[i + 1..].iter().map(move |b| (a, b)))
.enumerate()
{
if i % 2 != 0 {
draw.line().points(a, b).color(BLACK);
}
}
draw.to_frame(app, &frame).unwrap();

View File

@ -0,0 +1,9 @@
[package]
name = "subtitled12"
version = "0.1.0"
edition = "2018"
[dependencies]
nannou = "0.17"
rand_distr = "0.4.1"
utils = { path = "../utils" }

View File

@ -0,0 +1,67 @@
use nannou::prelude::*;
use nannou::rand::prelude::*;
use rand_distr::Normal;
use utils::*;
fn main() {
nannou::app(model).update(update).simple_window(view).run();
}
struct Model {
lines: Vec<Vec<Vec2>>,
}
fn lines(max_width: f32) -> Vec<Vec<Vec2>> {
let normal = Normal::new(0.0, 0.2).unwrap();
(0..20)
.map(|_| {
let mut line = vec![Vec2::Y];
// generate the y coordinates for all points
let n = random_range(4, 12);
let mut ys = (0..n).map(|_| random_range(-1.0, 1.0)).collect::<Vec<_>>();
ys.sort_by(|a, b| b.partial_cmp(a).unwrap());
// make the actual points and add them to the vec
for y in ys {
let w = map_range(1.0 - y.abs(), 0.0, 1.0, 0.01, max_width);
let x = nannou::rand::thread_rng().sample::<f32, _>(normal) * w;
line.push(vec2(x, y));
}
line.push(-Vec2::Y);
line
})
.collect()
}
fn model(_app: &App) -> Model {
Model { lines: lines(0.0) }
}
fn update(app: &App, model: &mut Model, _update: Update) {
let t = app.elapsed_frames() as f32 / 60.0;
if app.elapsed_frames() % 2 == 0 {
model.lines = lines(map_sin(t, 0.1, 1.0));
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let _t = frame.nth() as f32 / 60.0;
let draw = app.draw();
draw.background().color(BLACK);
for line in &model.lines {
draw.polyline()
.stroke_weight(1.0)
.points(line.iter().map(|v| *v * 300.0))
.color(PINK);
}
draw.to_frame(app, &frame).unwrap();
utils::record::record(app, &frame);
}

View File

@ -0,0 +1,8 @@
[package]
name = "subtitled13"
version = "0.1.0"
edition = "2018"
[dependencies]
nannou = "0.17"
utils = { path = "../utils" }

View File

@ -0,0 +1,94 @@
use nannou::prelude::*;
use utils::*;
fn main() {
nannou::app(model).update(update).simple_window(view).run();
}
struct Model {
walkers: Vec<Vec2>,
clustered: Vec<Vec2>,
}
fn model(_app: &App) -> Model {
Model {
walkers: (0..5000).map(|_| vec2_range(-1.0, 1.0) * 300.0).collect(),
clustered: vec![Vec2::ZERO],
}
}
fn update(app: &App, model: &mut Model, _update: Update) {
let _t = app.elapsed_frames() as f32 / 60.0;
// sort them by x to be a bit more efficient with the collision detection
model
.clustered
.sort_by(|a, b| a.x.partial_cmp(&b.x).unwrap());
let clusters = model.clustered.clone();
let mut to_remove = vec![];
for (i, p) in &mut model.walkers.iter_mut().enumerate() {
*p += vec2_range(-1.0, 1.0) * 3.5 + 0.5 * vec2(p.y, -p.x).normalize();
const RAD: f32 = 6.0;
for &c in &clusters {
// skip the ones outside the x range
if c.x < p.x - RAD {
continue;
}
if c.x > p.x + RAD {
break;
}
// if it's colliding, make it be a clustered point
if p.distance_squared(c) < RAD * RAD {
model.clustered.push(*p);
to_remove.push(i);
break;
}
}
}
// remove the ones that have become clustered
// backwards cause otherwise you shift the indexes
for i in to_remove.into_iter().rev() {
model.walkers.remove(i);
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let t = frame.nth() as f32 / 60.0;
let draw = app.draw();
drawing::draw_soft_bg(&draw, app, SNOW, 1.0);
for &p in &model.clustered {
let v = map_sin(t + (p.x.powi(2) + p.y.powi(2) + t) * 0.00003, -20.0, 20.0);
let h = (100.0 + v) / 360.0;
draw.ellipse().xy(p).radius(4.0).color(hsl(h, 0.5, 0.5));
}
for &p in &model.walkers {
draw.ellipse().xy(p).radius(0.0).color(BLACK);
}
// use nannou::rand::seq::SliceRandom;
// let mut rng = nannou::rand::thread_rng();
// let n = (frame.nth() as f32 * 0.7) as usize;
// for _ in 0..n {
// let a = model.clustered.choose(&mut rng);
// let b = model.clustered.choose(&mut rng);
// if let (Some(&a), Some(&b)) = (a, b) {
// let v = map_sin(t * 2.0 + a.x * a.y, -20.0, 20.0);
// let h = (100.0 + v) / 360.0;
// draw.line()
// .stroke_weight(3.0)
// .points(a, b)
// .color(hsla(h, 0.5, 0.5, 0.04));
// }
// }
draw.to_frame(app, &frame).unwrap();
utils::record::record(app, &frame);
}

View File

@ -0,0 +1,8 @@
[package]
name = "subtitled14"
version = "0.1.0"
edition = "2018"
[dependencies]
nannou = "0.17"
utils = { path = "../utils" }

View File

@ -0,0 +1,152 @@
use nannou::prelude::*;
// use utils::*;
// from https://fabiensanglard.net/doom_fire_psx/
fn main() {
nannou::app(model).update(update).simple_window(view).run();
}
struct Model {
fire: Vec<Vec<f32>>,
colors: Vec<Rgb8>,
uwu: wgpu::Texture,
}
const WIDTH: usize = 400;
const HEIGHT: usize = 300;
const BALL_SIZE: f32 = 3.0;
fn model(app: &App) -> Model {
let fire = vec![vec![0.0; WIDTH]; HEIGHT];
let colors = vec![
(0x07, 0x07, 0x07),
(0x1F, 0x07, 0x07),
(0x2F, 0x0F, 0x07),
(0x47, 0x0F, 0x07),
(0x57, 0x17, 0x07),
(0x67, 0x1F, 0x07),
(0x77, 0x1F, 0x07),
(0x8F, 0x27, 0x07),
(0x9F, 0x2F, 0x07),
(0xAF, 0x3F, 0x07),
(0xBF, 0x47, 0x07),
(0xC7, 0x47, 0x07),
(0xDF, 0x4F, 0x07),
(0xDF, 0x57, 0x07),
(0xDF, 0x57, 0x07),
(0xD7, 0x5F, 0x07),
(0xD7, 0x5F, 0x07),
(0xD7, 0x67, 0x0F),
(0xCF, 0x6F, 0x0F),
(0xCF, 0x77, 0x0F),
(0xCF, 0x7F, 0x0F),
(0xCF, 0x87, 0x17),
(0xC7, 0x87, 0x17),
(0xC7, 0x8F, 0x17),
(0xC7, 0x97, 0x1F),
(0xBF, 0x9F, 0x1F),
(0xBF, 0x9F, 0x1F),
(0xBF, 0xA7, 0x27),
(0xBF, 0xA7, 0x27),
(0xBF, 0xAF, 0x2F),
(0xB7, 0xAF, 0x2F),
(0xB7, 0xB7, 0x2F),
(0xB7, 0xB7, 0x37),
(0xCF, 0xCF, 0x6F),
(0xDF, 0xDF, 0x9F),
(0xEF, 0xEF, 0xC7),
(0xFF, 0xFF, 0xFF),
]
.into_iter()
.map(|c| c.into())
.collect();
let assets = app.assets_path().unwrap();
let img_path = assets.join("images").join("blahaj.png");
let uwu = wgpu::Texture::from_path(app, img_path).unwrap();
let mut model = Model { fire, colors, uwu };
// presimulate fire
for _ in 0..400 {
advance(app, &mut model);
}
model
}
fn update(app: &App, model: &mut Model, _update: Update) {
let _t = app.elapsed_frames() as f32 / 60.0;
advance(app, model);
}
fn advance(app: &App, model: &mut Model) {
let (w, h) = app.window_rect().w_h();
let cols = (w / BALL_SIZE) as usize;
let rows = (h / BALL_SIZE) as usize - 50;
if app.elapsed_frames() > 200 {
for i in 0..cols {
model.fire[rows][i] = 0.0;
}
} else {
for i in 0..cols {
model.fire[rows][i] = 36.0;
}
}
for x in 0..cols {
for y in 0..rows {
let disp = random_range(0, 2);
model.fire[y][(x + disp) % cols] = model.fire[y + 1][x] - random_range(0., 1.0);
}
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let _t = frame.nth() as f32 / 60.0;
let draw = app.draw();
draw.background().color(BLACK);
draw.texture(&model.uwu)
.w_h(400.0, 282.6)
.y((-200.0 + frame.nth() as f32).min(0.0));
let (l, top, w, h) = app.window_rect().l_t_w_h();
let cols = w / BALL_SIZE;
let rows = h / BALL_SIZE;
for (i, row) in model.fire.iter().enumerate() {
for (j, c) in row.iter().enumerate() {
let col_index = c.max(0.0).trunc() as usize % model.colors.len();
if i as f32 <= rows && j as f32 <= cols && col_index != 0 {
let x = l + j as f32 * BALL_SIZE;
let y = top - i as f32 * BALL_SIZE;
let p = vec2(x, y);
let r = BALL_SIZE;
// * map_range(i as f32, 0 as f32, rows, 0., 1.0)
// * random_range(0.9, 1.1);
draw.quad()
.points(
p + r * vec2(1., 1.),
p + r * vec2(1., -1.),
p + r * vec2(-1., -1.),
p + r * vec2(-1., 1.),
)
.xy(p)
.color(model.colors[col_index]);
}
}
}
draw.to_frame(app, &frame).unwrap();
utils::record::record(app, &frame);
}

View File

@ -1,5 +1,17 @@
use nannou::{color::IntoLinSrgba, draw::properties::ColorScalar, prelude::*};
pub fn draw_soft_bg(draw: &Draw, app: &App, color: impl IntoLinSrgba<ColorScalar>, alpha: f32) {
if app.elapsed_frames() <= 1 {
draw.background().color(color);
} else {
let mut color = color.into_lin_srgba();
color.alpha = alpha;
let win = app.window_rect();
draw.rect().wh(win.wh()).color(color);
}
}
/// Draws the opposite of a box
pub fn draw_exterior(draw: &Draw, size: f32, color: impl IntoLinSrgba<ColorScalar> + Clone) {
draw.quad()

View File

@ -42,3 +42,7 @@ impl Tup2Extension for (f32, f32) {
self.into()
}
}
pub fn vec2_range(min: f32, max: f32) -> Vec2 {
vec2(random_range(min, max), random_range(min, max))
}