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.
Touch Delay
-
My apologies if this has been answered before, I searched but couldn’t find it. Also, it should be noted that I’m just learning Python so I could be making silly mistakes.
I’m having an issue where there is a slight delay (about 2 seconds) when touching the left or down touchscreen arrows before the sprite starts moving. This only happens on the edges of the arrows. If you touch the same arrows a bit more away from the edge of the screen they move instantly. There are no issues with the up and right arrows. It almost seems to me like there is some sort of delay built into iOS or Pythonista 3 to allow for accidental screen-edge touches, although I know this isn’t the case as none of my games or apps suffer from this. Here’s my code. Any help would be appreciated.
from scene import * class MyScene(Scene): #--------------------------------------------- # All game setup goes here. #--------------------------------------------- def setup(self): sz=get_screen_size() print("Screen: " + str(sz)) self.background_color = '#004f82' # Load player sprite. self.player = SpriteNode('emj:Alien_Monster') self.player.position = (200, 200) self.player.mv = 1 self.player.moving = False self.player.direction = 0 self.player.x_mov = 0 self.player.y_mov = 0 self.player.mov_rate = 2 self.add_child(self.player) print(self.player.size) # Load Arrow controls. self.left_arrow = SpriteNode('iow:arrow_left_a_256') self.left_arrow.alpha = 0.5 self.left_arrow.size = (72, 72) self.left_arrow.anchor_point = (0, 0) self.left_arrow.position = (0, 48) self.add_child(self.left_arrow) self.right_arrow = SpriteNode('iow:arrow_right_a_256') self.right_arrow.alpha = 0.5 self.right_arrow.size = (72, 72) self.right_arrow.anchor_point = (0, 0) self.right_arrow.position = (96, 48) self.add_child(self.right_arrow) self.up_arrow = SpriteNode('iow:arrow_up_a_256') self.up_arrow.alpha = 0.5 self.up_arrow.size = (72, 72) self.up_arrow.anchor_point = (0, 0) self.up_arrow.position = (48, 96) self.add_child(self.up_arrow) self.down_arrow = SpriteNode('iow:arrow_down_a_256') self.down_arrow.alpha = 0.5 self.down_arrow.size = (72, 72) self.down_arrow.anchor_point = (0, 0) self.down_arrow.position = (48, 0) self.add_child(self.down_arrow) def did_change_size(self): pass #--------------------------------------------- # Main game loop. Ran 60 time per second. #--------------------------------------------- def update(self): self.update_player() #--------------------------------------------- # All player logic here. #--------------------------------------------- def update_player(self): # Calculate player movement. x, y = self.player.position x += self.player.x_mov * self.player.mov_rate y += self.player.y_mov * self.player.mov_rate # Keep player on screen. x = max(0 + self.player.size.w/2, min(x, self.size.w - self.player.size.w/2)) y = max(0 + self.player.size.h/2, min(y, self.size.h - self.player.size.h/2)) # Set new player position. self.player.position = (x, y) #--------------------------------------------- # Handle touch screen. #--------------------------------------------- def touch_began(self, touch): self.handle_touch(touch) def touch_moved(self, touch): self.handle_touch(touch) def touch_ended(self, touch): self.player.moving = False self.player.x_mov = 0 self.player.y_mov = 0 #self.player.direction = 0 def handle_touch(self, touch): if touch.location in self.left_arrow.frame: self.player.x_mov = -1 self.player.y_mov = 0 if touch.location in self.right_arrow.frame: self.player.x_mov = 1 self.player.y_mov = 0 if touch.location in self.up_arrow.frame: self.player.y_mov = 1 self.player.x_mov = 0 if touch.location in self.down_arrow.frame: self.player.y_mov = -1 self.player.x_mov = 0 if __name__ == '__main__': run(MyScene(), orientation=LANDSCAPE, show_fps=True)
-
There may very well be some gesture delay, as there are some app wide gestures.
I believe @mikael's pythonista_gestures module will let you disable the pan/edge pan gestures for your view.
-
@Varaxcale, 2 seconds sounds like an awfully long time... Anyway, try putting the following in your setup method to see if it changes anything:
from objc_util import * UILayoutContainerView = ObjCClass('UILayoutContainerView') UIScreenEdgePanGestureRecognizer = ObjCClass('UIScreenEdgePanGestureRecognizer') v = self.view.objc_instance while not v.isKindOfClass_(UILayoutContainerView.ptr): v = v.superview() for gr in v.gestureRecognizers(): if gr.isKindOfClass_(UIScreenEdgePanGestureRecognizer.ptr): gr.setEnabled(False)
-
@Varaxcale, also, tested your code as-is on my iPhone X, and there were no delays, near the edge or otherwise.
-
@Varaxcale and @mikael On iPad mini 4, I get some delay also at down arrow when very close to the bottom edge of my screen
-
-
-
@JonB Good to know. I did not even think about searching the web 😅
-
@Varaxcale, affects me as well, at the very edge/tip of the arrow.
Implementing the status bar suggestion from @JonB’s link seems pretty tricky to me, as it would require subclassing the view controller.
-
Mikel, you could also swizzle the view controller, rather than subclass.
Of course the simpler option might be to just move the arrows away from the edge far enough so it is not an issue.
I wonder if simply hiding the status bar works the same way
-
-
In any case I don’t think that hiding the status bar has a big effect on recent iOS versions, where the swipe up gesture is now a multitasking, not control center gesture?
-
I found this doing a quick search and it seems to be at least similar to the issue I’m having. My device is an iPhone 6S Plus with 3D Touch. I added another arrow to the top of the screen just for testing. It suffers the same two seconds of delay that the bottom and left arrows do when touches are at the very edge of the screen. When I disable 3D Touch, the left arrow responds to touches correctly all the way to the edge of the screen. Unfortunately there is no change in the bottom or top arrows.
-
ok, good find. we can implement that solution:
from objc_util import * windows=list(UIApplication.sharedApplication().windows())+[UIApplication.sharedApplication().statusBar().window()] for w in windows: gr = w.gestureRecognizers() if gr: for g in gr: print(g) g.delaysTouchesBegan=False g.delaysTouchesEnded=False g.cancelsTouchesInView=False
I suspect that will fix the top/bottom edge delays?
edit: added the status bar gestureRecognizer.
-
That fixed it @JonB!
Thank you all for all of your help.
-
@JonB Not bad at all for an admin 😂
Sorry, I could not stop myself😇