omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    [SOLVED] Calling methods every n seconds in scene.update()

    Pythonista
    5
    25
    12864
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Splefix
      Splefix last edited by Splefix

      Hi, I want to know if it is possible to call a method every n seconds (example: every 1 second) in scene.update.

      If this is possible, can you please provide the right way of going about this?

      Thank you, and God bless you all abundantly in Jesus Christ!!!

      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @Splefix last edited by

        @Splefix see here

        1 Reply Last reply Reply Quote 0
        • Splefix
          Splefix last edited by Splefix

          @cvp Yield causes the LabelNodes to disappear, and other code seems to stop working when using it in the scene.update function. Do you maybe know why?

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @Splefix last edited by

            @Splefix No, sorry, I'm not skilled in Scene..

            1 Reply Last reply Reply Quote 0
            • Splefix
              Splefix last edited by

              Basically, I want to add a point every 1 second automatically if a statement is currently true. How can I do this?

              1 Reply Last reply Reply Quote 0
              • JonB
                JonB last edited by

                you will need to post some code.

                you have a few choices. either an Action.delay/Action.call Action.sequence.

                or, in scene.update you would check if self.t, and take action as approppriate.

                or depend on update being called every 1/60 second, and just count frames:
                in update:
                if condition_is_true:
                someobject.points += 1/60/n

                then you will have a fractional points, and you would just floor when displaying it.

                update should always try to exit as fast as it can -- nothing in your scene can change until it does.

                1 Reply Last reply Reply Quote 0
                • Splefix
                  Splefix last edited by

                  @JonB

                  Here is the code for the update subclass:

                  	def update(self):
                  		self.score_label.run_action(Action.remove())
                  		self.goal_label.run_action(Action.remove())
                  		self.score_label = LabelNode(str(f'Score: {self.score}'), ('Arial Rounded MT Bold', 33), position=(self.size.x/2, (self.size.y/1)-133))
                  		
                  		self.goal_label = LabelNode(f'Goal: {self.goal}', position=(self.size.x/2, ((self.size.y/1)-133)+50))
                  		
                  		self.add_child(self.score_label)
                  		self.add_child(self.goal_label)
                  		
                  		if self.auto_amount >= 1:
                  			spawn_bubble(self, False)
                  		
                  		if self.chest_visible == True:
                  			if self.score >= self.goal:
                  				buy_automate_chest = SpriteNode('plc:Chest_Open', position=(self.size.x/2, self.size.y/5), parent=self)
                  				
                  				self.chest_location = buy_automate_chest.frame
                  			else:
                  				buy_automate_chest.run_action(Action.remove())```
                  1 Reply Last reply Reply Quote 0
                  • themusicman
                    themusicman last edited by

                    So @Splefix - I have done something similar previously, where I needed to run different tasks at different intervals. Specifically, it was to upload IoT data from a pressure/temp/humidity sensor I have here, to an online MQTT server - but that is by the by.

                    This script shows how to set up 3 separate timers for task1, task2 and task3 (obviously amend the number of variables for your specific requirements)

                    # you will need the time module, so...
                    import time
                    
                    # Then simply set up timers for each task you wish to run
                    last_task1=time.time()
                    last_task2=time.time()
                    last_task3=time.time()
                    
                    # Execute specific tasks within each variable you have set up above
                    
                    # to execute task1 every 5 seconds
                    if time.time()-last_task1>=5: 
                        # run whatever code you need to execute every 5 seconds here
                        # put your code for task1 here
                        
                        # then reset the timer for this task1
                        last_task1=time.time()
                        
                    
                    # to execute task2 every 300 seconds
                    if time.time()-last_task2>300: 
                        # run whatever code you need to execute every 300 seconds here
                        # put your code for task2 here
                    
                        # then reset the timer for this task2
                        last_task2=time.time()
                        
                    
                    # to execute task3 every 3 seconds
                    if time.time()-last_task3>3: 
                        # run whatever code you need to execute every 300 seconds here
                        # put your code for task2 here
                    
                        # then reset the timer for this task3
                        last_task3=time.time()
                    

                    Hope this helps.

                    1 Reply Last reply Reply Quote 0
                    • themusicman
                      themusicman last edited by

                      @Splefix - specifically for your example...

                      # you will need the time module, so...
                      import time
                      
                      # set the variable for your single timer
                      last_task1=time.time()
                      
                      # then execute task1 every 1 second if 'your_statement' is true
                      if your_statement == True:
                          if time.time()-last_task1>=1:
                              # run whatever code you need to execute every 1 second here
                              # put your code for task1 here
                      
                              # then reset the timer for this task1
                              last_task1=time.time()
                      
                      1 Reply Last reply Reply Quote 0
                      • JonB
                        JonB last edited by

                        dont use time module in scene. use the scene t parameter.

                        https://gist.github.com/5d3930c460014de1ad4b09ccb9479ecd

                        here is an example showing three methods i mentioned

                        1 Reply Last reply Reply Quote 1
                        • Splefix
                          Splefix last edited by

                          @musicman305 Haha brother, God just helped me figure that out myself! Thank you very much though for your answer! God bless you abundantly and may peace be with you!!!

                          Nice meeting you brother!

                          themusicman 1 Reply Last reply Reply Quote 0
                          • JonB
                            JonB last edited by

                            why are you deleting you goal/score label every frame! instead of just updating the text?

                            1 Reply Last reply Reply Quote 0
                            • Splefix
                              Splefix last edited by Splefix

                              @JonB Hey, can I ask you to show me an example of calling a method containing args using the example you gave me above?

                              1 Reply Last reply Reply Quote 0
                              • JonB
                                JonB last edited by

                                use lambda, or functools.partial.

                                i.e Action.call(lambda arg1:self.some_method(arg1) )

                                1 Reply Last reply Reply Quote 0
                                • themusicman
                                  themusicman @Splefix last edited by

                                  @Splefix said:

                                  @themusicman Haha brother, God just helped me figure that out myself! Thank you very much though for your answer! God bless you abundantly and may peace be with you!!!

                                  Nice meeting you brother!

                                  You're very welcome matey...

                                  1 Reply Last reply Reply Quote 0
                                  • Splefix
                                    Splefix last edited by

                                    @JonB Concerning your question above: Can you show me how to update the text? This is my first time using the scene module.

                                    Also, say I have two args, and the function is out of the MyScene class: How would I tackle this?

                                    1 Reply Last reply Reply Quote 0
                                    • JonB
                                      JonB last edited by

                                      see my example, the .text attribute is used to update text.
                                      note, you probably want to set the anchor_point=(0,0) for left justification, unless you want the text centered.

                                      Lambdas accept multiple args
                                      lambda arg1,arg2:some_function(arg1, arg2)

                                      1 Reply Last reply Reply Quote 0
                                      • mikael
                                        mikael last edited by

                                        If you do a lot of these types of things, I (once again) promote the scripter, which works with views and scenes, for example like this:

                                        from scene import *
                                        from scripter import *
                                        
                                        class MyScene (Scene):
                                            def setup(self):
                                                self.ship = SpriteNode('spc:PlayerShip1Orange')
                                                self.ship.position = self.size / 2
                                                self.add_child(self.ship)
                                                self.do_a_thing_every_second()
                                                
                                            @script
                                            def do_a_thing_every_second(self):
                                              while(True):
                                                print('do the thing')
                                                yield 1.0
                                        
                                        run(MyScene())
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • Splefix
                                          Splefix last edited by

                                          @mikael Hi friend, I am having trouble with importing scripter? It says that this is invalid syntax:

                                          from scripter import *
                                          
                                          mikael 1 Reply Last reply Reply Quote 0
                                          • mikael
                                            mikael @Splefix last edited by

                                            @Splefix, as an unfortunate barrier to entry, you need to download scripter.py from the link and place it in your site-packages.

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors