|
| 1 | +use std::time::Duration; |
1 | 2 | use std::{path::Path, time::Instant};
|
2 | 3 |
|
| 4 | +use bidrum_data_struct_lib::janggu::JangguFace; |
3 | 5 | use bidrum_data_struct_lib::song::GameSong;
|
4 |
| -use sdl2::{ |
5 |
| - event::Event, image::LoadTexture, keyboard::Keycode, pixels::Color, rect::Rect, render::Texture, |
6 |
| -}; |
| 6 | +use sdl2::{image::LoadTexture, rect::Rect, render::Texture}; |
7 | 7 |
|
8 | 8 | use crate::constants::DEFAULT_FONT_PATH as FONT_PATH;
|
9 | 9 | use crate::constants::DEFAULT_IMG_PATH as IMG_PATH;
|
10 | 10 | use crate::constants::SELECT_SONG_FONT_COLOR;
|
11 | 11 |
|
| 12 | +use super::game_player::janggu_state_with_tick::JangguStateWithTick; |
12 | 13 | use super::util::create_outlined_font_texture::create_font_texture;
|
13 | 14 | use super::{
|
14 | 15 | common::{event_loop_common, render_common},
|
@@ -40,6 +41,13 @@ pub(crate) fn select_song(
|
40 | 41 | songs: &Vec<GameSong>,
|
41 | 42 | ) -> SongSelectionResult {
|
42 | 43 | let texture_creator = common_context.canvas.texture_creator();
|
| 44 | + let mut janggu_state = JangguStateWithTick::new(); |
| 45 | + |
| 46 | + let mut hit_left = false; |
| 47 | + let mut hit_right = false; |
| 48 | + let mut last_left_hit_time = Instant::now(); |
| 49 | + let mut last_right_hit_time = Instant::now(); |
| 50 | + let hit_both_side_time_delay = 100; // ms |
43 | 51 |
|
44 | 52 | // font information
|
45 | 53 | let font_path = &(FONT_PATH.to_owned() + "/sans.ttf");
|
@@ -108,52 +116,76 @@ pub(crate) fn select_song(
|
108 | 116 |
|
109 | 117 | let mut selected_song_item_moving_center_x = selected_song_item_center_x; // x position of center of moving selected song item
|
110 | 118 |
|
| 119 | + let selecting_song_started_at = Instant::now(); |
111 | 120 | // enable alpha blending
|
112 | 121 | common_context
|
113 | 122 | .canvas
|
114 | 123 | .set_blend_mode(sdl2::render::BlendMode::Blend);
|
115 | 124 | 'running: loop {
|
116 |
| - // waiting user input |
| 125 | + let tick = selecting_song_started_at.elapsed().as_millis(); |
| 126 | + |
| 127 | + // waiting keyboard input |
117 | 128 | for event in common_context.event_pump.poll_iter() {
|
118 | 129 | if event_loop_common(&event, &mut common_context.coins) {
|
119 | 130 | break 'running;
|
120 | 131 | }
|
| 132 | + } |
121 | 133 |
|
122 |
| - match event { |
123 |
| - Event::KeyDown { |
124 |
| - // if user press right key, then song menu moves to right for specific distance |
125 |
| - keycode: Some(Keycode::Right), |
126 |
| - repeat: false, |
127 |
| - .. |
128 |
| - } => { |
129 |
| - if moving_direction == MovingDirection::Stop { |
130 |
| - // to prevent changing direction when moving |
131 |
| - moving_direction = MovingDirection::Right; |
132 |
| - last_key_press_time = Instant::now(); |
133 |
| - } |
134 |
| - } |
135 |
| - Event::KeyDown { |
136 |
| - // if user press right key, then song menu moves to left for specific distance |
137 |
| - keycode: Some(Keycode::Left), |
138 |
| - repeat: false, |
139 |
| - .. |
140 |
| - } => { |
141 |
| - if moving_direction == MovingDirection::Stop { |
142 |
| - // to prevent changing direction when moving |
143 |
| - moving_direction = MovingDirection::Left; |
144 |
| - last_key_press_time = Instant::now(); |
145 |
| - } |
| 134 | + // process janggu input |
| 135 | + janggu_state.update(common_context.read_janggu_state(), tick as i128); |
| 136 | + if (janggu_state.궁채.is_keydown_now |
| 137 | + && matches!(janggu_state.궁채.face, Some(JangguFace::궁편))) |
| 138 | + && (janggu_state.열채.is_keydown_now |
| 139 | + && matches!(janggu_state.열채.face, Some(JangguFace::열편))) |
| 140 | + { |
| 141 | + if moving_direction == MovingDirection::Stop { |
| 142 | + break 'running; |
| 143 | + } |
| 144 | + } else if (janggu_state.궁채.is_keydown_now |
| 145 | + && matches!(janggu_state.궁채.face, Some(JangguFace::궁편))) |
| 146 | + || (janggu_state.열채.is_keydown_now |
| 147 | + && matches!(janggu_state.열채.face, Some(JangguFace::궁편))) |
| 148 | + { |
| 149 | + // to prevent changing direction when moving |
| 150 | + if moving_direction == MovingDirection::Stop { |
| 151 | + if hit_left == false { |
| 152 | + // If hitting left side, don't react directly. Just assign false to hit_left |
| 153 | + hit_left = true; |
| 154 | + last_left_hit_time = Instant::now(); |
146 | 155 | }
|
147 |
| - Event::KeyDown { |
148 |
| - // if user press enter key, then song is selected |
149 |
| - keycode: Some(Keycode::Return), |
150 |
| - .. |
151 |
| - } => { |
152 |
| - if moving_direction == MovingDirection::Stop { |
153 |
| - break 'running; |
154 |
| - } |
| 156 | + } |
| 157 | + } else if (janggu_state.궁채.is_keydown_now |
| 158 | + && matches!(janggu_state.궁채.face, Some(JangguFace::열편))) |
| 159 | + || (janggu_state.열채.is_keydown_now |
| 160 | + && matches!(janggu_state.열채.face, Some(JangguFace::열편))) |
| 161 | + { |
| 162 | + // to prevent changing direction when moving |
| 163 | + if moving_direction == MovingDirection::Stop { |
| 164 | + if hit_right == false { |
| 165 | + // If hitting right side, don't react directly. Just assign false to hit_right |
| 166 | + hit_right = true; |
| 167 | + last_right_hit_time = Instant::now(); |
155 | 168 | }
|
156 |
| - _ => {} |
| 169 | + } |
| 170 | + } |
| 171 | + |
| 172 | + // to detect delay for hitting both side |
| 173 | + if hit_left && hit_right { |
| 174 | + // detect hitting both side |
| 175 | + break 'running; |
| 176 | + } else if hit_left { |
| 177 | + if last_left_hit_time.elapsed() > Duration::from_millis(hit_both_side_time_delay) { |
| 178 | + // after the limit, regard as going to left song |
| 179 | + moving_direction = MovingDirection::Left; |
| 180 | + last_key_press_time = Instant::now(); |
| 181 | + hit_left = false; |
| 182 | + } |
| 183 | + } else if hit_right { |
| 184 | + if last_right_hit_time.elapsed() > Duration::from_millis(hit_both_side_time_delay) { |
| 185 | + // after the limit, regard as going to right song |
| 186 | + moving_direction = MovingDirection::Right; |
| 187 | + last_key_press_time = Instant::now(); |
| 188 | + hit_right = false; |
157 | 189 | }
|
158 | 190 | }
|
159 | 191 |
|
|
0 commit comments