mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-14 19:55:02 +01:00
Console, experimental tile graphic for continuous tiles
This commit is contained in:
parent
8ee0c9d535
commit
4dfb0ff7d7
12 changed files with 201 additions and 23 deletions
BIN
res/graphics/tiles/panzerium.png
Normal file
BIN
res/graphics/tiles/panzerium.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 962 B |
65
src/app.rs
65
src/app.rs
|
|
@ -13,6 +13,7 @@ use sfml::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
command::{Cmd, CmdVec},
|
||||||
debug::{self, DebugState},
|
debug::{self, DebugState},
|
||||||
game::{for_each_tile_on_screen, Biome, GameState},
|
game::{for_each_tile_on_screen, Biome, GameState},
|
||||||
graphics::{self, ScreenSc, ScreenVec},
|
graphics::{self, ScreenSc, ScreenVec},
|
||||||
|
|
@ -39,6 +40,7 @@ pub struct App {
|
||||||
/// Light map overlay, blended together with the non-lighted version of the scene
|
/// Light map overlay, blended together with the non-lighted version of the scene
|
||||||
pub light_map: RenderTexture,
|
pub light_map: RenderTexture,
|
||||||
pub project_dirs: ProjectDirs,
|
pub project_dirs: ProjectDirs,
|
||||||
|
pub cmdvec: CmdVec,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
|
@ -69,6 +71,7 @@ impl App {
|
||||||
rt,
|
rt,
|
||||||
light_map,
|
light_map,
|
||||||
project_dirs,
|
project_dirs,
|
||||||
|
cmdvec: CmdVec::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +90,14 @@ impl App {
|
||||||
fn do_event_handling(&mut self) {
|
fn do_event_handling(&mut self) {
|
||||||
while let Some(ev) = self.rw.poll_event() {
|
while let Some(ev) = self.rw.poll_event() {
|
||||||
self.sf_egui.add_event(&ev);
|
self.sf_egui.add_event(&ev);
|
||||||
self.input.update_from_event(&ev);
|
{
|
||||||
|
let ctx = self.sf_egui.context();
|
||||||
|
self.input.update_from_event(
|
||||||
|
&ev,
|
||||||
|
ctx.wants_keyboard_input(),
|
||||||
|
ctx.wants_pointer_input(),
|
||||||
|
);
|
||||||
|
}
|
||||||
match ev {
|
match ev {
|
||||||
Event::Closed => self.should_quit = true,
|
Event::Closed => self.should_quit = true,
|
||||||
Event::Resized { width, height } => {
|
Event::Resized { width, height } => {
|
||||||
|
|
@ -100,13 +110,20 @@ impl App {
|
||||||
let view = View::from_rect(Rect::new(0., 0., width as f32, height as f32));
|
let view = View::from_rect(Rect::new(0., 0., width as f32, height as f32));
|
||||||
self.rw.set_view(&view);
|
self.rw.set_view(&view);
|
||||||
}
|
}
|
||||||
|
Event::KeyPressed { code, .. } => match code {
|
||||||
|
Key::F11 => {
|
||||||
|
self.debug.console.show ^= true;
|
||||||
|
self.debug.console.just_opened = true;
|
||||||
|
}
|
||||||
|
Key::F12 => self.debug.panel ^= true,
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_update(&mut self) {
|
fn do_update(&mut self) {
|
||||||
self.debug.update(&self.input);
|
|
||||||
let rt_size = self.rt.size();
|
let rt_size = self.rt.size();
|
||||||
if self.debug.freecam {
|
if self.debug.freecam {
|
||||||
self.do_freecam();
|
self.do_freecam();
|
||||||
|
|
@ -246,9 +263,21 @@ impl App {
|
||||||
let t = self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen);
|
let t = self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen);
|
||||||
match &def.use_action {
|
match &def.use_action {
|
||||||
UseAction::PlaceTile { layer, id } => match layer {
|
UseAction::PlaceTile { layer, id } => match layer {
|
||||||
TileLayer::Bg => t.bg = *id,
|
TileLayer::Bg => {
|
||||||
TileLayer::Mid => t.mid = *id,
|
if t.bg == 0 {
|
||||||
TileLayer::Fg => t.fg = *id,
|
t.bg = *id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TileLayer::Mid => {
|
||||||
|
if t.mid == 0 {
|
||||||
|
t.mid = *id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TileLayer::Fg => {
|
||||||
|
if t.fg == 0 {
|
||||||
|
t.fg = *id
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
UseAction::RemoveTile { layer } => match layer {
|
UseAction::RemoveTile { layer } => match layer {
|
||||||
TileLayer::Bg => t.bg = 0,
|
TileLayer::Bg => t.bg = 0,
|
||||||
|
|
@ -340,10 +369,10 @@ impl App {
|
||||||
&mut self.game,
|
&mut self.game,
|
||||||
&mut self.res,
|
&mut self.res,
|
||||||
&mut self.scale,
|
&mut self.scale,
|
||||||
|
&mut self.cmdvec,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.sf_egui.draw(&mut self.rw, None);
|
|
||||||
if self.debug.show_atlas {
|
if self.debug.show_atlas {
|
||||||
let atlas = &self.res.atlas.tex;
|
let atlas = &self.res.atlas.tex;
|
||||||
let size = atlas.size();
|
let size = atlas.size();
|
||||||
|
|
@ -352,7 +381,31 @@ impl App {
|
||||||
self.rw.draw(&rs);
|
self.rw.draw(&rs);
|
||||||
self.rw.draw(&Sprite::with_texture(atlas));
|
self.rw.draw(&Sprite::with_texture(atlas));
|
||||||
}
|
}
|
||||||
|
self.sf_egui.draw(&mut self.rw, None);
|
||||||
self.rw.display();
|
self.rw.display();
|
||||||
|
drop(spr);
|
||||||
|
self.execute_commands();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_commands(&mut self) {
|
||||||
|
for cmd in self.cmdvec.drain(..) {
|
||||||
|
match cmd {
|
||||||
|
Cmd::QuitApp => self.should_quit = true,
|
||||||
|
Cmd::ToggleFreecam => self.debug.freecam ^= true,
|
||||||
|
Cmd::TeleportPlayer { pos, relative } => {
|
||||||
|
if relative {
|
||||||
|
let s2dc = pos.to_s2dc();
|
||||||
|
self.game.world.player.col_en.en.pos.x += s2dc.x;
|
||||||
|
self.game.world.player.col_en.en.pos.y += s2dc.y;
|
||||||
|
} else {
|
||||||
|
self.game.world.player.col_en.en.pos = pos.to_s2dc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cmd::TeleportPlayerSpawn => {
|
||||||
|
self.game.world.player.col_en.en.pos = self.game.spawn_point.to_s2dc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
54
src/cmdline.rs
Normal file
54
src/cmdline.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
use clap::Parser;
|
||||||
|
|
||||||
|
use crate::{command::Cmd, math::WorldPos};
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
pub enum CmdLine {
|
||||||
|
Quit,
|
||||||
|
Freecam,
|
||||||
|
Clear,
|
||||||
|
Tp(Tp),
|
||||||
|
Spawn,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
pub struct Tp {
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
/// Relative to current position
|
||||||
|
#[arg(short, long)]
|
||||||
|
rel: bool,
|
||||||
|
}
|
||||||
|
impl Tp {
|
||||||
|
fn to_world_pos(&self) -> WorldPos {
|
||||||
|
WorldPos {
|
||||||
|
x: self.x,
|
||||||
|
y: self.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Dispatch {
|
||||||
|
Cmd(Cmd),
|
||||||
|
ClearConsole,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CmdLine {
|
||||||
|
pub fn parse_cmdline(cmdline: &str) -> anyhow::Result<Self> {
|
||||||
|
let words = std::iter::once(" ").chain(cmdline.split_whitespace());
|
||||||
|
Ok(Self::try_parse_from(words)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn dispatch(&self) -> Dispatch {
|
||||||
|
match self {
|
||||||
|
CmdLine::Quit => Dispatch::Cmd(Cmd::QuitApp),
|
||||||
|
CmdLine::Freecam => Dispatch::Cmd(Cmd::ToggleFreecam),
|
||||||
|
CmdLine::Clear => Dispatch::ClearConsole,
|
||||||
|
CmdLine::Tp(tp) => Dispatch::Cmd(Cmd::TeleportPlayer {
|
||||||
|
pos: tp.to_world_pos(),
|
||||||
|
relative: tp.rel,
|
||||||
|
}),
|
||||||
|
CmdLine::Spawn => Dispatch::Cmd(Cmd::TeleportPlayerSpawn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/command.rs
Normal file
15
src/command.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
use crate::math::WorldPos;
|
||||||
|
|
||||||
|
/// A command that can change application or game state
|
||||||
|
pub enum Cmd {
|
||||||
|
/// Quit the application
|
||||||
|
QuitApp,
|
||||||
|
ToggleFreecam,
|
||||||
|
TeleportPlayer {
|
||||||
|
pos: WorldPos,
|
||||||
|
relative: bool,
|
||||||
|
},
|
||||||
|
TeleportPlayerSpawn,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CmdVec = Vec<Cmd>;
|
||||||
63
src/debug.rs
63
src/debug.rs
|
|
@ -1,9 +1,12 @@
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
use egui_inspect::{derive::Inspect, inspect};
|
use egui_inspect::{derive::Inspect, inspect};
|
||||||
use sfml::{audio::SoundSource, window::Key};
|
use sfml::audio::SoundSource;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
cmdline::CmdLine,
|
||||||
|
command::CmdVec,
|
||||||
game::GameState,
|
game::GameState,
|
||||||
input::Input,
|
|
||||||
math::{px_per_frame_to_km_h, WorldPos},
|
math::{px_per_frame_to_km_h, WorldPos},
|
||||||
res::Res,
|
res::Res,
|
||||||
stringfmt::LengthDisp,
|
stringfmt::LengthDisp,
|
||||||
|
|
@ -13,21 +16,19 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Default, Debug, Inspect)]
|
#[derive(Default, Debug, Inspect)]
|
||||||
pub struct DebugState {
|
pub struct DebugState {
|
||||||
panel: bool,
|
pub panel: bool,
|
||||||
pub freecam: bool,
|
pub freecam: bool,
|
||||||
tiledb_edit: bool,
|
pub tiledb_edit: bool,
|
||||||
pub show_atlas: bool,
|
pub show_atlas: bool,
|
||||||
|
pub console: Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugState {
|
#[derive(Default, Debug, Inspect)]
|
||||||
pub fn update(&mut self, input: &Input) {
|
pub struct Console {
|
||||||
if input.pressed(Key::F12) {
|
pub show: bool,
|
||||||
self.panel ^= true;
|
pub cmdline: String,
|
||||||
}
|
pub log: String,
|
||||||
if input.pressed(Key::F10) {
|
pub just_opened: bool,
|
||||||
self.freecam ^= true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_panel_ui(
|
fn debug_panel_ui(
|
||||||
|
|
@ -112,6 +113,7 @@ pub(crate) fn do_debug_ui(
|
||||||
game: &mut GameState,
|
game: &mut GameState,
|
||||||
res: &mut Res,
|
res: &mut Res,
|
||||||
scale: &mut u8,
|
scale: &mut u8,
|
||||||
|
cmd: &mut CmdVec,
|
||||||
) {
|
) {
|
||||||
if debug.panel {
|
if debug.panel {
|
||||||
debug_panel_ui(debug, game, ctx, res, scale);
|
debug_panel_ui(debug, game, ctx, res, scale);
|
||||||
|
|
@ -119,4 +121,39 @@ pub(crate) fn do_debug_ui(
|
||||||
if debug.tiledb_edit {
|
if debug.tiledb_edit {
|
||||||
tiledb_edit_ui(ctx, &mut game.tile_db);
|
tiledb_edit_ui(ctx, &mut game.tile_db);
|
||||||
}
|
}
|
||||||
|
if debug.console.show {
|
||||||
|
console_ui(ctx, debug, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn console_ui(ctx: &egui::Context, debug: &mut DebugState, cmd: &mut CmdVec) {
|
||||||
|
egui::Window::new("Console (F11)").show(ctx, |ui| {
|
||||||
|
let re =
|
||||||
|
ui.add(egui::TextEdit::singleline(&mut debug.console.cmdline).hint_text("Command"));
|
||||||
|
if debug.console.just_opened {
|
||||||
|
re.request_focus();
|
||||||
|
}
|
||||||
|
if re.lost_focus() && ui.input(|inp| inp.key_pressed(egui::Key::Enter)) {
|
||||||
|
re.request_focus();
|
||||||
|
let cmdline = match CmdLine::parse_cmdline(&debug.console.cmdline) {
|
||||||
|
Ok(cmd) => cmd,
|
||||||
|
Err(e) => {
|
||||||
|
writeln!(&mut debug.console.log, "{e}").unwrap();
|
||||||
|
debug.console.cmdline.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
debug.console.cmdline.clear();
|
||||||
|
match cmdline.dispatch() {
|
||||||
|
crate::cmdline::Dispatch::Cmd(command) => cmd.push(command),
|
||||||
|
crate::cmdline::Dispatch::ClearConsole => debug.console.log.clear(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
egui::ScrollArea::vertical()
|
||||||
|
.stick_to_bottom(true)
|
||||||
|
.show(ui, |ui| {
|
||||||
|
ui.add(egui::TextEdit::multiline(&mut &debug.console.log[..]));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
debug.console.just_opened = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ pub struct GameState {
|
||||||
pub inventory: Inventory,
|
pub inventory: Inventory,
|
||||||
pub itemdb: ItemDb,
|
pub itemdb: ItemDb,
|
||||||
pub selected_inv_slot: usize,
|
pub selected_inv_slot: usize,
|
||||||
|
pub spawn_point: WorldPos,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Inspect)]
|
#[derive(Debug, Inspect)]
|
||||||
|
|
@ -182,6 +183,7 @@ impl GameState {
|
||||||
inventory: Inventory::new_debug(),
|
inventory: Inventory::new_debug(),
|
||||||
itemdb: ItemDb::default(),
|
itemdb: ItemDb::default(),
|
||||||
selected_inv_slot: 0,
|
selected_inv_slot: 0,
|
||||||
|
spawn_point,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/input.rs
11
src/input.rs
|
|
@ -14,7 +14,7 @@ pub struct Input {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn update_from_event(&mut self, ev: &Event) {
|
pub fn update_from_event(&mut self, ev: &Event, egui_kbd: bool, egui_ptr: bool) {
|
||||||
match ev {
|
match ev {
|
||||||
&Event::KeyPressed { code, .. } => {
|
&Event::KeyPressed { code, .. } => {
|
||||||
self.pressed.insert(code);
|
self.pressed.insert(code);
|
||||||
|
|
@ -52,6 +52,15 @@ impl Input {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
if egui_kbd {
|
||||||
|
self.pressed.clear();
|
||||||
|
self.down.clear();
|
||||||
|
}
|
||||||
|
if egui_ptr {
|
||||||
|
self.lmb_down = false;
|
||||||
|
self.rmb_down = false;
|
||||||
|
self.mid_pressed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// Pressed event should be cleared every frame
|
/// Pressed event should be cleared every frame
|
||||||
pub fn clear_pressed(&mut self) {
|
pub fn clear_pressed(&mut self) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
mod app;
|
mod app;
|
||||||
mod bitmanip;
|
mod bitmanip;
|
||||||
|
mod cmdline;
|
||||||
|
mod command;
|
||||||
mod debug;
|
mod debug;
|
||||||
mod game;
|
mod game;
|
||||||
mod graphics;
|
mod graphics;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,13 @@ impl WorldPos {
|
||||||
x: Self::CENTER,
|
x: Self::CENTER,
|
||||||
y: Self::SURFACE,
|
y: Self::SURFACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub(crate) fn to_s2dc(self) -> s2dc::Vec2 {
|
||||||
|
s2dc::Vec2 {
|
||||||
|
x: self.x as i32,
|
||||||
|
y: self.y as i32,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wp_to_tp(wp: WPosSc) -> TPosSc {
|
pub fn wp_to_tp(wp: WPosSc) -> TPosSc {
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ pub struct AtlasBundle {
|
||||||
impl AtlasBundle {
|
impl AtlasBundle {
|
||||||
pub fn new() -> anyhow::Result<Self> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let cfg = TexturePackerConfig {
|
let cfg = TexturePackerConfig {
|
||||||
max_width: 4096,
|
max_width: 512,
|
||||||
max_height: 4096,
|
max_height: 512,
|
||||||
allow_rotation: false,
|
allow_rotation: false,
|
||||||
border_padding: 0,
|
border_padding: 0,
|
||||||
texture_padding: 0,
|
texture_padding: 0,
|
||||||
|
|
@ -65,7 +65,6 @@ fn make_pix_buf(packer: &TexturePacker<image::DynamicImage, String>) -> Vec<u8>
|
||||||
let (w, h) = (packer.width(), packer.height());
|
let (w, h) = (packer.width(), packer.height());
|
||||||
let px_size = 4;
|
let px_size = 4;
|
||||||
let mut vec = vec![0; w as usize * h as usize * px_size as usize];
|
let mut vec = vec![0; w as usize * h as usize * px_size as usize];
|
||||||
dbg!(w, h);
|
|
||||||
for y in 0..h {
|
for y in 0..h {
|
||||||
for x in 0..w {
|
for x in 0..w {
|
||||||
let idx = ((y * w + x) * px_size) as usize;
|
let idx = ((y * w + x) * px_size) as usize;
|
||||||
|
|
|
||||||
BIN
tiles.dat
BIN
tiles.dat
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue