コード例 #1
0
ファイル: main.py プロジェクト: ubuntunux/KivyProject
class GameView(ScreenManager):
    def __init__ (self, app):
        super(GameView, self).__init__(transition=WipeTransition())
        self.app = app
        self.graphics_widget = FloatLayout()
        image = Image(source = PATH + "splash.png", keep_ratio=False, allow_stretch=True,\
               size=(SCREEN_WIDTH, SCREEN_HEIGHT), size_hint=(None, None), pos=(0,0))
        self.graphics_widget.add_widget(image)
        screen = Screen(name="0")
        screen.add_widget(self.graphics_widget)
        self.add_widget(screen)
        self.current = "0"
        #
        self.load_sounds()
        self.load_textures()
        #self.load_sprites()
        self.load_gems()
        #
        self.schedules = []
        self.image_hero = None
        #
        self.image_score = MyImage(source = PATH + "score_bg.png", allow_stretch=True)
        self.image_score.set_score(0)
        self.image_score.set_shadow(False)
        self.image_score.set_font_size(30)
        self.image_score.set_label_position(3,4)        
        self.image_score.size_hint = (.2, .2)
        self.image_score.pos_hint = {'x':.8, 'y':.8}
        #
        self.button_reset = MyButton(source=PATH + "restart.png", on_press=self.reset, opacity=0.5,\
                       background_color = (0,0,0,0), size = (X_BLOCK, Y_BLOCK), border=(0,0,0,0))
        self.button_reset.size_hint = (.1, .1)
        self.button_reset.pos_hint = {'x': 0, 'y':.9}
        
        self.progress_bar = ProgressBar(max=500, opacity=0) #CURRENTLY HIDDEN
        with self.progress_bar.canvas:
            Color(0,0,0,0)
        self.progress_bar.size_hint = (.6, .05)
        self.progress_bar.pos_hint = {'x': 0.2, 'y': 0}
        self.progress_bar.value = 0

        self.schedule(self.reset_level, 3)
        
    def unschedule_all(self):
        for s in self.schedules:
            Clock.unschedule(s)
        self.schedules = []       

    def unschedule_single(self, dt=None):
        self.schedules = self.schedules[1:]

    def schedule(self, func, delay):
        if func not in self.schedules:
            self.schedules.append(func)
        Clock.schedule_once(func, delay)
        Clock.schedule_once(self.unschedule_single, delay)

    def reset(self, widget=None):
        print "Reset"
        #save_state(1)
        #self.reset_level()
        self.level = 1
        save_state(1)
        self.app.stop()

    def reset_level(self, dt=None):
        self.level = int(get_state())
        try:
            Animation.cancel_all(self.scatter_hero)
        except:
            pass
        try:
            Animation.cancel_all(self.scatter_baddy)
        except:
            pass
        Animation.cancel_all(self.progress_bar)
        self.unschedule_all()
        self.setup_battle()
        
    def get_level_data(self):
        data = get_level_data(self.level)
        self.baddy_points_for_level = int(data[0])
        self.weapons = [int(x) for x in data[1].split(",")]
        self.score_threshold = int(data[2])
        self.maximum_attacks = int(data[3])
        self.time_limit = int(data[4])
        self.baddy_image = data[5]
        self.baddy_ratio_for_level = int(data[6])
        self.baddy_label_deltax = int(data[7])
        self.baddy_label_deltay = int(data[8])
        self.level_potions = [int(x) for x in data[9].split(",") if x]
        self.textures_data = data[10].split(";")
        #self.sprites_data = data[11].split(";")
        #if self.sprites_data == ['']:
        #    self.sprites_data = []
        
    def setup_battle(self, dt=None):
        self.graphics_widget.remove_widget(self.button_reset)
        self.graphics_widget.remove_widget(self.image_score)
        self.graphics_widget.remove_widget(self.progress_bar)
        if self.level == 11:
            graphics_widget = FloatLayout()
            image = Image(source = PATH + "end.png", keep_ratio=False, allow_stretch=True,\
               size=(SCREEN_WIDTH, SCREEN_HEIGHT), size_hint=(None, None), pos=(0,0))
            graphics_widget.add_widget(image)
            graphics_widget.add_widget(self.button_reset)
            screen = Screen(name="end")
            screen.add_widget(graphics_widget)
            self.add_widget(screen)
            self.current=screen.name
        else:
            self.get_level_data()

            graphics_widget = self.set_background()
            screen = Screen(name=str(self.level))
            screen.add_widget(graphics_widget)
            self.graphics_widget = graphics_widget
            self.add_widget(screen)
            self.current=screen.name
            if self.score_threshold > 0:
                self.level_score = - self.score_threshold
            else:
                self.level_score = 0
            self.image_score.set_score(self.level_score)
            if self.level < 3:
                self.start_battle()
            else:
                self.schedule(self.start_battle, 0) #WAS 2
            self.graphics_widget.add_widget(self.button_reset)
            self.graphics_widget.add_widget(self.progress_bar)
            self.graphics_widget.add_widget(self.image_score)
        
    def repeat_battle(self, dt=None):
        self.image_hero = None
        self.level_score = 0
        self.image_score.set_score(self.level_score)
        self.start_battle()

    def start_battle(self, dt=None):
        self.attacks_tried = 0
        self._picked_gems = []
        if self.level_potions:
            self.create_potions(self.level_potions)
        else:
            self.potion_buttons = []
        self.create_gems(self.weapons)
        #
        min_wait = 0 #WAS 3
        if self.level < 3:
            min_wait = 0
        self.schedule(self.introduce_hero, min_wait)
        if self.level == 1:
            self.schedule(self.introduce_baddy, min_wait)
        else:
            self.schedule(self.introduce_baddy, min_wait + 2)
        self.schedule(self.talk_baddy, min_wait + 4)
        self.schedule(self.talk_hero, min_wait + 5.5)
        self.schedule(self.talk_baddy, min_wait + 6.5)
        if self.level == 1:
            self.schedule(self.show_gems, 0)
        else:
            self.schedule(self.show_gems, min_wait + 8)
        if self.score_threshold > 0:
            self.image_score.flash(10)
        self.schedule(self.show_potions, min_wait + 8)
        self.schedule(self.look_alive, min_wait + 8)
        self.schedule(self.handle_timed_battle, min_wait + 8)
        if self.level == 1:
            self.schedule(self.flash_gem, min_wait + 11)
            #self.schedule(self.flash_hero, min_wait + 15)
        
    def flash_gem(self, dt=None):
        for g in self.gems:
            if g:
                g.flash(10)

    def flash_hero(self, widget=None, event=None):
        self.image_hero.flash(10)
        
    def handle_timed_battle(self, dt=None):
        if self.time_limit > 0:
            anim1 = Animation(x = X_BLOCK, duration=self.time_limit)
            anim1.bind(on_complete = self.level_failed)
            anim1.start(self.scatter_baddy)
            self.progress_bar.value = self.progress_bar.max
            anim2 = Animation(value = 0, duration=self.time_limit)
            anim2.start(self.progress_bar)
            
    def create_gems(self, numbers):
        self.gems = [None] * 10
        self.gem_values = [0] * 10
        for i in range(len(numbers)):
            n = numbers[i]
            #gem = MyImage(keep_ratio=True, allow_stretch=False, color=(0,0,0,0), keep_data=True)
            #gem.set_shadow(False)
            #with gem.canvas:
            #    gem.rectangle = Rectangle(texture=self.gem_sprites[n].texture, size = (X_BLOCK,Y_BLOCK))
            gem = MyImage(source = self.gem_sources[n],keep_ratio=False, allow_stretch=True, keep_data=True)
            gem.set_shadow(False)
            self.gems[n] = gem
            self.gem_values[n] = n
            
    def drop_gem(self, widget=None, event=None):
        if widget not in self.graphics_widget.children:
            return True

        if widget.x > self.scatter_hero.x and widget.x < self.scatter_hero.x + self.image_hero.width * 2:
            if widget.y > self.scatter_hero.y and widget.y < self.scatter_hero.y + self.image_hero.height * 2:
                self.image_hero.stop_flash()
                self.handle_player_action(widget)
                return True
            else:
                self.hide_gems()
                self.show_gems()
                self.hide_potions()
                self.show_potions()
        else:
            self.hide_gems()
            self.show_gems()
            self.hide_potions()
            self.show_potions()
        return False
        
    def pick_gem(self, widget=None, event=None):
        self._picked_gems.append(widget)
        self.flash_hero()

    def hide_gems(self, dt=None, dummy=None):
        for scatter in self.gem_scatters:
            if scatter.children:
                scatter.remove_widget(scatter.children[-1])
            self.graphics_widget.remove_widget(scatter)
    
    def show_gems(self, dt=None, dummy=None):
        self.gem_scatters = []
        filler = (8 - len(self.weapons)) / 2.0
        for i in range(len(self.weapons)):
            gem = self.gems[self.weapons[i]]
            scatter = Scatter(do_rotation=False, do_scale=False, color=(0,0,0,0), size_hint=(0.1,0.1))
            scatter.add_widget(gem)
            gem.bind(on_touch_down=self.flash_hero)            
            scatter.bind(on_touch_up=self.drop_gem)
            scatter.pos = ((filler + i) * X_BLOCK, 0)
            scatter.scale = 1
            try:
                self.graphics_widget.add_widget(scatter)
                self.gem_scatters.append(scatter)
            except:
                pass

    def bring_to_front(self, widget):
        self.graphics_widget.remove_widget(widget)        
        self.graphics_widget.add_widget(widget)        
        
    def set_background(self):
        graphics_widget = FloatLayout()

        for td in self.textures_data:
            filename,xpos,ypos,width,height = td.split(":")
            xpos = float(xpos)
            ypos = float(ypos)
            image = MyImage(keep_ratio=True, allow_stretch=False, color=(0,0,0,0))
            image.set_shadow(False)
            with image.canvas:
                Rectangle(texture=self.textures[filename].texture, size=(float(width) * X_BLOCK, float(height) * Y_BLOCK))
            scatter = Scatter(do_rotation=False, do_scale=False, do_translation=False)
            scatter.pos = (xpos * X_BLOCK, ypos * Y_BLOCK)
            scatter.add_widget(image)
            graphics_widget.add_widget(scatter)

        #for td in self.sprites_data:
        #    filename,xpos,ypos,width,height = td.split(":")
        #    xpos = float(xpos)
        #    ypos = float(ypos)
        #    image = MyImage(texture = self.sprites[filename].texture, keep_ratio=True, allow_stretch=False)
        #    image.set_shadow(False)
        #    scatter = Scatter(do_rotation=False, do_scale=False, do_translation=False)
        #    scatter.pos = (xpos * X_BLOCK, (ypos + 4) * Y_BLOCK / 2)
        #    scatter.add_widget(image)
        #    graphics_widget.add_widget(scatter)
        #    scatter.scale = 6 -  ypos * 1.5

        return graphics_widget

    def introduce_hero(self, dt=None):
        self.image_hero = MyImage(source = PATH + "hero.png", keep_ratio=False, allow_stretch=True, keep_data=True)
        self.image_hero.set_label_position(-4, -12)
        self.image_hero.set_shadow(True)
        self.scatter_hero = Scatter(do_rotation=False, do_scale=False, do_translation=False)
        self.scatter_hero.add_widget(self.image_hero)
        self.scatter_hero.scale= 2 + (0.5 * SCREEN_DENSITY)
        if self.level < 3:
            self.hero_position = [X_BLOCK, Y_BLOCK]
            self.scatter_hero.pos = (self.hero_position[0], self.hero_position[1])
            self.graphics_widget.add_widget(self.scatter_hero)
        else:    
            self.schedule(self.sounds['hero_song'].play, 1.0)
            self.hero_position = [- 2 * X_BLOCK, Y_BLOCK]
            self.scatter_hero.pos = (self.hero_position[0], self.hero_position[1])
            self.graphics_widget.add_widget(self.scatter_hero)
            #
            self.image_hero.walk(60, 2.4 * X_BLOCK)
            anim = Animation(x = X_BLOCK, duration=4)
            anim.start(self.scatter_hero)

        self.image_score.set_score(self.level_score)
        
    def introduce_baddy(self, dt=None):        
        self.baddy_size_ratio = self.baddy_ratio_for_level
        self.baddy_points = self.baddy_points_for_level
        self.image_baddy = MyImage(source = PATH + self.baddy_image, keep_ratio=False, allow_stretch=True)
        self.image_baddy.set_label_position(self.baddy_label_deltax, self.baddy_label_deltay)
        self.image_baddy.set_score(self.baddy_points)
        self.scatter_baddy = Scatter(do_rotation=False, do_scale=False, do_translation=False)
        self.scatter_baddy.add_widget(self.image_baddy)

        self.baddy_size = [X_BLOCK, Y_BLOCK]
        self.baddy_step = (4 * X_BLOCK + 0.0) / self.maximum_attacks

        self.scatter_baddy.scale = self.baddy_size_ratio # * SCREEN_DENSITY
        self.scatter_baddy.pos = (8 * X_BLOCK, Y_BLOCK)
        self.graphics_widget.add_widget(self.scatter_baddy)
        self.image_baddy.walk(30, 60)
        anim = Animation(x=5 * X_BLOCK, duration=2)
        anim.start(self.scatter_baddy)
        self.baddy_position = [5 * X_BLOCK, Y_BLOCK]

    def create_potions(self, numbers):
        self.potion_buttons = []
        self.potion_button_values = []
        for n in numbers:
            button = MyButton(source=PATH + "potion.png",background_color=[0,0,0,0], label_text="-1", font_size = 30)
            self.potion_buttons.append(button)
            self.potion_button_values.append(n)
            button.pos_hint = {'x': .45,'y': .85}
            button.size_hint = (0.12, 0.12)
            button.bind(on_press=self.handle_potion)
            
    def show_potions(self, dt=None):
        for button in self.potion_buttons:
            self.graphics_widget.add_widget(button)
            
    def hide_potions(self):
        for button in self.potion_buttons:
            self.graphics_widget.remove_widget(button)

    def handle_potion(self, widget=None):
        value = self.potion_button_values[self.potion_buttons.index(widget)]
        self.image_baddy.flash(5)
        self.baddy_points = self.baddy_points +  value
        self.image_baddy.set_score(self.baddy_points)

        self.graphics_widget.remove_widget(widget)
        self.potion_buttons.remove(widget)
        self.potion_button_values.remove(value)
        self.decide_next_stage()
        
    def handle_player_action(self, widget=None):
        # HANDLE MULTIPLE WIDGETS USING self._PICKED_GEMS AND THEN CLEAR IT!
        try:
            self.graphics_widget.remove_widget(widget)
        except:
            pass

        image = widget.children[-1]
        self.hide_gems()

        Clock.unschedule(self.image_hero.look_alive)
        Clock.unschedule(self.image_baddy.look_alive)
        #
        widget.pos = (X_BLOCK / (20.0 * (SCREEN_DENSITY **2) * SCREEN_RATIO ), Y_BLOCK / (16 * (SCREEN_DENSITY**2) * SCREEN_RATIO) )
        #
        widget.scale = 0.3
        widget.add_widget(image)
        self.current_gem = widget
        self.scatter_hero.add_widget(widget)

        self.image_hero.walk(40, 60)
        self.image_baddy.walk(40, 60)

        anim1 = Animation(x = 3 * X_BLOCK, t='out_quad')
        anim1.start(self.scatter_hero)
        anim2 = Animation(x = 3.1 * X_BLOCK, t='out_quad')
        anim2.start(self.scatter_baddy)
        
        self.attacks_tried = self.attacks_tried + 1
        if self.maximum_attacks > 0:
            self.baddy_position[0] = self.baddy_position[0] - ((self.attacks_tried +0.0) / self.maximum_attacks) * self.baddy_step
        self.schedule(self.sounds['hero_charge'].play, 0.1)
        self.schedule(self.sounds['baddy_charge'].play, 0.5)
        
        #Handle hit
        hit_value = self.gems.index(widget.children[-1])
        if self.baddy_points / (hit_value + 0.0) == self.baddy_points / hit_value:
            if self.baddy_size_ratio <= self.baddy_ratio_for_level:
                self.level_score = self.level_score + hit_value * self.baddy_points
            self.baddy_points = self.baddy_points / hit_value
            self.baddy_size_ratio = self.baddy_size_ratio - 1
            if self.baddy_size_ratio == 0:
                self.baddy_size_ratio = 0.1
        else:
            self.baddy_points = self.baddy_points * hit_value
            self.baddy_size_ratio = self.baddy_size_ratio + 1
        
        anim1.bind(on_complete = self.update)

    def baddy_vanquished(self, widget=None, event=None):
        self.graphics_widget.remove_widget(self.progress_bar)        
        Animation.cancel_all(self.progress_bar)
        Animation.cancel_all(self.scatter_baddy, 'x')
        self.celebrate()
        self.image_baddy.walk(20, 40) 
        self.image_baddy.children[-1].text=""
        anim1 = Animation(size = (1,1))
        anim1.start(self.image_baddy)        
        self.hide_gems()
        if self.level_score < 0:
            print "NOTIFY USER ABOUT THRESHOLD!"
            self.image_score.flash(10)
            self.schedule(self.level_failed, 2)
        else:
            self.schedule(self.move_to_next_battle, 2)
        
    def level_failed(self, widget=None, event=None):
        self.graphics_widget.remove_widget(self.progress_bar)
        Animation.cancel_all(self.progress_bar)
        Animation.cancel_all(self.scatter_baddy, 'x')
        if self.baddy_points < 2 and self.level_score >= self.score_threshold:
            return
        self.hide_gems()
        anim = Animation(x = - 4 * X_BLOCK, duration = 2)
        self.image_hero.walk(10, 4 * X_BLOCK)        
        anim.start(self.image_hero)

        self.image_baddy.celebrate(240,60)
        self.schedule(self.move_to_repeat_battle, 2)

    def move_to_repeat_battle(self, widget=None, event=None):
        self.graphics_widget.remove_widget(self.scatter_hero)        
        anim = Animation(x = 8 * X_BLOCK, duration = 12)
        self.image_baddy.walk(30, 8 * X_BLOCK)        
        anim.start(self.image_baddy)
        
        self.schedule(self.repeat_battle, 3)        
        
    def move_to_next_battle(self, widget=None, event=None):
        self.graphics_widget.remove_widget(self.scatter_baddy)
        if self.level == 1:
            self.next_battle()
        else:                
            self.schedule(self.sounds['hero_song'].play, .5)            
            self.schedule(self.sounds['hero_song'].play, 3) 
            anim = Animation(x = 8 * X_BLOCK, duration = 4.5)
            self.image_hero.walk(30, 6 * X_BLOCK)        

            anim.start(self.scatter_hero)
            anim.bind(on_complete = self.next_battle)

    def keep_hero_in_same_position(self, dt=None):
        self.image_hero.x = self.image_hero.x + 0.0
        
    def stop_hero_motion(self, event=None, widget=None):
        Clock.unschedule(self.keep_hero_in_same_position)

    def next_battle(self, widget=None, event=None):
        self.scatter_baddy.rotation = 0
        if self.level > 1:
            self.graphics_widget.remove_widget(self.scatter_hero)
        
        self.level = self.level + 1
        self.schedule(self.setup_battle, 2.0)

    def remove_item(self, animation=None, widget=None):
        self.graphics_widget.remove_widget(widget)
        widget.canvas.clear()
        widget = None
        
    def update(self, widget=None, event=None):
        self.image_hero.angle = 0
        self.image_baddy.angle = 0
        
        try:
            self.current_gem.remove_widget(self.current_gem.children[-1])
            self.scatter_hero.remove_widget(self.current_gem)
        except:
            pass

        anim1 = Animation(scale=self.baddy_size_ratio) 
        anim2 = Animation(y= self.baddy_position[1]) 
        anim3 = Animation(x= self.baddy_position[0]) 
        anim4 = Animation(x = X_BLOCK)
        anim1.start(self.scatter_baddy)
        anim2.start(self.scatter_baddy)
        if self.time_limit < 0:
            anim3.start(self.scatter_baddy)
        anim4.start(self.scatter_hero)
        self.image_baddy.set_score(self.baddy_points)
        self.image_score.set_score(self.level_score)
        
        if self.scatter_baddy.scale > self.baddy_size_ratio:
            self.hero_celebrate()
        else:
            self.baddy_celebrate()
            
        if self.level_score < 0:
            self.image_score.flash(10)
        
        anim4.bind(on_complete = self.decide_next_stage)

    def decide_next_stage(self, widget=None, event=None):
        if self.baddy_points == 1:
            self.baddy_vanquished()
        elif self.attacks_tried == self.maximum_attacks:
            self.level_failed()
        elif self.baddy_points > 1 and (self.is_impossible(self.baddy_points)) and not self.potion_buttons:
            self.level_failed()            
        else:
            self.hide_gems()
            self.show_gems()
            
    def talk_hero(self, dt=None):
        self.sounds['hero_talk'].play()
        self.image_hero.jump(60, 60)

    def talk_baddy(self, dt=None):
        self.sounds['baddy_talk'].play()
        self.image_baddy.jump(60, 60)
        
    def look_alive(self, dt=None, dummy=None):
        Clock.schedule_interval(self.image_baddy.look_alive, 1.5)
        Clock.schedule_interval(self.image_hero.look_alive, 2.0)

    def celebrate(self):
        self.image_hero.celebrate(60, 60)

    def hero_celebrate(self, widget=None, event=None):
        self.image_hero.celebrate(60, 60)

    def baddy_celebrate(self, widget=None, event=None):
        self.image_baddy.celebrate(60, 60)
                       
    def load_sounds(self):
        self.sounds = {}
        for f in ["hero_charge", "hero_song", "hero_talk", "baddy_charge", "baddy_talk", "sword1", "sword2", "sword3"]:
            sound = SoundLoader.load(PATH + "sounds/" + f + '.wav')
            self.sounds[f] = MySound(sound)

    def load_gems(self):
        self.gem_sprites = [None] * 10
        self.gem_sources = [""] * 10
        for i in range(2,10,1):
            self.gem_sources[i] = PATH + "gems/" +"gem_0"+str(i)+".png"
            self.gem_sprites[i] = CoreImage(PATH + "gems/" +"gem_0"+str(i)+".png", color=(0,0,0,1))

    def load_textures(self):
        self.textures = {}
        for f in ["splash", "bg_1", "bg_2", "bg_3", "bg_4", "bg_5", "bg_6", "bg_7", "bg_8", "bg_9"]:
            self.textures[f] = CoreImage(PATH+f+".png")

    #def load_sprites(self):
    #    self.sprites = {}
    #    for f in ["tree_green","tree_red","tree_yellow", "castle", "moon"]:
    #        self.sprites[f] = CoreImage(PATH+f+".png")
       
    def calc_baddy_points(self, numbers, n_multiplications):
        product = 1
        for i in range(n_multiplications):
            product = product * random.choice(numbers)
        return product
        
    #def is_prime(self, num):
    #    if divide(num):
    #        return False
    #    return True

    def is_impossible(self, num):
        for weapon in self.weapons:
            if num % weapon == 0:
                return False
        return True
コード例 #2
0
ファイル: server.py プロジェクト: biinlab/kaleidoscope
class MapServer(KalScenarioServer):
    json_filename = StringProperty('')
    scenariol = NumericProperty(-2)
    layers = ListProperty( ["mountains","rivers","cities","regions"] )

    def search_data_files(self):
        blacklist = ('__init__.py', )
        curdir = realpath(dirname(__file__))
        for root, dirnames, filenames in walk(dirname(__file__)):
            for filename in filenames:
                if filename.startswith('.'):
                    continue
                if filename in blacklist:
                    continue
                filename = join(root, filename)
                filename = realpath(filename)
                if filename.startswith(curdir):
                    filename = filename[len(curdir):]
                if filename.startswith('/'):
                    filename = filename[1:]
                yield filename

    def __init__(self, *largs):
        self.resources = list(self.search_data_files())
        resource_add_path(dirname(__file__))
        Builder.load_file(join(dirname(__file__), 'map.kv'))
        super(MapServer, self).__init__(*largs)
        self.timeout = 0
        self.timemsg = 0
        self.players = {}

        # init client table
        for client in self.controler.clients:
            self.players[client] = {
                'client': client,
                'name': self.controler.get_client_name(client),
                'ready': False,
                'done': False,
                'place': self.controler.metadata[client]['place'],
                'count': 0
            }
        #store mapitems and thumbs in order to display them on main screen
        #or remove them from clients
        self.mapitems = {} #filename: [client, index]
        self.thumbs = {} #index: [client, pos]

        #get map layers list from json
        self.load_json() 

    def load_json(self):
        global layers
        curdir = join(dirname(__file__), 'data')
        json_filename = join(curdir, 'scenario.json')
        resource_add_path(curdir)
        with open(json_filename, 'r') as fd:
            data = load(fd)
        layers = data['layers']       

    def client_login(self, client):
        self.players[client]['ready'] = True

    def client_logout(self, client):
        del self.players[client]

    def start(self):
        '''Scenario start, wait for all player to be ready
        '''
        super(MapServer, self).start()
        self.send_all('WAITREADY')
        self.state = 'waitready'

    def stop(self):
        Builder.unload_file(join(dirname(__file__), 'map.kv'))
        resource_remove_path(dirname(__file__))

    def init_ui(self):   
        size = map_coordinates[1]
        cx,cy = Window.center
        pos = (cx - size[0]/3.,cy - size[1]/3.)
        if scenariol == -2 : layers2 = []
        elif scenariol == -1 : layers2 = layers
        else : layers2 = layers[int(scenariol)]

        self.layout = MapServerLayout()
        self.imagemap = imagemap = Map(
                server=True, 
                size_hint=(None, None),
                size = size,
                layers = layers2
                )
        self.map_background = ImageWidget(
                 source = 'data/map.png',
                 size_hint = imagemap.size_hint,
                 size = imagemap.size,
                 )
        self.scat = Scatter(
                size_hint = imagemap.size_hint,
                size = imagemap.size,
                center = pos, 
                scale = .8,
                rotation = 0,
                do_translation = False,
                do_scale = False   
                )
        self.layout.add_widget(self.scat)
        self.scat.add_widget(self.map_background)
        self.scat.add_widget(self.imagemap)
        self.controler.app.show(self.layout)

    #
    # Client commands received
    # do_client_<command>(client, [...])
    #
    def do_client_scenario(self, client, args):
        global scenariol
        scenariol = int(args[0])

    def do_client_ready(self, client, args):
        self.players[client]['ready'] = True
        count = len([x for x in self.players.itervalues() if not x['ready']])
        if count:
            self.msg_all('@%s ok, en attente de %d joueur(s)' % (
                self.players[client]['name'], count))

    def do_client_flagchange(self, client, args):
        filename = self.index2filename( int(args[0]) )
        thumb_index = int(args[1])
        #print "SERVER : do_client_flagchange: "+ str(client)+','+str(filename)+str(thumb_index)

        if filename not in self.mapitems.keys():
            self.mapitems[filename] = []
        if thumb_index not in self.thumbs.keys():
            self.thumbs[thumb_index] = [None, (0,-300)]
        c = len( self.mapitems[filename] )    

        #hide from screen and free current thumb_index 
        if thumb_index == -1 :
            #get thumb
            d = self.mapitems[filename]
            for i in d:
                cl,ti = i
                if cl == client :
                    d = ti
            thumb = self.index2thumb(d) 
            #remove thumb from screen
            self.scat.remove_widget(thumb)
            #save
            if (client, d) in self.mapitems[filename] :
                self.mapitems[filename].remove( (client, d) )      
            #remove mapitem from screen
            if len( self.mapitems[filename] ) == 0 :
                self.imagemap.hide_mapitem(filename)
            """ 
            #add thumb to other clients
            self.display_thumb(client, d)
            self.display_mapitem(client,filename) 
            """
            
        #display
        elif c >= 0 :
            #store new
            self.mapitems[filename].append( (client, thumb_index) )
            self.thumbs[thumb_index] = [client, self.thumbs[thumb_index][1] ]
            if c == 0:
                #display mapitem on main screen
                self.imagemap.display_mapitem(filename, True, (0,0,0,1))
            thumb = self.create_and_add_item(client, thumb_index)
            """
            #hide thumb on clients except client
            self.hide_thumb(client, thumb_index)
            self.hide_mapitem(client, filename)         
            """ 
    def index2filename(self,index):
        #trick to pass mapitem.filename (string) as a integer (protocol blocks strings..)
        return self.imagemap.data[index]['filename']

    def create_and_add_item(self, client, index):
        th = self.index2thumb(index) 
        thumb = self.imagemap.get_thumb(index)
        player_place = int(self.players[client]["place"])-1
        r,g,b = map_colors[ player_place ]
        thumb.color = [r/255.,g/255.,b/255.,1.]
        thumb.pos = (0,-400)
        right_pos = self.imagemap.retrieve_pixels_location(thumb.item['filename'])
        if right_pos is not None : 
            thumb.right_pos = right_pos
        else : 
            thumb.right_pos = (0,0)
        self.scat.add_widget(thumb)
        if index in self.thumbs.keys() and thumb != None:
            thumb.center = self.thumbs[index][1]
        thumb.locked = True
        return thumb

    def do_client_pos(self, client, args):
        index = int(args[0])
        x = int(args[1])
        y = int(args[2])
        thumb = self.index2thumb(index)
        if thumb is not None :
            thumb.center = (x,y)
            self.thumbs[index] = [client, (x,y)]

    def do_client_color(self, client, args):
        index = int(args[0])
        a = int(args[1])/255.
        b = int(args[2])/255.
        c = int(args[3])/255.
        thumb = self.index2thumb(index)
        if thumb is not None :
            thumb.color = (a,b,c)
            
        
    def index2thumb(self,index):
        for child in self.scat.children:
            if isinstance(child,MapThumbnail) and child.index == index:
                return child
        return None

    def index2filename(self,index):
        data = self.imagemap.data
        return data[index]['filename'] 

    def do_client_scale(self, client, scale): 
        pass

    def do_client_rotate(self, client, rot):
        #anim = Animation(rotation = rot)
        #anim.start(self.scat)
        self.scat.rotation += int(rot[0])

    #
    # Commands to send to clients
    #
    
    def hide_thumb(self, client, index):
        for cl in self.players.itervalues() :
            cl = cl['client']
            if cl != client :
                self.send_to(cl, 'HIDETH %d' % index)

    def display_thumb(self,client, index):
        for cl in self.players.itervalues() :
            cl = cl['client']
            if cl != client :
                self.send_to(cl, 'DISPLAYTH %d' % index)

    def hide_mapitem(self,client,filename):
        for cl in self.players.itervalues() :
            cl = cl['client']
            if cl != client :
                self.send_to(cl, 'HIDEMAPITEM %s' % str(filename))

    def display_mapitem(self,client,filename):
        for cl in self.players.itervalues() :
            cl = cl['client']
            if cl != client :
                self.send_to(cl, 'DISPLAYMAPITEM %s' % str(filename))
    
    def thumb_index_match_layer(self, index, client):
        filename = self.imagemap.data[index]['filename']
        return self.filename_match_layer(filename, client)

    def filename_match_layer(self, filename, client):
        #print self.f1(self.layers)
        parts = filename.rsplit('-', 1)
        #print parts[0], self.layers_given, client
        if len(parts) != 2 : 
            return False
        if client not in self.layers_given.keys():
            return False  
        if parts[0] != self.layers_given[ client ]:
            return False
        #print parts[0], self.layers_given, client
        return True

    def clear(self):
        self.send_all('CLEAR')
        #self clear as well
        self.mapitems = {}
        self.thumbs = {}
        self.layout.remove_widget(self.scat)
        self.scat.remove_widget(self.map_background)
        self.scat.remove_widget(self.imagemap)
        self.scat = ''
        self.imagemap = ''
        self.map_background = ''
        self.layout = ''
        
    
    #
    # State machine
    #

    def run_waitready(self):
        '''Wait for all player to be ready
        '''
        ready = True
        for player in self.players.itervalues():
            ready = ready and player['ready']
        if not ready:
            return

        #create clients layout
        self.send_all('GAME1')
        self.timeout = time() + TIMER_1
        self.send_all('TIME %d %d' % (time(), int(self.timeout)))

        #display sub-scenarii selector on clients
        self.send_all('SELECTOR') 
        self.state = 'game0'  

    def run_game0(self):

        if scenariol == -2:
            sleep(0.2)
            return

        #self.layout.remove_widget(self.selector)
        self.send_all('REMOVESELECTOR')
        self.init_ui()
        self.items_given = []
        self.layers_given = {}
        
        affected = [-1]
        self.imagemap.layers = []
        for client in self.controler.clients:
            place = int(self.players[client]['place']) - 1
            self.send_to(client, 'COLOR %d %d %d' % map_colors[place])
            self.send_to(client, 'LOGO %s' % map_logos[place])
            #deal with "all layers" (one on each client)
            if not scenariol == -1 : 
                layer = str(layers[scenariol])
            else :
                l = len(layers) - 1
                r = -1
                if place > l : 
                    place = 0
                else : 
                    while r in affected :
                        r = int( random() * l )
                affected.append(r)
                #print affected
                place = r 
                layer = str(layers[place])
            self.imagemap.layers = self.imagemap.layers + [layer] 
            self.send_to(client, 'LAYER %s' % layer)
            self.layers_given[client] = layer 
            self.send_to(client, 'MAPSIZE %d %d' % map_coordinates[1] )
            self.send_to(client, 'MAPPOS %d %d' % map_coordinates[0])

        #create map
        self.send_all('MAP')
        
        # deliver randomly index
        litems = len(self.imagemap.data)
        if litems:
            r = range(litems)
            allfinished = False
            while not allfinished:
                allfinished = True
                index = r.pop(randint(0, litems - 1))
                litems -= 1
                #print litems
                for client in self.controler.clients: 
                    player = self.players[client]
                    if player['ready'] is False:
                        continue
                    if player['count'] > MAX_CLIENT_ITEMS - 1:
                        continue 
                    if self.thumb_index_match_layer(index, client) == True :
                        #print r, litems
                        self.send_to(client, 'GIVE %d' % index)
                        player['count'] += 1
                        self.items_given.append((client, index))
                        allfinished = allfinished and False 
                        break
                    allfinished = allfinished and False
                if litems == 0 : allfinished = True       
  
        self.state = 'game1'
        self.send_all('LAYOUTALL')

 
    def run_game1(self):
        '''First game, place items on the imagemap without ordering
        '''
        if time() > self.timeout:
            self.state = 'reset_for_game2'
            return

    def run_reset_for_game2(self):
        '''Make correction on imagemap !
        '''
        # order !
        index_sent = []
        for thumb in self.scat.children:
            if not isinstance(thumb, MapThumbnail):
                continue
            #print thumb.item
            # are we far ? Check if thumb matches the place
            x,y = thumb.pos
            x += thumb.width/2. 
            filename = self.imagemap.pos2mapitem(x,y)
            if filename is False :
                continue
            if filename == thumb.item['filename'] : #, thumb.item['filename']
                for client in self.controler.clients:
                    thumb.update_color(True)
                    self.send_to(client, 'THVALID %d' % thumb.index)
            else :
                for client in self.controler.clients:
                    thumb.update_color(False)
                    thumb.shake()
                    self.send_to(client, 'THNOTVALID %d' % thumb.index)
            index_sent.append(thumb.index)

        for client, index in self.items_given:
            if index in index_sent:
                continue
            self.send_to(client, 'THNOTVALID %d' % index)
        
        # do game 2
        self.timeout = time() + TIMER_2
        self.send_all('TIME %d %d' % (time(), int(self.timeout)))
        self.send_all('GAME2')
        self.send_all('GAME2')
        self.send_all('GAME2')
        self.state = 'game2'

    def run_game2(self):
        if time() > self.timeout:
            self.state = 'reset_for_game3'
            return

    def run_reset_for_game3(self):
        #move all thumbs to the right location on map
        
        #delete all existing items
        for child in self.scat.children[:]:
            if isinstance(child,MapThumbnail):
                self.scat.remove_widget(child)
        #place all thumbs on the map
        index = 0
        clients = self.controler.clients
        #add all items to the map 
        for item in self.imagemap.data :
            filename = item['filename']
            if self.imagemap.filename_match_layer(filename):
                self.imagemap.display_mapitem(filename, True, (0,0,0,1))    
            item = self.create_and_add_item(clients.keys()[0] ,index)
            item.auto_color = False
            index +=1
        
        #move thumbs to the right position
        self.send_all('PLACETHUMBS')
        self.send_all('GAME2')
        self.state = 'game3'
        self.timeout = time() + TIMER_3
        self.send_all('TIME %d %d' % (time(), int(self.timeout)))
        
    def run_game3(self):
        if time() > self.timeout:
            self.clear()
            self.controler.switch_scenario('choose')
            self.controler.load_all()
コード例 #3
0
ファイル: field.py プロジェクト: triselectif/Rongo-Rongo
class Field(Widget):
    app = ObjectProperty(None)
    style = DictProperty({'geometry_square_margin':0  })
    activate_animations = BooleanProperty( False )
    #internal variables
    squares = DictProperty( {} )#stores all the squares widgets
    geometry = DictProperty( {} )#geometry = squares' target relative positions and sizes on the field
    geometry_detailed = DictProperty( {} ) #real positions on the field
    geometry_squares = DictProperty( {} )
    square_parameters = DictProperty( {} ) #defines the details of the square 
    #stores all the geometry empty squares as widgets so that we can easily
    #compare their positions with the real squares
    apps = DictProperty( {} )#stores all the apps information
    video = ObjectProperty( None )
    video_scatter = ObjectProperty( None )
    video_size_pos = DictProperty( {} )
    #bar_width = NumericProperty(135)
    spacing = NumericProperty(0.0)
    square_padding = NumericProperty(10)
    title = StringProperty('')

    def __init__(self,**kwargs) :
        super(Field, self).__init__(**kwargs)
        
        self.berkelium_is_installed = self.berkelium_is_installed()
        self.init_geometry()
        self.init_app()
        self.init_geometry_detailed()
        self.draw_geometry()
        self.apps = self.init_apps()
        self.init_square_parameters()
        self.init_squares()       

    def get_field_size(self):
        width,height = self.geometry["screen_size"]
        spacing = s= self.spacing#0.012# = 0.02
        #bar = self.bar_width / width
        width_wb = 0.90 #int(width) - bar#width without bar
        """
        #Explanation of the math calculation
        #1)
        large = 3*small + 2*s
        large = 2*medium + s
        small = 2/3*medium - 1/3*s
        #2)
        width_wb = 4*s + large + medium + small
        #inject 1 into 2
        width_wb = 4*s + 2*medium + s + medium + 2/3*medium - 1/3*s
        width_wb = s*(5 -1/3) + medium * (3+ 2/3)
        """
        medium = (width_wb - s*(5 -1/3)) / (3+ 2/3)  
        #get the rest
        large = 2*medium + s 
        small = 0.66666*medium - 0.33333*s
               
        #large = self.geometry['large']
        height = large *width# * float(large[0])
        return width*width_wb, height*width_wb, small*width_wb, medium*width_wb, large*width_wb

    def get_size(self, layout_type) :
        if layout_type == 'icon':
            l,h = self.geometry["icon_px"]
            return (l,h) 
        #Current screen size is applied
        width,height,small,medium,large = self.get_field_size()
        #in px
        small = small * width
        medium = medium * width
        large = large * width  
        
        x = eval(layout_type)
        return (x,x)
        #return (l,h) 

    def square_is_in_the_bar(self,square):
        return False

    def init_app(self):
        #Import the json file that defines it
        file_path = join(dirname(__file__), 'config')
                
        with open(file_path, 'r') as fd:
            config = loads(fd.read())
            #print self.geometry

        if config is None:
            print 'Unable to load', file_path
            return

        self.title = config['title']
        width,height,sm,me,la = self.get_field_size()  
        self.title_label = Label(text = self.title, pos = (width*0.835,-20), font_size = 22, color = (.3,.3,.3,1), halign = 'right' )
        self.add_widget(self.title_label)
        
    def init_geometry(self):
        #Import the json file that defines it
        file_path = join(dirname(__file__), 'field_geometry')
                
        with open(file_path, 'r') as fd:
            self.geometry = loads(fd.read())
            #print self.geometry

        if self.geometry is None:
            print 'Unable to load', file_path
            return

        self.bar_width = int(self.geometry['bar_width'])
        #self.spacing = float(self.geometry['spacing'])
    
    def init_geometry_detailed(self):
        #calculates detailed geometry
        style = self.style
        #margin = style['geometry_square_margin']
        #bar_width = self.bar_width
        
        #Current screen size is applied
        #width,height = self.size
        width,height,sm,me,la = self.get_field_size()
        screen_size = self.geometry['screen_size']   
        bar_width = int(screen_size[0]) - width
        margin_height = (int(screen_size[1]) - height*0.9)*0.5
        print bar_width,height,margin_height
        if margin_height < 0: margin_height = 0
        #print self.geometry['screen_size'][1], height, margin_height
        spacing = self.spacing
        
        #MODE AUTO : calculates every dimensions based on screen size, but for a specific arrow
        #draw small
        array = { 0:["small","small","small"], 1:["medium","medium"], 2:["large"] }
        x_hint = 0
        key = 0
        for i,list in array.iteritems():
            size = self.get_size( list[0] )
            l,h = size   
            x_hint = x_hint + spacing
            index = 0
            y_hint = 0
            for j in list:
                #update geometry_detailed
                self.geometry[str(key)] = [x_hint,y_hint,list[0]]
                x = x_hint *width + bar_width
                y = y_hint *height + margin_height
                self.geometry_detailed[str(key)] = {'pos':(x,y),'size':(l,h),'layout_type':list[0]}
                index += 1
                y_hint = (index) * (float(h)/height+spacing)
                key += 1
            x = x + size[0]
            x_hint = x_hint + float(l)/width
        #print self.geometry #:insert that into field_geometry for specific array
        #and apply code below instead 

        """
        #in case we refer to all the dimensions inside the field_geometry file
        for key,val in self.geometry.iteritems() :
            if not key in ["screen_size","icon_px","vertical","bar_width","spacing"]:
                x,y,square_layout_type = val
                x = x * width + bar_width #+ self.x #+ margin
                y = y * height +margin_height#+ self.y #+ margin
                l,h = self.get_size(square_layout_type)
                #print (l,h)
 
                #update geometry_detailed
                self.geometry_detailed[key] = {'pos':(x,y),'size':(l,h), 'layout_type':square_layout_type }
        
        """

    def draw_geometry(self):
        self.draw_empty_squares()
    
    def draw_empty_squares(self):
        #draw the shape of all empty locations on the field
        for key,val in self.geometry_detailed.iteritems() :
                id = key    
                pos = val['pos']
                size = val['size']
                layout_type = val['layout_type']
                self.geometry_squares[key] = GeometrySquare(
                           geometry_id = int(id), 
                           pos = pos, 
                           size =size, 
                           layout_type = layout_type, 
                           do_scale = False, 
                           do_rotation = False, 
                           do_translation = False, 
                           auto_bring_to_front = False, 
                           )
                self.add_widget( self.geometry_squares[id] )
        #print self.geometry_squares
    
    def init_square_parameters(self):
        #Import the json files that defines each type of square
        for i in ['small','medium','large']:
            file_path = join(dirname(__file__), i)
            #print file_path
                
            with open(file_path, 'r') as fd:
                self.square_parameters[i] = loads(fd.read())
                #print self.square_parameters[i]

            if self.square_parameters[i] is None:
                print 'Unable to load', file_path
                return
        #print self.square_parameters 

    def init_apps(self):
        #Import the json file that defines apps
        file_path = join(dirname(__file__), 'apps','detail')
        apps = {}
        nb = 0
        for subdir, dirs, files in walk(file_path):
            for file in files:
                with open(file_path +'/'+file, 'r') as fd:
                    t = loads(fd.read())
                    if self.validate_web_app(t) :
                        apps[str(nb)] = t
                        print 'Load app: '+str(file)
                        nb +=1
                    else : 
                        print 'Unable to load '+str(file)+', which has html/web content'  
                

        if apps is None:
            print 'Unable to load', file_path
            return
        return apps    

    def init_squares(self):
        #create and display squares
               
        for key,val in self.geometry_detailed.iteritems():
            id = key
            pos = val['pos']
            size = val['size']
            layout_type = val['layout_type']
            square = self.init_square(self.apps, key, pos, size, layout_type)
            if square is not None :
                self.add_square(square)

    def add_square(self, square):
            id = str(square.id)
            self.squares[id] = square
            self.add_widget( self.squares[id] )

            #in case the screen is displayed vertically
            if self.geometry["vertical"] == 'True' :
                self.squares[id].rotation_90d -= 90
                self.rotate(self.squares[id], -90)
            
    def remove_square(self,square, animation, touch):
            if animation :
                #remove some elements
                for i in square.children :
                    square.remove_widget(i)
                kwargs = {'duration' : 1.1,'t':'in_quart'} 
                anim = Animation(pos = touch.pos, size = (0,0), **kwargs )
                anim.bind(on_complete = self.remove_square2 )
                anim.start(square)
                
            else :
                self.remove_square2(1,square)

    def remove_square2(self,a,square):
            #avoid sound running after widget being removed and deleted
            if square.main_media_type == 'video':
                    square.video.mute(1)
            self.remove_widget( square )
            id = str(square.id)
            if id in self.squares.keys():
                del(self.squares[id] )


    def berkelium_is_installed(self):
        try : 
            #from kivy.ext import load
            berkelium = load('berkelium', (1, 1))
            return True
        except :
            return False

    def validate_web_app(self,app):
            #avoid the case of webpage without Berkelium installed
            #first case: main media is web
            main_media_type = app['main_media_type']
            if (self.berkelium_is_installed == False and main_media_type == 'webpage') :
                return False
            #second case: layers are html
            layers =                  {
                                      "large" : str( app['layer_large'] ), 
                                      "medium" : str( app['layer_medium'] ), 
                                      "small": str( app["layer_small"] )
                                      }
            for key,path in layers.iteritems():
                if path[:4] in ['http','file']:
                    if self.berkelium_is_installed == False : 
                        return False
            return True
       

    def init_square(self,apps,key,pos,size, layout_type):
            
            return Square(
                            app =self.app,
                            pos = pos, 
                            size = size, 
                            layout_type = layout_type, 
                            do_scale = False, 
                            geometry_id = int(key),
                            icon_size = self.get_size('icon'),
                            small_size = self.get_size('small'),
                            medium_size = self.get_size('medium'),
                            large_size = self.get_size('large'),

                            id = key,
                            title = apps[key]['title'],
                            app_type = apps[key]['app_type'],
                            color_text = apps[key]['color_text'],
                            color_up = apps[key]['color_up'],
                            color_down = apps[key]['color_down'],
                            authors = apps[key]['authors'],
                            main_media_type = apps[key]['main_media_type'],
                            image_path = apps[key]['image_path'],
                            video_path = apps[key]['video_path'],
                            webpage_path = apps[key]['webpage_path'],
                            layers = {
                                      "large" : str( apps[key]['layer_large'] ), 
                                      "medium" : str( apps[key]['layer_medium'] ), 
                                      "small": str( apps[key]["layer_small"] )
                                      }, 
                            alternative_image_path = apps[key]['alternative_image_path'],
                            main_description = apps[key]['main_description'] ,
                            long_description = apps[key]['long_description'],
                            info_title = apps[key]['info_title'],
                            info_text = apps[key]['info_text'],
                            info_conclusion = apps[key]['info_conclusion'],

                            square_parameters = self.square_parameters,
                            padding = self.square_padding,
                            berkelium_is_installed = self.berkelium_is_installed
                            )
            
   
    def geometry_square2square(self,key):
        ret = None
        g = self.geometry_squares
        for i,val in self.squares.iteritems() :
            #print val.geometry_id
            if g[key].collide_point(*val.center) :
                #if int(key) == val.geometry_id : 
                ret = i
        return ret

    def shake_square(self, touch, key, intensity):
        square  = self.squares[key]
        square.reshape_when_touch_down(touch,intensity)
        square.reshape_when_touch_up(touch)
        self.process_touch_up( square )
                
    def add_app(self, key, touch):
            #function to be used by the bar to add an app to the field
            #print 'add_app_key :'+ key
            if key in self.squares.keys():
                pass
                #self.shake_square(touch,key,6)
            else : 
                #create the square 
                square = self.init_square(self.apps,key,touch.pos, self.get_size('small'), 'small')
                      
                #find matching location
                #focus on translation
                matcher = self.find_matcher(square)#matcher = the key of geometry_squares that fits the best
                
                if matcher is not None :
                    #find the square that sits on matcher
                    matching_square = self.geometry_square2square(matcher)
                    #print "matcher: "+matcher
                    #sq = geometry_id = str(square.geometry_id)
                    self.add_square(square)
                    self.app.bar.images[key].opacify()
                    print 'add square '+key  
                    self.switch(square, matcher)
                    if matching_square in self.squares.keys():
                        self.remove_square( self.squares[str(matching_square)], True, touch )
                        self.app.bar.images[str(matching_square)].unopacify()
                        print 'remove square '+matching_square
                    else :
                        print matching_square +' not in self.squares'
                else : 
                    #destroy square
                    self.remove_square(square, False, touch)
            #print self.squares.keys()  
            #switch
            #remove current app from the field
            #send back the bar icon to its location
            
    def process_touch_up(self, square) :
            if square.process_touch_up_forbidden : return
            
            #focus on translation
            matcher = self.find_matcher(square)
            if matcher is not None :
                self.switch(square, matcher)
            else : 
                self.push_back_into_place(square)

            #focus on rotation
            if len(square._touches)<=1 : return
            #calculate angle between previous pos and now
            a = square.rotation
            b = square.rotation_90d
            if a > (b + 45) : 
                square.rotation_90d +=90
            elif a < (b - 45) : 
                square.rotation_90d -=90
            rot = square.rotation_90d
            
            #fix an issue : flip 180 when smallest angle is negative
            smallest_angle = min( (180 - abs(a - b), abs(a - b)) )
            if a > b : r=1
            else : r=-1
            if smallest_angle <0 : 
                rot = rot + r*180
            #print a,b,rot
            
            self.rotate(square, rot)
        
    def push_back_into_place(self,square) :
        id = str(square.geometry_id)
        if self.activate_animations : 
            animation = Animation(pos = self.geometry_squares[id].pos, duration = 0.9,t='in_out_back')
            animation.start(square)
        else : 
            square.pos = self.geometry_squares[id].pos

    def rotate(self,square, rotation) :
        animation = Animation(rotation = rotation, duration =0.3)
        animation.start(square)
        #square.rotation = rotation  
        
    
    def find_matcher(self,square):
        geometry_id = str(square.geometry_id)
        geometry_squares = self.geometry_squares
        
        def find(x1,y1,target_is_bar) : 
            matching_list = []
            for key,val in geometry_squares.iteritems() :
                if not str(key) == geometry_id :
                    if target_is_bar is False :
                        if val.collide_point(x1,y1) :
                            matching_list.append(key)
                    
            l = len(matching_list)
            #one matches
            if l == 1:
                return matching_list[0]
            #several match, get the closest
            elif l>1 :
                closest_dist = 1000000000000000000000
                closest_widget = 0 
                for key in matching_list :
                    #get distance to target widget center
                    x2,y2 = geometry_squares[key].center        
                    dist = Vector(x1,y1).distance( Vector(x2,y2) )
                    if dist < closest_dist : 
                        closest_dist = dist
                        closest_widget = key
                return closest_widget
            #none matches
            elif l == 0 : 
                return None

        #the center of the current widget is the reference
        x1,y1 = square.center
        m = find(x1,y1, False)

        return m

    def switch(self, square, matcher) :    
        #switch position with another widget
        #self.activate_animations = False

        def get_layout_type(geometry_id) :
            return self.geometry[ str(geometry_id) ][2]

        def switch_layouts():
            square.layout_type = target_layout
            target.layout_type = current_layout
            #if square.layout_type <> target.layout_type :
            square.refresh_layout(target_layout)
            target.refresh_layout(current_layout)
        
        def place_square(square):
            animate_square(square, target_layout, target_param,target_pos, target_size)
            square.refresh_layout(target_layout)
            square.geometry_id = int(matcher)

        def animate_square(square,layout_type,param,pos,size):#move, resize etc
          if self.activate_animations :
            kwargs = {'duration' : 1.1,'t':'in_quart'}
            square.process_touch_up_forbidden = True            
            #switch pos and size 
            animation = Animation(pos = pos, size = size, **kwargs) #+ Animation(size = target_size, duration = 0.5,t='in_quart') 
            animation.bind(on_complete = self.adjust_position) 
            animation.bind(on_complete = self.allow_process_touch_up)
            animation.start(square)
            #title size
            font_size = square.process_font_size( square.title ,int( param['title_label_font_size'] ) )
            #text_size = (len(square.title)*font_size,None )
            #text_size = (len(square.title)*font_size +100,None)
            animation = Animation(font_size = font_size, **kwargs)
            animation.start(square.title_label)
            #animation = Animation(width = len(square.title)*font_size, **kwargs)
            #animation.start(square.box2)
            #authors
            #animation = Animation(font_size = int( param['authors_label_font_size'] ), **kwargs)
            #animation.start(square.authors_label)
            #box top size
            animation = Animation(size_hint = param['box_top_size_hint'], **kwargs)
            animation.start(square.box_top)
            #box middle size
            animation = Animation(size_hint = param['box_middle_size_hint'], **kwargs)
            animation.start(square.box_middle)
            animation = Animation(size_hint = param['box_middle1_size_hint'], **kwargs)
            animation.start(square.box_middle1)
            animation = Animation(size_hint = param['box_middle2_size_hint'], **kwargs)
            animation.start(square.box_middle2)
            #box bottom size
            animation = Animation(size_hint = param['box_bottom_size_hint'], **kwargs)
            animation.start(square.box_bottom)
            #animation.bind(on_complete = self.switch_layouts)
            #launch button size
            animation = Animation(size = param["launch_button_size"], **kwargs)
            animation.start(square.launch_button)
            #vote button size
            animation = Animation(size = param["vote_button_size"], **kwargs)
            animation.start(square.vote_button)
            #vote feedback size
            animation = Animation(size = param["launch_button_size"], **kwargs)
            animation.start(square.fb)
            #spacing
            box_bottom_spacing = (self.get_size(layout_type)[0] -2*square.padding - param['vote_button_size'][0] - param['launch_button_size'][0]) * 0.97
            animation = Animation(spacing = box_bottom_spacing, **kwargs)
            animation.start(square.box_bottom)
          else :
            square.size = size
            square.center = pos                           
            
        #get current properties of the target empty square to switch with
        target = self.geometry_squares[matcher]
        target_layout = get_layout_type(int(matcher))
        target_param = self.square_parameters[target_layout]
        target_pos = target.pos
        target_size = target.size #target_size = self.get_size(target_layout) 
        
        #if current place cannot be found
        if str(square.geometry_id) not in self.geometry.keys():
            place_square(square)
            return

        #get current square properties
        #current_layout = square.layout_type #this way was buggy
        current_layout = square.layout_type#get_layout_type(square.geometry_id)
        current_param = self.square_parameters[current_layout]
        current_pos = self.geometry_squares[str(square.geometry_id)].pos
        current_size = square.size #current_size = self.get_size(current_layout)#target.size

        #get the target square
        target = 0
        for key,val in self.squares.iteritems() :
            if val.geometry_id == int(matcher) : 
                target = self.squares[key]
                break
        """
        #adjust square pos in order to avoid jumping while changing layout
        if not target_size == current_size :    
            if target_size > current_size : 
                d = 1#and not target_size == current_size :
            elif target_size < current_size :
                d = -1
            #get differencial vector between current square pos and future layout square pos
            #case of an empty destination 
            if target == 0 and not target_layout == 'icon':
                if target_size > current_size :
                    delta_square = Vector( (-d*target_size[0]*0.4, -d*target_size[1]*0.4) )
                elif target_size < current_size :
                    delta_square = Vector( (-d*target_size[0]*0.9, -d*target_size[1]*0.9) )
            #case of an empty destination in the margin
            elif target_layout == 'icon':
                delta_square = Vector( (-d*current_size[0]*0.7, -d*current_size[1]*0.7) )
            else : 
                delta_square = ( d*Vector( target.pos ) - d*Vector( target.center ) )
            rot = round(square.rotation,0)
            #print rot, delta_square
            a = (1,1)
            if rot == 90 : a = (-1,1)
            elif rot == 180 : a = (-1,-1)
            elif rot == 270 : a= (1,-1)
            b,c = a
            square.x += b * delta_square.x/2
            square.y += c * delta_square.y/2           
        """
        
        
        #fake a different pos to match user behaviour (i.e. placing the square in the center of the target)
        #square.center = square.pos #(changes with rotation .. )        
        
        #if empty location
        if target == 0 :
            place_square()
            return
        
        #square
        animate_square(square, target_layout, target_param, target_pos, target_size) 
 
        #switch layouts
        switch_layouts() 
        """
        #adjust square pos in order to avoid jumping while changing layout
        if not target_size == current_size and not current_layout == 'icon':
            #case of an empty destination 
            #if target == 0:
            if target_size > current_size :
                d = 1
            elif target_size < current_size :
                d = -1 
            delta_target = d*Vector( target_pos ) - d*Vector( target.pos )
            rot = round(target.rotation,0)
            a = (1,1)
            if rot == 90 : 
                if target_size > current_size : a = (1,1)
                elif target_size < current_size : a = (-2,1)
            elif rot == 180 : a = (-1,-1)
            elif rot == 270 : a= (1,-1)
            b,c = a
            target.x += b * delta_target.x/2
            target.y += c * delta_target.y/2 
        """
        #target
        animate_square(target, current_layout, current_param, current_pos, current_size)
        
        #store pos
        target.geometry_id = square.geometry_id
        square.geometry_id = int(matcher)    
    
    def allow_process_touch_up(self,a,square):
        square.process_touch_up_forbidden = False
   
    def switch_layouts(self, animation,square):
        def get_layout_type(geometry_id) :
            return self.geometry[ str(geometry_id) ][2]

        #get target layout
        target_layout = get_layout_type(square.geometry_id)
        square.layout_type = target_layout
        square.refresh_layout(target_layout)

    def adjust_position(self,a,square):
        gs= self.geometry_squares
        key = str(square.geometry_id)
        if not key in gs.keys():return
        match = gs[key]
        #pos size
        anim = Animation(pos = match.pos, size = match.size, duration = 0.2)
        anim.start(square)
        #layout
        #square.layout.pos = (square.padding, square.padding)
        #box bottom
        param = self.square_parameters[square.layout_type]
        box_bottom_spacing = (self.get_size(square.layout_type)[0] -2*square.padding - param['vote_button_size'][0] - param['launch_button_size'][0]) * 0.97
        anim = Animation(pos = square.layout.pos, spacing = box_bottom_spacing, duration = 0.2)
        anim.start(square.box_bottom) 

    def mute(self,uid):
        #mute all the square, unmute the given one
        for i in self.squares.itervalues():
            if not i.uid == uid :
                i.mute()
    
    def play_video_fullscreen(self, video_path, pos, size, position):
        
        self.video = VideoPlayer2(source = video_path, options = {'position':position} )
        self.video.bind(on_leave_fullscreen = self.on_leave_fullscreen)
        self.video.size = size
        #self.video.pos = pos
        self.video_scatter = Scatter(size = size, pos = pos)
        self.video_scatter.add_widget(self.video)
        self.add_widget(self.video_scatter)
        #store size and pos for later
        self.video_size_pos = {'size':size, 'pos':pos}
        Clock.schedule_once(self.video.start, 2.5)
        w,h = self.geometry['screen_size'] #(self.width - self.bar_width,self.height)#w,h,s,m,l = self.get_field_size()##
        
        
        if self.geometry['vertical'] == "True":
            #from kivy.graphics import Rotate
            """
            rot = Rotate()
            rot.angle =  90
            rot.axis =(0,0,1)
            """
            #self.video.video.canvas.add(Rotate( 45,0,0,1 ))
            '''
            with self.video.video.canvas :
                Rotate( 45,0,0,1 )
            self.video.video.canvas.ask_update()
            #self.video.canvas.draw()
            '''
            self.video_scatter.pos = self.pos #= (self.bar_width,0)
            self.video_scatter.rotation = -90
            width = w
            w = h
            h = width
            #self.video_scatter.pos = self.center
            self.video_scatter.pos = (self.bar_width,w/2+self.bar_width/2)#center = (h/2,w/2-self.bar_width/2)#(self.center[0] +2*self.bar_width -25, w/2 +self.bar_width+25)#
            self.video_scatter.size = (w,h)
            self.video.size = (w,h)
        else : 
            w = w - self.bar_width
            anim = Animation(size = (w,h),pos = (self.x +self.bar_width, self.y) )
            anim.start(self.video_scatter)
            anim = Animation(size = (w,h) )
            anim.start(self.video) 

    def on_leave_fullscreen(self,a):
        if self.geometry['vertical'] == "True":
            self.video_scatter.rotation = 90
        size = self.video_size_pos['size']
        pos = self.video_size_pos['pos']
        anim = Animation(size = size, pos = pos)
        anim.bind(on_complete = self.after_leaving_fullscreen)
        anim.start(self.video_scatter)
        anim = Animation(size = size)
        anim.start(self.video)

    def after_leaving_fullscreen(self,a,b):
        self.video.video.volume = 0
        self.video_scatter.remove_widget(self.video )
        self.remove_widget(self.video_scatter )
コード例 #4
0
class KivyVisor(ModalView):
    MODO_NORMAL = 1
    MODO_AJUSTADO_ALTURA = 2
    MODO_AJUSTADO_ANCHO = 3

    def __init__(self, comicBook, **kwargs):
        super(KivyVisor, self).__init__(**kwargs)
        self.modoVisualizacion = KivyVisor.MODO_NORMAL
        self.scatter = Scatter()
        self.scatter.center = Window.center
        print("scatter center: {}".format(self.scatter.center))
        self.bind(on_touch_down=self.on_touch)
        self.comic = comicBook
        self.comic.openCbFile()
        self.imagenPagina = self.comic.getImagePage()
        self.imagenPagina.size = self.imagenPagina.texture_size
        self.imagenPagina.size_hint = (None, None)
        self.scatter.size_hint = (None, None)
        self.scatter.size = self.imagenPagina.texture_size
        self.scatter.center = Window.center
        print("image size: {}".format(self.imagenPagina.size))
        print("scatter center: {}".format(self.scatter.center))
        print("window center: {}".format(Window.center))
        self.scatter.pos_hint = (None, None)
        self.scatter.add_widget(self.imagenPagina)
        self.scatter.do_rotation = False

        self.scatter.center = (0, 0)
        self.imagenPagina.center = (0, 0)
        '''recordar que la imagen se mueve desde el centro. y la posicion es relativa al centro del contenedor en este caso es el scatter'''
        self.imagenPagina.pos = (0, Window.center[1] -
                                 self.imagenPagina.size[1] / 2)

        self.add_widget(self.scatter)
        # self.scatter.x = 1111
        print("scatter center: {}".format(self.scatter.center))
        print("scatter Heiht: {}".format(self.scatter.height))
        Window.bind(on_motion=self.on_motion)
        Window.bind(on_resize=self.on_sizeWindow)

    def on_sizeWindow(self, arg1, arg2, arg3):
        self.__refreshPage__()

    def on_motion(self, etype, motionevent, other):
        if other.is_mouse_scrolling:
            if other.button == 'scrolldown':
                self.scatter.y -= 10
            if other.button == 'scrollup':
                self.scatter.y += 10

        else:
            # print(self.scatter.pos)
            print("pos imagen :{}".format(self.imagenPagina.pos))
            print("tamaño scatter :{}".format(self.scatter.size))
        # help(other)
        # print(motionevent)
        # print(other)
        # print("Capturan scroll")

    def on_touch(self, obj, event):
        '''
        vamos a capturar eventos en estas zonas
        *************************
        *1*       *0*         *2*
        ***       ***         ***
        *                       *
        *                       *
        * *                   * *
        *3*                   *4*
        * *                   * *
        *                       *
        *                       *
        *                       *
        ***                   ***
        *5*                   *6*
        *************************
        :param widget:
        :param event:
        :return:
        '''
        #zona1 = ((0, Window.width * 0.1), (Window.height, (Window.height - Window.height * 0.1)))
        #zona2 = ((Window.width - Window.width * 0.1, Window.width), (Window.height, (Window.height - Window.height * 0.1)))
        zona0 = ((Window.width * 0.5 - Window.width * 0.1,
                  Window.width * 0.5 + Window.width * 0.1),
                 (Window.height - Window.height * 0.1, Window.height))
        zona3 = ((0, Window.width * 0.1),
                 (Window.height * 0.1 + Window.height * 0.5,
                  Window.height * -0.1 + Window.height * 0.5))
        zona4 = ((Window.width - Window.width * 0.1, Window.width),
                 (Window.height * 0.1 + Window.height * 0.5,
                  Window.height * -0.1 + Window.height * 0.5))

        if (zona3[0][0] < event.pos[0] and event.pos[0] < zona3[0][1]) and (
                event.pos[1] < zona3[1][0] and event.pos[1] > zona3[1][1]):
            self.scatter.remove_widget(self.imagenPagina)
            self.comic.gotoPrevPage()
            self.__refreshPage__()

        if (zona4[0][0] < event.pos[0] and event.pos[0] < zona4[0][1]) and (
                event.pos[1] < zona4[1][0] and event.pos[1] > zona4[1][1]):
            self.scatter.remove_widget(self.imagenPagina)
            self.comic.gotoNextPage()
            self.__refreshPage__()
        if (zona0[0][0] < event.pos[0] and event.pos[0] < zona0[0][1]) and (
                zona0[1][0] < event.pos[1] and event.pos[1] < zona0[1][1]):
            box = GridLayout(cols=5)
            botonAncho = Button(text="Ancho")
            botonAncho.bind(on_press=self.ancho)
            box.add_widget(botonAncho)

            botonAjustarAlto = Button(text="Alto")
            botonAjustarAlto.bind(on_press=self.ajustarAlto)
            box.add_widget(botonAjustarAlto)

            botonCentrado = Button(text="normal")
            botonCentrado.bind(on_press=self.sinAjuste)
            box.add_widget(botonCentrado)

            botonRotar = Button(text="Rotar")
            botonRotar.bind(on_press=self.rotar)
            box.add_widget(botonRotar)

            p = Popup(title='Comic View popup',
                      size_hint=(None, None),
                      size=(400, 150))
            p.add_widget(box)

            p.open()

    def ancho(self, event):
        print(Window.width)
        self.modoVisualizacion = KivyVisor.MODO_AJUSTADO_ANCHO
        self.scatter.scale = Window.width / self.imagenPagina.width
        self.__refreshPage__()
        #
        # self.scatter.pos = (0, 0)

    def __refreshPage__(self):
        self.scatter.remove_widget(self.imagenPagina)
        self.imagenPagina = self.comic.getImagePage()
        self.scatter.center = self.imagenPagina.center = Window.center
        self.imagenPagina.size = self.imagenPagina.texture_size
        self.scatter.add_widget(self.imagenPagina)

        if self.modoVisualizacion == KivyVisor.MODO_NORMAL:
            self.imagenPagina.pos = (0, Window.center[1] -
                                     self.imagenPagina.size[1] / 2)
        elif self.modoVisualizacion == KivyVisor.MODO_AJUSTADO_ALTURA:
            self.imagenPagina.pos = (0, 0)
        elif self.modoVisualizacion == KivyVisor.MODO_AJUSTADO_ANCHO:

            self.imagenPagina.pos = (0, (self.scatter.scale, (
                Window.center[1] -
                (self.imagenPagina.size[1] / 2) * self.scatter.scale)))
            print("Centro window {} size_y {} factor {} new_pos_Y {}".format(
                Window.center[1], self.imagenPagina.size[1],
                self.scatter.scale,
                (Window.center[1] -
                 (self.imagenPagina.size[1] / 2) * self.scatter.scale)))

    def ajustarAlto(self, event):
        print("alto: {}".format(Window.height))
        self.modoVisualizacion = KivyVisor.MODO_AJUSTADO_ALTURA
        self.scatter.scale = Window.height / self.imagenPagina.height
        self.__refreshPage__()
        #
        # self.scatter.pos = (0, 0)

    def rotar(self, event):
        print("rotar")

    def sinAjuste(self, event):
        self.scatter.scale = 1
        self.scatter.pos = (0, 0)
        print("centrado")
        self.scatter.center = Window.center
コード例 #5
0
ファイル: main.py プロジェクト: IanCal/Baess
class MyApp(App):

    def build(self):
        Window.bind(on_key_down=self.on_key_down) 
        self.loadData()
        self.activeTrack = None
        self.currentLayer = 0
        self.appstructure = FloatLayout()
        width, height = Window.size
        self.menu = Menu()
        self.menu.onNewTrack(self.newTrack)
        self.menu.onNewPoint(self.newPoint)
        self.menu.onDeletePoint(self.deletePoint)
        self.menu.onSetClass(self.setClass)
        self.menu.onFindUnclassified(self.jumpToUnclassified)
        self.menu.onShowStats(self.showStats)
        self.menu.onSave(self.save)
        self.core = Scatter(auto_bring_to_front=False)
        self.core.add_widget(self.getCurrentLayer().getContents())
        self.appstructure.add_widget(self.core)
        self.appstructure.add_widget(self.menu.getContents())
        self.zoomSlider = Slider(orientation='vertical', min=1, max=10, size_hint=(0.05,1),pos_hint={'x':0.95})
        self.zoomSlider.bind(on_touch_move=self.on_touch_move)
        self.zoomSlider.bind(on_touch_down=self.on_touch_down)
        self.zoomSlider.bind(on_touch_up=self.on_touch_up)
        self.appstructure.add_widget(self.zoomSlider)
        self.imagelabel = Label(text=self.getCurrentLayer().getSource(), size_hint=(1,0.05), pos_hint={'y':0})
        self.appstructure.add_widget(self.imagelabel)
        self.zooming = False
        return self.appstructure


    def loadImages(self):
        def isImage(fname):
            for ext in [".png", ".jpg", ".tiff", ".jpeg", ".bmp"]:
                if fname.lower().endswith(ext):
                    return True
            return False
                    
        self.layers = []
        for img in sortByFirstNumber(listdir("images")):
            if isImage(img):
                self.layers.append(Layer("images/"+img))

    def loadData(self):
        self.loadImages()
        self.tracks = []
        try:
            trackreps = load(open("saveFile.data"))
        except:
            return
        for trackrep in trackreps:
            track = Track(self.setActive)
            for pointrep in trackrep['points']:
                point = Point(pointrep[1])
                track.addPoint(point, pointrep[0])
                self.layers[pointrep[0]].addPoint(point)
                point.setPos(pointrep[1])
            track.setClassification(trackrep['classification'])
            track.setInactive()
            self.tracks.append(track)
    
    def save(self):
        self.saveTo("backup-"+datetime.today().strftime("%Y-%m-%d-%H-%M-%S")+".data")
        self.saveTo("saveFile.data")

    def saveTo(self, fileName):
        #save to file ...
        def trackRepresentation(track):
            trackrep = {'classification':track.getClassification()}
            trackrep['points'] = []
            for layer in range(len(self.layers)):
                point = track.getPointForLayer(layer) 
                if point:
                    trackrep['points'].append((layer, point.getPos()))
            return trackrep

        savetracks = []
        for track in self.tracks:
            savetracks.append(trackRepresentation(track))
        print savetracks
        dump(savetracks, open(fileName, 'w+'))

    def on_touch_down(self, slider, ev):
        if (slider.collide_point(ev.pos[0], ev.pos[1])):
            self.zooming = True

    def on_touch_move(self, slider, ev):
        if (self.zooming):
            zoom = self.zoomSlider.value
            self.core.scale = zoom

    def on_touch_up(self, slider, ev):
        self.zooming = False

    def showStats(self, *args):
        classCounts = {}
        for classification in classesToColours:
            classCounts[classification] = 0
        for track in self.tracks:
            if track.getClassification():
                classCounts[track.getClassification()] += 1

        text = ""
        for classification in classCounts:
            text +=  "    %s : %s \n"%(classification,classCounts[classification])
        popup = Popup(title='Statistics',
            content=Label(text=text),
            size_hint=(None, None), size=(400, 400))
        popup.open()

    def setClass(self, classification):
        if (self.activeTrack):
            self.activeTrack.setClassification(classification)

    def setActive(self, track):
        if (self.activeTrack):
            self.activeTrack.setInactive()
        self.activeTrack = track
        track.setActive()
    def newPoint(self):
        if (self.activeTrack == None):
            return
        point = Point((width/2,height/2))
        if (self.activeTrack.addPoint(point, self.currentLayer)):
            self.getCurrentLayer().addPoint(point)
    def deletePoint(self):
        if (self.activeTrack == None):
            return
        point = self.activeTrack.getPointForLayer(self.currentLayer)
        if (point == None):
            return
        if not(self.activeTrack.deletePoint(self.currentLayer)):
            return 
        self.getCurrentLayer().deletePoint(point)
        if (self.activeTrack.getClassification() == None):
            self.tracks.remove(self.activeTrack)
            self.activeTrack = None
        

    def newTrack(self):
        track = Track(self.setActive)
        point = Point((width/2, height/2))
        track.addPoint(point, self.currentLayer)
        track.setActive()
        track.setClassification('unclassified')
        self.tracks.append(track)
        self.setActive(track)
        self.getCurrentLayer().addPoint(point)
    def getCurrentLayer(self):
        return self.layers[self.currentLayer]

    def jumpToUnclassified(self):
        for track in self.tracks:
            if track.getClassification() == 'unclassified':
                for i, layer in enumerate(self.layers):
                    if track.getPointForLayer(i):
                        self.setActive(track)
                        self.swapLayer(self.getCurrentLayer(), layer)
                        self.currentLayer = i
                        return
        popup = Popup(title='',
            content=Label(text="No unclassified tracks found!"),
            size_hint=(None, None), size=(400, 400))
        popup.open()
                        
            

    def moveUpLayer(self):
        if (self.currentLayer < (len(self.layers) - 1)):
            original = self.getCurrentLayer()
            self.currentLayer += 1
            new = self.getCurrentLayer()
            self.swapLayer(original, new)
    def moveDownLayer(self):
        if (self.currentLayer > 0):
            original = self.getCurrentLayer()
            self.currentLayer -= 1
            new = self.getCurrentLayer()
            self.swapLayer(original, new)

    def swapLayer(self, old, new):
        if (old == new):
            return
        self.imagelabel.text = new.getSource()
        self.core.add_widget(new.getContents())
        self.core.remove_widget(old.getContents())
        # current transform is layer * user
        layer = new.getTransform()
        transform = self.core.transform
        user = transform.multiply(layer.inverse())
        # put back to start
        self.core.apply_transform(self.core.transform_inv)
        # apply layer transformation
        self.core.apply_transform(old.getTransform())
        # reapply user transformation
        self.core.apply_transform(user)
    def on_key_down(self, instance, code, *args):
        if (code == 275):
            self.moveUpLayer()
        if (code == 276):
            self.moveDownLayer()
コード例 #6
0
class CompasTest(App):
    def Hardware(self, *args):
        try:
            self.Encender()
            self.tetha = 0
            print "Encendiendo compas"
            if True:
                print "Empezando lectura"
                Hilo1 = Clock.schedule_interval(self.Lectura, 1 / 20.)
                Hilo2 = Clock.schedule_interval(self.Empareja_todo, 1 / 20.)
                self.Disparar()
                return True

        except NotImplementedError:
            import traceback
            traceback.print_exc()
            status = "No reconoce el sensor magnetico en su dispositivo"
            print "No reconoce el compas"
            return False

    def Encender(self, *args):
        print "Se esta encendiendo"
        compass.enable()

    def Apagar(self, *args):
        print "Se esta apagando"
        compass.disable()

    def Lectura(self, *args):
        x, y, z = compass.orientation
        try:
            xf = round(x, 3)
            yf = round(y, 3)
            zf = round(z, 3)
            self.Bx = xf
            self.By = yf
            self.Bz = zf
            lbl1.text = "Sensor de Campo Magnetico \nBx = " + str(
                xf) + "\n" + "By = " + str(yf) + "\n" + "Bz = " + str(zf)

        except:
            print "No hay ningun dato todavia espere"

    def Empareja_todo(self, *args):
        try:
            self.Clasifica_tetha()
            self.Dispercion1()
            self.Disparar()
        except:
            print "Fallo al emparejar todo"

    def Dispersion1(self):
        self.dis1 = Scatter()
        self.dis1.pos = 100, 300
        #self.dis1.pos =  random.randrange(100,680), 100
        self.dis1.size_hint = None, None
        #self.dis1.size = 100, 100
        self.dis1.do_rotation = False
        self.dis1.do_scale = False
        self.dis1.do_translation = False
        self.dis1.scale = 1.8
        lbl2.text = "HACK-VISION DEMO \n Angulo tetha: " + str(self.tetha)
        self.dis1.rotation = self.tetha + 90

    def Clasifica_tetha(self):
        #Sentido MAnecillas del reloj
        #Primer cuadrante
        try:
            self.tetha != None
            if ((self.Bz > -25) & (self.Bz <= 0) & (self.Bx <= 0) &
                (self.By <= 0)):
                tetha = (self.Bz * 90) / 25 + 90
                self.tetha = round(tetha, 3)
                return self.tetha

                #segundo cuadrante
            if ((self.Bz > 0) & (self.Bz <= 25) & (self.Bx <= 0) &
                (self.By <= 0)):
                tetha = self.Bz * 90 / 25 + 90
                self.tetha = round(tetha, 3)
                return self.tetha

                #tercer cuadrante
            if ((self.Bz > 0) & (self.Bz <= 25) & (self.Bx >= 0) &
                (self.By <= 0)):
                tetha = (-1) * (self.Bz * 90 / 25 - 270)
                self.tetha = round(tetha, 3)
                return self.tetha

                #Quinto cuadrante
            if ((self.Bz > -25) & (self.Bz <= 0) & (self.Bx >= 0) &
                (self.By <= 0)):
                tetha = (-1) * (self.Bz * 90 / 25 - 270)
                self.tetha = round(tetha, 3)
                return self.tetha

        except:
            print "Nada"

    def Dispersion2(self):
        self.dis2 = Scatter()
        self.dis2.pos = -90, -50
        #self.dis2.pos =  random.randrange(100,680), 100
        self.dis2.size_hint = None, None
        #      self.dis2.size = 86, 86
        self.dis2.do_rotation = False
        self.dis2.do_scale = False
        self.dis2.do_translation = False
        self.dis2.rotation = 0
        self.dis2.scale = 1.7

    def Animacion1(self, *args):
        global Anim
        lol = Widget()
        Anim = Image()
        Anim.source = "img/fondo_brujula.png"
        # Anim.size = 700,700
        #Anim.source = "img/caballo.zip"
        #Anim.anim_delay=(0.15)
        # Anim.pos_hint= {"x": -0.1, "center_y": -1}
        # Anim.pos = 10, 10
        #Anim.pos = random.randrange(100,680), random.randrange(100,460)
        self.dis1.add_widget(Anim)
        lol.add_widget(self.dis1)
        self.widget1.add_widget(lol)

    def Camara(self, *args):
        #        self.Dispersion2()

        camwidget = Widget()  #Create a camera Widget
        cam = Camera()  #Get the camera
        cam.resolution = (640, 480)
        cam.size = 1000, 800
        cam.pos = (-100, -100)

        cam.play = True  #Start the camera

        camwidget.add_widget(cam)
        # self.widget1.add_widget(camwidget)
        self.dis2.add_widget(camwidget)
        self.widget1.add_widget(self.dis2)

    def Label1(self):
        global lbl1
        lbl1 = Label()
        #   lbl1.text =  "Esperando instrucciones:"
        lbl1.pos = 200, 100
        self.widget1.add_widget(lbl1)

    def Label2(self):
        global lbl2
        lbl2 = Label()
        #   lbl2.text =  "Esperando instrucciones:"
        lbl2.pos = 200, 10
        self.widget1.add_widget(lbl2)

    def Disparar(self):
        self.x = 0
        Hilo2 = Clock.schedule_interval(self.disparo1, 0.9)

    #   self.disparo1()

    def disparo1(self, *args):
        if self.opcion == 1:
            self.dis1.remove_widget(Anim)
            self.widget1.remove_widget(self.dis1)
            self.opcion = 0

        if self.opcion == 0:
            self.Dispersion1()
            self.Animacion1()
            self.x = self.x + 10
            self.opcion = 1

    def build(self):
        self.opcion = 0
        self.widget1 = Widget()
        self.Dispersion2()
        self.Camara()
        self.Label1()
        self.Label2()
        self.Hardware()

        return self.widget1
コード例 #7
0
class AnalogeGauge(Widget):
    '''
    Gauge class

    '''
    unit = NumericProperty(1.8)
    size_text = NumericProperty(10)
    value = BoundedNumericProperty(0, min_value=0, max_value=100, errorvalue=0)
    start_angle = BoundedNumericProperty(90,
                                         min_value=-360,
                                         max_value=360,
                                         errorvalue=0)
    angle_width = BoundedNumericProperty(180,
                                         min_value=0,
                                         max_value=360,
                                         errorvalue=0)
    min_value = NumericProperty(0)
    max_value = NumericProperty(100)
    rotate_clock = BooleanProperty(True)
    file_background = StringProperty("cadran.png")
    file_gauge = StringProperty("")
    file_needle = StringProperty("")

    half_widget_view = BooleanProperty(False)

    padding = BoundedNumericProperty(10,
                                     min_value=0,
                                     max_value=360,
                                     errorvalue=0)

    mark_count = BoundedNumericProperty(10,
                                        min_value=0,
                                        max_value=360,
                                        errorvalue=0)
    mark_sub_count = BoundedNumericProperty(10,
                                            min_value=0,
                                            max_value=100,
                                            errorvalue=0)
    show_middle_marks = BooleanProperty(True)
    show_sub_marks = BooleanProperty(True)
    mark_size = BoundedNumericProperty(20,
                                       min_value=0,
                                       max_value=300,
                                       errorvalue=0)
    mark_mid_size = BoundedNumericProperty(15,
                                           min_value=0,
                                           max_value=300,
                                           errorvalue=0)
    mark_sub_size = BoundedNumericProperty(10,
                                           min_value=0,
                                           max_value=300,
                                           errorvalue=0)

    mark_color = ColorProperty('#ffffffff')
    mark_sub_color = ColorProperty('#ffffffff')
    mark_mid_color = ColorProperty('#ffffffff')

    needle_color = ColorProperty('#ff0000ff')
    glab_color = ColorProperty('#ff0000ff')

    def __init__(self, **kwargs):
        super(AnalogeGauge, self).__init__(**kwargs)
        self._gauge_widget = Widget()
        self._gauge = self._gauge_widget

        self._needle_widget_safe = Widget()
        self._needle_widget = self._needle_widget_safe

        self._form_processor_constants()

        self._needle = Scatter(size=self.size,
                               do_rotation=False,
                               do_scale=False)

        self._background_widget = Widget()
        self._background = Scatter(size=self.size,
                                   do_rotation=False,
                                   do_scale=False)

        self._glab = Label(font_size=self.size_text,
                           markup=True,
                           font_name='digital')

        self._needle.add_widget(self._needle_widget)

        self.add_widget(self._background)
        self.add_widget(self._gauge)
        self.add_widget(self._glab)
        self.add_widget(self._needle)

        self.bind(pos=self._update)
        self.bind(size=self._update)
        self.bind(value=self._turn)

        self.bind(file_gauge=self._reform_widget_graphics)
        self.bind(file_needle=self._reform_widget_graphics)
        self.bind(file_background=self._reform_widget_graphics)

        self.bind(min_value=self._form_processor_constants)
        self.bind(rotate_clock=self._form_processor_constants)
        self.bind(max_value=self._form_processor_constants)
        self.bind(start_angle=self._form_processor_constants)
        self.bind(angle_width=self._form_processor_constants)

        self.bind(mark_color=self._create_gaudge)
        self.bind(mark_sub_color=self._create_gaudge)
        self.bind(mark_mid_color=self._create_gaudge)
        self.bind(show_middle_marks=self._create_gaudge)
        self.bind(show_middle_marks=self._create_gaudge)
        self.bind(mark_count=self._create_gaudge)
        self.bind(mark_sub_count=self._create_gaudge)

        self.bind(needle_color=self._create_needle)

        self.bind(padding=self._update)

        self._update()
        self._reform_widget_graphics()
        self._turn()

    def _form_processor_constants(self, *args):
        self.property('value').set_min(self, self.min_value)
        self.property('value').set_max(self, self.max_value)
        self.unit = self.angle_width / abs(self.max_value - self.min_value) * (
            -1 if self.rotate_clock else 1)
        #print(self.unit, self.angle_width)

    def _reform_widget_graphics(self, *args):
        #print(self.size)

        if self.file_gauge:
            self.remove_widget(self._gauge)
            self._gauge = get_module_resource_path(self.file_gauge,
                                                   size=self.size,
                                                   resource_package=__name__)
            self.add_widget(self._gauge)
        else:
            self.remove_widget(self._gauge)
            self._gauge = self._gauge_widget
            self.add_widget(self._gauge)

        if self.file_background:
            self._background.remove_widget(self._background_widget)
            self._background_widget = get_module_resource_path(
                self.file_background,
                size=self.size,
                resource_package=__name__)
            self._background.add_widget(self._background_widget)

        if self.file_needle:
            self._needle.remove_widget(self._needle_widget)
            self._needle_widget = get_module_resource_path(
                self.file_needle, size=self.size, resource_package=__name__)
            self._needle.add_widget(self._needle_widget)
        else:
            self._needle.remove_widget(self._needle_widget)
            self._needle_widget = self._needle_widget_safe
            self._needle.add_widget(self._needle_widget)

    def _turn(self, *args):
        '''
        Turn needle, 1 degree = 1 unit, 0 degree point start on 50 value.

        '''
        self._needle.center_x = self._gauge.center_x
        self._needle.center_y = self._gauge.center_y
        self._needle.rotation = self.start_angle + (self.value -
                                                    self.min_value) * self.unit
        #print(self.start_angle, self.unit,self.value,self.min_value,self._needle.rotation)
        self._glab.text = "[b]{0:.0f}[/b]".format(self.value)

    def _create_needle(self, *args):
        if self._needle_widget == self._needle_widget_safe:
            self._needle_widget_safe.canvas.clear()
            with self._needle_widget_safe.canvas:
                Color(*self.needle_color)
                Line(points=(*self._needle_widget_safe.center,
                             self._needle_widget_safe.center_x,
                             self._needle_widget_safe.center_y +
                             self.circle_radius))
                Line(points=(*self._needle_widget_safe.center,
                             self._needle_widget_safe.center_x,
                             self._needle_widget_safe.center_y +
                             self.circle_radius - 20),
                     width=1.5)
                Ellipse(pos=(self._needle_widget_safe.center_x - 5,
                             self._needle_widget_safe.center_y - 5),
                        size=(10, 10))

    def _create_gaudge(self, *args):
        if self._gauge == self._gauge_widget:

            self._gauge_widget.canvas.clear()
            if self.mark_count > 0:
                delta_mark = self.angle_width / self.mark_count
                mark_width = 10
                mark_end = min(self.width, self.height) / 2
                with self._gauge_widget.canvas:

                    if self.show_sub_marks:
                        Color(*self.mark_sub_color)
                        sub_delta_mark = delta_mark / self.mark_sub_count
                        count = self.mark_count * self.mark_sub_count + 1
                        sub_start_size = self.circle_radius - self.mark_sub_size
                        for i in range(count):
                            Line(points=get_mark_vector(
                                *self.circle_pos, sub_start_size,
                                self.mark_sub_size, self.start_angle -
                                sub_delta_mark * i))

                    if self.show_middle_marks:
                        Color(*self.mark_mid_color)
                        sub_delta_mark = delta_mark / 2
                        count = self.mark_count * 2 + 1
                        sub_start_size = self.circle_radius - self.mark_mid_size
                        for i in range(count):
                            Line(points=get_mark_vector(
                                *self.circle_pos, sub_start_size,
                                self.mark_mid_size, self.start_angle -
                                sub_delta_mark * i))

                    Color(*self.mark_color)
                    start_size = self.circle_radius - self.mark_size
                    for i in range(self.mark_count + 1):
                        Line(points=get_mark_vector(
                            *self.circle_pos, start_size, self.mark_size,
                            self.start_angle - delta_mark * i))

    def _update(self, *args):
        '''
        Update gauge and needle positions after sizing or positioning.

        '''
        if self.half_widget_view:
            self.circle_radius = min(*self.size) - self.padding * 2
            self.circle_size = (self.circle_radius, self.circle_radius)
            self.circle_pos = (self.center_x,
                               self.center_y - self.circle_radius / 2)
            self._bg_pos = (self.x, self.y - self.circle_radius / 2)
        else:
            self.circle_radius = min(*self.size) / 2 - self.padding
            self.circle_size = (self.circle_radius, self.circle_radius)
            self.circle_pos = self.center
            self._bg_pos = (self.x, self.y)

        self._needle.size = self.size
        self._gauge.size = self.size
        self._gauge.pos = self.pos
        self._gauge.center = self.circle_pos

        self._needle.pos = (self.x, self.y)
        self._needle.center = self.circle_pos

        self._background.pos = self._bg_pos

        self._needle_widget.size = self.size
        self._background_widget.size = self.size

        self._glab.center_x = self._gauge.center_x
        self._glab.center_y = self.center_y + (self.height / 4)

        self._create_gaudge()
        self._create_needle()

    def set_animate(self, value, easing='in_out_quad', speed=1):
        from kivy.animation import Animation
        Animation(value=value, duration=speed, t=easing).start(self)