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.
Ghostly icons?
-
In a <Scene> script that places a series of emojis on the Node, it seems that even after I have removed the images, their ghost still remained.
I have solved the issue by the use of z-position.
But I can’t figure out why something that is removed and not visible, can be found on the node?
Any ideas?Also any one know how I can access the iPads emojis?
# coding: utf-8 from scene import * from random import choice, uniform, shuffle import sound from itertools import product from math import sqrt, pi A = Action ROWS = 3 COLS = 14 screen_size = min(get_screen_size())/2 #print(screen_size) center = (683,512) class ButtonNode (SpriteNode): def __init__(self, title, *args, **kwargs): SpriteNode.__init__(self, 'pzl:Button1', *args, **kwargs) button_font = ('Avenir Next', 20) self.title_label = LabelNode(title, font=button_font, color='black', position=(0, 1), parent=self) self.title = title print(self.title_label) return self.title_label class Object (SpriteNode): def __init__(self, img, col=0, row=0): SpriteNode.__init__(self, img, position=((col-0.5*col)*190+60, (row-0.5*row)*152+200)) self.img_name = img # image name self.title = img[4:] # img with 'emj:' stripped from name self.grid_pos = (col, row) # not used in this app self.i = col + (row * COLS) # not used in this app class MyScene (Scene): def setup(self): self.space = Node(parent=self) self.background_color = '#004f82' #self.center = self.size/2 self.img = [] # List of 38 emoji picture names, eg 'emj:Alien' self.emojis = [] # stores the emoji id's self.emoji_names = [] # List of emoji names sripped of 'emj:' , not used to read emoji names self.emoji_original = [] # Alpha list of the emoji names self.namesis = [] # stores the label id's self.names_title = [] self.touchdisabled = False post = (650, 970) self.show_title_label = self.show_message("Drag each emoji to it's correct title", pos = post, font = 48) self.img = ('emj:Alien', 'emj:Angry', 'emj:Confounded', 'emj:Cold_Sweat_1', 'emj:Cold_Sweat_2', 'emj:Crying_1', 'emj:Crying_2', 'emj:Disappointed', 'emj:Dizzy', 'emj:Fear_1', 'emj:Fear_2', 'emj:Flushed', 'emj:Grinning', 'emj:Imp', 'emj:Kissing_1', 'emj:Kissing_2', 'emj:Look_Of_Triumph', 'emj:Medical_Mask', 'emj:Relieved', 'emj:Pensive', 'emj:Pouting', 'emj:Relieved', 'emj:Sleepy', 'emj:Smiling_1', 'emj:Smiling_2', 'emj:Smiling_3', 'emj:Smiling_4', 'emj:Smiling_5', 'emj:Smiling_6', 'emj:Smirking', 'emj:Stuck-Out_Tongue_1', 'emj:Stuck-Out_Tongue_2', 'emj:Stuck-Out_Tongue_3', 'emj:Tears_Of_Joy', 'emj:Tired', 'emj:Unamused', 'emj:Weary', 'emj:Winking') # print(len(self.img)) for i, t in enumerate(self.img): # populates self.emoji_names self.emoji_names.append (t[4:]) self.emoji_original = self.emoji_names.copy() # creates the original alphabetic copy shuffle(self.emoji_names) # shuffled values of emojis for row, col in product(range(ROWS), range(COLS)): # paints emojis and populates list of 'emojis' id i = (row*COLS+col) if i > len(self.img)-1: break self.emojis.append(Object(self.img[i],col,row)) # emojis id's' self.space.add_child(self.emojis[i]) for r, c in product(range(10), range(4)): i = (r*4+c) if i > len(self.img)-1: break post = ((c-0.5*2)*350 + 500, 900-(r*50)) self.label=self.show_message(self.emoji_names[i], pos=post, font = 24) self.namesis.append(self.label) # print('namesis', self.namesis) def show_message(self, message, pos = (200, 600), font = 24): self.label = LabelNode(message, font=('American Typewriter', 24),position=pos) self.label.blend_mode = BLEND_ADD self.space.add_child(self.label) #print(label) #print('namesis in show message', self.namesis) return self.label def touch_began(self, touch): # print('touch began') self.touched_emoji = self.emojitouched(touch) # returns touched emoji id # print(self.touched_emoji.title) # prints title of emoji created in class Object def touch_moved(self, touch): if not self.touched_emoji: # ('no emoji near') print ('touched background') else: if self.touchdisabled == True: return else: self.touched_emoji.position = touch.location # print(self.touched_emoji.position) self.check_item_collisions() self.restart_touch() def emojitouched(self, touch): # Returns touched emoji touch_pos = self.space.point_from_scene(touch.location) for touched_emoji in self.emojis: if touched_emoji.frame.contains_point(touch_pos): # print('et', touched_emoji, touched_emoji.title, len(self.emojis), touch_pos) return touched_emoji def check_item_collisions(self): #print('collision check') for i, item in enumerate(self.namesis): item.z_position = 0.1 if item.frame.intersects(self.touched_emoji.frame): if self.touched_emoji.title == self.emoji_names[i]: self.touchdisabled = True self.emoji_names[i] = '' # why did I do this? self.touched_emoji.z_position = 0.5 item.z_position = 0.5 #self.touchdisabled = True sound.play_effect('digital:PepSound5') # print ('collision detected') item.run_action(A.sequence(A.move_to(700,100), A.scale_to(5, 0.1, TIMING_EASE_OUT_2), A.wait(2), A.fade_to(0.0, 0.15),A.remove())) self.touched_emoji.run_action(A.sequence(A.move_to(700,725), A.scale_to(9, 0.1, TIMING_EASE_OUT_2), A.wait(2), A.fade_to(0.0, 0.15), A.remove())) self.touched_emoji.z_position = 0.2 # This "hides" the emoji ghosts, not sure why they exist? # print('got one!') def restart_touch(self): self.touchdisabled = False run(MyScene(), show_fps=True)
-
@adrius42 iPads emojis are characters, not images
-
So more, properly any ideas on changing a character to an image?
-
i could not reproduce your "ghosts", though you had some logic errors related to restarting touch -- for instance, you needed to set touched_emojis to None in check_collisions otherwise you kept moving it, and you needed to reset touch in touch_ended. that might make you think there is a ghost stealing touches.
# coding: utf-8 from scene import * from random import choice, uniform, shuffle import sound from itertools import product from math import sqrt, pi A = Action ROWS = 3 COLS = 14 screen_size = min(get_screen_size())/2 #print(screen_size) center = (683,512) class ButtonNode (SpriteNode): def __init__(self, title, *args, **kwargs): SpriteNode.__init__(self, 'pzl:Button1', *args, **kwargs) button_font = ('Avenir Next', 20) self.title_label = LabelNode(title, font=button_font, color='black', position=(0, 1), parent=self) self.title = title print(self.title_label) return self.title_label class Object (SpriteNode): def __init__(self, img, col=0, row=0): SpriteNode.__init__(self, img, position=((col-0.5*col)*190+60, (row-0.5*row)*152+200)) self.img_name = img # image name self.title = img[4:] # img with 'emj:' stripped from name self.grid_pos = (col, row) # not used in this app self.i = col + (row * COLS) # not used in this app class MyScene (Scene): def setup(self): self.space = Node(parent=self) self.background_color = '#004f82' #self.center = self.size/2 self.img = [] # List of 38 emoji picture names, eg 'emj:Alien' self.emojis = [] # stores the emoji id's self.emoji_names = [] # List of emoji names sripped of 'emj:' , not used to read emoji names self.emoji_original = [] # Alpha list of the emoji names self.namesis = [] # stores the label id's self.names_title = [] self.touchdisabled = False post = (650, 970) self.show_title_label = self.show_message("Drag each emoji to it's correct title", pos = post, font = 48) self.img = ('emj:Alien', 'emj:Angry', 'emj:Confounded', 'emj:Cold_Sweat_1', 'emj:Cold_Sweat_2', 'emj:Crying_1', 'emj:Crying_2', 'emj:Disappointed', 'emj:Dizzy', 'emj:Fear_1', 'emj:Fear_2', 'emj:Flushed', 'emj:Grinning', 'emj:Imp', 'emj:Kissing_1', 'emj:Kissing_2', 'emj:Look_Of_Triumph', 'emj:Medical_Mask', 'emj:Relieved', 'emj:Pensive', 'emj:Pouting', 'emj:Relieved', 'emj:Sleepy', 'emj:Smiling_1', 'emj:Smiling_2', 'emj:Smiling_3', 'emj:Smiling_4', 'emj:Smiling_5', 'emj:Smiling_6', 'emj:Smirking', 'emj:Stuck-Out_Tongue_1', 'emj:Stuck-Out_Tongue_2', 'emj:Stuck-Out_Tongue_3', 'emj:Tears_Of_Joy', 'emj:Tired', 'emj:Unamused', 'emj:Weary', 'emj:Winking') # print(len(self.img)) for i, t in enumerate(self.img): # populates self.emoji_names self.emoji_names.append (t[4:]) self.emoji_original = self.emoji_names.copy() # creates the original alphabetic copy shuffle(self.emoji_names) # shuffled values of emojis for row, col in product(range(ROWS), range(COLS)): # paints emojis and populates list of 'emojis' id i = (row*COLS+col) if i > len(self.img)-1: break self.emojis.append(Object(self.img[i],col,row)) # emojis id's' self.space.add_child(self.emojis[i]) for r, c in product(range(10), range(4)): i = (r*4+c) if i > len(self.img)-1: break post = ((c-0.5*2)*350 + 500, 900-(r*50)) self.label=self.show_message(self.emoji_names[i], pos=post, font = 24) self.namesis.append(self.label) # print('namesis', self.namesis) self.touched_emoji={} def show_message(self, message, pos = (200, 600), font = 24): self.label = LabelNode(message, font=('American Typewriter', 24),position=pos) self.label.blend_mode = BLEND_ADD self.space.add_child(self.label) #print(label) #print('namesis in show message', self.namesis) return self.label def touch_began(self, touch): # print('touch began') #to handle multiple touches, we will keep track of list of touches, and which emoji is associated touched_emoji=self.emojitouched(touch) if touched_emoji and not touched_emoji in self.touched_emoji.values(): print(touched_emoji.z_position) #only associate this finger with the touch if it is not already being moved self.touched_emoji[touch.touch_id] = touched_emoji # returns touched emoji id # print(touched_emoji.title) # prints title of emoji created in class Object self.touched_emoji[touch.touch_id].z_position+=0.1 def touch_moved(self, touch): if touch.touch_id in self.touched_emoji: self.touched_emoji[touch.touch_id].position = touch.location # we only need to check collisions on the current touch self.check_item_collisions(touch.touch_id) def touch_ended(self, touch): if touch.touch_id in self.touched_emoji: #get list of all emoji touching current emoji, and move this emiji to top colliding_z=[e.z_position for e in self.emojis if not e in self.touched_emoji.values() and e.frame.intersects(self.touched_emoji[touch.touch_id].frame)] if colliding_z: print self.touched_emoji[touch.touch_id].z_position=max(colliding_z)+0.0001 else: self.touched_emoji[touch.touch_id].z_position=0 del self.touched_emoji[touch.touch_id] #remive from the touch list def emojitouched(self, touch): # Returns topmost touched emoji touch_pos = self.space.point_from_scene(touch.location) emojis_touched=[] for touched_emoji in self.emojis: if touched_emoji.frame.contains_point(touch_pos): # print('et', touched_emoji, touched_emoji.title, len(self.emojis), touch_pos) emojis_touched.append(touched_emoji) #get top emoji emojis_touched.sort(key=lambda e:e.z_position) if emojis_touched: return emojis_touched[-1] def check_item_collisions(self, touch_id): #print('collision check') touched_emoji=self.touched_emoji[touch_id] for i, item in enumerate(self.namesis): item.z_position = 0.1 if item.frame.intersects(touched_emoji.frame): if touched_emoji.title == self.emoji_names[i]: touched_emoji.z_position = 0.5 item.z_position = 0.5 #self.touchdisabled = True sound.play_effect('digital:PepSound5') # print ('collision detected') item.run_action(A.sequence(A.move_to(700,100), A.scale_to(5, 0.1, TIMING_EASE_OUT_2), A.wait(2), A.fade_to(0.0, 0.15),A.remove())) touched_emoji.run_action(A.sequence(A.move_to(700,725), A.scale_to(9, 0.1, TIMING_EASE_OUT_2), A.wait(2), A.fade_to(0.0, 0.15), A.remove())) del self.touched_emoji[touch_id] #so it stops touch processing! return # otherwise loop keeps going, no need to keep checking collision #self.touched_emoji.z_position = 0.2 # This "hides" the emoji ghosts, not sure why they exist? # print('got one!') def restart_touch(self): self.touchdisabled = False run(MyScene(), show_fps=True)
this also deals with multiple touches, which your original code got confused with. for multiple touch, you keep a dict of touches and the associated emoji you are dragging. you might want to snap emoji back to their starting point when tiuch ended, or only allow one touch at a time,etc, but this at least gives a starting point
-
@JonB you are just amazing Thankyou!
-
@adrius42 Up to you for list, names, size and position, this is only an example:
class Object (SpriteNode): def __init__(self, img, col=0, row=0): if img == 'emj:Alien': with ui.ImageContext(64,64) as ctx: ui.draw_string('🤠',font=('Menlo',64)) img2 = Texture(ctx.get_image()) else: img2 = img SpriteNode.__init__(self, img2, position=((col-0.5*col)*190+60, (row-0.5*row)*152+200))
-