Add screen fade-in and card deal-in animations
Cards slide in one after another when a game starts and can't be picked until they have landed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
83ff9511ec
commit
3794a9e2e9
4 files changed
+1751
-1159
No files matched your search
+21
-5
@@ -15,6 +15,8 @@ ROUNDNESS :: 0.16
|
||||
SEGMENTS :: 16
|
||||
|
||||
FLIP_SPEED :: 2.6 // flips per second
|
||||
DEAL_SPEED :: 3.5 // how fast a dealt card settles
|
||||
DEAL_STAGGER :: 0.12 // delay between consecutive cards, in deal_t units
|
||||
PULSE_DURATION :: 0.35 // seconds
|
||||
HOVER_LIFT :: 4
|
||||
|
||||
@@ -28,6 +30,7 @@ Card :: struct {
|
||||
matched: bool,
|
||||
flip_t: f32, // 0 = back showing, 1 = face showing
|
||||
pulse_t: f32, // counts down after a match
|
||||
deal_t: f32, // > 0 while being dealt onto the table (0 = resting)
|
||||
face_art: raylib.RenderTexture2D,
|
||||
}
|
||||
|
||||
@@ -214,6 +217,14 @@ update :: proc(card: ^Card, dt: f32) {
|
||||
if card.pulse_t > 0 {
|
||||
card.pulse_t = max(card.pulse_t - dt, 0)
|
||||
}
|
||||
if card.deal_t > 0 {
|
||||
card.deal_t = max(card.deal_t - dt * DEAL_SPEED, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Starts the deal-in animation; later cards in the deal arrive later
|
||||
start_deal :: proc(card: ^Card, order: int) {
|
||||
card.deal_t = 1 + f32(order) * DEAL_STAGGER
|
||||
}
|
||||
|
||||
start_pulse :: proc(card: ^Card) {
|
||||
@@ -241,7 +252,12 @@ draw :: proc(card: ^Card, theme: themes.Theme, clickable: bool, focused := false
|
||||
hovered := mouse_over || (clickable && focused)
|
||||
if hovered { lift += HOVER_LIFT }
|
||||
|
||||
scale: f32 = 1
|
||||
// Dealing: slide up from below and grow in
|
||||
dealt := smoothstep(1 - clamp(card.deal_t, 0, 1))
|
||||
if dealt == 0 { return }
|
||||
deal_offset := (1 - dealt) * 60
|
||||
|
||||
scale: f32 = 0.85 + 0.15 * dealt
|
||||
if card.pulse_t > 0 {
|
||||
progress := 1 - card.pulse_t / PULSE_DURATION
|
||||
scale += 0.09 * math.sin(progress * math.PI)
|
||||
@@ -249,20 +265,20 @@ draw :: proc(card: ^Card, theme: themes.Theme, clickable: bool, focused := false
|
||||
|
||||
width := card.rect.width * scale
|
||||
height := card.rect.height * scale
|
||||
center := raylib.Vector2{card.rect.x + card.rect.width / 2, card.rect.y + card.rect.height / 2 - lift}
|
||||
center := raylib.Vector2{card.rect.x + card.rect.width / 2, card.rect.y + card.rect.height / 2 - lift + deal_offset}
|
||||
|
||||
// Shadow stays on the table and spreads as the card lifts
|
||||
shadow := raylib.Rectangle{
|
||||
center.x - width * squash / 2 + 2,
|
||||
card.rect.y + card.rect.height * (1 - scale) / 2 + 4 + lift * 0.15,
|
||||
card.rect.y + card.rect.height * (1 - scale) / 2 + 4 + lift * 0.15 + deal_offset,
|
||||
max(width * squash, 2),
|
||||
height,
|
||||
}
|
||||
raylib.DrawRectangleRounded(shadow, ROUNDNESS, SEGMENTS, raylib.Fade(themes.BLACK, 0.12 - lift * 0.004))
|
||||
raylib.DrawRectangleRounded(shadow, ROUNDNESS, SEGMENTS, raylib.Fade(themes.BLACK, (0.12 - lift * 0.004) * dealt))
|
||||
|
||||
// Darken the card while it is edge-on, to fake lighting
|
||||
shade := u8(255 - (1 - squash) * 70)
|
||||
tint := raylib.Color{shade, shade, shade, 255}
|
||||
tint := raylib.Color{shade, shade, shade, u8(255 * dealt)}
|
||||
if hovered && !showing_face {
|
||||
tint = raylib.ColorBrightness(tint, 0.08)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user