some stuff related to touch controls

This commit is contained in:
Alula 2020-10-20 22:45:56 +02:00
parent 2f111919d6
commit beb7bfe3e6
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
4 changed files with 93 additions and 23 deletions

View File

@ -44,7 +44,7 @@ bitflags = "1"
bitvec = "0.17.4" bitvec = "0.17.4"
byteorder = "1.3" byteorder = "1.3"
case_insensitive_hashmap = "1.0.0" case_insensitive_hashmap = "1.0.0"
cpal = {git = "https://github.com/alula/cpal.git", branch = "android-support"} cpal = {git = "https://github.com/doukutsu-rs/cpal.git", branch = "android-support"}
directories = "2" directories = "2"
gfx = "0.18" gfx = "0.18"
gfx_core = "0.9" gfx_core = "0.9"

View File

@ -22,7 +22,7 @@ use winit::event::{ElementState, Event, KeyboardInput, WindowEvent, TouchPhase};
use winit::event_loop::ControlFlow; use winit::event_loop::ControlFlow;
use crate::builtin_fs::BuiltinFS; use crate::builtin_fs::BuiltinFS;
use crate::ggez::{Context, ContextBuilder, filesystem, GameResult}; use crate::ggez::{Context, ContextBuilder, filesystem, GameResult, GameError};
use crate::ggez::conf::{Backend, WindowMode, WindowSetup}; use crate::ggez::conf::{Backend, WindowMode, WindowSetup};
use crate::ggez::event::{KeyCode, KeyMods}; use crate::ggez::event::{KeyCode, KeyMods};
use crate::ggez::graphics; use crate::ggez::graphics;
@ -34,7 +34,6 @@ use crate::scene::loading_scene::LoadingScene;
use crate::scene::Scene; use crate::scene::Scene;
use crate::shared_game_state::{SharedGameState, TimingMode}; use crate::shared_game_state::{SharedGameState, TimingMode};
use crate::ui::UI; use crate::ui::UI;
use crate::ggez::event::winit_event::ModifiersState;
mod bmfont; mod bmfont;
mod bmfont_renderer; mod bmfont_renderer;
@ -64,6 +63,7 @@ mod stage;
mod sound; mod sound;
mod text_script; mod text_script;
mod texture_set; mod texture_set;
mod touch_controls;
mod ui; mod ui;
mod weapon; mod weapon;
@ -128,6 +128,9 @@ impl Game {
if let Some(scene) = self.scene.as_mut() { if let Some(scene) = self.scene.as_mut() {
scene.draw(&mut self.state, ctx)?; scene.draw(&mut self.state, ctx)?;
if self.state.settings.touch_controls {
self.state.touch_controls.draw(&self.state.constants, &mut self.state.texture_set, ctx)?;
}
graphics::set_transform(ctx, self.def_matrix); graphics::set_transform(ctx, self.def_matrix);
graphics::apply_transformations(ctx)?; graphics::apply_transformations(ctx)?;
@ -234,27 +237,34 @@ pub fn android_main() {
init().unwrap(); init().unwrap();
} }
fn init_ctx<P: Into<path::PathBuf>>(event_loop: &winit::event_loop::EventLoopWindowTarget<()>, resource_dir: P) -> GameResult<Context> { static BACKENDS: [Backend; 4] = [
let backend = if cfg!(target_os = "android") { Backend::OpenGL {major: 3, minor: 2},
Backend::OpenGLES { major: 2, minor: 0 } Backend::OpenGLES { major: 3, minor: 2},
} else { Backend::OpenGLES { major: 3, minor: 0},
Backend::OpenGL { major: 3, minor: 2 } Backend::OpenGLES { major: 2, minor: 0}
}; ];
let mut ctx = ContextBuilder::new("doukutsu-rs") fn init_ctx<P: Into<path::PathBuf> + Clone>(event_loop: &winit::event_loop::EventLoopWindowTarget<()>, resource_dir: P) -> GameResult<Context> {
.window_setup(WindowSetup::default().title("Cave Story (doukutsu-rs)")) for backend in BACKENDS.iter() {
.window_mode(WindowMode::default() let mut ctx = ContextBuilder::new("doukutsu-rs")
.resizable(true) .window_setup(WindowSetup::default().title("Cave Story (doukutsu-rs)"))
.min_dimensions(320.0, 240.0) .window_mode(WindowMode::default()
.dimensions(854.0, 480.0)) .resizable(true)
.add_resource_path(resource_dir) .min_dimensions(320.0, 240.0)
.add_resource_path(path::PathBuf::from(str!("./"))) .dimensions(854.0, 480.0))
.backend(backend) .add_resource_path(resource_dir.clone())
.build(event_loop)?; .add_resource_path(path::PathBuf::from(str!("./")))
.backend(*backend)
.build(event_loop);
ctx.filesystem.mount_vfs(Box::new(BuiltinFS::new())); if let Ok(mut ctx) = ctx {
ctx.filesystem.mount_vfs(Box::new(BuiltinFS::new()));
Ok(ctx) return Ok(ctx);
}
}
Err(GameError::EventLoopError("Failed to initialize OpenGL backend. Perhaps the driver is outdated?".to_string()))
} }
pub fn init() -> GameResult { pub fn init() -> GameResult {
@ -345,7 +355,7 @@ pub fn init() -> GameResult {
} }
WindowEvent::Touch(touch) => { WindowEvent::Touch(touch) => {
if let Some(game) = &mut game { if let Some(game) = &mut game {
game.state.touch_controls.process_winit_event(game.state.scale, &mut game.state.key_state, touch);
} }
} }
WindowEvent::KeyboardInput { WindowEvent::KeyboardInput {
@ -405,5 +415,5 @@ pub fn init() -> GameResult {
} }
_ => {} _ => {}
} }
}); })
} }

View File

@ -19,6 +19,7 @@ use crate::str;
use crate::text_script::{TextScriptExecutionState, TextScriptVM, ScriptMode}; use crate::text_script::{TextScriptExecutionState, TextScriptVM, ScriptMode};
use crate::texture_set::TextureSet; use crate::texture_set::TextureSet;
use crate::ggez::graphics::Canvas; use crate::ggez::graphics::Canvas;
use crate::touch_controls::TouchControls;
#[derive(PartialEq, Eq, Copy, Clone)] #[derive(PartialEq, Eq, Copy, Clone)]
pub enum TimingMode { pub enum TimingMode {
@ -43,6 +44,7 @@ pub struct Settings {
pub original_textures: bool, pub original_textures: bool,
pub enhanced_graphics: bool, pub enhanced_graphics: bool,
pub debug_outlines: bool, pub debug_outlines: bool,
pub touch_controls: bool,
} }
pub struct SharedGameState { pub struct SharedGameState {
@ -57,6 +59,7 @@ pub struct SharedGameState {
pub carets: Vec<Caret>, pub carets: Vec<Caret>,
pub key_state: KeyState, pub key_state: KeyState,
pub key_trigger: KeyState, pub key_trigger: KeyState,
pub touch_controls: TouchControls,
pub font: BMFontRenderer, pub font: BMFontRenderer,
pub texture_set: TextureSet, pub texture_set: TextureSet,
pub base_path: String, pub base_path: String,
@ -115,6 +118,7 @@ impl SharedGameState {
carets: Vec::with_capacity(32), carets: Vec::with_capacity(32),
key_state: KeyState(0), key_state: KeyState(0),
key_trigger: KeyState(0), key_trigger: KeyState(0),
touch_controls: TouchControls::new(),
font, font,
texture_set: TextureSet::new(base_path), texture_set: TextureSet::new(base_path),
base_path: str!(base_path), base_path: str!(base_path),
@ -127,6 +131,7 @@ impl SharedGameState {
original_textures: false, original_textures: false,
enhanced_graphics: true, enhanced_graphics: true,
debug_outlines: false, debug_outlines: false,
touch_controls: cfg!(target_os = "android")
}, },
constants, constants,
new_npcs: Vec::with_capacity(8), new_npcs: Vec::with_capacity(8),

55
src/touch_controls.rs Normal file
View File

@ -0,0 +1,55 @@
use winit::event::TouchPhase;
use crate::texture_set::TextureSet;
use crate::ggez::{Context, GameResult};
use crate::common::{KeyState, Rect};
use crate::engine_constants::EngineConstants;
struct TouchPoint {
id: u64,
position: (f64, f64),
last_position: (f64, f64),
}
pub struct TouchControls {
points: Vec<TouchPoint>,
}
impl TouchControls {
pub fn new() -> TouchControls {
TouchControls {
points: Vec::with_capacity(8),
}
}
pub fn process_winit_event(&mut self, scale: f32, key_state: &mut KeyState, touch: winit::event::Touch) {
match touch.phase {
TouchPhase::Started | TouchPhase::Moved => {
if let Some(point) = self.points.iter_mut().find(|p| p.id == touch.id) {
point.last_position = point.position;
point.position = (touch.location.x, touch.location.y);
} else {
self.points.push(TouchPoint {
id: touch.id,
position: (touch.location.x, touch.location.y),
last_position: (0.0, 0.0)
});
}
}
TouchPhase::Ended | TouchPhase::Cancelled => {
self.points.retain(|p| p.id != touch.id);
}
}
}
pub fn draw(&self, constants: &EngineConstants, texture_set: &mut TextureSet, ctx: &mut Context) -> GameResult {
let batch = texture_set.get_or_load_batch(ctx, constants, "Caret")?;
let rect = Rect::new_size(104, 120, 24, 24);
for point in self.points.iter() {
batch.add_rect(point.position.0 as f32 - 12.0, point.position.1 as f32 - 12.0, &rect);
}
batch.draw(ctx)?;
Ok(())
}
}