#[cfg(not(target_arch = "wasm32"))] fn main() { example::main(); } #[cfg(target_arch = "wasm32")] fn main() { println!("This example is not supported on WebAssembly"); } #[cfg(not(target_arch = "wasm32"))] mod example { extern crate lazy_static; extern crate minifb; extern crate pest; extern crate pest_derive; extern crate rand; extern crate regex; use minifb::{Key, KeyRepeat, Window, WindowOptions}; use std::{thread, time}; const WIDTH: usize = 100; const HEIGHT: usize = 200; pub fn main() { let mut window = Window::new( "Test - ESC to exit", WIDTH, HEIGHT, WindowOptions::default(), ) .unwrap_or_else(|e| { panic!("{}", e); }); let mut context = throne::ContextBuilder::new() .text(include_str!("blocks.throne")) .build() .unwrap_or_else(|e| panic!("{}", e)); let kd = context.str_to_atom("kd"); let ku = context.str_to_atom("ku"); let kp = context.str_to_atom("kp"); let left = context.str_to_atom("left"); let right = context.str_to_atom("right"); let up = context.str_to_atom("up"); let down = context.str_to_atom("down"); while window.is_open() && !window.is_key_down(Key::Escape) { context.push_state("#tick"); context.push_state("dt 3"); // context.print(); let string_to_key = |s: &throne::Atom| match s { s if *s == left => Some(Key::Left), s if *s == right => Some(Key::Right), s if *s == up => Some(Key::Up), s if *s == down => Some(Key::Down), _ => None, }; context .update_with_side_input(|p: &throne::Phrase| { if p.len() != 2 { return None; } match &p[0].atom { a if *a == kd => string_to_key(&p[1].atom).and_then(|k| { if window.is_key_down(k) { Some(p.to_vec()) } else { None } }), a if *a == ku => string_to_key(&p[1].atom).and_then(|k| { if !window.is_key_down(k) { Some(p.to_vec()) } else { None } }), a if *a == kp => string_to_key(&p[1].atom).and_then(|k| { if window.is_key_pressed(k, KeyRepeat::Yes) { Some(p.to_vec()) } else { None } }), _ => None, } }) .unwrap(); let mut buffer: Vec = vec![0; WIDTH * HEIGHT]; let is_valid_pos = |x, y| x < WIDTH as i32 && y < HEIGHT as i32; for phrase_id in context.core.state.iter() { let p = context.core.state.get(phrase_id); match ( p.get(0).and_then(|t| t.as_str(&context.string_cache)), p.get(2).and_then(|t| t.as_integer()), p.get(3).and_then(|t| t.as_integer()), ) { (Some("block-falling"), Some(x), Some(y)) | (Some("block-set"), Some(x), Some(y)) => { let color = 0x00b27474; let x0 = x * 10; let x1 = x0 + 10; let y0 = y * 10; let y1 = y0 + 10; for y in y0..y1 { for x in x0..x1 { if is_valid_pos(x, y) { let idx = x + WIDTH as i32 * (HEIGHT as i32 - 1 - y); buffer[idx as usize] = color; } } } } _ => (), } } // We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way window.update_with_buffer(&buffer, WIDTH, HEIGHT).unwrap(); thread::sleep(time::Duration::from_millis(33)); } } }