fix(engine): resize cards along with the rest of the layout
The first resize-jitter fix (366fd6d) only snapped card transforms, not the Sprite::custom_size. Cards stayed at the old size after a window resize until the next StateChangedEvent (move, draw, undo, new-game) refreshed them via sync_cards_on_change. Reported during smoke testing: "the placeholder grey boxes change size but the cards do not until I make an update to the window". Replace the manual transform-only loop in snap_cards_on_window_resize with a call to sync_cards(slide_secs = 0.0). update_card_entity unconditionally inserts a fresh Sprite via card_sprite() with the current layout.card_size, so cards now visibly resize. With slide_secs=0 it also takes the snap branch (no CardAnim slide), so the underlying jitter fix from366fd6dis preserved. apply_stock_empty_indicator is still called separately because sync_cards doesn't touch the stock-empty "↺" label. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1116,7 +1116,8 @@ fn update_stock_empty_indicator(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Snaps every card sprite to its target position when the window is resized.
|
/// Snaps every card sprite to its target position and size when the window
|
||||||
|
/// is resized.
|
||||||
///
|
///
|
||||||
/// This replaces the old "fire `StateChangedEvent` from `on_window_resized`"
|
/// This replaces the old "fire `StateChangedEvent` from `on_window_resized`"
|
||||||
/// path. That path went through `sync_cards_on_change` → `update_card_entity`,
|
/// path. That path went through `sync_cards_on_change` → `update_card_entity`,
|
||||||
@@ -1125,10 +1126,11 @@ fn update_stock_empty_indicator(
|
|||||||
/// retargeted the tween from the card's mid-slide position, so cards never
|
/// retargeted the tween from the card's mid-slide position, so cards never
|
||||||
/// reached steady state — the visible "snap back and forth" jitter.
|
/// reached steady state — the visible "snap back and forth" jitter.
|
||||||
///
|
///
|
||||||
/// Cards now snap directly (no slide), matching the instant repositioning
|
/// Calls `sync_cards` with `slide_secs = 0.0` so `update_card_entity` snaps
|
||||||
/// already used for backgrounds and pile markers in
|
/// instantly (line `(cur - target).length() > 1.0 && slide_secs > 0.0` falls
|
||||||
/// `table_plugin::on_window_resized`. Any in-flight `CardAnim` is removed so
|
/// to the snap branch), refreshes the `Sprite` with the new
|
||||||
/// it cannot keep writing the old target translation after the snap.
|
/// `layout.card_size` (so cards visibly resize, not just reposition), and
|
||||||
|
/// removes any in-flight `CardAnim`.
|
||||||
///
|
///
|
||||||
/// The "↺" stock-empty label's `font_size` is derived from
|
/// The "↺" stock-empty label's `font_size` is derived from
|
||||||
/// `layout.card_size.x`, so this system also reapplies the stock indicator —
|
/// `layout.card_size.x`, so this system also reapplies the stock indicator —
|
||||||
@@ -1137,13 +1139,15 @@ fn update_stock_empty_indicator(
|
|||||||
///
|
///
|
||||||
/// Scheduled `.after(LayoutSystem::UpdateOnResize)` so `LayoutResource` has
|
/// Scheduled `.after(LayoutSystem::UpdateOnResize)` so `LayoutResource` has
|
||||||
/// been refreshed by `table_plugin::on_window_resized` before this runs.
|
/// been refreshed by `table_plugin::on_window_resized` before this runs.
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn snap_cards_on_window_resize(
|
fn snap_cards_on_window_resize(
|
||||||
mut events: MessageReader<WindowResized>,
|
mut events: MessageReader<WindowResized>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
game: Option<Res<GameStateResource>>,
|
game: Option<Res<GameStateResource>>,
|
||||||
layout: Option<Res<LayoutResource>>,
|
layout: Option<Res<LayoutResource>>,
|
||||||
mut entities: Query<(Entity, &CardEntity, &mut Transform)>,
|
settings: Option<Res<SettingsResource>>,
|
||||||
|
card_images: Option<Res<CardImageSet>>,
|
||||||
|
entities: Query<(Entity, &CardEntity, &Transform)>,
|
||||||
mut pile_markers: Query<(Entity, &PileMarker, &mut Sprite)>,
|
mut pile_markers: Query<(Entity, &PileMarker, &mut Sprite)>,
|
||||||
label_children: Query<(Entity, &ChildOf), With<StockEmptyLabel>>,
|
label_children: Query<(Entity, &ChildOf), With<StockEmptyLabel>>,
|
||||||
) {
|
) {
|
||||||
@@ -1153,16 +1157,21 @@ fn snap_cards_on_window_resize(
|
|||||||
let Some(game) = game else { return };
|
let Some(game) = game else { return };
|
||||||
let Some(layout) = layout else { return };
|
let Some(layout) = layout else { return };
|
||||||
|
|
||||||
let mut targets: HashMap<u32, (Vec2, f32)> = HashMap::new();
|
let selected_back = settings.as_ref().map_or(0, |s| s.0.selected_card_back);
|
||||||
for (card, pos, z) in card_positions(&game.0, &layout.0) {
|
let back_colour = card_back_colour(selected_back);
|
||||||
targets.insert(card.id, (pos, z));
|
let color_blind = settings.as_ref().is_some_and(|s| s.0.color_blind_mode);
|
||||||
}
|
|
||||||
for (entity, marker, mut transform) in &mut entities {
|
sync_cards(
|
||||||
if let Some(&(pos, z)) = targets.get(&marker.card_id) {
|
commands.reborrow(),
|
||||||
transform.translation = Vec3::new(pos.x, pos.y, z);
|
&game.0,
|
||||||
commands.entity(entity).remove::<CardAnim>();
|
&layout.0,
|
||||||
}
|
0.0,
|
||||||
}
|
back_colour,
|
||||||
|
color_blind,
|
||||||
|
&entities,
|
||||||
|
card_images.as_deref(),
|
||||||
|
selected_back,
|
||||||
|
);
|
||||||
|
|
||||||
apply_stock_empty_indicator(
|
apply_stock_empty_indicator(
|
||||||
&mut commands,
|
&mut commands,
|
||||||
|
|||||||
Reference in New Issue
Block a user