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.


    Scene module touch controls

    Pythonista
    controls games touch scene
    3
    6
    10138
    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.
    • lachlantula
      lachlantula last edited by

      Hi all,
      my friend and I are working on a little game together, making use of the Scene module. However we've found that the tilt controls aren't very intuitive for what we're aiming to make, but we're kind of clueless on how to make buttons or similar. One idea was to make a sprite that detects when it's pressed by checking if the touch was within a certain range, but there's probably a more elegant way of doing this.

      Thanks :)

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

        It's definitely not the best solution, but using halves of the screen for moving left and right does work well enough for now.

        def touch_began(self, touch):
        	x, y = touch.location
        	self.a = x
        	if self.a <= 500:
        		self.b = 'moveright'
        	else:
        		self.b = 'moveleft'
        	self.update_player(True)	
        		
        def update_player(self, touch):
        	x = self.player.position.x
        	if touch == True:
        		x += 32
        		y = 32
        		if self.b == 'moveleft':
        			move_action = Action.move_to(x+32, y, 0.01)
        			self.player.run_action(move_action)
        		else:
        			move_action = Action.move_to(x-64, y, 0.01)
        			self.player.run_action(move_action)
        

        If anyone has any ideas on how to improve that code suggestions are very welcome :)

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

          May be try the following.

          import scene, ui
          
          class ButtonNode (scene.SpriteNode):
              def __init__(self, title, *args, **kwargs):
                  scene.SpriteNode.__init__(self, 'pzl:Button1', *args, **kwargs)        
                  button_font = ('Avenir Next', 20)
                  font_color = 'black'
                  self.title_label = scene.LabelNode(title, 
                      font=button_font,
                      color=font_color,
                      position=(0, 0),
                      parent=self)
                  self.title = title
                  #self.color = 'lime' #background color
                  
              def touch_began(self, touch):
                  if self.title == '←':
                      x, y = self.parent.sprite.position 
                      self.parent.sprite.position = ((x-20) if (x-20) > 0 else x, y)        
                  elif self.title == '→':
                      x, y = self.parent.sprite.position 
                      self.parent.sprite.position = ((x+20) if (x+20) < self.parent.size[0] else x, y)        
                  elif self.title == '↓':
                      x, y = self.parent.sprite.position 
                      self.parent.sprite.position = (x, (y-20) if (y-20) > 0 else y)   
                  elif self.title == '↑':      
                      x, y = self.parent.sprite.position 
                      self.parent.sprite.position = (x, (y+20) if (y+20) < self.parent.size[1] else y)   
          
          class MyScene(scene.Scene):
              def setup(self):
                  self.sprite = scene.SpriteNode('Dog_Face', position=self.size/2, parent=self)
                  self.left_button = ButtonNode('←', 
                      position=(self.size[0]/2.0 - 300, self.size[1]/2-300), parent=self)
                  self.right_button = ButtonNode('→', 
                      position=(self.size[0]/2.0-100, self.size[1]/2-300), parent=self)
                  self.down_button = ButtonNode('↓', 
                      position=(self.size[0]/2.0 +100, self.size[1]/2-300), parent=self)
                  self.up_button = ButtonNode('↑', 
                      position=(self.size[0]/2.0+300, self.size[1]/2-300), parent=self)
                     
              def touch_began(self, touch):
                  for node in self.children:
                      if hasattr(node, 'touch_began'):
                          if touch.location in node.frame:
                              node.touch_began(touch)
                     
          scene.run(MyScene())
          
          
          1 Reply Last reply Reply Quote 0
          • ccc
            ccc last edited by ccc

            @lachlantula One thing that is confusing to the reader is that the touch in touch.begin()is a scene.Touch object but touch in update_player() is a Boolean. Perhaps the second could be renamed was_touched or perhaps it could be removed and you could only call update_player() (with no parameters) when a touch happens.

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

              @abcabc that works wonderfully - thanks so much for the help!
              @ccc Thanks for picking up on that!

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

                Using min() and max() simplifies keeping sprites in bounds...

                import scene
                
                
                class ButtonNode(scene.SpriteNode):
                    def __init__(self, title, *args, **kwargs):
                        scene.SpriteNode.__init__(self, 'pzl:Button1', *args, **kwargs)
                        self.title = title
                        scene.LabelNode(title, color='blue', font=('Avenir Next', 20),
                                        parent=self, position=(0, 0))
                        
                    def touch_began(self, touch):
                        sprite = self.parent.sprite
                        x, y = sprite.position
                        if self.title == '←':
                            sprite.position = max(x - 20, 0), y
                        elif self.title == '→':
                            sprite.position = min(x + 20, self.parent.size.w), y
                        elif self.title == '↓':
                            sprite.position = x, max(y - 20, 0)
                        elif self.title == '↑':
                            sprite.position = x, min(y + 20, self.parent.size.h)
                
                
                class MyScene(scene.Scene):
                    def setup(self):
                        center = self.size/2
                        self.sprite = scene.SpriteNode('Dog_Face', parent=self, position=center)
                        ButtonNode('←', parent=self, position=center - (300,  300))
                        ButtonNode('→', parent=self, position=center - (100,  300))
                        ButtonNode('↓', parent=self, position=center + (100, -300))
                        ButtonNode('↑', parent=self, position=center + (300, -300))
                           
                    def touch_began(self, touch):
                        for node in self.children:
                            if touch.location in node.frame and hasattr(node, 'touch_began'):
                                    node.touch_began(touch)
                           
                
                scene.run(MyScene())
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                Powered by NodeBB Forums | Contributors