add screen shake intensity setting (closes #129)
This commit is contained in:
parent
d8636bc693
commit
75b077c772
|
@ -63,6 +63,12 @@
|
||||||
"graphics_menu": {
|
"graphics_menu": {
|
||||||
"lighting_effects": "Lighting effects:",
|
"lighting_effects": "Lighting effects:",
|
||||||
"weapon_light_cone": "Weapon light cone:",
|
"weapon_light_cone": "Weapon light cone:",
|
||||||
|
"screen_shake": {
|
||||||
|
"entry": "Screen shake intensity:",
|
||||||
|
"full": "1x",
|
||||||
|
"half": "0.5x",
|
||||||
|
"off": "Off"
|
||||||
|
},
|
||||||
"motion_interpolation": "Motion interpolation:",
|
"motion_interpolation": "Motion interpolation:",
|
||||||
"subpixel_scrolling": "Subpixel scrolling:",
|
"subpixel_scrolling": "Subpixel scrolling:",
|
||||||
"original_textures": "Original textures:",
|
"original_textures": "Original textures:",
|
||||||
|
|
|
@ -56,6 +56,12 @@
|
||||||
"graphics_menu": {
|
"graphics_menu": {
|
||||||
"lighting_effects": "ライティング効果:",
|
"lighting_effects": "ライティング効果:",
|
||||||
"weapon_light_cone": "兵器のライトコーン:",
|
"weapon_light_cone": "兵器のライトコーン:",
|
||||||
|
"screen_shake": {
|
||||||
|
"entry": "画面の揺れ:",
|
||||||
|
"full": "1x",
|
||||||
|
"half": "0.5x",
|
||||||
|
"off": "オフ"
|
||||||
|
},
|
||||||
"motion_interpolation": "モーション補間:",
|
"motion_interpolation": "モーション補間:",
|
||||||
"subpixel_scrolling": "サブピクセルスクロール:",
|
"subpixel_scrolling": "サブピクセルスクロール:",
|
||||||
"original_textures": "オリジナルテクスチャ:",
|
"original_textures": "オリジナルテクスチャ:",
|
||||||
|
|
19
src/frame.rs
19
src/frame.rs
|
@ -95,7 +95,8 @@ impl Frame {
|
||||||
screen_width += 10.0;
|
screen_width += 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.wait == 0 { // prevent zero division
|
if self.wait == 0 {
|
||||||
|
// prevent zero division
|
||||||
self.wait = 1;
|
self.wait = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,18 +132,26 @@ impl Frame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let intensity = state.settings.screen_shake_intensity.to_val();
|
||||||
|
|
||||||
if state.super_quake_counter > 0 {
|
if state.super_quake_counter > 0 {
|
||||||
state.super_quake_counter -= 1;
|
state.super_quake_counter -= 1;
|
||||||
|
|
||||||
self.x += state.effect_rng.range(-0x300..0x300) * 5 as i32;
|
let new_x = state.effect_rng.range(-0x300..0x300) * 5;
|
||||||
self.y += state.effect_rng.range(-0x300..0x300) * 3 as i32;
|
let new_y = state.effect_rng.range(-0x300..0x300) * 3;
|
||||||
|
|
||||||
|
self.x += (f64::from(new_x) * intensity).round() as i32;
|
||||||
|
self.y += (f64::from(new_y) * intensity).round() as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.quake_counter > 0 {
|
if state.quake_counter > 0 {
|
||||||
state.quake_counter -= 1;
|
state.quake_counter -= 1;
|
||||||
|
|
||||||
self.x += state.effect_rng.range(-0x300..0x300) as i32;
|
let new_x = state.effect_rng.range(-0x300..0x300) as i32;
|
||||||
self.y += state.effect_rng.range(-0x300..0x300) as i32;
|
let new_y = state.effect_rng.range(-0x300..0x300) as i32;
|
||||||
|
|
||||||
|
self.x += (f64::from(new_x) * intensity).round() as i32;
|
||||||
|
self.y += (f64::from(new_y) * intensity).round() as i32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::input::combined_menu_controller::CombinedMenuController;
|
||||||
use crate::menu::MenuEntry;
|
use crate::menu::MenuEntry;
|
||||||
use crate::menu::{Menu, MenuSelectionResult};
|
use crate::menu::{Menu, MenuSelectionResult};
|
||||||
use crate::scene::title_scene::TitleScene;
|
use crate::scene::title_scene::TitleScene;
|
||||||
use crate::shared_game_state::{Language, SharedGameState, TimingMode};
|
use crate::shared_game_state::{Language, ScreenShakeIntensity, SharedGameState, TimingMode};
|
||||||
use crate::sound::InterpolationMode;
|
use crate::sound::InterpolationMode;
|
||||||
use crate::{graphics, VSyncMode};
|
use crate::{graphics, VSyncMode};
|
||||||
|
|
||||||
|
@ -74,6 +74,15 @@ impl SettingsMenu {
|
||||||
state.t("menus.options_menu.graphics_menu.weapon_light_cone"),
|
state.t("menus.options_menu.graphics_menu.weapon_light_cone"),
|
||||||
state.settings.light_cone,
|
state.settings.light_cone,
|
||||||
));
|
));
|
||||||
|
self.graphics.push_entry(MenuEntry::Options(
|
||||||
|
state.t("menus.options_menu.graphics_menu.screen_shake.entry"),
|
||||||
|
state.settings.screen_shake_intensity as usize,
|
||||||
|
vec![
|
||||||
|
state.t("menus.options_menu.graphics_menu.screen_shake.full"),
|
||||||
|
state.t("menus.options_menu.graphics_menu.screen_shake.half"),
|
||||||
|
state.t("menus.options_menu.graphics_menu.screen_shake.off"),
|
||||||
|
],
|
||||||
|
));
|
||||||
self.graphics.push_entry(MenuEntry::Toggle(
|
self.graphics.push_entry(MenuEntry::Toggle(
|
||||||
state.t("menus.options_menu.graphics_menu.motion_interpolation"),
|
state.t("menus.options_menu.graphics_menu.motion_interpolation"),
|
||||||
state.settings.motion_interpolation,
|
state.settings.motion_interpolation,
|
||||||
|
@ -218,7 +227,7 @@ impl SettingsMenu {
|
||||||
self.graphics.update_width(state);
|
self.graphics.update_width(state);
|
||||||
self.graphics.update_height();
|
self.graphics.update_height();
|
||||||
self.graphics.x = ((state.canvas_size.0 - self.graphics.width as f32) / 2.0).floor() as isize;
|
self.graphics.x = ((state.canvas_size.0 - self.graphics.width as f32) / 2.0).floor() as isize;
|
||||||
self.graphics.y = 30 + ((state.canvas_size.1 - self.graphics.height as f32) / 2.0).floor() as isize;
|
self.graphics.y = 20 + ((state.canvas_size.1 - self.graphics.height as f32) / 2.0).floor() as isize;
|
||||||
|
|
||||||
self.sound.update_width(state);
|
self.sound.update_width(state);
|
||||||
self.sound.update_height();
|
self.sound.update_height();
|
||||||
|
@ -332,7 +341,35 @@ impl SettingsMenu {
|
||||||
*value = state.settings.light_cone;
|
*value = state.settings.light_cone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuSelectionResult::Selected(3, toggle) => {
|
MenuSelectionResult::Selected(3, toggle) | MenuSelectionResult::Right(3, toggle, _) => {
|
||||||
|
if let MenuEntry::Options(_, value, _) = toggle {
|
||||||
|
let (new_intensity, new_value) = match *value {
|
||||||
|
0 => (ScreenShakeIntensity::Half, 1),
|
||||||
|
1 => (ScreenShakeIntensity::Off, 2),
|
||||||
|
_ => (ScreenShakeIntensity::Full, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
*value = new_value;
|
||||||
|
state.settings.screen_shake_intensity = new_intensity;
|
||||||
|
|
||||||
|
let _ = state.settings.save(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuSelectionResult::Left(3, toggle, _) => {
|
||||||
|
if let MenuEntry::Options(_, value, _) = toggle {
|
||||||
|
let (new_intensity, new_value) = match *value {
|
||||||
|
0 => (ScreenShakeIntensity::Off, 2),
|
||||||
|
1 => (ScreenShakeIntensity::Full, 0),
|
||||||
|
_ => (ScreenShakeIntensity::Half, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
*value = new_value;
|
||||||
|
state.settings.screen_shake_intensity = new_intensity;
|
||||||
|
|
||||||
|
let _ = state.settings.save(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuSelectionResult::Selected(4, toggle) => {
|
||||||
if let MenuEntry::Toggle(_, value) = toggle {
|
if let MenuEntry::Toggle(_, value) = toggle {
|
||||||
state.settings.motion_interpolation = !state.settings.motion_interpolation;
|
state.settings.motion_interpolation = !state.settings.motion_interpolation;
|
||||||
let _ = state.settings.save(ctx);
|
let _ = state.settings.save(ctx);
|
||||||
|
@ -340,7 +377,7 @@ impl SettingsMenu {
|
||||||
*value = state.settings.motion_interpolation;
|
*value = state.settings.motion_interpolation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuSelectionResult::Selected(4, toggle) => {
|
MenuSelectionResult::Selected(5, toggle) => {
|
||||||
if let MenuEntry::Toggle(_, value) = toggle {
|
if let MenuEntry::Toggle(_, value) = toggle {
|
||||||
state.settings.subpixel_coords = !state.settings.subpixel_coords;
|
state.settings.subpixel_coords = !state.settings.subpixel_coords;
|
||||||
let _ = state.settings.save(ctx);
|
let _ = state.settings.save(ctx);
|
||||||
|
@ -348,7 +385,7 @@ impl SettingsMenu {
|
||||||
*value = state.settings.subpixel_coords;
|
*value = state.settings.subpixel_coords;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuSelectionResult::Selected(5, toggle) => {
|
MenuSelectionResult::Selected(6, toggle) => {
|
||||||
if let MenuEntry::Toggle(_, value) = toggle {
|
if let MenuEntry::Toggle(_, value) = toggle {
|
||||||
state.settings.original_textures = !state.settings.original_textures;
|
state.settings.original_textures = !state.settings.original_textures;
|
||||||
if self.on_title {
|
if self.on_title {
|
||||||
|
@ -361,7 +398,7 @@ impl SettingsMenu {
|
||||||
*value = state.settings.original_textures;
|
*value = state.settings.original_textures;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuSelectionResult::Selected(6, toggle) => {
|
MenuSelectionResult::Selected(7, toggle) => {
|
||||||
if let MenuEntry::Toggle(_, value) = toggle {
|
if let MenuEntry::Toggle(_, value) = toggle {
|
||||||
state.settings.seasonal_textures = !state.settings.seasonal_textures;
|
state.settings.seasonal_textures = !state.settings.seasonal_textures;
|
||||||
state.reload_graphics();
|
state.reload_graphics();
|
||||||
|
@ -370,7 +407,7 @@ impl SettingsMenu {
|
||||||
*value = state.settings.seasonal_textures;
|
*value = state.settings.seasonal_textures;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuSelectionResult::Selected(8, _) | MenuSelectionResult::Canceled => {
|
MenuSelectionResult::Selected(9, _) | MenuSelectionResult::Canceled => {
|
||||||
self.current = CurrentMenu::MainMenu
|
self.current = CurrentMenu::MainMenu
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::input::keyboard_player_controller::KeyboardController;
|
||||||
use crate::input::player_controller::PlayerController;
|
use crate::input::player_controller::PlayerController;
|
||||||
use crate::input::touch_player_controller::TouchPlayerController;
|
use crate::input::touch_player_controller::TouchPlayerController;
|
||||||
use crate::player::TargetPlayer;
|
use crate::player::TargetPlayer;
|
||||||
use crate::shared_game_state::{Language, TimingMode};
|
use crate::shared_game_state::{Language, ScreenShakeIntensity, TimingMode};
|
||||||
use crate::sound::InterpolationMode;
|
use crate::sound::InterpolationMode;
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -50,6 +50,8 @@ pub struct Settings {
|
||||||
pub locale: Language,
|
pub locale: Language,
|
||||||
#[serde(default = "default_vsync")]
|
#[serde(default = "default_vsync")]
|
||||||
pub vsync_mode: VSyncMode,
|
pub vsync_mode: VSyncMode,
|
||||||
|
#[serde(default = "default_screen_shake_intensity")]
|
||||||
|
pub screen_shake_intensity: ScreenShakeIntensity,
|
||||||
pub debug_mode: bool,
|
pub debug_mode: bool,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub noclip: bool,
|
pub noclip: bool,
|
||||||
|
@ -61,7 +63,7 @@ fn default_true() -> bool {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn current_version() -> u32 {
|
fn current_version() -> u32 {
|
||||||
9
|
10
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -94,6 +96,11 @@ fn default_vsync() -> VSyncMode {
|
||||||
VSyncMode::VSync
|
VSyncMode::VSync
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn default_screen_shake_intensity() -> ScreenShakeIntensity {
|
||||||
|
ScreenShakeIntensity::Full
|
||||||
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
pub fn load(ctx: &Context) -> GameResult<Settings> {
|
pub fn load(ctx: &Context) -> GameResult<Settings> {
|
||||||
if let Ok(file) = user_open(ctx, "/settings.json") {
|
if let Ok(file) = user_open(ctx, "/settings.json") {
|
||||||
|
@ -146,6 +153,11 @@ impl Settings {
|
||||||
self.debug_mode = false;
|
self.debug_mode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.version == 9 {
|
||||||
|
self.version = 10;
|
||||||
|
self.screen_shake_intensity = default_screen_shake_intensity();
|
||||||
|
}
|
||||||
|
|
||||||
if self.version != initial_version {
|
if self.version != initial_version {
|
||||||
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
||||||
}
|
}
|
||||||
|
@ -198,6 +210,7 @@ impl Default for Settings {
|
||||||
fps_counter: false,
|
fps_counter: false,
|
||||||
locale: Language::English,
|
locale: Language::English,
|
||||||
vsync_mode: VSyncMode::VSync,
|
vsync_mode: VSyncMode::VSync,
|
||||||
|
screen_shake_intensity: ScreenShakeIntensity::Full,
|
||||||
debug_mode: false,
|
debug_mode: false,
|
||||||
noclip: false,
|
noclip: false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,23 @@ impl Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Copy, Clone, num_derive::FromPrimitive, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub enum ScreenShakeIntensity {
|
||||||
|
Full,
|
||||||
|
Half,
|
||||||
|
Off,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScreenShakeIntensity {
|
||||||
|
pub fn to_val(self) -> f64 {
|
||||||
|
match self {
|
||||||
|
ScreenShakeIntensity::Full => 1.0,
|
||||||
|
ScreenShakeIntensity::Half => 0.5,
|
||||||
|
ScreenShakeIntensity::Off => 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FontData {
|
pub struct FontData {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
|
|
Loading…
Reference in New Issue