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.


    (How to) Virtual d-pad that moves a sprite only when screen touched.

    Pythonista
    sprite character touch began d-pad scene
    2
    5
    4128
    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.
    • Sketo
      Sketo last edited by

      Maybe someone knows a better way but I'm trying to test a way to move a sprite around the screen using a virtual d-pad at bottom left of the screen. I tried creating a global variable that is set to 0 at the beginning. When you touch the screen it changes to 1 and when you stop touching the screen it changes back to 0 again.

      In update() I expected touch() to change the global variable on the fly but it just does not work like I thought. Any help would be appreciated.

      from scene import *
      import sound
      # Global variable that will be changed when you touch the screen.
      sp = 0
      
      class MyScene (Scene):
      	def setup(self):
      		self.background_color = 'midnightblue'
      		self.ship = SpriteNode('spc:PlayerShip1Orange')
      		self.ship.position = self.size / 2
      		self.add_child(self.ship)
      
      	def touch_began(self, touch):
      		if touch.location < 100:
      			# when the screen is touched then the global variable changes to 1 and should update the movement of the ship in update()... but ship movement does not change.
      			sp = 1
      	
      	def touch_ended(self, touch):
      		if touch.location < 100:
      			# i was hoping that once touch_began() started moving ship, that touch_ended() would stop movement so that it works like a simple directional pad.
      			sp = 0
      
      	def update(self):
      		pos = self.ship.position
      		'''pos += x + sp, y + sp'''
      		#this is just a test to see if touch would change the global variable "sp" and update accordingly. If i change it on line 4 it will update and move the ship. I dont know how to alter sp on the fly to move ship with touch until i stop touching the screen. like a controler moving mario or something.
      		pos.y += sp
      		# Don't allow the ship to move beyond the screen bounds:
      		pos.x = max(0, min(self.size.w, pos.x))
      		pos.y = max(0, min(self.size.h, pos.y))
      		self.ship.position = pos
      
      run(MyScene(), PORTRAIT)```
      1 Reply Last reply Reply Quote 0
      • abcabc
        abcabc last edited by abcabc

        The following code works. You need to declare variable sp as global in the methods. Otherwise it will be treated as local variable. Better to have it as instance variable. (Initialize self.sp in setup and use self.sp in other methods.)

        It is better to use Scene.Action instead of 'update'.

        from scene import *
        import sound
        # Global variable that will be changed when you touch the screen.
        sp = 0
        
        class MyScene (Scene):
            def setup(self):
                self.background_color = 'midnightblue'
                self.ship = SpriteNode('spc:PlayerShip1Orange')
                self.ship.position = self.size / 2
                self.add_child(self.ship)
        
            def touch_began(self, touch):
                global sp
                if touch.location.x < 100:
                    # when the screen is touched then the global variable changes to 1 and should update the movement of the ship in update()... but ship movement does not change.
                    sp = 1
            
            def touch_ended(self, touch):
                global sp
                if touch.location.x < 100:
                    # i was hoping that once touch_began() started moving ship, that touch_ended() would stop movement so that it works like a simple directional pad.
                    sp = 0
        
            def update(self):
                global sp
                x, y = self.ship.position
                '''pos += x + sp, y + sp'''
                #this is just a test to see if touch would change the global variable "sp" and update accordingly. If i change it on line 4 it will update and move the ship. I dont know how to alter sp on the fly to move ship with touch until i stop touching the screen. like a controler moving mario or something.
                y += sp
                # Don't allow the ship to move beyond the screen bounds:
                x = max(0, min(self.size.w, x))
                y = max(0, min(self.size.h, y))
                self.ship.position = (x, y)
        
        run(MyScene(), PORTRAIT)
        
        
        Sketo 1 Reply Last reply Reply Quote 0
        • Sketo
          Sketo @abcabc last edited by

          @abcabc Thank you for the reply. If you don't mind me asking... how do you achieve this with the Action method?

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

            Here is the code with scene.Action

            from scene import *
            
            class MyScene (Scene):
                def setup(self):
                    self.background_color = 'midnightblue'
                    self.ship = SpriteNode('spc:PlayerShip1Orange',
                                    position=self.size/2,
                                    parent=self)
                    self.sp = self.size.y - self.ship.size.y
            
                def touch_began(self, touch):
                    if touch.location.x < 100:
                        self.ship.run_action(
                             Action.move_to(self.ship.position[0], self.sp, 2, TIMING_EASE_IN_OUT), 'move_action_key')
                
                def touch_ended(self, touch):
                    if touch.location.x < 100:
                        self.ship.remove_action('move_action_key')
            
            run(MyScene(), PORTRAIT)
            
            Sketo 1 Reply Last reply Reply Quote 0
            • Sketo
              Sketo @abcabc last edited by

              @abcabc Thank you very much for this. You have shown me a new way that seams to make the motion smoother. Thank you again.

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