fix(engine): resize cards along with the rest of the layout
CI / Test & Lint (push) Failing after 24s
CI / Release Build (push) Has been skipped

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 from 366fd6d is 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:
funman300
2026-04-29 22:52:16 +00:00
parent 366fd6d127
commit b10e1a5a87
+26 -17
View File
@@ -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`"
/// 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
/// reached steady state — the visible "snap back and forth" jitter.
///
/// Cards now snap directly (no slide), matching the instant repositioning
/// already used for backgrounds and pile markers in
/// `table_plugin::on_window_resized`. Any in-flight `CardAnim` is removed so
/// it cannot keep writing the old target translation after the snap.
/// Calls `sync_cards` with `slide_secs = 0.0` so `update_card_entity` snaps
/// instantly (line `(cur - target).length() > 1.0 && slide_secs > 0.0` falls
/// to the snap branch), refreshes the `Sprite` with the new
/// `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
/// `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
/// 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(
mut events: MessageReader<WindowResized>,
mut commands: Commands,
game: Option<Res<GameStateResource>>,
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)>,
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(layout) = layout else { return };
let mut targets: HashMap<u32, (Vec2, f32)> = HashMap::new();
for (card, pos, z) in card_positions(&game.0, &layout.0) {
targets.insert(card.id, (pos, z));
}
for (entity, marker, mut transform) in &mut entities {
if let Some(&(pos, z)) = targets.get(&marker.card_id) {
transform.translation = Vec3::new(pos.x, pos.y, z);
commands.entity(entity).remove::<CardAnim>();
}
}
let selected_back = settings.as_ref().map_or(0, |s| s.0.selected_card_back);
let back_colour = card_back_colour(selected_back);
let color_blind = settings.as_ref().is_some_and(|s| s.0.color_blind_mode);
sync_cards(
commands.reborrow(),
&game.0,
&layout.0,
0.0,
back_colour,
color_blind,
&entities,
card_images.as_deref(),
selected_back,
);
apply_stock_empty_indicator(
&mut commands,