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.


    Execute a series of actions on touch

    Pythonista
    touch began scene
    3
    8
    1528
    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.
    • jellybeard
      jellybeard last edited by jellybeard

      How can I execute a series of actions on a single touch? For example, if I have this example from the Pythonista documentation but I want to shoot say 3 lasers, one right after the other or with a slight pause between. I tried adding the three lines defining the laser, it’s action, and it’s sound in a loop, but instead of firing the lasers in succession it fired all three at once.

      Second question, is there a “do while touch” method that would repeatedly fire lasers while the touch is held?

      EDIT:
      Updated script to include Action.sequence. I get an error that the action sequence does not include any actions.

      
      from scene import *
      import sound
      import random
      import math
      
      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):
      		x, y, z = gravity()
      		pos = self.ship.position
      		pos += (x * 15, y * 15)
      		# 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
      
      	
      	def touch_began(self, touch):
      		self.run_action(Action.sequence(self.fire_laser(),self.fire_laser(),self.fire_laser()))
      	
      	def fire_laser(self):
      		a=random.random()*500-250
      		laser = SpriteNode('spc:LaserBlue9', position=self.ship.position, z_position=-1, parent=self)
      		laser.run_action(Action.sequence(Action.move_by(a, 1000), Action.remove()))
      		sound.play_effect('arcade:Laser_1')
      
      
      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @jellybeard last edited by

        @jellybeard could you try this little script

        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)
        
            def touch_began(self, touch):
                self.laser = scene.SpriteNode('spc:LaserBlue9', position=self.size/2, z_position=-1, parent=self)
                self.laser.run_action(scene.Action.repeat_forever(scene.Action.sequence(scene.Action.move_by(0, 1000), scene.Action.move_by(0, -1000,0))), 'move_action_key')
                    
            def touch_ended(self, touch):
                 self.laser.remove_action('move_action_key')       
                 self.laser.remove_from_parent()
                 del self.laser
        
        scene.run(MyScene(), show_fps=True)
        
        1 Reply Last reply Reply Quote 0
        • jellybeard
          jellybeard last edited by

          Thanks for the replies.

          I tried a sequence (see updated example above) but it looks as if calling a method (fire_laser) doesn’t count as an action as I get an error. The ship still fires three at once.

          I tried your example too and that’s close to what I am after! The lasers stop mid flight on touch end.

          cvp 2 Replies Last reply Reply Quote 1
          • cvp
            cvp @jellybeard last edited by cvp

            @jellybeard said

            The lasers stop mid flight on touch end

            Did you not forget the two lines

                     self.laser.remove_from_parent()
                     del self.laser
            
            1 Reply Last reply Reply Quote 0
            • cvp
              cvp @jellybeard last edited by cvp

              @jellybeard said

              calling a method (fire_laser) doesn’t count as an action

              It is sure that a method is not an action! Thus normal error

              There is also
              classmethod Action.repeat(action, repeat_count)
              Creates an action that repeats another action a specified number of times. If repeat_count is <=0, the action repeats forever (or until it is removed explicitly).

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

                To get fire_laser to work, you need an Action.call.

                Also, be sure to use duration in your move_by otherwise they will always take 1 second.

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

                  @JonB I use the standard duration of 1 second to go up and a duration of 0 to come back at center of screen

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

                    How about this slight modification to the original -- should prevent the lasers from disappearing when touch ends. Also, keeps track of the lasers for use in hit detection

                    from scene import *
                    import sound
                    import random
                    import math
                    
                    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)
                            self.lasers=[]
                        def update(self):
                            x, y, z = gravity()
                            pos = self.ship.position
                            pos += (x * 15, y * 15)
                            # 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
                    
                        
                        def touch_began(self, touch):
                     
                            
                     laser_animation=Action.repeat_forever(Action.sequence(Action.call(self.fire_laser), Action.wait(0.1) ) )
                            self.run_action(laser_animation, 'laser')
                     
                        def touch_ended(self,touch):
                               self.remove_action('laser')
                        def remove_laser(self,laser):
                            del self.lasers[laser]
                        def fire_laser(self):
                            a=random.random()*500-250
                            laser = SpriteNode('spc:LaserBlue9', position=self.ship.position, z_position=-1, parent=self)
                            self.lasers.append(laser)
                            laser.run_action(Action.sequence(Action.move_by(a, 1000), Action.remove(), Action.call(lambda:self.remove_laser(laser))))
                            sound.play_effect('arcade:Laser_1')
                    
                    1 Reply Last reply Reply Quote 1
                    • First post
                      Last post
                    Powered by NodeBB Forums | Contributors