Working Purple Rain
commit
4d604add7a
@ -0,0 +1 @@
|
||||
/target
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "purple_rain"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.19"
|
||||
env_logger = "0.9.0"
|
||||
log = "0.4.17"
|
||||
pixels = "0.9.0"
|
||||
rand = "0.8.5"
|
||||
timer = "0.2.0"
|
||||
winit = "0.26.1"
|
||||
winit_input_helper = "0.12.0"
|
||||
|
||||
|
||||
@ -0,0 +1,126 @@
|
||||
use chrono::Duration;
|
||||
use log::error;
|
||||
use pixels::{Pixels, SurfaceTexture};
|
||||
use rand::Rng;
|
||||
use timer::Timer;
|
||||
use winit::{
|
||||
dpi::LogicalSize,
|
||||
event::{Event, VirtualKeyCode},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
use winit_input_helper::WinitInputHelper;
|
||||
|
||||
const WIDTH: u32 = 400;
|
||||
const HEIGHT: u32 = 300;
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let event_loop = EventLoop::new();
|
||||
let mut input = WinitInputHelper::new();
|
||||
|
||||
let window = {
|
||||
let size = LogicalSize::new(WIDTH as f64, HEIGHT as f64);
|
||||
let scaled_size = LogicalSize::new(WIDTH as f64 * 3.0, HEIGHT as f64 * 3.0);
|
||||
WindowBuilder::new()
|
||||
.with_title("Purple Rain")
|
||||
.with_inner_size(scaled_size)
|
||||
.with_min_inner_size(size)
|
||||
.build(&event_loop)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let mut pixels = {
|
||||
let window_size = window.inner_size();
|
||||
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
|
||||
Pixels::new(WIDTH, HEIGHT, surface_texture)
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
let mut drops = Vec::new();
|
||||
let mut rng = rand::thread_rng();
|
||||
for _i in 0..200 {
|
||||
drops.push(Drop {
|
||||
x: (rng.gen_range(0..WIDTH as i32)),
|
||||
y: (rng.gen_range(0..HEIGHT as i32)),
|
||||
z: (rng.gen_range(1..20)),
|
||||
})
|
||||
}
|
||||
|
||||
let timer = Timer::new();
|
||||
let guard = timer.schedule_repeating(Duration::milliseconds(10), move || {
|
||||
window.request_redraw();
|
||||
});
|
||||
guard.ignore();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
if let Event::RedrawRequested(_) = event {
|
||||
draw(&mut drops, pixels.get_frame());
|
||||
if pixels
|
||||
.render()
|
||||
.map_err(|e| error!("pixels.render() failed: {}", e))
|
||||
.is_err()
|
||||
{
|
||||
*control_flow = ControlFlow::Exit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if input.update(&event) {
|
||||
if input.key_pressed(VirtualKeyCode::Escape) || input.key_pressed(VirtualKeyCode::Q) || input.quit() {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
return;
|
||||
} else if input.key_pressed(VirtualKeyCode::Space) {
|
||||
//window.request_redraw();
|
||||
}
|
||||
|
||||
// Resize the window
|
||||
if let Some(size) = input.window_resized() {
|
||||
pixels.resize_surface(size.width, size.height);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn draw(drops: &mut Vec<Drop>, frame: &mut [u8]) {
|
||||
let pixels = frame.chunks_exact_mut(4);
|
||||
for pixel in pixels {
|
||||
pixel.copy_from_slice(&[0xd3, 0xb7, 0xf7, 0xff]);
|
||||
}
|
||||
|
||||
drops.iter_mut().for_each(|d| d.update());
|
||||
|
||||
for drop in drops {
|
||||
let mut drawn = false;
|
||||
for y in drop.y..(drop.y + drop.z) {
|
||||
for x in drop.x..(drop.x + drop.z/4) {
|
||||
let res = (y * (WIDTH as i32) * 4 + x * 4).try_into();
|
||||
if res.is_ok() {
|
||||
let i = res.unwrap();
|
||||
|
||||
if i < frame.len() {
|
||||
drawn = true;
|
||||
frame[i..i + 4].copy_from_slice(&[207, 100, 219, 0xff]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !drawn {
|
||||
drop.y = -drop.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Drop {
|
||||
x: i32,
|
||||
y: i32,
|
||||
z: i32,
|
||||
}
|
||||
|
||||
impl Drop {
|
||||
fn update(&mut self) {
|
||||
self.y += std::cmp::max(self.z/4, 1);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue