render some tiles

This commit is contained in:
Tao Tien 2026-01-09 23:14:29 -08:00
parent bea146d439
commit d506a25716
8 changed files with 129 additions and 60 deletions

View file

@ -6,8 +6,8 @@ use tui_logger::TuiLoggerWidget;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
pub(crate) enum ConsoleState {
#[default]
Open,
Closed,
Open,
}
impl std::ops::Not for ConsoleState {

View file

@ -1,11 +1,13 @@
use std::time::Duration;
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
use bevy_ratatui::{RatatuiContext, RatatuiPlugins};
use jong::{game::wall::Wall, tiles::Tile};
use ratatui::widgets::Paragraph;
use bevy_ratatui::RatatuiPlugins;
use jong::tiles::InWall;
use ratatui::{text::ToSpan, widgets::Paragraph};
mod console;
mod input;
mod render;
pub struct RiichiTui;
@ -26,50 +28,17 @@ impl Plugin for RiichiTui {
.init_state::<console::ConsoleState>()
.add_systems(Update, console::toggle_console)
.add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
.init_state::<TuiState>()
.add_systems(Update, input::keyboard_input_system)
.add_systems(Update, draw_system)
.add_systems(Update, render::draw_ingame.run_if(in_state(TuiState::InGame)))
// semicolon stopper
;
}
}
// #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States)]
// enum TuiState {
// MainMenu,
// InGame,
// }
pub(crate) fn draw_system(
// mut commands: Commands,
wall: Option<Single<&Wall>>,
tiles: Option<Populated<&Tile>>,
mut tui_ctx: ResMut<RatatuiContext>,
) -> Result {
let title = ratatui::text::Text::raw("tiny riichi");
let wall = if let Some(wall) = wall {
let text = (*wall)
.iter()
.map(|c| {
tiles
.as_ref()
.unwrap()
.get(c)
.map(|tile| format!("{tile:?}"))
})
.collect::<Result<String, _>>()?;
Some(Paragraph::new(text))
} else {
None
};
tui_ctx.draw(|frame| {
frame.render_widget(title, frame.area());
if let Some(wall) = wall {
frame.render_widget(wall, frame.area());
}
})?;
Ok(())
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)]
enum TuiState {
MainMenu,
#[default]
InGame,
}

55
src/tui/render.rs Normal file
View file

@ -0,0 +1,55 @@
use std::marker::PhantomData;
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
use bevy_ratatui::RatatuiContext;
use ratatui::widgets::Paragraph;
use jong::game::wall::Wall;
use jong::game::wall::WallTiles;
use jong::tiles::Tile;
mod tiles;
pub(crate) fn draw_ingame(
tiles: Query<&Tile>,
wall: Option<Single<&WallTiles, With<Wall>>>,
mut tui_ctx: ResMut<RatatuiContext>,
) -> Result {
use ratatui::layout::Flex;
use ratatui::prelude::*;
let title = ratatui::text::Text::raw("tiny riichi");
let wall = if let Some(wall) = wall {
let wall = wall
.iter()
.map(|inwall| -> Result<_> { Ok(tiles.get(inwall).map(tiles::draw_tile)?) })
.collect::<Result<Vec<_>>>()?;
// let paragraph = Paragraph::new(wall.join(", ")).wrap(ratatui::widgets::Wrap { trim: true });
Some(wall)
} else {
None
};
tui_ctx.draw(|frame| {
// frame.render_widget(title, frame.area());
debug!("{}", frame.area());
if let Some(wall) = wall {
// let tile_area = Rect::new(0, 0, 5, 4);
let layout = Layout::horizontal(vec![Constraint::Max(5); 13]).flex(Flex::Start);
let mut area = frame.area();
area.height = 4;
let areas = layout.areas::<13>(area);
// debug!("wall.len(): {}, areas.len(): {}", wall.len(), areas.len());
for (tile, rect) in wall.iter().zip(areas.iter()) {
// debug!("{rect:?}");
frame.render_widget(tile, *rect);
}
}
})?;
Ok(())
}

30
src/tui/render/tiles.rs Normal file
View file

@ -0,0 +1,30 @@
use ratatui::widgets::Paragraph;
use jong::tiles::Tile;
pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'_> {
use ratatui::prelude::*;
let block = ratatui::widgets::Block::bordered();
Paragraph::new(match &tile.suit {
jong::tiles::Suit::Pin(rank) => format!("{}\np", rank.0),
jong::tiles::Suit::Sou(rank) => format!("{}\ns", rank.0),
jong::tiles::Suit::Man(rank) => format!("{}\nm", rank.0),
jong::tiles::Suit::Wind(wind) => (match wind {
jong::tiles::Wind::Ton => "e\nw",
jong::tiles::Wind::Nan => "s\nw",
jong::tiles::Wind::Shaa => "w\nw",
jong::tiles::Wind::Pei => "n\nw",
})
.into(),
jong::tiles::Suit::Dragon(dragon) => (match dragon {
jong::tiles::Dragon::Haku => "w\nd",
jong::tiles::Dragon::Hatsu => "g\nd",
jong::tiles::Dragon::Chun => "r\nd",
})
.into(),
})
.block(block)
.centered()
}