def __init__(self, instruction: str, back_button_name: str,
                 forward_button_name: str, button_method):
        super().__init__()
        central_widget = QtWidgets.QWidget(self)
        self.setCentralWidget(central_widget)
        self.grid_layout = QtWidgets.QGridLayout(central_widget)
        central_widget.setStyleSheet(Style.get_window_style())

        self.label = QtWidgets.QLabel()
        self.label.setText(instruction)
        self.grid_layout.addWidget(self.label, 0, 0, 1, 2,
                                   QtCore.Qt.AlignCenter)
        self.label.setStyleSheet(Style.get_text_style())

        self.back_button = Button("Back", self)
        self.grid_layout.addWidget(self.back_button,
                                   1,
                                   0,
                                   1,
                                   1,
                                   alignment=QtCore.Qt.AlignCenter)
        self.back_button.setStyleSheet(Style.get_button_style())
        self.back_button.clicked.connect(button_method(back_button_name))

        self.forward_button = Button("Ok", self)
        self.grid_layout.addWidget(self.forward_button,
                                   1,
                                   1,
                                   1,
                                   1,
                                   alignment=QtCore.Qt.AlignCenter)
        self.forward_button.setStyleSheet(Style.get_button_style())
        self.forward_button.clicked.connect(button_method(forward_button_name))
예제 #2
0
 def dibujar_boton_selecion_avatar(self, archivo="no_avatar.png"):
     posicion_x_boton = self.textBox.rect[POS_X] + self.textBox.rect[ANCHO] + SEPARACIONES.SEPARACION
     posicion_y_boton = self.posY
     self.botonSeleccionAvatar = Button(posicion_x_boton, posicion_y_boton, archivo)
     self.botonSeleccionAvatar.dibujar()
     posicion_y_boton = self.posY + (self._mediaGrilla - self.botonSeleccionAvatar.rect[ALTO] / 2)
     self.botonSeleccionAvatar.posicionY = posicion_y_boton
     self.botonSeleccionAvatar.mover()
예제 #3
0
 def __dibujar_boton_borrar(self):
     self.botonBorrar = Button(self.posX, self.posY, "boton_borrar_habilitado.png")
     self.botonBorrar.agregar_imagen("boton_borrar_presionado.png")
     self.botonBorrar.agregar_imagen("boton_borrar_desactivado.png")
     self.botonBorrar.dibujar()
     posicion_y_boton = self.posY + (self._mediaGrilla - self.botonBorrar.rect[ALTO] / 2)
     self.botonBorrar.posicionY = posicion_y_boton
     self.botonBorrar.mover()
예제 #4
0
 def __init__(self, width, height, head_text, item_unit, can_sell_items, images):
     super(ItemDialog, self).__init__(width, height, head_text)
     self.unit = item_unit
     self.selected_item = None
     self.trait_labels = []
     
     # backpack slots
     self.item_icons = []
     y = self.rect.y + 32 
     x = self.rect.x + 32
     for i in range(hero.BACKPACK_SIZE):
         item_icon = ItemLabel(Rect(x,y,image.ITEM_ICON_WIDTH, image.ITEM_ICON_HEIGHT), 
                               images.backpack_slot, (PACK_SLOT, i))
         self.add_child(item_icon)
         self.item_icons.append(item_icon)
         y += image.ITEM_ICON_HEIGHT + 4
     x += image.ITEM_ICON_WIDTH + 16
     
     # equip slots
     y = self.rect.y + 32
     for i in range(len(hero.EQUIP_SLOTS)):
         item_icon = ItemLabel(Rect(x,y,image.ITEM_ICON_WIDTH, image.ITEM_ICON_HEIGHT), 
                                   images.equip_slots[hero.EQUIP_SLOTS[i]], (EQUIP_SLOT, i))
         self.add_child(item_icon)
         self.item_icons.append(item_icon)
         y += image.ITEM_ICON_HEIGHT + 4
     x += image.ITEM_ICON_WIDTH + 4
     
     # buttons
     x = self.rect.x + 44
     def transfer_callback():
         component.post_ui_event(component.KEY_DOWN, unicode = 't', key = 't')
     self.transfer_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH, image.SM_BUTTON_HEIGHT), images.transfer,  
                                   transfer_callback,  image_label = True,  tool_tip_text = "transfer (t)")
     x += image.SM_BUTTON_WIDTH + 4
     
     def disband_callback():
         component.post_ui_event(component.KEY_DOWN, unicode = 'x', key = 'x')
     self.disband_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH, image.SM_BUTTON_HEIGHT), images.disband,  
                                  disband_callback, image_label = True,  tool_tip_text = "discard (x)")
     self.add_child(self.transfer_button)
     self.add_child(self.disband_button)
     x += image.SM_BUTTON_WIDTH + 4
     
     if can_sell_items:
         def sell_callback():
             self.sell_selected()
        
         self.add_child(Button(Rect(x, y, image.SM_BUTTON_WIDTH, image.SM_BUTTON_HEIGHT), 
                               images.gold_small, sell_callback, image_label = True, 
                               tool_tip_text = "sell (s)"))
     x += image.SM_BUTTON_WIDTH + 4
     
     self.refresh_items()
     event_manager.add_listener(self.handle_game_events, event_manager.ITEM_ADDED)
     event_manager.add_listener(self.handle_game_events, event_manager.ITEM_SHIFTED)
     event_manager.add_listener(self.handle_game_events, event_manager.ITEM_REMOVED)
예제 #5
0
 def __init__(self, window, width, height):
     self.window = window
     self.window_width = width
     self.window_heigth = height
     self.start_button = Button(self.window_width / 2, 350, self.window)
     self.background_image = pygame.image.load('img/background_plain.png')
     self.background_image = pygame.transform.scale(self.background_image, (self.window_width, self.window_heigth))
     self.crown_image = pygame.image.load('img/crown.png')
     self.crown_image = pygame.transform.scale(self.crown_image, (100,50))
     self.crown_image = pygame.transform.rotate(self.crown_image,360-35)
예제 #6
0
 def is_button_hovered(self):
     x, y = pygame.mouse.get_pos()
     try:
         if self.start_button.is_hover(x, y):
             self.start_button.image = pygame.image.load(
                 Button.get_hover_image())
         else:
             self.start_button.image = pygame.image.load(Button.get_image())
     except Exception as e:
         print(e)
예제 #7
0
    def __init__(self):

        self.tablero = Tablero()
        self.corredores = []
        self.cazador = None
        self.boton_atras = Button(880, 680, "boton_iniciar_partida_habilitado.png")
        self.boton_atras.agregar_imagen("boton_iniciar_partida_presionado.png")
        self.boton_atras.agregar_imagen("boton_iniciar_partida_desactivado.png")
        self.turno = None
        self.primer_turno = True
        self.linea_doble_turno = False
        self.dado = None
        self.info = None
예제 #8
0
    def __init__(self, wm, surface, text, title=""):
        window = xpg.Window(surface, (200, 100), title, None, (400, 400))
        window.contents.append(Text(0, 0, text, (0, 0, 0)))
        window.contents.append(Button(0, 50, "Cancel", self.decline))
        window.contents.append(Button(100, 50, "Ok", self.confirm))

        window.closeable = False
        window.titlebar.reinit()

        wm.register_window(window)

        self.window = window

        self.status = "pending"
예제 #9
0
 def is_button_hovered(self):
     x, y = pygame.mouse.get_pos()
     if (self.start_button.is_hover(x, y)):
         self.start_button.image = pygame.image.load(
             Button.get_hover_image())
     else:
         self.start_button.image = pygame.image.load(Button.get_image())
     for i, button in enumerate(self.buttons):
         flag = button.is_hover(x, y)
         # print(flag,button.represent_value)
         if button.is_checked:
             self.background.is_hover_flag(button.represent_value, True)
         else:
             self.background.is_hover_flag(button.represent_value, flag)
예제 #10
0
 def __init__(self, position_rect, images, handler):
     super(ControlRenderer, self).__init__(position_rect)
     '''
     Constructor
     '''
     pad = 16
     top_pad = 16
     #        self.rect = position_rect
     handlers = [
         handler.previous_group, handler.next_group, handler.previous_site,
         handler.next_site, handler.center_view, handler.end_turn,
         handler.minimap, handler.tools
     ]
     image_labels = [
         images.l_arrow, images.r_arrow, images.prev_site, images.next_site,
         images.center_view, images.end_turn, images.minimap, images.tools
     ]
     tool_tips = [
         "prev. group (p)", "next group(n)", "prev. site (a)",
         "next site(s)", "center (c)", "end turn (e)", "mini-map (m)",
         "tools"
     ]
     x, y = self.rect.x + pad, self.rect.y + top_pad
     width, height = image.CONTROL_BUTTON_WIDTH, image.CONTROL_BUTTON_HEIGHT
     for i in range(len(handlers)):
         self.add_child(
             Button(Rect(x, y, width, height),
                    image_labels[i],
                    handlers[i],
                    image_label=True,
                    tool_tip_text=tool_tips[i]))
         x += image.CONTROL_BUTTON_WIDTH + pad
         if x > self.rect.x + self.rect.width - image.CONTROL_BUTTON_WIDTH:
             x = self.rect.x + pad
             y += image.CONTROL_BUTTON_HEIGHT + top_pad
예제 #11
0
 def update_buttons(self, buttons):
     self.buttons = []
     for (i, b) in enumerate(buttons):
         self.buttons.append(
             Button((i + 1) * self.width / (len(buttons) + 1),
                    self.y + self.height / 2))
         self.buttons[i].set_text(b, size=self.font_size)
예제 #12
0
 def update_units(self):
     super(HireRenderer, self).update_units()
     
     if self.curr_group == None:
         return
     
     hire_callbacks = [lambda i=x: self.do_hire(i) for x in range(self.curr_group.num_units())]
     self.hire_buttons = []
     
     for i in range(self.curr_group.num_units()):
         x, y = self.pixel_from_index(i)
         y += image.UNIT_HEIGHT + self.pad
         width, height = image.UNIT_WIDTH, image.UNIT_HEIGHT/ 3
         
         curr_unit = self.curr_group.get_unit(i)
         hire_cost = curr_unit.hire_cost(self.curr_hex.get_active_group())
         maint_cost = abs(curr_unit.maintenance())
         maint_label = "" if maint_cost == 0 else " / " + str(maint_cost)
         maint_tool_tip = "" if maint_cost == 0 else "\n and " + str(maint_cost) + " gold per week"
         
         label_text = str(hire_cost) + maint_label
         tool_tip =  "Hire this unit for " + str(hire_cost) + " gold" + maint_tool_tip
         
         self.hire_buttons.append(Button (Rect(x, y, width, height), label_text, hire_callbacks[i], tool_tip_text = tool_tip))
         self.add_child(self.hire_buttons[i])
     self.refresh_view()
예제 #13
0
    def createWidgets(self):
        """Creates all widgets for the dialog. Depending on wether we're a server or a client
        different widgets will be shown."""

        # are we a server?
        if not scenario.run_as_server:
            # we're running as client. need an additional label and editfield for the hostname
            self.wm.register(
                Label(self.smallfont,
                      "Server host: ", (250, 240),
                      color=(255, 255, 255)))

            self.host = EditField(self.smallfont,
                                  "localhost",
                                  200, (450, 240),
                                  color=(255, 255, 0),
                                  background=(80, 80, 80))

            self.wm.register(self.host)

        # common widgets
        self.wm.register(
            Label(self.titlefont,
                  "Setup network information", (10, 10),
                  color=(255, 0, 0)))

        self.wm.register(
            Label(self.smallfont,
                  "Server port: ", (250, 300),
                  color=(255, 255, 255)))
        self.port = EditField(self.smallfont,
                              str(properties.network_port),
                              200, (450, 300),
                              color=(255, 255, 0),
                              background=(80, 80, 80))

        self.wm.register(self.port)

        # buttons
        self.wm.register(
            Button(properties.path_dialogs + "butt-ok-moff.png",
                   properties.path_dialogs + "butt-ok-mover.png", (284, 650),
                   {widget.MOUSEBUTTONUP: self.ok}))
        self.wm.register(
            Button(properties.path_dialogs + "butt-back-moff.png",
                   properties.path_dialogs + "butt-back-mover.png", (528, 650),
                   {widget.MOUSEBUTTONUP: self.back}))
예제 #14
0
 def setUp(self):
     """
     set up data used in the tests.
     setUp is called before each test function execution.
     """
     pygame.init()        
     self.button = Button("Test", self.callback)
     self.button.rect = pygame.Rect(0,0,64,64)
     self.got_clicked = False
     self.input = Input()
예제 #15
0
    def __init__(self, position_rect, images):
        super(UnitRenderer, self).__init__(position_rect)
        self.selected_unit = None

        def item_callback():
            item_dialog = item_panel.ItemDialog(325, 325, "Items",
                                                self.selected_unit,
                                                self.can_sell_items, images)
            item_dialog.show()

        x, y = self.rect.x + self.rect.width / 3, self.rect.y + (
            self.rect.height * 3) / 4
        width, height = (self.rect.width) / 2, self.rect.height / 8
        self.item_button = Button(Rect(x, y, width, height), "Items",
                                  item_callback)

        def build_callback():
            command = misc_commands.BuildCommand(self.select_hex,
                                                 self.selected_unit)
            event_manager.queue_event(
                Event(event_manager.COMMAND_ISSUED, [command]))

        self.build_button = Button(Rect(x, y, width, height), "",
                                   build_callback)

        def embassy_callback():
            command = misc_commands.EmbassyCommand(self.select_hex,
                                                   self.selected_unit)
            event_manager.queue_event(
                Event(event_manager.COMMAND_ISSUED, [command]))

        self.embassy_button = Button(Rect(x, y, width, height), "",
                                     embassy_callback)

        self.can_sell_items = False
        self.map_data = None

        event_manager.add_listener(self.handle_game_events,
                                   event_manager.UNIT_SELECTED)
        event_manager.add_listener(self.handle_game_events,
                                   event_manager.HEX_SELECTED)
        event_manager.add_listener(self.handle_game_events,
                                   event_manager.UNIT_STATS_CHANGED)
 def add_button(self, name: str, text: str, button_method):
     self.buttons[name] = Button(text, self)
     self.grid_layout.addWidget(self.buttons[name],
                                len(self._settings) + len(self.buttons),
                                0,
                                1,
                                2,
                                alignment=QtCore.Qt.AlignCenter)
     self.buttons[name].setStyleSheet(Style.get_button_style())
     self.buttons[name].clicked.connect(button_method(name))
예제 #17
0
    def __init__(self):

        if App.instance:
            raise Exception

        GuiBoard.init()  # Initialize GuiBoard singleton

        App.instance = self

        self._running = False

        self.game = Controller()

        self.size = self.width, self.height = (1000, 1000)

        self.mode = App.Mode.title_screen

        self.button = Button(
            100, 100, 100, 100, "abc", App.button_font,
            lambda: print(crayons.cyan('clicked!')),
            Style(bg=(255, 255, 255), hbg=(0, 0, 0), tcolor=(255, 0, 0)))

        self.button.disabled = True

        self.exit = Button(
            0, 0, 200, 70, "Exit", App.button_font,
            lambda: App.instance.stop(),
            Style(bg=(233, 30, 99), hbg=(255, 96, 144), tcolor=(0, 0, 0)))

        self.exit.disabled = True

        s = Style((10, 123, 209), (10, 123, 209), (255, 255, 255))

        self.play_button = Button(300,
                                  450,
                                  400,
                                  125,
                                  "Play",
                                  App.title_screen_button_font,
                                  lambda: App.instance.set_mode(App.Mode.game),
                                  style=s)

        self.info_button = Button(300,
                                  600,
                                  400,
                                  125,
                                  "Info",
                                  App.title_screen_button_font,
                                  lambda: App.instance.set_mode(App.Mode.info),
                                  style=s)

        print(crayons.green('Instantiated App'))
 def add_button(self, name: str, position: int, size: int, text: str,
                method):
     self.buttons[name] = Button(text, self)
     self.grid_layout.addWidget(self.buttons[name],
                                1,
                                position,
                                1,
                                size,
                                alignment=QtCore.Qt.AlignCenter)
     self.buttons[name].setStyleSheet(Style.get_button_style())
     self.buttons[name].clicked.connect(method(name))
예제 #19
0
 def menu_content(self):
     self.check_box_fire = CheckBox(self.window_width / 2 - 150, 100,
                                    self.window, "fire")
     self.check_box_fire.is_checked = True
     self.check_box_water = CheckBox(self.window_width / 2 - 50, 100,
                                     self.window, "water")
     self.check_box_earth = CheckBox(self.window_width / 2 + 50, 100,
                                     self.window, "earth")
     self.check_box_wind = CheckBox(self.window_width / 2 + 150, 100,
                                    self.window, "wind")
     self.buttons = [
         self.check_box_fire, self.check_box_water, self.check_box_earth,
         self.check_box_wind
     ]
     self.currnet_button = self.check_box_fire
     self.start_button = Button(self.window_width / 2, 350, self.window)
     self.input_box1 = InputBox(self.window_width / 2, 200, 140, 32)
     self.background = Background(self.window, self.window_width,
                                  self.window_heigth)
     self.input_port = InputBox(self.window_width / 2, 300, 140, 32)
     self.input_ip = InputBox(self.window_width / 2, 250, 140, 32)
예제 #20
0
    def __init__(self, x=0, y=0, w=200, h=500, title='', buttons=None):
        # position and size
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        # buttons and title
        self.set_title(title)
        self.set_buttons(buttons)
        # create actual menu
        self.menu = RoundedRect(pygame.Rect(0, 0, w, h))
        self.menu.rect.center = self.x, self.y

        self.play_button = Button(
            pygame.display.get_surface().get_width() / 2,
            pygame.display.get_surface().get_height() * 0.4)
        self.play_button.set_text("Start Game", size=35)
        self.options_button = Button(
            pygame.display.get_surface().get_width() / 2,
            pygame.display.get_surface().get_height() * 0.55)
        self.options_button.set_text("Options", size=35)
        self.quit_button = Button(
            pygame.display.get_surface().get_width() / 2,
            pygame.display.get_surface().get_height() * 0.7)
        self.quit_button.set_text("Quit Game", size=35)
예제 #21
0
class TestButton(unittest.TestCase):
    """
    A test class for the Button module.
    """

    def setUp(self):
        """
        set up data used in the tests.
        setUp is called before each test function execution.
        """
        pygame.init()        
        self.button = Button("Test", self.callback)
        self.button.rect = pygame.Rect(0,0,64,64)
        self.got_clicked = False
        self.input = Input()
        
    def testClickedButton(self):
        self.input.mouse_x = 32
        self.input.mouse_y = 32
        self.input.mouse_left = True
        self.input.mouse_left_click = True
        
        self.button.update(self.input)
        
        self.input.mouse_left = False
        self.input.mouse_left_click = False
        self.input.mouse_left_clicked = False
        
        self.button.update(self.input)
        
        self.assertTrue(self.got_clicked)
        
    def testClickedSomethingElse(self):
        self.input.mouse_x = 128
        self.input.mouse_y = 128
        self.input.mouse_left = True
        self.input.mouse_left_click = True
        
        self.button.update(self.input)
        
        self.input.mouse_left = False
        self.input.mouse_left_click = False
        self.input.mouse_left_clicked = False
        
        self.button.update(self.input)
        
        self.assertFalse(self.got_clicked)
        
    def callback(self):
        self.got_clicked = True
예제 #22
0
    def set_buttons(self, buttons):
        self.buttons = []
        if not isinstance(buttons, list):
            return
        base = self.h * 0.15
        height = self.h - base
        base += self.y - self.h / 2

        for (i, b) in enumerate(buttons):
            x = int(self.x)
            y = int(height * ((i + 1) / (len(buttons) + 1)) + base)
            self.buttons.append(Button(x, y))
            self.buttons[i].set_text(b, size=35)
예제 #23
0
    def loop(self):
        running = True

        while running:
            self.ggf.mode.blit(self.ggf.bg, [0, 0])
            self.draw_text("Options", self.ggf.font, (255, 255, 255),
                           self.ggf.mode, 530, 10)

            self.back = Button("Retour", 450, 100, (450, 200), self.ggf)
            self.le_help = Button("Aide - Level Editor", 450, 100, (450, 300),
                                  self.ggf)
            self.game_help = Button("Aide - Jeu", 450, 100, (450, 400),
                                    self.ggf)

            lhelp = False
            ghelp = False

            click = False
            highlight = "None"

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit(0)
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        click = True
                        clic.play()

            if self.back.collides():
                highlight = "Retour"

                if click:
                    running = False
            if self.le_help.collides():
                lhelp = True
                self.le_help.custom_image("images/leveleditorhelp.png",
                                          (700, 700))
                self.le_help.move_to((300, 95))
            if self.game_help.collides():
                ghelp = True
                self.game_help.custom_image("images/gamehelp.png", (700, 700))
                self.game_help.move_to((300, 150))

            self.back.render(highlight)

            if not ghelp and not lhelp:
                self.le_help.render(highlight)
                self.game_help.render(highlight)
            elif ghelp:
                self.game_help.render(highlight)
            elif lhelp:
                self.le_help.render(highlight)

            pygame.display.update()
예제 #24
0
if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication

    from gui.button import Button

    app = QApplication(sys.argv)

    main = Button()
    main.show()

    sys.exit(app.exec_())
예제 #25
0
    def __init__( self, screen_width, screen_height, window_title, debug=False ):
        super( PixelEditor, self ).__init__( screen_width, screen_height, debug )
        pygame.init()

        self.color_palette = [
            Pixels.red,
            Pixels.blue,
            Pixels.green,
            Pixels.white,
            Pixels.black
        ]
        self.current_color = list( Pixels.blue )

        self.clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode(
            [screen_width, screen_height], pygame.RESIZABLE )
        self.font = pygame.font.SysFont( "monospace", 15 )

        self.window_title = window_title
        pygame.display.set_caption( self.window_title )

        # Draw grid overlay
        self.draw_grid = False

        # Drawing area and pixels for testing
        self.scale_multiplier = 32 # How big to draw each pixel on screen
        self.pan_amount = [0,0]

        self.drawing_area = DrawingArea( 110, 47, screen_width,
            screen_height, resize_mode='DYNAMIC', margin=(17, 15),
            color=Pixels.black, spritesize=16 , pixel_scaling=self.scale_multiplier,
            pan_amount=self.pan_amount )
        self.drawing_area.connect( "click", self.drawing_area.useCurrentTool,
            data={'position':True} )
        self.drawing_area.connect( "drag", self.drawing_area.useCurrentTool,
            data={'position':True} )
        self.append( self.drawing_area )

        # Hbox buttons
        self.save_button = Button( w=50, h=30, text="Save" )
        self.save_button.connect( "click", self.drawing_area.saveImage )

        self.open_button = Button( w=50, h=30, text="Open" )
        self.open_button.connect( "click", self.open )

        self.new_column_button = Button( w=100, h=30, text="New Column")
        self.new_column_button.connect( "click", self.drawing_area.newSheetColumn )

        self.new_row_button = Button( w=100, h=30, text="New Row")
        self.new_row_button.connect( "click", self.drawing_area.newSheetRow )

        # Hbox
        self.hbox = Container( 0, 0, screen_width, 30, 'WIDTH', axis="H" )
        self.hbox.append( self.save_button )
        self.hbox.append( self.open_button )
        self.hbox.append( self.new_column_button )
        self.hbox.append( self.new_row_button )
        self.append( self.hbox )

        # Vbox
        self.vbox = Container( 0, 31, 93, screen_height, 'HEIGHT', axis="V",
            multi_obj=True )
        # Vbox buttons. One for each color in the palette
        for value in self.color_palette:
            self.color_button = Button( w=30, h=30, color=value )
            self.color_button.connect( "mouse_down", self.drawing_area.setCurrentColor,
                data={'color':self.color_button.color})
            self.vbox.append( self.color_button )

        self.paint_tool_button = Button( w=92, h=30, text="Paint" )
        self.paint_tool_button.connect( "click", self.drawing_area.setCurrentTool,
            data={'tool':self.drawing_area.changePixel})
        self.vbox.append( self.paint_tool_button )

        self.append( self.vbox )

        self.run()
예제 #26
0
class PixelEditor( Wrapper ):
    def __init__( self, screen_width, screen_height, window_title, debug=False ):
        super( PixelEditor, self ).__init__( screen_width, screen_height, debug )
        pygame.init()

        self.color_palette = [
            Pixels.red,
            Pixels.blue,
            Pixels.green,
            Pixels.white,
            Pixels.black
        ]
        self.current_color = list( Pixels.blue )

        self.clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode(
            [screen_width, screen_height], pygame.RESIZABLE )
        self.font = pygame.font.SysFont( "monospace", 15 )

        self.window_title = window_title
        pygame.display.set_caption( self.window_title )

        # Draw grid overlay
        self.draw_grid = False

        # Drawing area and pixels for testing
        self.scale_multiplier = 32 # How big to draw each pixel on screen
        self.pan_amount = [0,0]

        self.drawing_area = DrawingArea( 110, 47, screen_width,
            screen_height, resize_mode='DYNAMIC', margin=(17, 15),
            color=Pixels.black, spritesize=16 , pixel_scaling=self.scale_multiplier,
            pan_amount=self.pan_amount )
        self.drawing_area.connect( "click", self.drawing_area.useCurrentTool,
            data={'position':True} )
        self.drawing_area.connect( "drag", self.drawing_area.useCurrentTool,
            data={'position':True} )
        self.append( self.drawing_area )

        # Hbox buttons
        self.save_button = Button( w=50, h=30, text="Save" )
        self.save_button.connect( "click", self.drawing_area.saveImage )

        self.open_button = Button( w=50, h=30, text="Open" )
        self.open_button.connect( "click", self.open )

        self.new_column_button = Button( w=100, h=30, text="New Column")
        self.new_column_button.connect( "click", self.drawing_area.newSheetColumn )

        self.new_row_button = Button( w=100, h=30, text="New Row")
        self.new_row_button.connect( "click", self.drawing_area.newSheetRow )

        # Hbox
        self.hbox = Container( 0, 0, screen_width, 30, 'WIDTH', axis="H" )
        self.hbox.append( self.save_button )
        self.hbox.append( self.open_button )
        self.hbox.append( self.new_column_button )
        self.hbox.append( self.new_row_button )
        self.append( self.hbox )

        # Vbox
        self.vbox = Container( 0, 31, 93, screen_height, 'HEIGHT', axis="V",
            multi_obj=True )
        # Vbox buttons. One for each color in the palette
        for value in self.color_palette:
            self.color_button = Button( w=30, h=30, color=value )
            self.color_button.connect( "mouse_down", self.drawing_area.setCurrentColor,
                data={'color':self.color_button.color})
            self.vbox.append( self.color_button )

        self.paint_tool_button = Button( w=92, h=30, text="Paint" )
        self.paint_tool_button.connect( "click", self.drawing_area.setCurrentTool,
            data={'tool':self.drawing_area.changePixel})
        self.vbox.append( self.paint_tool_button )

        self.append( self.vbox )

        self.run()


    def run( self ):
        self.middle_down = False

        self.running = True
        self.fps = 60

        while self.running:
            self.keys_down = pygame.key.get_pressed()
            self.clock.tick( self.fps )

            for pyevent in pygame.event.get():
                if pyevent.type == pygame.QUIT:
                    self.running = False
                if pyevent.type == pygame.KEYDOWN:
                    # Toggle grid
                    if pyevent.key == pygame.K_g:
                        self.draw_grid = not self.draw_grid
                    if pyevent.key == pygame.K_RIGHT:
                        self.pan_amount[0] -= 10
                    if pyevent.key == pygame.K_LEFT:
                        self.pan_amount[0] += 10
                    if pyevent.key == pygame.K_DOWN:
                        self.pan_amount[1] -= 10
                    if pyevent.key == pygame.K_UP:
                        self.pan_amount[1] += 10
                elif pyevent.type == pygame.MOUSEBUTTONDOWN:
                    if pyevent.button == 1:
                        self.mouseDown( pygame.mouse.get_pos() )
                    elif pyevent.button == 2:
                        self.middle_down = True
                    elif pyevent.button == 4:
                        if self.keys_down[pygame.K_LCTRL]:
                            self.scale_multiplier += 4
                            if self.scale_multiplier > 64: self.scale_multiplier = 64
                            self.drawing_area.pixel_scaling = self.scale_multiplier
                    elif pyevent.button == 5:
                        if self.keys_down[pygame.K_LCTRL]:
                            self.scale_multiplier -= 4
                            if self.scale_multiplier < 1: self.scale_multiplier = 1
                            self.drawing_area.pixel_scaling = self.scale_multiplier
                elif pyevent.type == pygame.MOUSEBUTTONUP:
                    if pyevent.button == 1:
                        self.mouseUp( pygame.mouse.get_pos() )
                    if pyevent.button == 2:
                        self.middle_down = False
                elif pyevent.type == pygame.MOUSEMOTION:
                    self.mouseMove( pygame.mouse.get_pos() )
                elif pyevent.type == pygame.VIDEORESIZE:
                    self.screen = pygame.display.set_mode(
                        (pyevent.w, pyevent.h), pygame.RESIZABLE)
                    self.resizeArea( (pyevent.w, pyevent.h) )

                # Move the spritsheet by using panning
                if self.middle_down:
                    self.move_amount = pygame.mouse.get_rel()
                    self.pan_amount[0] -= self.move_amount[0]
                    self.pan_amount[1] -= self.move_amount[1]
                else:
                    #Effectively pops the last mouse position
                    pygame.mouse.get_rel()

            # Display the FPS of the window in the title
            if self.debug == True: pygame.display.set_caption( self.window_title +
                "\t\t - FPS: " + str(int(self.clock.get_fps())) )

            self.render()
        pygame.quit()



    def render( self ):
        self.screen.fill( Pixels.white )
        if len( self ) > 0:
            for item in self:
                if item.getType() == 'Button':
                    pygame.draw.rect( self.screen, Pixels.silver, item.getRect() )
                elif item.getType() == 'DrawingArea':
                    # Background of the drawing area
                    pygame.draw.rect( self.screen, item.color, item.getRect() )

                    # -------------------------------------------------------------------
                    # TODO Precalculate what part of the surface will be displayed on screen,
                    # then scale that. Max will be around item.w, item.h and never much more

                    # Raw surface of pixels
                    self.surface = pygame.surfarray.make_surface(
                        self.drawing_area.getPixels() ).convert()

                    # Surface is scaled/zoomed in by the scale_multiplier
                    # if self.scale_multiplier > 64: self.scale_multiplier = 64

                    self.surface = pygame.transform.scale( self.surface,
                    (self.surface.get_width() * self.scale_multiplier,
                    self.surface.get_height() * self.scale_multiplier))
                    if self.debug==True: print self.surface.get_rect(), "scaletexture"

                    self.rect_drawarea = self.surface.get_rect()
                    self.rect_drawarea.x = self.pan_amount[0] - self.drawing_area.x_offset
                    self.rect_drawarea.y = self.pan_amount[1] - self.drawing_area.y_offset

                    self.rect_drawarea.w = item.w
                    self.rect_drawarea.h = item.h
                    if self.debug==True: print self.rect_drawarea

                    # Draw grid if it is enabled
                    if self.draw_grid == True:
                        s = self.drawing_area.spritesize
                        w = self.drawing_area.sheetsize[0] * s
                        h = self.drawing_area.sheetsize[1] * s
                        p = self.scale_multiplier
                        xo = self.drawing_area.x_offset
                        yo = self.drawing_area.y_offset
                        j = s * p

                        lines = []

                        lines.append([0,0])
                        lines.append([w*p, 0])
                        for y in range(0, h*p, j):
                            for x in range(0, w*p, j):
                                lines.append([x - xo, y - yo])
                                lines.append([x - xo, y - yo +j])
                                lines.append([x - xo +j, y - yo +j])
                        lines.append([w*p, 0])
                        try:
                            pygame.draw.lines(self.surface, Pixels.darksilver, False,
                                lines, 3 )
                        except Exception as e: "Error drawing lines, e: ", e

                    self.draw_position = (item.x, item.y)
                    self.screen.blit( self.surface, self.draw_position,
                        area=self.rect_drawarea )

                elif item.getType() == 'Container':
                    pygame.draw.rect( self.screen, Pixels.darksilver, item.getRect() )
                    for i in item.items:
                        if i.color is not None:
                            pygame.draw.rect( self.screen, i.color, i.getRect() )
                        else:
                            pygame.draw.rect( self.screen, Pixels.silver, i.getRect() )
                        if i.text is not None:
                            self.label_font = self.font.render(i.text, 1, Pixels.black)
                            self.screen.blit( self.label_font, (
                                i.getCenterPoint()[0] - self.label_font.get_width()/2,
                                i.getCenterPoint()[1] - self.label_font.get_height()/2 ) )
        pygame.display.flip()

    def save( self ):
        print "file is being saved"

    def open( self ):
        print "file is being opened"
예제 #27
0
from gui.button import Button


def button_onclick(button):
    button.move(10, 0)


wm = xpg.WindowManager()
ddm = xpg.DragDropManager(wm)

screen = pygame.display.set_mode((1200, 800))
xpg.GLOBAL_SURFACE = screen

window = xpg.Window(screen, (300, 300), "Moving Button")

b = Button(0, 0, "MOVE!", button_onclick)

window.contents.append(b)

wm.register_window(window)

pygame.display.update(xpg.UPDATE)
xpg.UPDATE.append(screen.get_rect())

while 1:
    wm.loop()
    ddm.loop()
    screen.fill((0, 0, 0))

    b.move(0, 0.1)
예제 #28
0

wm = xpg.WindowManager()
ddm = xpg.DragDropManager(wm)
im = xpg.InputManager()

screen = pygame.display.set_mode((1200, 800))
xpg.GLOBAL_SURFACE = screen

window = xpg.Window(screen, (300, 50), "Your Name:")

window.resizeable = False

tf = TextField(im, 0, 0, "", button_onclick)

b = Button(200, 5, "Submit", button_onclick)

window.contents.append(b)
window.contents.append(tf)

wm.register_window(window)

pygame.display.update(xpg.UPDATE)
xpg.UPDATE.append(screen.get_rect())

wm.reblit_all_windows()

while 1:
    screen.fill((0, 0, 0))
    ddm.loop()
    wm.loop()
예제 #29
0
class Menu:
    def __init__(self, window, width, height):

        self.window = window
        self.element = "fire"
        self.nick_name = "Please put your nickname here"
        self.nick_is_putted = False
        self.window_width = width
        self.window_heigth = height
        self.menu_content()
        self.ip = "127.0.0.1"
        self.port = 22000

    def menu_content(self):
        self.check_box_fire = CheckBox(self.window_width / 2 - 150, 100,
                                       self.window, "fire")
        self.check_box_fire.is_checked = True
        self.check_box_water = CheckBox(self.window_width / 2 - 50, 100,
                                        self.window, "water")
        self.check_box_earth = CheckBox(self.window_width / 2 + 50, 100,
                                        self.window, "earth")
        self.check_box_wind = CheckBox(self.window_width / 2 + 150, 100,
                                       self.window, "wind")
        self.buttons = [
            self.check_box_fire, self.check_box_water, self.check_box_earth,
            self.check_box_wind
        ]
        self.currnet_button = self.check_box_fire
        self.start_button = Button(self.window_width / 2, 350, self.window)
        self.input_box1 = InputBox(self.window_width / 2, 200, 140, 32)
        self.background = Background(self.window, self.window_width,
                                     self.window_heigth)
        self.input_port = InputBox(self.window_width / 2, 300, 140, 32)
        self.input_ip = InputBox(self.window_width / 2, 250, 140, 32)

    def buttons_checking(self, x, y):
        for i, button in enumerate(self.buttons):
            if (button.is_hover(x, y)):
                self.buttons[i].toggle()
                self.currnet_button.toggle()
                self.currnet_button = self.buttons[i]

        if (self.start_button.is_hover(x, y)):
            return True
        return False

    def buttons_display(self):
        for i, button in enumerate(self.buttons):
            self.buttons[i].display()
        self.start_button.display()

    def is_button_hovered(self):
        x, y = pygame.mouse.get_pos()
        if (self.start_button.is_hover(x, y)):
            self.start_button.image = pygame.image.load(
                Button.get_hover_image())
        else:
            self.start_button.image = pygame.image.load(Button.get_image())
        for i, button in enumerate(self.buttons):
            flag = button.is_hover(x, y)
            # print(flag,button.represent_value)
            if button.is_checked:
                self.background.is_hover_flag(button.represent_value, True)
            else:
                self.background.is_hover_flag(button.represent_value, flag)

    def display(self):
        clock = pygame.time.Clock()
        flag = False
        while True:

            clock.tick(30)

            # get all events
            ev = pygame.event.get()

            # proceed events
            for event in ev:

                # handle MOUSEBUTTONUP
                if event.type == pygame.MOUSEBUTTONUP:
                    x, y = pygame.mouse.get_pos()
                    flag = self.buttons_checking(x, y)
                self.input_box1.handle_event(event)
                self.input_port.handle_event(event)
                self.input_ip.handle_event(event)

            self.window.fill((255, 255, 255))
            self.background.display()
            self.is_button_hovered()
            self.background.display()
            self.buttons_display()
            self.input_box1.update()
            self.input_box1.draw(self.window)
            self.nick_name = self.input_box1.text

            self.input_ip.update()
            self.input_ip.draw(self.window)
            self.ip = self.input_ip.text

            self.input_port.update()
            self.input_port.draw(self.window)
            self.port = self.input_port.text
            pygame.display.flip()
            if flag:
                if self.nick_name != "Please put your nickname here" and self.nick_name != "":
                    break

        return self.nick_name, self.currnet_button.represent_value, self.ip, self.port
예제 #30
0
class SudokuBoard:
    INPUT = 0
    ACCEPTED = 1
    WRONG = -1

    def __init__(self):
        self.done = False
        self.remove_attempts = 5

        self.cells_in_row = 9
        self.row_group_size = 3

        self.cells_in_column = 9
        self.column_group_size = 3

        self.groups_in_row = int(self.cells_in_row / self.row_group_size)
        self.groups_in_column = int(self.cells_in_column /
                                    self.column_group_size)

        pygame.font.init()
        self.font = pygame.font.SysFont("cambriacambriamath", 30)
        self.button_font = pygame.font.SysFont("cambriacambriamath", 19)
        self.info_font = pygame.font.SysFont("cambriacambriamath",
                                             45,
                                             bold=True)

        self.cell_width = 40
        self.cell_height = 40
        self.margin = 10
        self.button_height = Button.check_size('', self.button_font)[1]

        self.grid_width = self.cell_width * self.cells_in_row + 2 * self.margin
        self.grid_height = self.cell_height * self.cells_in_column + 2 * self.margin
        self.window_width = self.grid_width
        self.window_height = self.grid_height + self.button_height + 1 * self.margin

        self.screen = pygame.display.set_mode(
            (self.window_width, self.window_height))
        pygame.display.set_caption("Sudoku")

        self.line_color = (0, 0, 0)
        self.input_value_color = (0, 0, 0)
        self.accepted_value_color = (44, 181, 2)
        self.wrong_value_color = (181, 20, 20)
        self.info_color = (0, 0, 0)
        self.highlight_color = (174, 237, 111)

        self.selected_row = 0
        self.selected_column = 0

        self.navigation_keys = {
            pygame.K_LEFT: (-1, 0),
            pygame.K_RIGHT: (1, 0),
            pygame.K_UP: (0, -1),
            pygame.K_DOWN: (0, 1),
        }

        self.grid = np.zeros(shape=(self.cells_in_row, self.cells_in_column),
                             dtype=int)
        self.grid_status = np.full(shape=(self.cells_in_row,
                                          self.cells_in_column),
                                   fill_value=SudokuBoard.ACCEPTED)

        self.elements_set = set([
            i
            for i in range(1, self.row_group_size * self.column_group_size + 1)
        ])

        self.observers = []
        self.puzzle_button = Button(parent=self,
                                    surface=self.screen,
                                    text="New puzzle",
                                    font=self.button_font)
        self.puzzle_button.set_on_click_event(
            lambda: threading.Thread(target=self.generate_puzzle).start())
        self.hint_button = Button(parent=self,
                                  surface=self.screen,
                                  text="Hint",
                                  font=self.button_font)
        self.hint_button.set_on_click_event(
            lambda: threading.Thread(target=self.hint).start())
        self.check_button = Button(parent=self,
                                   surface=self.screen,
                                   text="Check",
                                   font=self.button_font)
        self.check_button.set_on_click_event(self.check_and_display_info)
        self.solve_button = Button(parent=self,
                                   surface=self.screen,
                                   text="Solve",
                                   font=self.button_font)
        self.solve_button.set_on_click_event(
            lambda: threading.Thread(target=self.solve).start())
        self.clean_button = Button(parent=self,
                                   surface=self.screen,
                                   text="Clean",
                                   font=self.button_font)
        self.clean_button.set_on_click_event(
            lambda: threading.Thread(target=self.clean).start())

        self.buttons_layout = Layout(start=(self.margin, self.grid_height),
                                     max_size=self.window_width -
                                     2 * self.margin)
        self.buttons_layout.add_element(self.puzzle_button)
        self.buttons_layout.add_element(self.hint_button)
        self.buttons_layout.add_element(self.check_button)
        self.buttons_layout.add_element(self.solve_button)
        self.buttons_layout.add_element(self.clean_button)

        self.info = None

    def clean(self):
        self.grid = np.zeros(shape=(self.cells_in_row, self.cells_in_column),
                             dtype=int)
        self.grid_status = np.full(shape=(self.cells_in_row,
                                          self.cells_in_column),
                                   fill_value=SudokuBoard.ACCEPTED)

    def add_observer(self, observer):
        self.observers.append(observer)

    def quit(self):
        self.done = True

    def draw_lines(self, number_of_lines, step, horizontal):
        for i in range(number_of_lines):
            current_position = i * step + self.margin
            start = self.margin
            end = self.grid_width if horizontal else self.grid_height
            end -= self.margin

            start_pos = (start, current_position)
            end_pos = (end, current_position)

            if not horizontal:
                start_pos = start_pos[::-1]
                end_pos = end_pos[::-1]

            pygame.draw.line(surface=self.screen,
                             color=self.line_color,
                             start_pos=start_pos,
                             end_pos=end_pos,
                             width=(2 if i % 3 == 0 else 1))

    def draw_value(self, value, row, column):
        color = self.input_value_color
        if self.grid_status[row][column] == SudokuBoard.WRONG:
            color = self.wrong_value_color
        if self.grid_status[row][column] == SudokuBoard.ACCEPTED:
            color = self.accepted_value_color
        text = self.font.render(str(value), True, color)
        text_rect = text.get_rect(center=(
            (column * self.cell_width) + self.margin + self.cell_width / 2,
            (row * self.cell_height) + self.margin + self.cell_height / 2,
        ))
        self.screen.blit(text, text_rect)

    def draw_values(self):
        for i in range(self.cells_in_row):
            for j in range(self.cells_in_column):
                if self.grid[i][j] != 0:
                    self.draw_value(self.grid[i][j], i, j)

    def highlight_cell(self):
        if self.selected_row is None or self.selected_column is None:
            return
        line_fix_row = 2 if self.selected_row % self.row_group_size == 0 else 1
        line_fix_column = 2 if self.selected_column % self.column_group_size == 0 else 1
        pygame.draw.rect(
            surface=self.screen,
            color=self.highlight_color,
            rect=pygame.Rect(
                self.margin + self.selected_row * self.cell_width +
                line_fix_row, self.margin +
                self.selected_column * self.cell_height + line_fix_column,
                self.cell_width - line_fix_row,
                self.cell_height - line_fix_column))

    @staticmethod
    def check_limitations(new_value, minimum, maximum):
        if new_value > maximum:
            return False
        if new_value < minimum:
            return False
        return True

    def get_cell_pos(self, pos):
        cell_x = (pos[0] - self.margin) // (self.cell_width + 1)
        cell_y = (pos[1] - self.margin) // (self.cell_height + 1)
        return cell_x, cell_y

    def update_selected_cell(self, cell_x, cell_y):
        if SudokuBoard.check_limitations(cell_x, 0, self.cells_in_row - 1):
            if SudokuBoard.check_limitations(cell_y, 0,
                                             self.cells_in_column - 1):
                self.selected_row = cell_x
                self.selected_column = cell_y

    def check_mouse_navigation(self):
        self.update_selected_cell(*self.get_cell_pos(pygame.mouse.get_pos()))

    def check_keyboard_navigation(self, key):
        if key in self.navigation_keys.keys():
            self.update_selected_cell(
                self.selected_row + self.navigation_keys[key][0],
                self.selected_column + self.navigation_keys[key][1])
        elif key is pygame.K_BACKSPACE:
            self.grid[self.selected_column][self.selected_row] = 0
            self.grid_status[self.selected_column][
                self.selected_row] = SudokuBoard.INPUT
        else:
            s = pygame.key.name(key)
            s = s.replace('[', '')
            s = s.replace(']', '')
            if s.isdigit() and int(s) != 0:
                self.grid[self.selected_column][self.selected_row] = int(s)
                self.grid_status[self.selected_column][
                    self.selected_row] = SudokuBoard.INPUT

    def draw_info(self):
        if self.info is None:
            return
        info_text = self.info.split('\n')
        for i, text in enumerate(info_text):
            info = self.info_font.render(text, True, self.info_color)
            into_text_rect = info.get_rect(
                center=(self.grid_width / 2,
                        self.grid_height / 2 + info.get_size()[1] * i -
                        info.get_size()[1] * len(info_text) / 2))
            self.screen.blit(info, into_text_rect)

    def draw(self):
        self.draw_lines(self.cells_in_row + 1, self.cell_width, False)
        self.draw_lines(self.cells_in_column + 1, self.cell_height, True)
        self.highlight_cell()
        self.draw_values()
        self.buttons_layout.draw()
        self.draw_info()

    def animate_and_hide_info(self):
        text = self.info
        for i in range(10):
            time.sleep(0.1)
            if i % 2 == 0:
                self.info = text
            else:
                self.info = None

    def display_info(self, message, positive=True):
        self.info = message
        self.info_color = (22, 112, 4) if positive else (186, 0, 0)
        threading.Thread(target=self.animate_and_hide_info).start()

    def check_and_display_info(self):
        correct = self.check()
        self.display_info("Correct" if correct else "Incorrect!", correct)

    def is_iterable_valid(self, iter_obj):
        return set(iter_obj) == self.elements_set

    def are_rows_valid(self, grid):
        return not any(not self.is_iterable_valid(row) for row in grid)

    def get_group(self, array, group_x_number, group_y_number):
        r_s = group_x_number * self.row_group_size
        c_s = group_y_number * self.column_group_size
        return array[r_s:r_s + self.row_group_size, c_s:c_s + self.column_group_size] \
            .reshape(self.row_group_size * self.column_group_size)

    def are_groups_valid(self):
        return not any(
            not self.is_iterable_valid(self.get_group(self.grid, i, j))
            for i in range(self.groups_in_row)
            for j in range(self.groups_in_column))

    @staticmethod
    def get_wrong(line):
        c = Counter(line)
        for key in c:
            if c[key] > 1:
                for i, cell in enumerate(line):
                    if cell == key:
                        yield i

    def hint(self):
        for i, row in enumerate(self.grid):
            for j in SudokuBoard.get_wrong(row):
                if self.grid_status[i][j] != SudokuBoard.ACCEPTED:
                    self.grid_status[i][j] = SudokuBoard.WRONG
        for j in range(self.cells_in_column):
            column = self.grid[:, j]
            for i in SudokuBoard.get_wrong(column):
                if self.grid_status[i][j] != SudokuBoard.ACCEPTED:
                    self.grid_status[i][j] = SudokuBoard.WRONG

    def check(self):
        rows_correct = self.are_rows_valid(self.grid)
        columns_correct = self.are_rows_valid(np.rot90(self.grid))
        groups_correct = self.are_groups_valid()
        return rows_correct and columns_correct and groups_correct

    @staticmethod
    def modify_values_in_line(value, line, modify_function):
        for i, element in enumerate(line):
            if value in element:
                modify_function(element, value)
                # element.remove(value)

    def modify_candidate_values(self, grid, candidate_values, cell_x, cell_y,
                                modify_function):
        value = grid[cell_x][cell_y]

        self.modify_values_in_line(value, candidate_values[cell_x],
                                   modify_function)
        self.modify_values_in_line(value, candidate_values[:, cell_y],
                                   modify_function)

        group_x, group_y = cell_x // self.row_group_size, cell_y // self.column_group_size
        self.modify_values_in_line(
            value, self.get_group(candidate_values, group_x, group_y),
            modify_function)

    def get_empty_cell(self, grid, candidate_values):
        minimum = len(self.elements_set)
        x, y = -1, -1
        for i in range(self.cells_in_row):
            for j in range(self.cells_in_column):
                if grid[i][j] == 0 and len(candidate_values[i][j]) < minimum:
                    minimum = len(candidate_values[i][j])
                    x, y = i, j
                    if minimum == 1:
                        return x, y
        return x, y

    def prepare_run(self, values, candidate_values, option, x, y):
        # v = values.copy()
        # c_v = candidate_values.copy()
        values[x][y] = option
        self.modify_candidate_values(values, candidate_values, x, y,
                                     lambda s, v: s.remove(v))
        return self.run_solver(values, self.prepare_candidate_values(values))

    def run_solver(self, values, candidate_values):
        # Solved
        if not any(0 in row for row in values):
            yield values
        # Choose empty cell with fewest candidate values
        x, y = self.get_empty_cell(values, candidate_values)
        options = candidate_values[x][y]
        # Unsolvable
        if len(options) == 0:
            yield None
        else:
            options_list = list(options)
            shuffle(options_list)
            for option in options_list:
                values[x][y] = option
                self.modify_candidate_values(values, candidate_values, x, y,
                                             lambda s, v: s.remove(v))
                yield from self.run_solver(
                    values, self.prepare_candidate_values(values))
                values[x][y] = 0
                self.modify_candidate_values(values, candidate_values, x, y,
                                             lambda s, v: s.add(v))

    def prepare_candidate_values(self, grid):
        candidate_values = np.array([[
            self.elements_set.copy() if grid[i][j] == 0 else {grid[i][j]}
            for j in range(self.cells_in_row)
        ] for i in range(self.cells_in_column)])

        for i in range(self.cells_in_row):
            for j in range(self.cells_in_column):
                if grid[i][j] != 0:
                    self.modify_candidate_values(grid, candidate_values, i, j,
                                                 lambda s, v: s.remove(v))
        return candidate_values

    def solve(self):
        if not any(0 in row for row in self.grid):
            self.display_info('Solved!', positive=True)
            return

        if np.count_nonzero(
                self.grid == 0) == self.cells_in_row * self.cells_in_column:
            self.display_info('Enter values!', positive=False)
            return

        grid = self.grid.copy()
        counter = 0
        solution = None
        for result in self.run_solver(grid,
                                      self.prepare_candidate_values(grid)):
            if counter > 1:
                self.display_info('Not uniquely\n solvable!', positive=False)
                return
            if result is not None:
                counter += 1
                solution = result.copy()
        if solution is not None:
            self.display_info('Solved!', positive=True)
            self.grid = solution
            return
        self.display_info('Unsolvable!', positive=False)

    def generate_grid(self):
        self.clean()
        grid = self.grid.copy()
        candidate_values = self.prepare_candidate_values(grid)
        for _ in range(10):
            row_random, column_random = randrange(
                0, self.cells_in_row, 1), randrange(0, self.cells_in_column, 1)
            grid[row_random][column_random] = choice(
                list(candidate_values[row_random][column_random]))
            self.modify_candidate_values(grid, candidate_values, row_random,
                                         column_random,
                                         lambda s, v: s.remove(v))

        for result in self.run_solver(grid,
                                      self.prepare_candidate_values(grid)):
            if result is not None:
                return result.copy()

    def generate_puzzle(self):
        grid = self.generate_grid()

        remove = 0
        while remove < self.remove_attempts:
            row_random, column_random = randrange(
                0, self.cells_in_row, 1), randrange(0, self.cells_in_column, 1)
            if grid[row_random][column_random] == 0:
                continue
            value = grid[row_random][column_random]
            grid[row_random][column_random] = 0
            counter = 0
            for result in self.run_solver(grid.copy(),
                                          self.prepare_candidate_values(grid)):
                if result is not None:
                    counter += 1
                if counter > 1:
                    remove += 1
                    grid[row_random][column_random] = value
                    break
        self.grid = grid

    def start(self):
        while not self.done:
            self.screen.fill((255, 255, 255))
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quit()
                if event.type == pygame.KEYDOWN:
                    self.check_keyboard_navigation(event.key)
                if event.type == pygame.MOUSEBUTTONDOWN:
                    self.check_mouse_navigation()
                for observer in self.observers:
                    observer.process_event(event, pygame.mouse.get_pos())
            self.draw()
            pygame.display.update()
        pygame.quit()
예제 #31
0
    def __init__(self):
        self.done = False
        self.remove_attempts = 5

        self.cells_in_row = 9
        self.row_group_size = 3

        self.cells_in_column = 9
        self.column_group_size = 3

        self.groups_in_row = int(self.cells_in_row / self.row_group_size)
        self.groups_in_column = int(self.cells_in_column /
                                    self.column_group_size)

        pygame.font.init()
        self.font = pygame.font.SysFont("cambriacambriamath", 30)
        self.button_font = pygame.font.SysFont("cambriacambriamath", 19)
        self.info_font = pygame.font.SysFont("cambriacambriamath",
                                             45,
                                             bold=True)

        self.cell_width = 40
        self.cell_height = 40
        self.margin = 10
        self.button_height = Button.check_size('', self.button_font)[1]

        self.grid_width = self.cell_width * self.cells_in_row + 2 * self.margin
        self.grid_height = self.cell_height * self.cells_in_column + 2 * self.margin
        self.window_width = self.grid_width
        self.window_height = self.grid_height + self.button_height + 1 * self.margin

        self.screen = pygame.display.set_mode(
            (self.window_width, self.window_height))
        pygame.display.set_caption("Sudoku")

        self.line_color = (0, 0, 0)
        self.input_value_color = (0, 0, 0)
        self.accepted_value_color = (44, 181, 2)
        self.wrong_value_color = (181, 20, 20)
        self.info_color = (0, 0, 0)
        self.highlight_color = (174, 237, 111)

        self.selected_row = 0
        self.selected_column = 0

        self.navigation_keys = {
            pygame.K_LEFT: (-1, 0),
            pygame.K_RIGHT: (1, 0),
            pygame.K_UP: (0, -1),
            pygame.K_DOWN: (0, 1),
        }

        self.grid = np.zeros(shape=(self.cells_in_row, self.cells_in_column),
                             dtype=int)
        self.grid_status = np.full(shape=(self.cells_in_row,
                                          self.cells_in_column),
                                   fill_value=SudokuBoard.ACCEPTED)

        self.elements_set = set([
            i
            for i in range(1, self.row_group_size * self.column_group_size + 1)
        ])

        self.observers = []
        self.puzzle_button = Button(parent=self,
                                    surface=self.screen,
                                    text="New puzzle",
                                    font=self.button_font)
        self.puzzle_button.set_on_click_event(
            lambda: threading.Thread(target=self.generate_puzzle).start())
        self.hint_button = Button(parent=self,
                                  surface=self.screen,
                                  text="Hint",
                                  font=self.button_font)
        self.hint_button.set_on_click_event(
            lambda: threading.Thread(target=self.hint).start())
        self.check_button = Button(parent=self,
                                   surface=self.screen,
                                   text="Check",
                                   font=self.button_font)
        self.check_button.set_on_click_event(self.check_and_display_info)
        self.solve_button = Button(parent=self,
                                   surface=self.screen,
                                   text="Solve",
                                   font=self.button_font)
        self.solve_button.set_on_click_event(
            lambda: threading.Thread(target=self.solve).start())
        self.clean_button = Button(parent=self,
                                   surface=self.screen,
                                   text="Clean",
                                   font=self.button_font)
        self.clean_button.set_on_click_event(
            lambda: threading.Thread(target=self.clean).start())

        self.buttons_layout = Layout(start=(self.margin, self.grid_height),
                                     max_size=self.window_width -
                                     2 * self.margin)
        self.buttons_layout.add_element(self.puzzle_button)
        self.buttons_layout.add_element(self.hint_button)
        self.buttons_layout.add_element(self.check_button)
        self.buttons_layout.add_element(self.solve_button)
        self.buttons_layout.add_element(self.clean_button)

        self.info = None
예제 #32
0
def main():

    # parse Profile XML
    doc = minidom.parse('profile.xml')
    rootNode = doc.documentElement
    player_name = rootNode.getAttribute('player')
    print 'Player:', player_name

    lang = 'english' # default languaje
    settings = []
    for setting in rootNode.getElementsByTagName('setting'):
        settings.append(setting.getAttribute('value'))
    lang = settings[0]

    # parse Translations XML
    doc = minidom.parse('language.xml')
    rootNode = doc.documentElement
    author = rootNode.getAttribute('author')
    print 'Translation author:', author

    butt_labels = []
    for language in rootNode.getElementsByTagName('language'):
        if language.getAttribute('type') == lang:
            for string in language.getElementsByTagName('string'):
                print string.getAttribute('data')
                butt_labels.append(string.getAttribute('data'))
                
    pygame.init()
    screen = pygame.display.set_mode((640,480),16)
    back = load_image(os.path.join('gui','data'),'back.png')
    screen.blit(back,(0,0))

    clock = pygame.time.Clock()
    
    MyEvent = Event()

##    cb_images = []
##    cb_images.append(load_image(os.path.join('data'),'checkbox_off.png'))
##    cb_images.append(load_image(os.path.join('data'),'checkbox_on.png'))

    b_images = []
    b_images.append(load_image(os.path.join('gui','data'),'button_off2.png'))
    b_images.append(load_image(os.path.join('gui','data'),'button_on2.png'))

    cmdNewGame = Button(butt_labels[0],b_images,(320-110,300))
    cmdLoadGame = Button(butt_labels[1],b_images,(320+10,300))
    cmdOptions = Button(butt_labels[2],b_images,(320-110,350))
    cmdCredits = Button(butt_labels[3],b_images,(320+10,350))
    cmdQuit = Button(butt_labels[4],b_images,(320-50,400))

    buttons = [cmdNewGame,cmdLoadGame,cmdOptions,cmdCredits,cmdQuit]
    

    while 1:
        btn = 0
        key = 0
        
        clock.tick(40)

        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    return
                else:
                    key = event.key
            elif event.type == MOUSEBUTTONDOWN:
                btn = event.button

        for button in buttons:
            button.notify(MyEvent)
            button.update(screen)

        if cmdQuit.isClicked():
            return

        pygame.display.flip()
예제 #33
0
class Menu:
    def __init__(self, x=0, y=0, w=200, h=500, title='', buttons=None):
        # position and size
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        # buttons and title
        self.set_title(title)
        self.set_buttons(buttons)
        # create actual menu
        self.menu = RoundedRect(pygame.Rect(0, 0, w, h))
        self.menu.rect.center = self.x, self.y

        self.play_button = Button(
            pygame.display.get_surface().get_width() / 2,
            pygame.display.get_surface().get_height() * 0.4)
        self.play_button.set_text("Start Game", size=35)
        self.options_button = Button(
            pygame.display.get_surface().get_width() / 2,
            pygame.display.get_surface().get_height() * 0.55)
        self.options_button.set_text("Options", size=35)
        self.quit_button = Button(
            pygame.display.get_surface().get_width() / 2,
            pygame.display.get_surface().get_height() * 0.7)
        self.quit_button.set_text("Quit Game", size=35)

    def get_event(self, event):
        for b in self.buttons:
            if b.handle_event(event):
                return b.get_text()
        else:
            return None

    def update(self):
        for b in self.buttons:
            b.update()

    def render(self, surface):
        self.menu.render(surface)
        self.title.render(surface)
        for b in self.buttons:
            b.render(surface)

    def set_title(self, title):
        self.title = Label(title)
        self.title.set_pos((self.x, int(self.y - self.h / 2 + self.h * 0.15)))

    def set_pos(self, pos):
        self.x, self.y = pos
        self.menu.rect.center = self.x, self.y

    def set_buttons(self, buttons):
        self.buttons = []
        if not isinstance(buttons, list):
            return
        base = self.h * 0.15
        height = self.h - base
        base += self.y - self.h / 2

        for (i, b) in enumerate(buttons):
            x = int(self.x)
            y = int(height * ((i + 1) / (len(buttons) + 1)) + base)
            self.buttons.append(Button(x, y))
            self.buttons[i].set_text(b, size=35)
예제 #34
0
    def __init__(self, position_rect, images):
        super(HexInfoRenderer, self).__init__(position_rect)

        self.engineering_active = False
        self.selected_hex = None

        # probably need to allow for some padding in these calculations
        self.site_rect = Rect(self.rect.x, self.rect.y, self.rect.width / 4,
                              self.rect.height)

        def hire_callback(toggle_down):
            if toggle_down:
                self.for_hire_renderer.show()
                self.garrison_renderer.hide()
            else:
                self.for_hire_renderer.hide()
                self.garrison_renderer.show()

        def upgrade_callback():
            upgrade_dialog = UpgradeDialog(250, 300, "Site Upgrades",
                                           self.selected_hex.site)
            upgrade_dialog.show()

        x, y = self.site_rect.x + self.site_rect.width / 4, self.site_rect.y + (
            self.site_rect.height * 3) / 4
        width, height = self.site_rect.width / 4, self.site_rect.height / 8
        self.upgrade_button = Button(Rect(x, y, width, height), "Upg.",
                                     upgrade_callback)

        self.hire_button = Toggle(Rect(x + width + 8, y, width, height),
                                  "Hire", hire_callback)

        self.add_child(self.hire_button)
        self.add_child(self.upgrade_button)

        active_group_rect = Rect(self.rect.x + self.site_rect.width,
                                 self.rect.y + 1, (3 * self.rect.width) / 4,
                                 image.UNIT_HEIGHT + 8)
        self.active_group_renderer = group_panel.OccupantRenderer(
            "Active", active_group_rect, False)

        x = active_group_rect.x + (active_group_rect.width) / 2
        y = active_group_rect.y + active_group_rect.height + 12

        def transfer_callback():
            component.post_ui_event(component.KEY_DOWN, unicode='t', key='t')

        self.transfer_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH,
                                           image.SM_BUTTON_HEIGHT),
                                      images.transfer,
                                      transfer_callback,
                                      image_label=True,
                                      tool_tip_text="transfer (t)")
        x += image.SM_BUTTON_WIDTH + 4

        def disband_callback():
            component.post_ui_event(component.KEY_DOWN, unicode='x', key='x')

        self.disband_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH,
                                          image.SM_BUTTON_HEIGHT),
                                     images.disband,
                                     disband_callback,
                                     image_label=True,
                                     tool_tip_text="disband (x)")
        self.add_child(self.transfer_button)
        self.add_child(self.disband_button)
        self.transfer_button.hide()
        self.disband_button.hide()

        y = self.disband_button.rect.y + self.disband_button.rect.height + 2

        second_group_rect = Rect(self.rect.x + self.site_rect.width, y,
                                 (3 * self.rect.width) / 4,
                                 self.rect.height - (y - self.rect.y))
        self.garrison_renderer = group_panel.OccupantRenderer(
            "Garrison", second_group_rect, True)
        self.for_hire_renderer = group_panel.HireRenderer(
            "Hire", second_group_rect)

        self.add_child(self.active_group_renderer)
        self.add_child(self.garrison_renderer)
        self.add_child(self.for_hire_renderer)
        self.garrison_renderer.set_partner(self.active_group_renderer)
        self.active_group_renderer.set_partner(self.garrison_renderer)

        x = self.rect.x + 34 + image.UI_ICON_WIDTH + 25
        y = self.rect.y + 50 + image.UNIT_HEIGHT
        self.revolt_icon = Label(
            Rect(x, y, image.UI_ICON_WIDTH, image.UI_ICON_HEIGHT),
            images.revolt,
            image_label=True,
            tool_tip_text="Revolt chance,\nchecked at week start")

        event_manager.add_listener(self.handle_game_events,
                                   event_manager.HEX_SELECTED)
예제 #35
0
class HexInfoRenderer(component.Window):
    '''
    panel that renders info about selected hex, including any site there, any active
    group of characters/units, and garrison, and any units available for hire.
    '''
    def __init__(self, position_rect, images):
        super(HexInfoRenderer, self).__init__(position_rect)

        self.engineering_active = False
        self.selected_hex = None

        # probably need to allow for some padding in these calculations
        self.site_rect = Rect(self.rect.x, self.rect.y, self.rect.width / 4,
                              self.rect.height)

        def hire_callback(toggle_down):
            if toggle_down:
                self.for_hire_renderer.show()
                self.garrison_renderer.hide()
            else:
                self.for_hire_renderer.hide()
                self.garrison_renderer.show()

        def upgrade_callback():
            upgrade_dialog = UpgradeDialog(250, 300, "Site Upgrades",
                                           self.selected_hex.site)
            upgrade_dialog.show()

        x, y = self.site_rect.x + self.site_rect.width / 4, self.site_rect.y + (
            self.site_rect.height * 3) / 4
        width, height = self.site_rect.width / 4, self.site_rect.height / 8
        self.upgrade_button = Button(Rect(x, y, width, height), "Upg.",
                                     upgrade_callback)

        self.hire_button = Toggle(Rect(x + width + 8, y, width, height),
                                  "Hire", hire_callback)

        self.add_child(self.hire_button)
        self.add_child(self.upgrade_button)

        active_group_rect = Rect(self.rect.x + self.site_rect.width,
                                 self.rect.y + 1, (3 * self.rect.width) / 4,
                                 image.UNIT_HEIGHT + 8)
        self.active_group_renderer = group_panel.OccupantRenderer(
            "Active", active_group_rect, False)

        x = active_group_rect.x + (active_group_rect.width) / 2
        y = active_group_rect.y + active_group_rect.height + 12

        def transfer_callback():
            component.post_ui_event(component.KEY_DOWN, unicode='t', key='t')

        self.transfer_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH,
                                           image.SM_BUTTON_HEIGHT),
                                      images.transfer,
                                      transfer_callback,
                                      image_label=True,
                                      tool_tip_text="transfer (t)")
        x += image.SM_BUTTON_WIDTH + 4

        def disband_callback():
            component.post_ui_event(component.KEY_DOWN, unicode='x', key='x')

        self.disband_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH,
                                          image.SM_BUTTON_HEIGHT),
                                     images.disband,
                                     disband_callback,
                                     image_label=True,
                                     tool_tip_text="disband (x)")
        self.add_child(self.transfer_button)
        self.add_child(self.disband_button)
        self.transfer_button.hide()
        self.disband_button.hide()

        y = self.disband_button.rect.y + self.disband_button.rect.height + 2

        second_group_rect = Rect(self.rect.x + self.site_rect.width, y,
                                 (3 * self.rect.width) / 4,
                                 self.rect.height - (y - self.rect.y))
        self.garrison_renderer = group_panel.OccupantRenderer(
            "Garrison", second_group_rect, True)
        self.for_hire_renderer = group_panel.HireRenderer(
            "Hire", second_group_rect)

        self.add_child(self.active_group_renderer)
        self.add_child(self.garrison_renderer)
        self.add_child(self.for_hire_renderer)
        self.garrison_renderer.set_partner(self.active_group_renderer)
        self.active_group_renderer.set_partner(self.garrison_renderer)

        x = self.rect.x + 34 + image.UI_ICON_WIDTH + 25
        y = self.rect.y + 50 + image.UNIT_HEIGHT
        self.revolt_icon = Label(
            Rect(x, y, image.UI_ICON_WIDTH, image.UI_ICON_HEIGHT),
            images.revolt,
            image_label=True,
            tool_tip_text="Revolt chance,\nchecked at week start")

        event_manager.add_listener(self.handle_game_events,
                                   event_manager.HEX_SELECTED)

    def handle_game_events(self, event):
        if event.type == event_manager.HEX_SELECTED:
            self.set_hex(event.data['loc'])

    def set_data(self, map_data, curr_player, curr_mask):
        self.map_data = map_data
        self.curr_mask = curr_mask
        self.curr_player = curr_player
        # reselect hex to reset what's shown according to new player data
        self.set_hex(self.selected_hex)

    def deselect_all(self):
        self.active_group_renderer.mark_selected(None)
        self.garrison_renderer.mark_selected(None)
        self.for_hire_renderer.mark_selected(None)

    def set_hex(self, new_hex_loc):
        self.deselect_all()
        self.upgrade_button.hide()
        self.hire_button.hide()
        self.hire_button.reset()
        self.engineering_active = False
        if new_hex_loc == None:
            return

        self.selected_hex = self.map_data.get_hex(new_hex_loc.x, new_hex_loc.y)
        if self.selected_hex == None:
            return

        self.active_group_renderer.set_data(self.selected_hex,
                                            self.curr_player, self.curr_mask)
        if self.selected_hex.deep_garrison():
            self.garrison_renderer.set_data(None, self.curr_player,
                                            self.curr_mask)
        else:
            self.garrison_renderer.set_data(self.selected_hex,
                                            self.curr_player, self.curr_mask)

        self.for_hire_renderer.set_data(self.selected_hex, self.curr_player,
                                        self.curr_mask)
        self.for_hire_renderer.hide()

        if self.curr_mask.get_visibility(self.selected_hex.x,
                                         self.selected_hex.y) == mask.VISIBLE:
            self.active_group_renderer.show()
            self.garrison_renderer.show()
        else:
            self.active_group_renderer.hide()
            self.garrison_renderer.hide()

        if self.selected_hex.has_site() and self.selected_hex.site.hireable_by(
                self.curr_player):
            self.hire_button.show()

        if self.selected_hex.has_site() and self.selected_hex.site.get_owner(
        ) == self.curr_player:
            self.upgrade_button.show()
            if self.selected_hex.get_active_group() != None:
                self.transfer_button.show()
                self.disband_button.show()
            else:
                self.transfer_button.hide()
                self.disband_button.hide()
        else:
            self.transfer_button.hide()
            self.disband_button.hide()

        self.add_child(self.revolt_icon)
        self.revolt_icon.hide()

    def event_handler(self, event):
        if event.type == component.MOUSE_CLICK:
            self.deselect_all()
            return True

        return super(HexInfoRenderer, self).event_handler(event)

    def render_site(self, surface, images, active_site, curr_player,
                    mask_player):
        x = self.site_rect.x + (self.site_rect.width / 2)
        y = self.site_rect.y + 14
        images.text.draw_text(active_site.get_name(), text.lg_font, x, y,
                              surface)

        y += 16
        images.text.draw_text(
            "Lv. " + str(active_site.level) + " " + active_site.site_type.name,
            text.sm_font, x, y, surface)
        y += 16

        if active_site.status == site_type.SACKED:
            status_text = "Sacked"
        else:
            status_text = active_site.owner.get_name()

        images.text.draw_text(status_text, text.sm_font, x, y, surface)
        #
        y += 10
        x -= image.UNIT_WIDTH / 2
        images.draw_site(active_site, surface, mask_player, (x, y))

        y += image.UNIT_HEIGHT - 10
        icon_y = y
        x = self.rect.x + 30
        if active_site.is_active() and active_site.get_income() != 0:
            surface.blit(images.income, (x, y))
            x += image.UI_ICON_WIDTH + 10
            y += image.UI_ICON_WIDTH / 2
            images.text.draw_text(str(active_site.get_income()), text.sm_font,
                                  x, y, surface)
        x = self.rect.x + 34 + image.UI_ICON_WIDTH + 25
        y = icon_y
        if active_site.is_active() and active_site.revolt_chance() != 0:
            self.revolt_icon.show()
            x = self.revolt_icon.rect.x + image.UI_ICON_WIDTH + 16
            y = self.revolt_icon.rect.y + image.UI_ICON_WIDTH / 2
            images.text.draw_text(
                str(int(active_site.revolt_chance() * 100)) + "%",
                text.sm_font, x, y, surface)
        else:
            self.revolt_icon.hide()

    def render(self, surface, images):
        super(HexInfoRenderer, self).render(surface, images)

        if self.selected_hex == None:
            return

        mask_state = self.curr_mask.get_visibility(self.selected_hex.x,
                                                   self.selected_hex.y)

        if mask_state == mask.NEVER_VISIBLE:
            return

        # render site info
        active_site = self.selected_hex.site
        if active_site != None:
            self.render_site(surface, images, active_site, self.curr_player,
                             self.curr_mask.get_player())

        # render groups in hex
        active_group = self.selected_hex.active_group
        if active_group != None and mask_state == mask.VISIBLE:

            x, y = self.active_group_renderer.rect.x + 4, self.active_group_renderer.rect.y + 24
            if active_group.get_move_mode() == move_mode.NAVAL:
                surface.blit(images.naval_move, (x, y))
            else:
                surface.blit(images.foot_move, (x, y))
            images.text.draw_text(str(active_group.get_moves_left()),
                                  text.lg_font, x + image.UI_ICON_WIDTH + 10,
                                  y + (image.UI_ICON_HEIGHT / 2), surface)

            if active_group.get_owner() == self.curr_player:
                x = self.rect.x + (5 * self.rect.width) / 8
                y = self.rect.y + self.rect.height / 2