Forum Archive

Basic Touch Question

procryon

Hello all, I've been following the scene tutorial on Pythonista 3 and I've been trying to find a way to make the spaceship in the following code move constantly while i hold down on the button (which is the ellipse). I know it's a basic question but I've looked at examples and on the forum and have not found a solution.

Thanks in advance for dealing with my simple questions lol.

from scene import *
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 update(self):
       fill('green')
       ellipse(200, 100, 100, 100)

   def touch_began(self, touch):
       x,y = touch.location
       if x>200 and x<300 and y>100 and y<200:
           move_action = Action.move_by(10, 10, 0.7, TIMING_SINODIAL)
           self.ship.run_action(move_action)
if __name__ == '__main__':
   run(MyScene(), LANDSCAPE, show_fps=True)
jmv38

here is a possible solution

from scene import *
class MyScene(Scene):

   def setup(self):
       self.background_color = 'midnightblue'
       self.ship = SpriteNode('spc:PlayerShip1Orange')
       self.ship.position = self.size / 2
       self.dx=100
       self.dy=100
       self.ship.speed = 0
       self.add_child(self.ship)

   def update(self):
       fill('green')
       ellipse(200, 100, 100, 100)
       x,y = self.ship.position
       self.ship.position = (x+self.dx*self.dt*self.ship.speed, y+self.dy*self.dt*self.ship.speed)

   def touch_began(self, touch):
       x,y = touch.location
       if x>200 and x<300 and y>100 and y<200: 
         self.touch_id = touch.touch_id
         self.ship.speed = 1

   def touch_ended(self, touch):
       x,y = touch.location
       if self.touch_id == touch.touch_id: 
         self.touch_id = None
         self.ship.speed = 0

if __name__ == '__main__':
   run(MyScene(), LANDSCAPE, show_fps=True)
abcabc
  1. Use shape node instead of "fill and ellipse"
  2. Use Move_to instead of move_by
  3. Action is usually preferred over update
import scene, ui

class MyScene(scene.Scene):
    def setup(self):
        self.background_color = 'midnightblue'
        self.ship = scene.SpriteNode('spc:PlayerShip1Orange',
                                    position=self.size/2,
                                    parent=self)
        self.button = scene.ShapeNode(ui.Path.oval(0,0, 100, 100),
                                    position=(200, 100),
                                    fill_color='green',
                                    parent=self)

    def touch_began(self, touch):
        if touch.location in self.button.frame:
            self.ship.run_action(
                scene.Action.move_to(self.size[0], self.size[1], 2, 
                    scene.TIMING_SINODIAL),
                'move_action_key')

    def touch_ended(self, touch):
        if touch.location in self.button.frame:
            self.ship.remove_action('move_action_key')                                  

scene.run(MyScene(), show_fps=True)

jmv38

@abcabc your implementation is better because it uses scene features nicely, but i would still use touch_id to check the button release (closer behaviour to what the user expects)


import scene,ui

class MyScene(scene.Scene):
    def setup(self):
        self.background_color = 'midnightblue'
        self.ship = scene.SpriteNode('spc:PlayerShip1Orange',
                                    position=self.size/2,
                                    parent=self)
        self.button = scene.ShapeNode(ui.Path.oval(0,0, 100, 100),
                                    position=(200, 100),
                                    fill_color='green',
                                    parent=self)

    def touch_began(self, touch):
        if touch.location in self.button.frame:
            self.buttonTouchId = touch.touch_id
            self.ship.run_action(
                scene.Action.move_to(self.size[0], self.size[1], 2, 
                    scene.TIMING_SINODIAL),
                'move_action_key')

    def touch_ended(self, touch):
        if touch.touch_id == self.buttonTouchId:
            self.buttonTouchId = None
            self.ship.remove_action('move_action_key')                                  

if __name__ == '__main__':
   scene.run(MyScene(), scene.LANDSCAPE, show_fps=True)

also: the "if location in frame" syntax is great, i didnt know it was available.