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"
byteorder = "1.3"
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"
gfx = "0.18"
gfx_core = "0.9"

View File

@ -22,7 +22,7 @@ use winit::event::{ElementState, Event, KeyboardInput, WindowEvent, TouchPhase};
use winit::event_loop::ControlFlow;
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::event::{KeyCode, KeyMods};
use crate::ggez::graphics;
@ -34,7 +34,6 @@ use crate::scene::loading_scene::LoadingScene;
use crate::scene::Scene;
use crate::shared_game_state::{SharedGameState, TimingMode};
use crate::ui::UI;
use crate::ggez::event::winit_event::ModifiersState;
mod bmfont;
mod bmfont_renderer;
@ -64,6 +63,7 @@ mod stage;
mod sound;
mod text_script;
mod texture_set;
mod touch_controls;
mod ui;
mod weapon;
@ -128,6 +128,9 @@ impl Game {
if let Some(scene) = self.scene.as_mut() {
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::apply_transformations(ctx)?;
@ -234,27 +237,34 @@ pub fn android_main() {
init().unwrap();
}
fn init_ctx<P: Into<path::PathBuf>>(event_loop: &winit::event_loop::EventLoopWindowTarget<()>, resource_dir: P) -> GameResult<Context> {
let backend = if cfg!(target_os = "android") {
Backend::OpenGLES { major: 2, minor: 0 }
} else {
Backend::OpenGL { major: 3, minor: 2 }
};
static BACKENDS: [Backend; 4] = [
Backend::OpenGL {major: 3, minor: 2},
Backend::OpenGLES { major: 3, minor: 2},
Backend::OpenGLES { major: 3, minor: 0},
Backend::OpenGLES { major: 2, minor: 0}
];
let mut ctx = ContextBuilder::new("doukutsu-rs")
.window_setup(WindowSetup::default().title("Cave Story (doukutsu-rs)"))
.window_mode(WindowMode::default()
.resizable(true)
.min_dimensions(320.0, 240.0)
.dimensions(854.0, 480.0))
.add_resource_path(resource_dir)
.add_resource_path(path::PathBuf::from(str!("./")))
.backend(backend)
.build(event_loop)?;
fn init_ctx<P: Into<path::PathBuf> + Clone>(event_loop: &winit::event_loop::EventLoopWindowTarget<()>, resource_dir: P) -> GameResult<Context> {
for backend in BACKENDS.iter() {
let mut ctx = ContextBuilder::new("doukutsu-rs")
.window_setup(WindowSetup::default().title("Cave Story (doukutsu-rs)"))
.window_mode(WindowMode::default()
.resizable(true)
.min_dimensions(320.0, 240.0)
.dimensions(854.0, 480.0))
.add_resource_path(resource_dir.clone())
.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 {
@ -345,7 +355,7 @@ pub fn init() -> GameResult {
}
WindowEvent::Touch(touch) => {
if let Some(game) = &mut game {
game.state.touch_controls.process_winit_event(game.state.scale, &mut game.state.key_state, touch);
}
}
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::texture_set::TextureSet;
use crate::ggez::graphics::Canvas;
use crate::touch_controls::TouchControls;
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum TimingMode {
@ -43,6 +44,7 @@ pub struct Settings {
pub original_textures: bool,
pub enhanced_graphics: bool,
pub debug_outlines: bool,
pub touch_controls: bool,
}
pub struct SharedGameState {
@ -57,6 +59,7 @@ pub struct SharedGameState {
pub carets: Vec<Caret>,
pub key_state: KeyState,
pub key_trigger: KeyState,
pub touch_controls: TouchControls,
pub font: BMFontRenderer,
pub texture_set: TextureSet,
pub base_path: String,
@ -115,6 +118,7 @@ impl SharedGameState {
carets: Vec::with_capacity(32),
key_state: KeyState(0),
key_trigger: KeyState(0),
touch_controls: TouchControls::new(),
font,
texture_set: TextureSet::new(base_path),
base_path: str!(base_path),
@ -127,6 +131,7 @@ impl SharedGameState {
original_textures: false,
enhanced_graphics: true,
debug_outlines: false,
touch_controls: cfg!(target_os = "android")
},
constants,
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(())
}
}