Commit | Line | Data |
---|---|---|
296187ca TW |
1 | extern crate rand; |
2 | extern crate sdl2; | |
3 | extern crate time; | |
4 | ||
296187ca TW |
5 | use std::f32::consts::PI; |
6 | ||
7 | use rand::Rng; | |
8 | use sdl2::event::Event; | |
fcbc5786 | 9 | use sdl2::event::WindowEvent; |
296187ca | 10 | use sdl2::gfx::primitives::DrawRenderer; |
296187ca TW |
11 | use sdl2::keyboard::Keycode; |
12 | use sdl2::pixels::Color; | |
13 | use sdl2::rect::Rect; | |
cf7dc104 | 14 | use sdl2::video::FullscreenType; |
296187ca TW |
15 | use time::PreciseTime; |
16 | ||
3bfea951 | 17 | use app::*; |
cdf8f998 | 18 | use boll::{Boll, CircleBoll, SquareBoll}; |
296187ca TW |
19 | use common::Point2D; |
20 | ||
3bfea951 | 21 | mod app; |
296187ca TW |
22 | #[macro_use] mod common; |
23 | mod boll; | |
cdf8f998 | 24 | mod sprites; |
296187ca TW |
25 | |
26 | const SCREEN_WIDTH: u32 = 1280; | |
27 | const SCREEN_HEIGHT: u32 = (SCREEN_WIDTH as f64 * (1440.0 / 2560.0)) as u32; | |
28 | const FPS: u32 = 60; | |
29 | const NS_PER_FRAME: u32 = 1_000_000_000 / FPS; | |
30 | ||
c315bb31 TW |
31 | type Bollar = Vec<Box<dyn Boll>>; |
32 | ||
296187ca TW |
33 | fn main() { |
34 | println!("starting..."); | |
fcbc5786 TW |
35 | let mut app = App::new(); |
36 | app.load_sprites(&[ | |
37 | ("block", "res/block.bmp"), | |
38 | ("mario", "res/mario-trans.png"), | |
39 | ]); | |
296187ca TW |
40 | |
41 | let mut frame_count: u64 = 0; | |
42 | let mut fps_time = PreciseTime::now(); | |
43 | ||
c315bb31 | 44 | let mut bolls: Bollar = Bollar::new(); |
296187ca TW |
45 | let mut boll_size = 1; |
46 | ||
296187ca TW |
47 | let mut mario_angle = 0.0; |
48 | ||
49 | 'running: loop { | |
50 | let loop_start = PreciseTime::now(); | |
fcbc5786 TW |
51 | app.canvas.set_draw_color(Color::RGB(0, 0, 0)); |
52 | app.canvas.clear(); | |
296187ca TW |
53 | { |
54 | let blocks = 20; | |
55 | let size = 32; | |
56 | let offset = point!((SCREEN_WIDTH as i32 - (blocks + 1) * size) / 2, (SCREEN_HEIGHT as i32 - (blocks + 1) * size) / 2); | |
fcbc5786 | 57 | let block = app.sprites.get("block"); |
296187ca | 58 | for i in 0..blocks { |
fcbc5786 TW |
59 | app.canvas.copy(block, None, Rect::new((i) * size + offset.x, (0) * size + offset.y, size as u32, size as u32)).unwrap(); |
60 | app.canvas.copy(block, None, Rect::new((blocks - i) * size + offset.x, (blocks) * size + offset.y, size as u32, size as u32)).unwrap(); | |
61 | app.canvas.copy(block, None, Rect::new((0) * size + offset.x, (blocks - i) * size + offset.y, size as u32, size as u32)).unwrap(); | |
62 | app.canvas.copy(block, None, Rect::new((blocks) * size + offset.x, (i) * size + offset.y, size as u32, size as u32)).unwrap(); | |
296187ca TW |
63 | } |
64 | } | |
65 | { | |
66 | let size = 64; | |
67 | let offset = point!((SCREEN_WIDTH as i32 - size) / 2, (SCREEN_HEIGHT as i32 - size) / 2); | |
68 | let radius = 110.0 + size as f32 * 0.5; | |
69 | let angle = (mario_angle as f32 - 90.0) * PI / 180.0; | |
70 | let offset2 = point!((angle.cos() * radius) as i32, (angle.sin() * radius) as i32); | |
fcbc5786 | 71 | app.canvas.copy_ex(app.sprites.get("mario"), None, Rect::new(offset.x + offset2.x, offset.y + offset2.y, size as u32, size as u32), mario_angle, sdl2::rect::Point::new(size / 2, size / 2), false, false).unwrap(); |
296187ca TW |
72 | mario_angle += 1.0; |
73 | if mario_angle >= 360.0 { mario_angle -= 360.0 } | |
74 | } | |
75 | { | |
76 | let p = point!((SCREEN_WIDTH / 2) as i16, (SCREEN_HEIGHT / 2) as i16); | |
fcbc5786 TW |
77 | app.canvas.circle(p.x, p.y, 100, Color::RGB(255, 255, 255)).unwrap(); |
78 | app.canvas.aa_circle(p.x, p.y, 110, Color::RGB(255, 255, 255)).unwrap(); | |
79 | app.canvas.ellipse(p.x, p.y, 50, 100, Color::RGB(255, 255, 255)).unwrap(); | |
80 | app.canvas.aa_ellipse(p.x, p.y, 110, 55, Color::RGB(255, 255, 255)).unwrap(); | |
296187ca TW |
81 | } |
82 | ||
83 | for b in &mut bolls { | |
84 | b.update(); | |
fcbc5786 | 85 | b.draw(&mut app.canvas, boll_size); |
296187ca TW |
86 | } |
87 | ||
88 | // window.gl_swap_window(); | |
fcbc5786 | 89 | for event in app.event_pump.poll_iter() { |
296187ca TW |
90 | match event { |
91 | Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { | |
92 | break 'running; | |
93 | } | |
94 | Event::KeyDown { keycode: Some(Keycode::F11), .. } => { | |
fcbc5786 TW |
95 | match app.canvas.window().fullscreen_state() { |
96 | FullscreenType::Off => app.canvas.window_mut().set_fullscreen(FullscreenType::Desktop), | |
97 | _ => app.canvas.window_mut().set_fullscreen(FullscreenType::Off) | |
cf7dc104 | 98 | }.unwrap(); |
296187ca TW |
99 | } |
100 | Event::KeyDown { keycode: Some(Keycode::KpPlus), .. } => { boll_size = std::cmp::min(boll_size + 1, 32) } | |
101 | Event::KeyDown { keycode: Some(Keycode::KpMinus), .. } => { boll_size = std::cmp::max(boll_size - 1, 1) } | |
6c5dd5cf TW |
102 | Event::MouseMotion { x, y, .. } => { |
103 | bolls.push(Box::new(CircleBoll::new( | |
104 | point!(x as f64, y as f64), | |
105 | point!(0.0, 0.0), | |
106 | ))) | |
107 | } | |
d0c9b1f5 TW |
108 | Event::Window { win_event: WindowEvent::Resized(x, y), .. } => { println!("window resized({}, {})", x, y) } |
109 | Event::Window { win_event: WindowEvent::Maximized, .. } => { println!("window maximized") } | |
110 | Event::Window { win_event: WindowEvent::Restored, .. } => { println!("window restored") } | |
111 | Event::Window { win_event: WindowEvent::Enter, .. } => { println!("window enter") } | |
112 | Event::Window { win_event: WindowEvent::Leave, .. } => { println!("window leave") } | |
113 | Event::Window { win_event: WindowEvent::FocusGained, .. } => { println!("window focus gained") } | |
114 | Event::Window { win_event: WindowEvent::FocusLost, .. } => { println!("window focus lost") } | |
296187ca TW |
115 | _ => {} |
116 | } | |
117 | } | |
fcbc5786 | 118 | app.canvas.present(); |
296187ca TW |
119 | |
120 | match loop_start.to(PreciseTime::now()).num_nanoseconds() { | |
121 | Some(ns) if ns < (NS_PER_FRAME - 50_0000) as i64 => { change_boll_count(&mut bolls, 100) } | |
122 | Some(ns) if ns > (NS_PER_FRAME + 50_0000) as i64 => { change_boll_count(&mut bolls, -100) } | |
123 | _ => {} | |
124 | } | |
125 | ||
126 | frame_count += 1; | |
127 | if frame_count == FPS as u64 { | |
128 | let duration = fps_time.to(PreciseTime::now()).num_nanoseconds().unwrap() as f64 / 1_000_000_000.0; | |
129 | println!("fps: {}", frame_count as f64 / duration); | |
130 | frame_count = 0; | |
131 | fps_time = PreciseTime::now(); | |
132 | } | |
133 | } | |
134 | ||
135 | println!("number of bolls: {}", bolls.len()); | |
136 | } | |
137 | ||
c315bb31 | 138 | fn change_boll_count(mut bolls: &mut Bollar, delta: i32) { |
296187ca TW |
139 | if delta > 0 { |
140 | for _i in 0..delta { | |
141 | add_boll(&mut bolls); | |
142 | } | |
143 | } else if delta < 0 { | |
144 | for _i in 0..delta { | |
145 | bolls.pop(); | |
146 | } | |
147 | } | |
148 | } | |
149 | ||
c315bb31 | 150 | fn add_boll(bolls: &mut Bollar) { |
296187ca | 151 | let mut rng = rand::thread_rng(); |
c315bb31 | 152 | bolls.push(Box::new(SquareBoll { |
296187ca TW |
153 | pos: point!(rng.gen_range(0, SCREEN_WIDTH) as f64, rng.gen_range(0, SCREEN_HEIGHT) as f64), |
154 | vel: point!(rng.gen_range(-2.0, 2.0), rng.gen_range(-2.0, 2.0)), | |
c315bb31 | 155 | })); |
296187ca | 156 | } |