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.
-
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)```
-
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)
-
@abcabc Thank you for the reply. If you don't mind me asking... how do you achieve this with the Action method?
-
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)
-
@abcabc Thank you very much for this. You have shown me a new way that seams to make the motion smoother. Thank you again.