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')