@@ -53,18 +53,35 @@ impl INode for Main {
5353 . signals ( )
5454 . start_game ( )
5555 . connect_obj ( & main, Self :: new_game) ;
56+
57+ // Connect Main.ScoreTimer::timeout -> Main::on_score_timer_timeout.
58+ self . score_timer ( )
59+ . signals ( )
60+ . timeout ( )
61+ . connect_obj ( & main, Self :: on_score_timer_timeout) ;
62+
63+ // Connect Main.MobTimer::timeout -> Main::on_mob_timer_timeout.
64+ self . mob_timer ( )
65+ . signals ( )
66+ . timeout ( )
67+ . connect_obj ( & main, Self :: on_mob_timer_timeout) ;
68+
69+ // Main.StartTimer::timeout -> Main::on_start_timer_timeout is set up in the Editor's Inspector UI, but could be done here as well,
70+ // as follows. Note that signal handlers connected via Rust do not need a #[func] annotation, they can remain entirely visible to Godot.
71+ //
72+ // self.start_timer()
73+ // .signals()
74+ // .timeout()
75+ // .connect_obj(&main, Self::on_start_timer_timeout);
5676 }
5777}
5878
5979#[ godot_api]
6080impl Main {
6181 // No #[func] here, this method is directly called from Rust (via type-safe signals).
6282 fn game_over ( & mut self ) {
63- let mut score_timer = self . base ( ) . get_node_as :: < Timer > ( "ScoreTimer" ) ;
64- let mut mob_timer = self . base ( ) . get_node_as :: < Timer > ( "MobTimer" ) ;
65-
66- score_timer. stop ( ) ;
67- mob_timer. stop ( ) ;
83+ self . score_timer ( ) . stop ( ) ;
84+ self . mob_timer ( ) . stop ( ) ;
6885
6986 self . hud . bind_mut ( ) . show_game_over ( ) ;
7087
@@ -75,12 +92,11 @@ impl Main {
7592 // No #[func].
7693 pub fn new_game ( & mut self ) {
7794 let start_position = self . base ( ) . get_node_as :: < Marker2D > ( "StartPosition" ) ;
78- let mut start_timer = self . base ( ) . get_node_as :: < Timer > ( "StartTimer" ) ;
7995
8096 self . score = 0 ;
8197
8298 self . player . bind_mut ( ) . start ( start_position. get_position ( ) ) ;
83- start_timer. start ( ) ;
99+ self . start_timer ( ) . start ( ) ;
84100
85101 let hud = self . hud . bind_mut ( ) ;
86102 hud. update_score ( self . score ) ;
@@ -89,22 +105,20 @@ impl Main {
89105 self . music . play ( ) ;
90106 }
91107
92- #[ func]
93- fn on_start_timer_timeout ( & self ) {
94- let mut mob_timer = self . base ( ) . get_node_as :: < Timer > ( "MobTimer" ) ;
95- let mut score_timer = self . base ( ) . get_node_as :: < Timer > ( "ScoreTimer" ) ;
96- mob_timer. start ( ) ;
97- score_timer. start ( ) ;
108+ #[ func] // needed because connected in Editor UI (see ready).
109+ fn on_start_timer_timeout ( & mut self ) {
110+ self . mob_timer ( ) . start ( ) ;
111+ self . score_timer ( ) . start ( ) ;
98112 }
99113
100- #[ func]
114+ // No #[func], connected in pure Rust.
101115 fn on_score_timer_timeout ( & mut self ) {
102116 self . score += 1 ;
103117
104118 self . hud . bind_mut ( ) . update_score ( self . score ) ;
105119 }
106120
107- #[ func]
121+ // No #[func], connected in pure Rust.
108122 fn on_mob_timer_timeout ( & mut self ) {
109123 let mut mob_spawn_location = self
110124 . base ( )
@@ -134,4 +148,17 @@ impl Main {
134148
135149 mob. set_linear_velocity ( Vector2 :: new ( range, 0.0 ) . rotated ( real:: from_f32 ( direction) ) ) ;
136150 }
151+
152+ // These timers could also be stored as OnReady fields, but are now fetched via function for demonstration purposes.
153+ fn start_timer ( & self ) -> Gd < Timer > {
154+ self . base ( ) . get_node_as :: < Timer > ( "StartTimer" )
155+ }
156+
157+ fn score_timer ( & self ) -> Gd < Timer > {
158+ self . base ( ) . get_node_as :: < Timer > ( "ScoreTimer" )
159+ }
160+
161+ fn mob_timer ( & self ) -> Gd < Timer > {
162+ self . base ( ) . get_node_as :: < Timer > ( "MobTimer" )
163+ }
137164}
0 commit comments