Skip to content

Commit a61aeb9

Browse files
committed
added helper hint nudge
1 parent 824291a commit a61aeb9

9 files changed

Lines changed: 244 additions & 14 deletions

export_presets.cfg

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ architectures/armeabi-v7a=false
9191
architectures/arm64-v8a=true
9292
architectures/x86=false
9393
architectures/x86_64=false
94-
version/code=4
95-
version/name="0.0.4"
94+
version/code=5
95+
version/name="0.0.5"
9696
package/unique_name="org.grassecon.cellular"
9797
package/name="Cellular"
9898
package/signed=true
@@ -321,8 +321,8 @@ architectures/armeabi-v7a=false
321321
architectures/arm64-v8a=true
322322
architectures/x86=false
323323
architectures/x86_64=false
324-
version/code=4
325-
version/name="0.0.4"
324+
version/code=5
325+
version/name="0.0.5"
326326
package/unique_name="org.grassecon.cellular"
327327
package/name="Cellular"
328328
package/signed=true

project.godot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ config_version=5
1111
[application]
1212

1313
config/name="Cellular"
14-
config/version="0.0.4"
14+
config/version="0.0.5"
1515
run/main_scene="res://scenes/title_screen.tscn"
1616
config/quit_on_go_back=false
1717
config/features=PackedStringArray("4.6", "C#", "GL Compatibility")

scenes/cellular_arcade_level.gd

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ const SCORE_PULSE_SECONDS := 0.72
6161
const HIGH_SCORE_PULSE_SECONDS := 1.18
6262
const HIGH_SCORE_SPARKLE_COUNT := 14
6363
const INVENTORY_FRESH_SECONDS := 1.55
64+
const IDLE_HINT_DELAY_SECONDS := 5.0
65+
const IDLE_HINT_PULSE_SECONDS := 2.0
66+
const IDLE_HINT_MAX_SCALE := 1.22
6467
const INVENTORY_SLOT_SCALE := 1.28
6568
const INVENTORY_CELL_SCALE := 1.10
6669
const INVENTORY_CELL_Y_OFFSET := 0.06
@@ -149,6 +152,9 @@ var _hint_inventory_cursor := 0
149152
var _hint_board_cursor := 0
150153
var _hint_next_inventory_board := true
151154
var _hint_text := ""
155+
var _idle_hint_elapsed := 0.0
156+
var _idle_hint_pulse_elapsed := IDLE_HINT_PULSE_SECONDS
157+
var _idle_hint_disabled_after_hint := false
152158
var _score := 0
153159
var _game_over := false
154160
var _full_board_pending_check := false
@@ -213,8 +219,9 @@ func _process(delta: float) -> void:
213219
return
214220
var score_pulse_active := _advance_score_pulse(delta)
215221
var high_score_pulse_active := _advance_high_score_pulse(delta)
222+
var idle_hint_active := _advance_idle_hint_nudge(delta)
216223
var inventory_fresh_active := _has_inventory_fresh_animation()
217-
var hud_pulse_active := score_pulse_active or high_score_pulse_active
224+
var hud_pulse_active := score_pulse_active or high_score_pulse_active or idle_hint_active
218225
if _is_clear_effect_active():
219226
_reset_full_board_game_over_grace()
220227
_clear_effect_elapsed += maxf(delta, 0.0)
@@ -423,6 +430,7 @@ func _start_run() -> void:
423430
_hint_board_cursor = 0
424431
_hint_next_inventory_board = true
425432
_hint_text = ""
433+
_enable_idle_hint_nudge()
426434
_status_text = ""
427435
_clear_effect_ids.clear()
428436
_clear_effect_elapsed = 0.0
@@ -934,6 +942,8 @@ func _clear_qualifying_groups() -> bool:
934942
var points := cleared_count + maxi(0, cleared_count - CLEAR_GROUP_MIN_SIZE)
935943
var previous_high_score := int(Global.high_score)
936944
_score += points
945+
if _score > 4:
946+
_reset_idle_hint_nudge()
937947
Global.add_score(points)
938948
if _score > previous_high_score and int(Global.high_score) > previous_high_score:
939949
_run_had_new_high_score = true
@@ -1116,6 +1126,7 @@ func _show_game_over() -> void:
11161126
if _game_over:
11171127
return
11181128
_game_over = true
1129+
_reset_idle_hint_nudge()
11191130
_reset_full_board_game_over_grace()
11201131
Global.record_last_score(_score)
11211132
_update_hud_text()
@@ -1516,6 +1527,104 @@ func _reset_high_score_pulse_visual() -> void:
15161527
_high_score_label.add_theme_constant_override("outline_size", 3)
15171528

15181529

1530+
func _idle_hint_should_pause() -> bool:
1531+
if _score > 4:
1532+
return true
1533+
if _visual_profile_enabled:
1534+
return true
1535+
if _drag_source != DRAG_SOURCE_NONE:
1536+
return true
1537+
return _game_over or _is_clear_effect_active()
1538+
1539+
1540+
func _advance_idle_hint_nudge(delta: float) -> bool:
1541+
if _idle_hint_disabled_after_hint:
1542+
if _is_idle_hint_nudge_active():
1543+
_reset_idle_hint_nudge()
1544+
return true
1545+
return false
1546+
if _idle_hint_should_pause():
1547+
if _is_idle_hint_nudge_active():
1548+
_reset_idle_hint_nudge()
1549+
return true
1550+
return false
1551+
if _is_idle_hint_nudge_active():
1552+
_idle_hint_pulse_elapsed = minf(IDLE_HINT_PULSE_SECONDS, _idle_hint_pulse_elapsed + maxf(delta, 0.0))
1553+
_apply_idle_hint_nudge_visual()
1554+
if _idle_hint_pulse_elapsed >= IDLE_HINT_PULSE_SECONDS:
1555+
_reset_idle_hint_button_visual()
1556+
_idle_hint_elapsed = 0.0
1557+
return true
1558+
_idle_hint_elapsed += maxf(delta, 0.0)
1559+
if _idle_hint_elapsed >= IDLE_HINT_DELAY_SECONDS:
1560+
_start_idle_hint_nudge()
1561+
return true
1562+
return false
1563+
1564+
1565+
func _start_idle_hint_nudge() -> void:
1566+
_idle_hint_pulse_elapsed = 0.0
1567+
_apply_idle_hint_nudge_visual()
1568+
1569+
1570+
func _reset_idle_hint_nudge() -> void:
1571+
_idle_hint_elapsed = 0.0
1572+
_idle_hint_pulse_elapsed = IDLE_HINT_PULSE_SECONDS
1573+
_reset_idle_hint_button_visual()
1574+
1575+
1576+
func _enable_idle_hint_nudge() -> void:
1577+
_idle_hint_disabled_after_hint = false
1578+
_reset_idle_hint_nudge()
1579+
1580+
1581+
func _is_idle_hint_nudge_active() -> bool:
1582+
return _idle_hint_pulse_elapsed < IDLE_HINT_PULSE_SECONDS
1583+
1584+
1585+
func _idle_hint_nudge_amount() -> float:
1586+
if not _is_idle_hint_nudge_active():
1587+
return 0.0
1588+
var progress := clampf(_idle_hint_pulse_elapsed / IDLE_HINT_PULSE_SECONDS, 0.0, 1.0)
1589+
return sin(progress * PI)
1590+
1591+
1592+
func _apply_idle_hint_nudge_visual() -> void:
1593+
if not is_instance_valid(_hint_button):
1594+
return
1595+
var pulse := _idle_hint_nudge_amount()
1596+
var scale := 1.0 + (IDLE_HINT_MAX_SCALE - 1.0) * pulse
1597+
_hint_button.pivot_offset = _hint_button.size * 0.5
1598+
_hint_button.scale = Vector2(scale, scale)
1599+
_hint_button.add_theme_color_override("font_color", Color(1.0, 0.95, 0.38, 1.0).lerp(Color(0.92, 1.0, 0.96, 1.0), 1.0 - pulse * 0.55))
1600+
_hint_button.add_theme_constant_override("outline_size", 3 + int(roundf(pulse * 3.0)))
1601+
1602+
1603+
func _reset_idle_hint_button_visual() -> void:
1604+
if not is_instance_valid(_hint_button):
1605+
return
1606+
_hint_button.scale = Vector2.ONE
1607+
_hint_button.pivot_offset = _hint_button.size * 0.5
1608+
_hint_button.add_theme_color_override("font_color", Color(0.92, 1.0, 0.96, 1.0))
1609+
_hint_button.add_theme_constant_override("outline_size", 3)
1610+
1611+
1612+
func _draw_idle_hint_nudge() -> void:
1613+
if not is_instance_valid(_hint_button) or not _is_idle_hint_nudge_active():
1614+
return
1615+
var pulse := _idle_hint_nudge_amount()
1616+
if pulse <= 0.0:
1617+
return
1618+
var rect := Rect2(_hint_button.position, _hint_button.size)
1619+
var center := rect.get_center()
1620+
var radius := maxf(rect.size.x, rect.size.y) * (0.54 + pulse * 0.24)
1621+
var teal := Color(0.36, 1.0, 0.78, 0.18 + pulse * 0.18)
1622+
var gold := Color(1.0, 0.88, 0.22, 0.22 + pulse * 0.24)
1623+
draw_circle(center, radius * 1.22, Color(teal.r, teal.g, teal.b, teal.a * pulse))
1624+
draw_circle(center, radius, Color(gold.r, gold.g, gold.b, gold.a * pulse))
1625+
draw_rect(rect.grow(4.0 + pulse * 8.0), Color(1.0, 0.90, 0.22, 0.10 + pulse * 0.18), false, 2.0 + pulse * 2.0)
1626+
1627+
15191628
func _make_panel_style(fill: Color, border: Color, border_width: int, radius: int) -> StyleBoxFlat:
15201629
var style := StyleBoxFlat.new()
15211630
style.bg_color = fill
@@ -2397,6 +2506,7 @@ func _renderer_needs() -> Dictionary:
23972506
func _draw() -> void:
23982507
var view_size := get_viewport_rect().size
23992508
draw_rect(Rect2(Vector2.ZERO, view_size), Color(0.025, 0.055, 0.065, 1.0), true)
2509+
_draw_idle_hint_nudge()
24002510
_sync_board_renderer()
24012511
if is_instance_valid(_overlay_layer):
24022512
_overlay_layer.queue_redraw()
@@ -2540,6 +2650,7 @@ func _finish_pinch() -> void:
25402650
func _begin_drag(screen_pos: Vector2, touch_id: int = -1) -> bool:
25412651
var board_cell := _board_cell_at(screen_pos)
25422652
if not board_cell.is_empty():
2653+
_reset_idle_hint_nudge()
25432654
_clear_hint(false)
25442655
_drag_source = DRAG_SOURCE_BOARD
25452656
_drag_cell_id = board_cell
@@ -2553,6 +2664,7 @@ func _begin_drag(screen_pos: Vector2, touch_id: int = -1) -> bool:
25532664
return true
25542665
var inventory_index := _inventory_cell_at(screen_pos)
25552666
if inventory_index >= 0:
2667+
_reset_idle_hint_nudge()
25562668
_clear_hint(false)
25572669
_drag_source = DRAG_SOURCE_INVENTORY
25582670
_drag_cell_id = str(_inventory_cells[inventory_index].get("id", ""))
@@ -2578,6 +2690,7 @@ func _update_drag(screen_pos: Vector2) -> void:
25782690
func _finish_drag(screen_pos: Vector2) -> void:
25792691
if _drag_source == DRAG_SOURCE_NONE:
25802692
return
2693+
_reset_idle_hint_nudge()
25812694
_drag_position = screen_pos + _drag_offset
25822695
var target_tile := _screen_to_tile(_drag_position)
25832696
var changed := false
@@ -2711,6 +2824,8 @@ func _on_main_menu_pressed() -> void:
27112824

27122825

27132826
func _on_hint_pressed() -> void:
2827+
_idle_hint_disabled_after_hint = true
2828+
_reset_idle_hint_nudge()
27142829
var candidates: Array = _arcade_hint_candidates()
27152830
if candidates.is_empty():
27162831
_hint_pair.clear()

0 commit comments

Comments
 (0)