Forum Archive

Ghostly icons?

adrius42

In a 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)
cvp

@adrius42 iPads emojis are characters, not images

adrius42

So more, properly any ideas on changing a character to an image?

JonB

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

adrius42

@JonB you are just amazing Thankyou!

cvp

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

cvp

@adrius42 and if you want the name of an emoji

see here

Or