Redesign the scaling of the game for depth to feel more meaningful

This commit is contained in:
crumblingstatue 2023-04-04 23:29:32 +02:00
parent d6f3eb07f2
commit 6c99beb47d
5 changed files with 42 additions and 17 deletions

View file

@ -10,6 +10,12 @@
# Details # Details
## Scale
Player character is slightly below 1.5 m height.
1 meter = 2 blocks.
1 block = 0.5 meters.
Player character is about 3 blocks high. (slightly less so they fit comfortably)
## Map Size ## Map Size
World is roughly 60000x60000 blocks large. World is roughly 60000x60000 blocks large.

View file

@ -13,7 +13,7 @@ use crate::{
game::{for_each_tile_on_screen, Biome, GameState}, game::{for_each_tile_on_screen, Biome, GameState},
graphics::{self, NATIVE_RESOLUTION}, graphics::{self, NATIVE_RESOLUTION},
input::Input, input::Input,
math::{px_per_frame_to_km_h, wp_to_tp, WorldPos, TILE_SIZE}, math::{px_per_frame_to_km_h, wp_to_tp, WorldPos, M_PER_PX, TILE_SIZE},
res::Res, res::Res,
world::Tile, world::Tile,
}; };
@ -239,15 +239,14 @@ fn debug_panel_ui(
ui.add(egui::DragValue::new(&mut game.camera_offset.x)); ui.add(egui::DragValue::new(&mut game.camera_offset.x));
ui.label("Cam y"); ui.label("Cam y");
ui.add(egui::DragValue::new(&mut game.camera_offset.y)); ui.add(egui::DragValue::new(&mut game.camera_offset.y));
let tp = game.camera_offset.tile_pos(); let co = game.camera_offset;
imm_dbg!(tp);
ui.label(format!( ui.label(format!(
"Cam Depth: {}", "Cam Depth: {}",
LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64) LengthDisp(co.y as f32 - WorldPos::SURFACE as f32)
)); ));
ui.label(format!( ui.label(format!(
"Cam offset from center: {}", "Cam offset from center: {}",
LengthDisp(tp.x as i64 - wp_to_tp(WorldPos::CENTER) as i64) LengthDisp(co.x as f32 - WorldPos::CENTER as f32)
)); ));
} else { } else {
ui.label("Player x"); ui.label("Player x");
@ -258,11 +257,11 @@ fn debug_panel_ui(
imm_dbg!(tp); imm_dbg!(tp);
ui.label(format!( ui.label(format!(
"Player Depth: {}", "Player Depth: {}",
LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64) LengthDisp(game.player.feet_y() as f32 - WorldPos::SURFACE as f32)
)); ));
ui.label(format!( ui.label(format!(
"Player offset from center: {}", "Player offset from center: {}",
LengthDisp(tp.x as i64 - wp_to_tp(WorldPos::CENTER) as i64) LengthDisp(game.player.col_en.en.pos.x as f32 - WorldPos::CENTER as f32)
)); ));
ui.label(format!( ui.label(format!(
"Hspeed: {} ({} km/h)", "Hspeed: {} ({} km/h)",
@ -296,12 +295,17 @@ fn debug_panel_ui(
}); });
} }
struct LengthDisp(i64); struct LengthDisp(f32);
impl fmt::Display for LengthDisp { impl fmt::Display for LengthDisp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let km = self.0 / 1000; let meters = self.0 * M_PER_PX;
let m = self.0 % 1000; if meters.abs() > 1000. {
let km = (meters / 1000.).floor();
let m = meters % 1000.;
write!(f, "{km} km, {m} m") write!(f, "{km} km, {m} m")
} else {
write!(f, "{meters} m")
}
} }
} }

View file

@ -1,6 +1,8 @@
mod player; mod player;
use sfml::graphics::{Rect, RectangleShape, RenderTarget, RenderWindow, Sprite, Transformable}; use sfml::graphics::{
Color, Rect, RectangleShape, RenderTarget, RenderWindow, Shape, Sprite, Transformable,
};
use crate::{ use crate::{
graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION}, graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION},
@ -56,6 +58,13 @@ impl GameState {
)); ));
rs.set_size((w as f32, h as f32)); rs.set_size((w as f32, h as f32));
rw.draw(&rs); rw.draw(&rs);
rs.set_size((2., 2.));
rs.set_fill_color(Color::RED);
rs.set_position((
(self.player.col_en.en.pos.x - self.camera_offset.x as i32) as f32,
(self.player.col_en.en.pos.y - self.camera_offset.y as i32) as f32,
));
rw.draw(&rs);
} }
} }
@ -79,7 +88,7 @@ pub fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePo
impl Default for GameState { impl Default for GameState {
fn default() -> Self { fn default() -> Self {
let mut spawn_point = WorldPos::SURFACE_CENTER; let mut spawn_point = WorldPos::SURFACE_CENTER;
spawn_point.y -= 300; spawn_point.y -= 304;
Self { Self {
camera_offset: spawn_point, camera_offset: spawn_point,
world: Default::default(), world: Default::default(),

View file

@ -15,7 +15,7 @@ pub struct Player {
impl Player { impl Player {
pub fn new_at(pos: WorldPos) -> Self { pub fn new_at(pos: WorldPos) -> Self {
Self { Self {
col_en: MobileEntity::from_pos_and_bb(vec2(pos.x as i32, pos.y as i32), vec2(15, 24)), col_en: MobileEntity::from_pos_and_bb(vec2(pos.x as i32, pos.y as i32), vec2(20, 46)),
vspeed: 0.0, vspeed: 0.0,
hspeed: 0.0, hspeed: 0.0,
jumps_left: 0, jumps_left: 0,
@ -30,4 +30,7 @@ impl Player {
pub fn can_jump(&self) -> bool { pub fn can_jump(&self) -> bool {
self.jumps_left > 0 self.jumps_left > 0
} }
pub fn feet_y(&self) -> i32 {
self.col_en.en.pos.y + self.col_en.en.bb.y
}
} }

View file

@ -8,13 +8,16 @@ pub struct WorldPos {
pub y: WorldPosScalar, pub y: WorldPosScalar,
} }
/// Tile size in pixels
pub const TILE_SIZE: u8 = 32; pub const TILE_SIZE: u8 = 32;
/// Pixels per meter. One meter = one tile, so this is the same as `TILE_SIZE`. /// Pixels per meter.
pub const PX_PER_M: u8 = TILE_SIZE; pub const PX_PER_M: f32 = TILE_SIZE as f32 * 2.;
/// Meters per pixel
pub const M_PER_PX: f32 = 1. / PX_PER_M;
pub const FPS_TARGET: u8 = 60; pub const FPS_TARGET: u8 = 60;
pub fn px_per_frame_to_m_per_s(px_per_frame: f32) -> f32 { pub fn px_per_frame_to_m_per_s(px_per_frame: f32) -> f32 {
let m_per_frame = px_per_frame / PX_PER_M as f32; let m_per_frame = px_per_frame / PX_PER_M;
m_per_frame * FPS_TARGET as f32 m_per_frame * FPS_TARGET as f32
} }