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.
Virtual Joystick
-
I'm working on a joystick UI element, and have run into some behavior I don't understand. For one, I find that the touch location seems to jump back and forth between the actual touch location, and some other location. The other is that I can pull the stick beyond the lower right boundry of the parent view even though the movement is successfully restricted in other directions.
Edit: fixed formatting. Thanks guys.
import ui from math import sin, cos, atan2, sqrt, pi class joystick(ui.View): #Sets up a view for the outside frame and one for the actual stick def __init__(self, stick_size, width): self.width = width self.height = width self.background_color = 'grey' self.corner_radius = self.width/2 self.border_width = 1 stick = ui.View() stick.width, stick.height = stick_size, stick_size stick.x, stick.y = self.width/2 - stick.width/2, self.width/2 - stick.width/2 stick.background_color = 'blue' stick.corner_radius = stick_size/2 stick.name = 'stick' self.pos = (0,0) self.add_subview(stick) def calc_pos(self, touch): x_comp = touch.location[0] - self.width/2 y_comp = self.width/2-touch.location[1] max_dist = self.width/2 - self['stick'].width/2 dist = sqrt(x_comp**2 + y_comp**2) #If the stick is not being pulled beyond the edge of the parent view, we just need to return the touch location if dist < max_dist: self.pos = (x_comp, y_comp) return touch.location #If the stick is pulled beyond the parent view boundry, limit the movement to the edge of the parent view else: angle = atan2(y_comp, x_comp) new_x = max_dist*cos(angle) new_y = max_dist*sin(angle) x_display = self.width/2 - self['stick'].width/2 + new_x y_display = self.width/2 - self['stick'].width/2 - new_y self.pos = (new_x, new_y) return x_display, y_display def touch_moved(self, touch): self['stick'].x, self['stick'].y = self.calc_pos(touch) def touch_ended(self, touch): self['stick'].x, self['stick'].y = self.width/2 - self['stick'].width/2, self.width/2 - self['stick'].width/2 stick = joystick(100, 200) stick.present('popover')
-
It looks like you have three single quotes surrounding your code above instead of three backticks.
To properly format your code, try clicking
edit
at the top right of your post and removing your code from the post (leaving the text in place). Then run your code throughThree_Backticks.py
and paste the clipboard contents into the post and save. -
Made a few changes. It works on my device.
import ui class joystick(ui.View): def __init__(self, stick_size, size): self.width = size self.height = size self.background_color = 'grey' self.corner_radius = self.width/2 self.border_width = 1 stick = ui.View() self.add_subview(stick) stick.width, stick.height = stick_size, stick_size stick.x, stick.y = self.width/2 - stick.width/2, self.height/2 - stick.height/2 stick.background_color = 'blue' stick.corner_radius = stick_size/2 stick.name = 'stick' def calc_pos(self, touch): x_comp = touch.location[0] - touch.prev_location[0] x = max(min(self['stick'].x + x_comp, self.width - self['stick'].width), 0) y_comp = touch.location[1] - touch.prev_location[1] y = max(min(self['stick'].y + y_comp, self.height - self['stick'].height), 0) return x, y def touch_moved(self, touch): self['stick'].x, self['stick'].y = self.calc_pos(touch) def touch_ended(self, touch): self['stick'].x, self['stick'].y = self.width/2 - self['stick'].width/2, self.height/2 - self['stick'].height/2 stick = joystick(100, 200) stick.present('popover') stick.touch_ended(None) # center the stick
-
touch_ended()
can be simplified:def touch_ended(self, touch): self['stick'].center = self.bounds.center
A similar thing can be done in
__init__()
.Also, you can replace
[0]
with.x
and[1]
with.y
to improve readability. -
@ywang, I like your solution alot. I wish I'd known it could be that simple. Thanks!
@ccc, I'd like to simplify it, but self.bounds.center throws an error because the bounds attribute doesn't have a center attribute. I'm confused as to why I can't just do:
self['stick'].center = self.center
-
Difference between Pythonista v1.6 beta on my iPad and v1.5 on yours?
-
I am on 1.5, so that's possible. I put my name on the list for the beta a while back but never heard anything in response.