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
-
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')
-
@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)
-
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.
-
@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
-
@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). -
To get fire_laser to work, you need an
Action.call
.Also, be sure to use
duration
in yourmove_by
otherwise they will always take 1 second. -
@JonB I use the standard duration of 1 second to go up and a duration of 0 to come back at center of screen
-
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')