fix(android): visual polish — green fallback, A-markers, wider fan, compact HUD
- camera clear colour → TABLE_COLOUR green so the background reads as felt even before bg_0.png finishes loading (async on Android) - foundation empty markers now show "A" child text (same pattern as the "K" on tableau markers) — no suit letter since any Ace claims any slot - HUD_BAND_HEIGHT = 128 on Android to accommodate the two-row button wrap on narrow phones; card grid reserves this space so buttons no longer overlap the top card row - TABLEAU_FACEDOWN_FAN_FRAC 0.12 → 0.20 (layout.rs + card_plugin.rs): face-down stacks show ~67% more back strip per card on fresh deal, bringing the deepest column from ~27% to ~40% of available screen height - update_tableau_fan_frac: return early when max face-up depth ≤ 1 instead of overwriting the layout-computed adaptive value with the desktop minimum (0.25); fixes a regression where the portrait-phone adaptive fan_frac was silently snapped to 0.25 on every new deal - update_tableau_fan_frac: also propagate facedown_fan_frac updates in the mid-game path (previously computed but immediately discarded) - Android HUD buttons: compact Unicode icon labels (≡ ↩ ? ⏸ ⚙▾ +) with tighter padding (4 dp) and min-size (44 dp), max-width 90% — all 7 buttons fit in a single 44 dp row on a 411 dp phone Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -151,9 +151,22 @@ fn setup_table(
|
||||
safe_area: Option<Res<SafeAreaInsets>>,
|
||||
) {
|
||||
// Only spawn a camera if one does not already exist (e.g. a parent app
|
||||
// may have added one in tests).
|
||||
// may have added one in tests). Use the felt-green clear colour so the
|
||||
// background reads as green even before the background PNG finishes
|
||||
// loading (which is asynchronous and can lag by several frames on
|
||||
// Android).
|
||||
if existing_camera.is_empty() {
|
||||
commands.spawn(Camera2d);
|
||||
commands.spawn((
|
||||
Camera2d,
|
||||
Camera {
|
||||
clear_color: ClearColorConfig::Custom(Color::srgb(
|
||||
crate::layout::TABLE_COLOUR[0],
|
||||
crate::layout::TABLE_COLOUR[1],
|
||||
crate::layout::TABLE_COLOUR[2],
|
||||
)),
|
||||
..default()
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
let (window_size, scale) = windows.iter().next().map_or(
|
||||
@@ -267,20 +280,31 @@ fn spawn_pile_markers(commands: &mut Commands, layout: &Layout) {
|
||||
PileMarker(pile.clone()),
|
||||
));
|
||||
|
||||
// Foundation slots no longer carry a suit letter — any Ace can claim
|
||||
// any empty slot, so a fixed C/D/H/S badge would be misleading. Empty
|
||||
// foundation markers render as plain translucent rectangles.
|
||||
|
||||
// Task #43 — King indicator on empty tableau placeholders.
|
||||
if let PileType::Tableau(_) = &pile {
|
||||
entity.with_children(|b| {
|
||||
b.spawn((
|
||||
Text2d::new("K"),
|
||||
TextFont { font_size, ..default() },
|
||||
TextColor(TEXT_PRIMARY.with_alpha(0.35)),
|
||||
Transform::from_xyz(0.0, 0.0, 0.1),
|
||||
));
|
||||
});
|
||||
// Tableau markers show "K" (only a King may start an empty column).
|
||||
// Foundation markers show "A" (only an Ace may claim an empty slot).
|
||||
// Neither label carries a suit because any suit may start any slot.
|
||||
match &pile {
|
||||
PileType::Tableau(_) => {
|
||||
entity.with_children(|b| {
|
||||
b.spawn((
|
||||
Text2d::new("K"),
|
||||
TextFont { font_size, ..default() },
|
||||
TextColor(TEXT_PRIMARY.with_alpha(0.35)),
|
||||
Transform::from_xyz(0.0, 0.0, 0.1),
|
||||
));
|
||||
});
|
||||
}
|
||||
PileType::Foundation(_) => {
|
||||
entity.with_children(|b| {
|
||||
b.spawn((
|
||||
Text2d::new("A"),
|
||||
TextFont { font_size, ..default() },
|
||||
TextColor(TEXT_PRIMARY.with_alpha(0.35)),
|
||||
Transform::from_xyz(0.0, 0.0, 0.1),
|
||||
));
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user