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.


    scenes updating each other’s variables

    Pythonista
    updating variab modal scenes scene
    4
    37
    8881
    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.
    • resserone13
      resserone13 last edited by resserone13

      Is there a way I can have one scene update a variable on another scene? How would I adjust a variable on a Modal scene that then updates a variable on the main scene? When a player runs runs out of money I have a modal scene pop up asking if the player would like a loan. They adjust the loan amount and press “ take loan” once they press take loan the modal scene is dismissed and I would like the bankroll amount on the main scene to be updated from the loan amount on the modal scene.

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

        Rather than calling your scene like

        run(MyScene())
        

        Assign it to a variable.

        main_scene=MyScene()
        run(main_scene)
        

        Then your modal scene can access the global main_scene.

        Or, if you launch your scene inside a function, you would create an attribute in your modal scene that points to the main scene.

        modal_scene=MyModalScene()
        modal_scene.main_scene = main_scene
        

        Then the modal scene can access this.main_scene.

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

          @JonB how would I do it in this example?

          
          from scene import *
          import sound
          import random
          import math
          A = Action	
          
          class MyScene (Scene):
          	def setup(self):
          		
          		self.bankroll_amount = 0
          		
          		self.text = LabelNode(
          			'MAIN SCREEN',
          			('Apple Color Emoji', 40), 
          			position= self.size/2,
          			parent=self
          			)
          
          		self.next_screen = LabelNode(
          			'Next SCREEN',
          			('Apple Color Emoji', 20), 
          			position= (self.size.w/2 * 0.55, self.size.h/2 * 1.33),
          			parent=self
          			)	
          		
          		self.bankroll_amount_label = LabelNode(
          			f'{self.bankroll_amount:,}', 
          			font = ('Bodoni 72', 28), 
          			position = (self.size.w/2 * 1.79, self.size.h/2 * 1.66), 
          			color = 'gold', 
          			parent=self
          			)		
          		
          	def update(self):
          		pass
          	
          	def touch_began(self, touch):
          		if touch.location in self.next_screen.frame:
          			self.present_modal_scene(Screen_1())
          
          	def touch_ended(self, touch):
          		pass
          
          class Screen_1(Scene):
          	def setup(self):
          
          		self.bg_color = SpriteNode('plc:Grass_Block', position= (self.size/2), scale=25, parent=self)
          		
          		self.text_1 = LabelNode(
          			'1st SCREEN',
          			('Apple Color Emoji', 40), 
          			position = (self.size.w/2 * 0.55, self.size.h/2 * 0.99),
          			parent=self)
          			
          		self.next_screen_1 = LabelNode(
          			'1st button',
          			('Apple Color Emoji', 20), 
          			position= (self.size.w/2 * 0.40, self.size.h/2 * 1.33),
          			parent=self
          			)			
          
          		self.loan_amount = 0
          		
          		self.loan_label = LabelNode(
          			'Loan Amount',
          			('DIN Condensed', 40),
          			color= 'black',
          			position = (self.size.w/2, self.size.h/2 * 1.10)
          			)
          
          		self.loan_amount_label = LabelNode(
          			f'${self.loan_amount}',
          			('Bodoni 72', 35),
          			color= 'black',			
          			position = (self.size.w/2, self.size.h/2 * 0.85)
          			)			
          			
          		self.take_loan = LabelNode(
          			'Take Loan',
          			('Avenir Next Condensed', 30),
          			position = (self.size.w/2, self.size.h/2 * 0.55),
          			color= 'black'			
          			)
          			
          		self.inc_loan_btn = SpriteNode(
          			'emj:Red_Triangle_1',
          			position= (self.size.w/2 * 1.33, self.size.h/2 * 1.25),
          			scale=2
          			)
          			
          		self.dec_loan_btn = SpriteNode(
          			'emj:Red_Triangle_2',
          			position= (self.size.w/2 * 1.33, self.size.h/2 * 0.75),
          			scale=2
          			)			
          
          		self.add_child(self.loan_label)
          		self.add_child(self.loan_amount_label)
          		self.add_child(self.take_loan)
          		self.add_child(self.inc_loan_btn)
          		self.add_child(self.dec_loan_btn)	
          
          	def touch_began(self, touch):
          		if touch.location in self.next_screen_1.frame:
          			self.present_modal_scene(Screen_2())
          
          		if touch.location in self.take_loan.frame:
          			self.bankroll_amount = self.loan_amount
          			self.dismiss_modal_scene()			
          
          		#--- inc loan ---
          		if touch.location in self.inc_loan_btn.frame:
          			self.loan_amount += 500
          			self.loan_amount_label.text = f'${self.loan_amount}'
          			if self.loan_amount >= 10_000:
          				self.loan_amount = 10_000
          				self.loan_amount_label.text = f'${self.loan_amount}'
          	
          		#--- dec loan ---								
          		if touch.location in self.dec_loan_btn.frame:
          			self.loan_amount -= 500
          			self.loan_amount_label.text = f'{self.loan_amount}'
          			if self.loan_amount < 0:
          				self.loan_amount = 0
          				self.loan_amount_label.text = f'{self.loan_amount}'			
          						
          	def touch_ended(self, touch):
          		pass
          		
          									
          class Screen_2(Scene):
          	
          	def setup(self):
          
          		self.bg_color = SpriteNode('plc:Brown_Block', position= (self.size/2), scale=25, parent=self)				
          		self.text_2 = LabelNode(
          			'2nd SCREEN',
          			('Apple Color Emoji', 40), 
          			position= self.size/2,
          			parent=self)
          			
          		self.next_screen_2 = LabelNode(
          			'2nd button',
          			('Apple Color Emoji', 20), 
          			position= (self.size.w/2 * 0.2, self.size.h/2),
          			parent=self)			
          
          	def touch_began(self, touch):
          		
          		if touch.location in self.next_screen_2.frame:
          			self.dismiss_modal_scene()
          
          	
          	def touch_ended(self, touch):
          		pass
          				
          
          if __name__ == '__main__':
          	run(MyScene(), LANDSCAPE, show_fps=False)
          
          
          
          1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by

            # instead of
            if __name__ == '__main__':
                run(MyScene(), LANDSCAPE, show_fps=False)
            
            # do 
            main_scene=MyScene()
            run(main_scene, LANDSCAPE, show_fps=False)
            

            Then, your other scenes can access attributes of main_scene.

            As an alternative, you use present_modal_scene. Use a variable for those modal scenes, then you can access attributes of the pop-up scenes after present_modal_scene completes.

            resserone13 1 Reply Last reply Reply Quote 1
            • resserone13
              resserone13 @JonB last edited by resserone13

              @JonB ive updated the run function to run off a variable. Is that literally all that’s needed. I ran the code with the change in the variable was not updated. I believe that your alternative method is what I’m already attempting to do in the example. I am very very new at not only Scene module and Pythonista but coding altogether. What else is needed besides putting in the class in a variable? How exactly do I access the attributes? Is my example Close to what your alternative method is? Thank you for taking the time to help me.

              cvp 2 Replies Last reply Reply Quote 0
              • cvp
                cvp @resserone13 last edited by

                @resserone13 what @JonB advices is

                def touch_began(self, touch):
                        if touch.location in self.next_screen.frame:
                            self.present_modal_scene(Screen_1())
                            |            
                            |            
                            |            
                            V           
                def touch_began(self, touch):
                        if touch.location in self.next_screen.frame:
                            sc1 = Screen_1()	
                            sc1.main_scene = self
                            self.present_modal_scene(sc1)
                
                resserone13 1 Reply Last reply Reply Quote 1
                • cvp
                  cvp @resserone13 last edited by

                  @resserone13 then you can access bankroll_amount of the main scene in other scene by

                  self.main_scene.bankroll_amount
                  
                  resserone13 1 Reply Last reply Reply Quote 1
                  • resserone13
                    resserone13 @cvp last edited by

                    @cvp @JonB I have incorporated your guises recommendations into my practice code and I’m getting an error I’ve never seen and can’t figure out. I’ve listed the error and the updated code below.

                    Error...

                    TypeError: bad argument type for built-in operation

                    The above exception was the direct cause of the following exception:

                    Traceback (most recent call last):
                    File "/var/containers/Bundle/Application/F3A42D55-5CB1-4DC2-AFF5-5BE7BB053375/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/scene.py", line 216, in _touch_began
                    self.presented_scene._touch_began(x, y, touch_id)
                    File "/var/containers/Bundle/Application/F3A42D55-5CB1-4DC2-AFF5-5BE7BB053375/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/scene.py", line 226, in _touch_began
                    self.touch_began(touch)
                    File "/private/var/mobile/Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents/modal_practice.py", line 111, in touch_began
                    self.main.bankroll_amount_label.text = f'{self.main.bankroll_amount:,}',
                    File "/var/containers/Bundle/Application/F3A42D55-5CB1-4DC2-AFF5-5BE7BB053375/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/scene.py", line 280, in setattr
                    self.update_texture()
                    File "/var/containers/Bundle/Application/F3A42D55-5CB1-4DC2-AFF5-5BE7BB053375/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/scene.py", line 285, in update_texture
                    w, h = ui.measure_string(self.text, font=self.font)
                    SystemError: <built-in function measure_string> returned a result with an error set

                    
                    from scene import *
                    import sound
                    import random
                    import math
                    A = Action	
                    
                    class MyScene (Scene):
                    	def setup(self):
                    		
                    		self.bankroll_amount = 0
                    		
                    		self.text = LabelNode(
                    			'MAIN SCREEN',
                    			('Apple Color Emoji', 40), 
                    			position= self.size/2,
                    			parent=self
                    			)
                    
                    		self.next_screen = LabelNode(
                    			'Next SCREEN',
                    			('Apple Color Emoji', 20), 
                    			position= (self.size.w/2 * 0.55, self.size.h/2 * 1.33),
                    			parent=self
                    			)	
                    		
                    		self.bankroll_amount_label = LabelNode(
                    			f'{self.bankroll_amount:,}', 
                    			font = ('Bodoni 72', 28), 
                    			position = (self.size.w/2 * 1.79, self.size.h/2 * 1.66), 
                    			color = 'gold', 
                    			parent=self
                    			)		
                    		
                    	def update(self):
                    		pass
                    	
                    	def touch_began(self, touch):
                    		if touch.location in self.next_screen.frame:
                    			sc1 = Screen_1()
                    			sc1.main = self
                    			self.present_modal_scene(sc1)
                    
                    	def touch_ended(self, touch):
                    		pass
                    
                    class Screen_1(Scene):
                    	def setup(self):
                    
                    		self.bg_color = SpriteNode('plc:Grass_Block', position= (self.size/2), scale=25, parent=self)
                    		
                    		self.text_1 = LabelNode(
                    			'1st SCREEN',
                    			('Apple Color Emoji', 40), 
                    			position = (self.size.w/2 * 0.55, self.size.h/2 * 0.99),
                    			parent=self)
                    			
                    		self.next_screen_1 = LabelNode(
                    			'1st button',
                    			('Apple Color Emoji', 20), 
                    			position= (self.size.w/2 * 0.40, self.size.h/2 * 1.33),
                    			parent=self
                    			)			
                    
                    		self.loan_amount = 0
                    		
                    		self.loan_label = LabelNode(
                    			'Loan Amount',
                    			('DIN Condensed', 40),
                    			color= 'black',
                    			position = (self.size.w/2, self.size.h/2 * 1.10)
                    			)
                    
                    		self.loan_amount_label = LabelNode(
                    			f'${self.loan_amount}',
                    			('Bodoni 72', 35),
                    			color= 'black',			
                    			position = (self.size.w/2, self.size.h/2 * 0.85)
                    			)			
                    			
                    		self.take_loan = LabelNode(
                    			'Take Loan',
                    			('Avenir Next Condensed', 30),
                    			position = (self.size.w/2, self.size.h/2 * 0.55),
                    			color= 'black'			
                    			)
                    			
                    		self.inc_loan_btn = SpriteNode(
                    			'emj:Red_Triangle_1',
                    			position= (self.size.w/2 * 1.33, self.size.h/2 * 1.25),
                    			scale=2
                    			)
                    			
                    		self.dec_loan_btn = SpriteNode(
                    			'emj:Red_Triangle_2',
                    			position= (self.size.w/2 * 1.33, self.size.h/2 * 0.75),
                    			scale=2
                    			)			
                    
                    		self.add_child(self.loan_label)
                    		self.add_child(self.loan_amount_label)
                    		self.add_child(self.take_loan)
                    		self.add_child(self.inc_loan_btn)
                    		self.add_child(self.dec_loan_btn)	
                    
                    	def touch_began(self, touch):
                    		if touch.location in self.next_screen_1.frame:
                    			self.present_modal_scene(Screen_2())
                    
                    		if touch.location in self.take_loan.frame:
                    			self.main.bankroll_amount = self.loan_amount
                    			self.main.bankroll_amount_label.text = f'{self.main.bankroll_amount:,}', 
                    			self.dismiss_modal_scene()			
                    
                    		#--- inc loan ---
                    		if touch.location in self.inc_loan_btn.frame:
                    			self.loan_amount += 500
                    			self.loan_amount_label.text = f'${self.loan_amount}'
                    			if self.loan_amount >= 10_000:
                    				self.loan_amount = 10_000
                    				self.loan_amount_label.text = f'${self.loan_amount}'
                    	
                    		#--- dec loan ---								
                    		if touch.location in self.dec_loan_btn.frame:
                    			self.loan_amount -= 500
                    			self.loan_amount_label.text = f'${self.loan_amount}'
                    			if self.loan_amount < 0:
                    				self.loan_amount = 0
                    				self.loan_amount_label.text = f'${self.loan_amount}'			
                    						
                    	def touch_ended(self, touch):
                    		pass
                    		
                    									
                    class Screen_2(Scene):
                    	
                    	def setup(self):
                    
                    		self.bg_color = SpriteNode('plc:Brown_Block', position= (self.size/2), scale=25, parent=self)				
                    		self.text_2 = LabelNode(
                    			'2nd SCREEN',
                    			('Apple Color Emoji', 40), 
                    			position= self.size/2,
                    			parent=self)
                    			
                    		self.next_screen_2 = LabelNode(
                    			'2nd button',
                    			('Apple Color Emoji', 20), 
                    			position= (self.size.w/2 * 0.2, self.size.h/2),
                    			parent=self)			
                    
                    	def touch_began(self, touch):
                    		
                    		if touch.location in self.next_screen_2.frame:
                    			self.dismiss_modal_scene()
                    
                    	
                    	def touch_ended(self, touch):
                    		pass
                    
                    main = MyScene()	
                    
                    if __name__ == '__main__':
                    	run(main, LANDSCAPE, show_fps=False)
                    
                    
                    1 Reply Last reply Reply Quote 0
                    • resserone13
                      resserone13 last edited by

                      I also tried just having everything inside of one scene and basically changing scenes by adding and removing nodes. It gives me the same error for some reason.

                      
                      class MyScene (Scene):
                      	def setup(self):
                      		
                      		self.bankroll_amount = 0
                      		
                      		self.text = LabelNode(
                      			'MAIN SCREEN',
                      			('Apple Color Emoji', 40), 
                      			position= self.size/2,
                      			parent=self
                      			)
                      
                      		self.next_screen = LabelNode(
                      			'Next SCREEN',
                      			('Apple Color Emoji', 20), 
                      			position= (self.size.w/2 * 0.55, self.size.h/2 * 1.33),
                      			parent=self
                      			)	
                      		
                      		self.bankroll_amount_label = LabelNode(
                      			f'{self.bankroll_amount:,}', 
                      			font = ('Bodoni 72', 28), 
                      			position = (self.size.w/2 * 1.79, self.size.h/2 * 1.66), 
                      			color = 'gold', 
                      			parent=self
                      			)		
                      
                      		self.bg_color_1 = SpriteNode(
                      			'plc:Grass_Block', 
                      			position= (self.size/2), 
                      			scale=25,
                      			)
                      			
                      		self.text_1 = LabelNode(
                      			'1st SCREEN',
                      			('Apple Color Emoji', 40), 
                      			position = (self.size.w/2 * 0.55, self.size.h/2 * 0.99)
                      			)
                      			
                      		self.next_screen_1 = LabelNode(
                      			'1st button',
                      			('Apple Color Emoji', 20), 
                      			position= (self.size.w/2 * 0.40, self.size.h/2 * 1.33)
                      			)			
                      
                      		self.loan_amount = 0
                      		
                      		self.loan_label = LabelNode(
                      			'Loan Amount',
                      			('DIN Condensed', 40),
                      			color= 'black',
                      			position = (self.size.w/2, self.size.h/2 * 1.10)
                      			)
                      
                      		self.loan_amount_label = LabelNode(
                      			f'${self.loan_amount}',
                      			('Bodoni 72', 35),
                      			color= 'black',			
                      			position = (self.size.w/2, self.size.h/2 * 0.85)
                      			)			
                      			
                      		self.take_loan = LabelNode(
                      			'Take Loan',
                      			('Avenir Next Condensed', 30),
                      			position = (self.size.w/2, self.size.h/2 * 0.55),
                      			color= 'black'			
                      			)
                      			
                      		self.inc_loan_btn = SpriteNode(
                      			'emj:Red_Triangle_1',
                      			position= (self.size.w/2 * 1.33, self.size.h/2 * 1.25),
                      			scale=2
                      			)
                      			
                      		self.dec_loan_btn = SpriteNode(
                      			'emj:Red_Triangle_2',
                      			position= (self.size.w/2 * 1.33, self.size.h/2 * 0.75),
                      			scale=2
                      			)			
                      		
                      	def update(self):
                      		pass
                      	
                      	def touch_began(self, touch):
                      		if touch.location in self.next_screen.frame:
                      			
                      			self.text.remove_from_parent()
                      			self.next_screen.remove_from_parent()
                      			self.bankroll_amount_label.remove_from_parent()
                      			
                      
                      			self.add_child(self.loan_label)
                      			self.add_child(self.loan_amount_label)
                      			self.add_child(self.take_loan)
                      			self.add_child(self.inc_loan_btn)
                      			self.add_child(self.dec_loan_btn)	
                      
                      		if touch.location in self.next_screen_1.frame:
                      			pass
                      
                      		if touch.location in self.take_loan.frame:
                      			self.add_child(self.text)
                      			self.add_child(self.next_screen)
                      			self.add_child(self.bankroll_amount_label)
                      			self.bankroll_amount = self.loan_amount
                      			self.bankroll_amount_label.text = f'{self.bankroll_amount:,}', 
                      
                      
                      		#--- inc loan ---
                      		if touch.location in self.inc_loan_btn.frame:
                      			self.loan_amount += 500
                      			self.loan_amount_label.text = f'${self.loan_amount}'
                      			if self.loan_amount >= 10_000:
                      				self.loan_amount = 10_000
                      				self.loan_amount_label.text = f'${self.loan_amount}'
                      	
                      		#--- dec loan ---								
                      		if touch.location in self.dec_loan_btn.frame:
                      			self.loan_amount -= 500
                      			self.loan_amount_label.text = f'${self.loan_amount}'
                      			if self.loan_amount < 0:
                      				self.loan_amount = 0
                      				self.loan_amount_label.text = f'${self.loan_amount}'	
                      				
                      	def touch_ended(self, touch):
                      		pass
                      
                      	
                      
                      if __name__ == '__main__':
                      	run(MyScene(), LANDSCAPE, show_fps=False)
                      
                      
                      cvp 1 Reply Last reply Reply Quote 0
                      • cvp
                        cvp @resserone13 last edited by

                        @resserone13 remove the comma at end of line

                                    self.main.bankroll_amount_label.text = f'{self.main.bankroll_amount:,}', 
                        
                        resserone13 1 Reply Last reply Reply Quote 0
                        • resserone13
                          resserone13 last edited by

                          I was able to figure out why I was getting the error. There was an extra comma on the end of this line. I have it working both ways now with individual scenes and with everything in one scene and you just remove notes on and off to make the scenes.

                          
                          			self.bankroll_amount_label.text = f'{self.bankroll_amount:,}'
                          
                          
                          1 Reply Last reply Reply Quote 0
                          • cvp
                            cvp last edited by

                            We cross our posts 😂

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

                              @cvp thank you. I just figured it out. Such a little thing.

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

                                @cvp hahah. We did. At first I was having trouble with the multiple scenes but now I see a bit more of how I can work it both ways. I’m writing a card game to learn more coding. I’m gonna post it soon on GitHub. Hopefully in the next few days. I would sure like to hear what everyone thinks. I’m sure it will be interesting interesting. I wrote it with very few functions. Once I post it I would like to work on converting the code to more of an oop approach.

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

                                  Thanks so much. I’ve got it working and it feels awesome.

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

                                    @cvp said:

                                    @resserone13 what @JonB advices is

                                    def touch_began(self, touch):
                                            if touch.location in self.next_screen.frame:
                                                self.present_modal_scene(Screen_1())
                                                |            
                                                |            
                                                |            
                                                V           
                                    def touch_began(self, touch):
                                            if touch.location in self.next_screen.frame:
                                                sc1 = Screen_1()	
                                                sc1.main_scene = self
                                                self.present_modal_scene(sc1)
                                    

                                    How would this work if a modal scene is presenting another modal scene on top of the main. I would like the 3rd scene (which is the 2nd modal scene on top of the main seven) to update a variable on the main scene. I’m sorry to ask but I’ve been rearranging the scenes and variables all day. I’ve also tried to do this when I first asked the question a while ago and can’t forgive it out.

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

                                      @resserone13 said:

                                      How would this work if a modal scene is presenting another modal scene on top of the main

                                      I never use scene thus I'll let real specialists answer...

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

                                        @cvp ok. Thanks for the reply. @JonB do you mind helping out?

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

                                          @resserone13 you could try, without promising it will work

                                          try:
                                          	# if current scene modal of main
                                          	self.main_scene.bankroll_amount = ...
                                          except:
                                          	# if current scene modal of modal of main
                                          	self.main_scene.main_scene.bankroll_amount = ...
                                          
                                          resserone13 2 Replies Last reply Reply Quote 0
                                          • resserone13
                                            resserone13 @cvp last edited by

                                            @cvp I’ll see if I can work this out. Thanks. I was think of some thing like.

                                            If self.presented_scene() then. Such and such will happen but I haven’t try that too much. Main been re arranging the scenes and variables. I’ll let you know.

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