-use rand::Rng;
-use sdl2::event::Event;
-use sdl2::EventPump;
-use sdl2::keyboard::Keycode;
-use sdl2::pixels::Color;
-use sdl2::render::BlendMode;
-use sdl2::render::Canvas;
-use sdl2::video::Window;
-
-use {SCREEN_HEIGHT, SCREEN_WIDTH};
-use boll::*;
-use common::Point2D;
-use sprites::SpriteManager;
-use NS_PER_FRAME;
-use point; // defined in common, but loaded from main...
-
-pub type Nanoseconds = u64;
-
-pub struct App {
- pub canvas: Canvas<Window>,
- pub event_pump: EventPump,
- pub sprites: SpriteManager,
- pub state: Box<AppState>,
-}
-
-impl App {
- pub fn new() -> App {
- let context = sdl2::init().unwrap();
- sdl2::image::init(sdl2::image::InitFlag::PNG).unwrap();
- let window = context.video().unwrap().window("SDL test", SCREEN_WIDTH, SCREEN_HEIGHT)
- .position_centered()
- .opengl()
- .build()
- .unwrap();
- context.mouse().show_cursor(false);
- let mut canvas = window.into_canvas().build().unwrap();
- canvas.set_blend_mode(BlendMode::Add);
- canvas.set_draw_color(Color::RGB(0, 0, 0));
- canvas.clear();
- canvas.present();
- let event_pump = context.event_pump().unwrap();
- let sprites = SpriteManager::new(canvas.texture_creator());
- App {
- canvas,
- event_pump,
- sprites,
- state: Box::new(ActiveState::new()),
- }
- }
-
- pub fn load_sprites(&mut self, sprites: &[(&'static str, &str)]) {
- for (name, file) in sprites {
- self.sprites.load(name, file);
- }
- }
-}
-
-pub trait AppState {
- fn update(&mut self, dt: Nanoseconds);
- fn render(&self, canvas: &mut Canvas<Window>);
- fn leave(&self);
- fn on_event(&mut self, event: Event);
-}
-
-type Bollar = Vec<Box<dyn Boll>>;
-
-pub struct ActiveState {
- bolls: Bollar,
- boll_size: u32,
-}
-
-impl ActiveState {
- fn new() -> ActiveState {
- ActiveState {
- bolls: Bollar::new(),
- boll_size: 1,
- }
- }
-
- fn change_boll_count(&mut self, delta: i32) {
- if delta > 0 {
- for _i in 0..delta {
- self.add_boll();
- }
- } else if delta < 0 {
- for _i in 0..delta {
- self.bolls.pop();
- }
- }
- }
-
- fn add_boll(&mut self) {
- let mut rng = rand::thread_rng();
- self.bolls.push(Box::new(SquareBoll {
- pos: point!(rng.gen_range(0, SCREEN_WIDTH) as f64, rng.gen_range(0, SCREEN_HEIGHT) as f64),
- vel: point!(rng.gen_range(-2.0, 2.0), rng.gen_range(-2.0, 2.0)),
- }));
- }
-}
-
-impl AppState for ActiveState {
- fn update(&mut self, dt: Nanoseconds) {
- for b in &mut self.bolls {
- b.update();
- }
-
- match dt {
- ns if ns < (NS_PER_FRAME - 90_0000) as u64 => { self.change_boll_count(100) }
- ns if ns > (NS_PER_FRAME + 90_0000) as u64 => { self.change_boll_count(-100) }
- _ => {}
- }
- }
-
- fn render(&self, canvas: &mut Canvas<Window>) {
- for b in &self.bolls {
- b.draw(canvas, self.boll_size);
- }
- }
-
- fn leave(&self) {
- println!("number of bolls: {}", self.bolls.len());
- }
-
- fn on_event(&mut self, event: Event) {
- match event {
- Event::KeyDown { keycode: Some(Keycode::KpPlus), .. } => { self.boll_size = std::cmp::min(self.boll_size + 1, 32) }
- Event::KeyDown { keycode: Some(Keycode::KpMinus), .. } => { self.boll_size = std::cmp::max(self.boll_size - 1, 1) }
- Event::MouseMotion { x, y, .. } => {
- self.bolls.push(Box::new(CircleBoll::new(
- point!(x as f64, y as f64),
- point!(0.0, 0.0),
- )))
- }
- _ => {}
- }
- }
-}