Beispiel #1
1
    def backup_attack_loop(self):
        g = self.g
        self.image = self.orginalImage.subsurface((160, 0, 32, 32))

        speed = self.walktimer
        self.walktimer += 1
        if self.walktimer > 6:
            self.walktimer = 6


        self.timer += 1
        timergate = self.timer % 100
        if timergate >= 80:
            if timergate == 80:
                self.face_the_player()
            if timergate == 85:
                Shot(g, self.direction, (self.rect.x + 16, self.rect.y + 8), 'shot8', 'enemy')
            self.walking = 0
        else:
            self.walking = 1
        if timergate % 100 == 0:
            self.face_the_player()

        dx = self.rect.x - g.player.rect.x
        if dx <40 and dx > -40:
            if self.dy == 10.0:
                self.dy = -10.0

        if self.walking:
            self.rect.x += (1 - (self.direction * 2)) * speed
            framen = self.timer / 2  % 3
            self.image = self.orginalImage.subsurface((32 + framen * 32, 0, 32, 32))
        else:
            self.walktimer = 0

        self.dy += .5
        if self.dy > 10.0:
            self.dy = 10.0
        self.rect.y += self.dy

        if self.rect.x < 416:
            self.direction = 0

        
        self.image = pygame.transform.flip(self.image, self.direction, 0)
        # hitting the bullets and player
        s = Rect(self.rect)
        if s.colliderect (g.player.rect):
            g.player.touch(self)
        for b in g.bullets:
            if b.owner == 'player':
                drect = (b.rect.x + 30, b.rect.y )
                if s.collidepoint(drect):
                    b.destroy()
                    self.health -= b.get_damage()
                    e = Effect(self.g, 'health', (self.rect.x, self.rect.y))
                    e.healthchange = -b.get_damage()
                    self.image = g.make_image_white(self.image)
Beispiel #2
0
class Button(GameObject):
    def __init__(self, x, y, w, h, text, button_text_color, font_name, font_size, on_click=lambda x: None, padding=0):
        super().__init__(x, y, w, h)
        self.bounds = Rect(x, y, w, h)
        self.state = 'normal'
        self.on_click = on_click

        self.text = TextObject(self.bounds.x + padding,
                               self.bounds.y + padding, text,
                               button_text_color,
                               font_name,
                               font_size)

    def draw(self, screen):
        pygame.draw.rect(screen,
                         self.back_color,
                         self.bounds)
        self.text.draw(screen)

    def handle_mouse_event(self, type, pos):
        if type == pygame.MOUSEMOTION:
            self.handle_mouse_move(pos)
        elif type == pygame.MOUSEBUTTONDOWN:
            self.handle_mouse_down(pos)
        elif type == pygame.MOUSEBUTTONUP:
            self.handle_mouse_up(pos)

    def handle_mouse_move(self, pos):
        if self.bounds.collidepoint(pos):
            if self.state != 'pressed':
                self.state = 'hover'
        else:
            self.state = 'normal'

    def handle_mouse_down(self, pos):
        if self.bounds.collidepoint(pos):
            self.state = 'pressed'

    def handle_mouse_up(self, pos):
        if self.state == 'pressed':
            self.on_click(self)
            self.state = 'hover'

    @property
    def back_color(self):
        return dict(normal=(0, 255, 0),
                    hover=(255, 255, 255),
                    pressed=(255, 255, 255))[self.state]
Beispiel #3
0
 def choice_button_at_position(self,
                               target_position: Vec2) -> Optional[int]:
     for choice_index, (component, position) in enumerate(
         (c for c in self._components if isinstance(c[0], _ChoiceButton))):
         rect = Rect(position, component.surface.get_size())
         if rect.collidepoint(target_position):
             return choice_index
Beispiel #4
0
def splash_screen():
    running = True
    while running:
        start_rect = Rect(170, 300, 180, 80)
        start_rect2 = Rect(450, 300, 180, 80)
        mouse = pygame.mouse.get_pressed()

        if start_rect.collidepoint(pygame.mouse.get_pos()) and mouse[0]:
            pygame.quit()
            return True

        if start_rect2.collidepoint(pygame.mouse.get_pos()) and mouse[0]:
            pygame.quit()
            running = False
            return False

        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                running = False
                pygame.quit()
                quit()

        screenDisplay.fill(dark_green)
        pygame.draw.polygon(screenDisplay, light_green, backgroundPolygon)
        title(x, y)
        playerimage(playerimagex, playerimagey)

        button_function(170, 300, 180, 80, dark_green, beige)
        button_function(450, 300, 180, 80, dark_green, beige)
        #mousepos = pygame.mouse.get_pos()

        #if 170+180 > mouse[0] > 170 and 300+80 > mouse[1] > 300:
        #   pygame.draw.rect(screenDisplay, greybuttonactive, (170, 300, 180, 80))
        #else:
        #   pygame.draw.rect(screenDisplay, greybuttoninactive, (170, 300, 180, 80))

        #if 450+180 > mouse[0] > 450 and 300+80 > mouse[1] > 300:
        #   pygame.draw.rect(screenDisplay, greybuttonactive, (450, 300, 180, 80))
        #else:
        #   pygame.draw.rect(screenDisplay, greybuttoninactive, (450, 300, 180, 80))

        #start_logo(x_s,y_s)
        #quitt_logo(x_q,x_q)

        pygame.display.update()
        clock.tick(60)
Beispiel #5
0
 def mouse_down(self, point):
     for index, item in enumerate(self.items):
         item_rect = Rect(self.rect.x + self.border_widths,
                          self.rect.y + self.border_widths + item.rect.y,
                          item.rect.w, item.rect.h)
         if item_rect.collidepoint(point):
             self.select(index)
             break
Beispiel #6
0
class Cell(object):
    def __init__(self, x, y, alive):
        self.x = x
        self.y = y
        self.x_pixels = x * cell_x
        self.y_pixels = y * cell_y

        self.rect = Rect(self.x_pixels, self.y_pixels, cell_x, cell_y)

        self.is_alive = alive
        self.was_alive = alive
        self.changed = False
        self.age = 0

        self.neighbours = None

    def set_neighbours(self, neighbours):
        self.neighbours = neighbours

    def before_evolve(self):
        self.changed = False
        self.was_alive = self.is_alive

    def evolve(self):
        alive_neighbour_count = sum(map(lambda n: n.was_alive,
                                        self.neighbours))
        self.is_alive = (self.was_alive and 2 <= alive_neighbour_count <= 3) \
                        or (not self.was_alive and alive_neighbour_count == 3)
        self.changed = self.is_alive != self.was_alive
        if self.changed:
            self.age = 0
        else:
            self.age += 1
        return self.changed

    def render(self, colour=None):
        if not colour:
            if self.is_alive:
                if self.age < 2:
                    colour = GREEN
                elif self.age < 4:
                    colour = YELLOW
                else:
                    colour = RED
            else:
                colour = BLACK
        pygame.draw.rect(screen, colour, self.rect, 0)

    def is_collision(self, pos):
        collision = self.rect.collidepoint(pos)
        return collision

    def on_click(self):
        self.toggle()

    def toggle(self):
        self.is_alive = not self.is_alive
Beispiel #7
0
def player_spot(pos):
    clicking_areas = [[Rect((int(j * w + w / 2 - w / 4), int(i * h + h / 2 - w / 4), w / 2, h / 2)) for i in range(3)]
                      for j in range(3)]
    for i, eaches in enumerate(clicking_areas):
        for j, each in enumerate(eaches):
            if Rect.collidepoint(each, pos[1], pos[0]):
                return i, j
    else:
        return None
Beispiel #8
0
Datei: ui.py Projekt: BUS410/Life
class Widget:
    def __init__(self, **kwargs):
        self.rect = Rect(kwargs.get('x', 0), kwargs.get('y', 0),
                         kwargs.get('width', 200), kwargs.get('height', 50))
        self.image = Surface((self.rect.width, self.rect.height))
        self.background_image = kwargs.get('background_image', 0)
        self.background_image_pos = kwargs.get('background_image_pos', (0, 0))
        self.background_color = kwargs.get('background_color', (32, 32, 32))
        self.background_color_cover = kwargs.get('background_color_cover',
                                                 self.background_color)
        self.background_color_click = kwargs.get('background_color_click',
                                                 self.background_color)
        self.text = kwargs.get('text', '')
        self.font_size = kwargs.get('font_size', 20)
        self.font_color = kwargs.get('font_color', (255, 255, 255))
        self.font_pos = kwargs.get('font_pos', None)
        self.font = SysFont('segoeui', self.font_size, 1)
        self.image.fill(self.background_color)
        self.onclick = kwargs.get('onclick', lambda: None)

    def show(self, surface):
        if self.background_image:
            self.image.blit(self.background_image, self.background_image_pos)
        font = self.font.render(self.text, 1, self.font_color)
        pos = self.font_pos or [
            (self.rect.width - font.get_rect().width) // 2,
            (self.rect.height - font.get_rect().height) // 2
        ]
        self.image.blit(font, pos)
        surface.blit(self.image, (self.rect.x, self.rect.y))

    def _onclick(self):
        self.onclick()

    def update(self, events):
        if self.rect.collidepoint(*get_mouse_pos()) and get_mouse_pressed()[0]:
            self.image.fill(self.background_color_click)
        elif self.rect.collidepoint(*get_mouse_pos()):
            self.image.fill(self.background_color_cover)
            for event in events:
                if event.type == MOUSEBUTTONUP:
                    self._onclick()
        else:
            self.image.fill(self.background_color)
Beispiel #9
0
class Button(GameSprite):
    def __init__(self, x, y, kind, resourcemgr):
        super(Button, self).__init__(x, y, kind, resourcemgr)
        set_button_stats(self)
        self.rect = Rect(x, y, self.w, self.h)
        self.was_hit = False
        self.set_areas()
        self.area = self.areas[MOUSE_POS.OUT]

    def set_areas(self):
        self.areas = {}
        self.areas[MOUSE_POS.OVER] = pygame.Rect(0, 0, self.rect.w,
            self.rect.h)
        self.areas[MOUSE_POS.OUT] = pygame.Rect(self.rect.w, 0, self.rect.w,
            self.rect.h)
        self.areas[MOUSE_POS.DOWN] = pygame.Rect(0, self.rect.h, self.rect.w,
            self.rect.h)
        self.areas[MOUSE_POS.UP] = pygame.Rect(self.rect.w, self.rect.h,
            self.rect.w, self.rect.h)

    def input(self, event):
        x, y = pygame.mouse.get_pos()

        if event.type == MOUSEMOTION:
            if self.rect.collidepoint(x, y):
                self.area = self.areas[MOUSE_POS.OVER]
            else:
                self.area = self.areas[MOUSE_POS.OUT]

        if event.type == MOUSEBUTTONDOWN and \
            event.button == MOUSE.LEFT and self.rect.collidepoint(x, y):
            self.area = self.areas[MOUSE_POS.DOWN]
        if event.type == MOUSEBUTTONUP and event.button == MOUSE.LEFT \
            and self.rect.collidepoint(x, y):
            self.area = self.areas[MOUSE_POS.UP]
            self.was_hit = True

    def render(self):
        self.resourcemgr.screen.blit(self.image, self.rect, self.area)
    def eat(self, snake):
        food = Rect(self.food_pos[0], self.food_pos[1], 10, 10)
        if food.collidepoint(snake.position[0], snake.position[1]):
            tail = snake.body[-1]
            horizontal_tail = tail[1] == snake.body[-2][1]
            vertical_tail = tail[0] == snake.body[-2][0]

            if horizontal_tail:
                change = -10 if snake.direction == 'RIGHT' else 10
                snake.body.append([tail[0] + change, tail[1]])
            elif vertical_tail:
                change = -10 if snake.direction == 'DOWN' else 10
                snake.body.append([tail[0], tail[1] + change])

            self.score += 1
            self.food_spawn()
    def draw_board(self):

        image_indexes = {None: 0, O: 1, X: 2}

        for row in range(3):
            for col in range(3):

                board_index = row * 3 + col

                # Cell rectangle
                cell = Rect(TILE_WIDTH * col, TILE_HEIGHT * row, TILE_WIDTH,
                            TILE_HEIGHT)

                # Check if mouse is over a cell
                mouse_over = self.mouse_pos is not None and cell.collidepoint(
                    self.mouse_pos)

                # Winner movement
                if self.game.winner and board_index in self.game.winner_movement:
                    fill_index = image_indexes[self.game.board[board_index]]
                    state_index = 3
                    self.screen.blit(self.tileset[fill_index][state_index],
                                     cell)

                # Mouse interaction
                elif mouse_over and self.is_human_turn():
                    if self.game.board[board_index] == None:
                        fill_index = image_indexes[self.game.turn]
                        state_index = 1
                    else:
                        fill_index = image_indexes[
                            self.game.board[board_index]]
                        state_index = 2
                    self.screen.blit(self.tileset[fill_index][state_index],
                                     cell)

                # Normal rendering
                else:
                    fill_index = image_indexes[self.game.board[board_index]]
                    if self.game.winner == False:  # Draw
                        state_index = 2
                    else:
                        state_index = 0
                    self.screen.blit(self.tileset[fill_index][state_index],
                                     cell)

        pygame.display.flip()
    def draw_board(self):

        image_indexes = {
            None: 0,
            O: 1,
            X: 2
        }

        for row in range(3):
            for col in range(3):

                board_index = row * 3 + col

                # Cell rectangle
                cell = Rect(TILE_WIDTH * col, TILE_HEIGHT * row, TILE_WIDTH, TILE_HEIGHT)

                # Check if mouse is over a cell
                mouse_over = self.mouse_pos is not None and cell.collidepoint(self.mouse_pos)

                # Winner movement
                if self.game.winner and board_index in self.game.winner_movement:
                    fill_index = image_indexes[self.game.board[board_index]]
                    state_index = 3
                    self.screen.blit(self.tileset[fill_index][state_index], cell)

                # Mouse interaction
                elif mouse_over and self.is_human_turn():
                    if self.game.board[board_index] == None:
                        fill_index = image_indexes[self.game.turn]
                        state_index = 1
                    else:
                        fill_index = image_indexes[self.game.board[board_index]]
                        state_index = 2
                    self.screen.blit(self.tileset[fill_index][state_index], cell)

                # Normal rendering
                else:
                    fill_index = image_indexes[self.game.board[board_index]]
                    if self.game.winner == False: # Draw
                        state_index = 2
                    else:
                        state_index = 0
                    self.screen.blit(self.tileset[fill_index][state_index], cell)

        pygame.display.flip()
    def selectatmouse(self):
        # User has touched the screen - is it inside the textbox, or inside a key rect?
        self.unselectall()
        pos = pygame.mouse.get_pos()
#        print 'touch {}'.format(pos)
        if self.input.rect.collidepoint(pos):
#            print 'input {}'.format(pos)
            self.input.setcursor(pos)
        else:
            for key in self.keys:
                keyrect = Rect(key.x, key.y, key.w, key.h)
                if keyrect.collidepoint(pos):
                    key.selected = True
                    key.dirty = True
                    self.paintkeys()
                    return

        self.paintkeys()        
Beispiel #14
0
class Button(MouseListener):
    def __init__(self, text, position, dimensions):
        self._hovered = False
        self._mouse_downed = False
        self._label = Label(position,
                            dimensions,
                            text,
                            font_size=dimensions[1],
                            padding=(constants.BUTTON_TEXT_PADDING,
                                     constants.BUTTON_TEXT_PADDING))
        self._hit_box = Rect(position, dimensions)
        self._position = position
        self._dimensions = dimensions
        super().__init__()

    def handle_mouse_motion(self, coords):
        self._hovered = self._hit_box.collidepoint(coords)

    def handle_mouse_button_up(self, coords):
        clicked = False

        if self._hovered and self._mouse_downed:
            clicked = True
        self._mouse_downed = False
        self._hovered = False
        return clicked

    def handle_mouse_button_down(self, coords):
        if self._hovered:
            self._mouse_downed = True

    def draw(self, screen):
        if self._hovered:
            border = constants.GREY
            background = constants.WHITE
        else:
            border = constants.WHITE
            background = constants.GREY
        screen.fill(border, self._hit_box)
        screen.fill(
            background,
            self._hit_box.inflate(-constants.BUTTON_BORDER_WEIGHT,
                                  -constants.BUTTON_BORDER_WEIGHT))
        self._label.draw(screen)
Beispiel #15
0
    def check_input_line_collision(self, pos):
        for p in self.inputs:
            if self.inputs[p]:
                obj, pin = self.inputs[p]
                if isinstance(obj, Invisible):
                    continue

                start = self.input_xy[p]
                end = obj.output_xy[pin]
                #basic rect TODO
                offset = self.parent.canvas.style["d_line_col"]
                
                x = min((start[0], end[0])) - offset
                y = min((start[1], end[1])) - offset
                w = abs(start[0] - end[0]) + offset * 2
                h = abs(start[1] - end[1]) + offset * 2
                
                basic = Rect(x, y, w, h)
                
                if basic.collidepoint(pos):
                
                    dx = end[0] - start[0]
                    dy = end[1] - start[1]
                    
                    if dx == 0 and dy == 0:
                        return False
                    
                    if abs(dx) < abs(dy):
                        k = float(dx) / float(dy)
                        x = start[0] + k * (pos[1] - start[1])
                
                        if abs(x - pos[0]) < offset:
                            return self, p, obj, pin                      
                    else:
                        k = float(dy) / float(dx)
                        y = start[1] + k * (pos[0] - start[0])
                        
                        if abs(y - pos[1]) < offset:
                            return self, p, obj, pin
        return False 
    def clickatmouse(self):
        ''' Check to see if the user is pressing down on a key and draw it selected '''
        self.unselectall()
        for key in self.keys:
            keyrect = Rect(key.x, key.y, key.w, key.h)
            if keyrect.collidepoint(pygame.mouse.get_pos()):
                key.dirty = True
                if key.bskey:
                    # Backspace
                    self.input.backspace()
                    self.paintkeys() 
                    return False
                if key.fskey:
                    self.input.inccursor()
                    self.paintkeys() 
                    return False
                if key.spacekey:                    
                    self.input.addcharatcursor(' ')
                    self.paintkeys() 
                    return False
                if key.shiftkey:
                    self.togglecaps()
                    self.paintkeys() 
                    return False
                if key.escape:
                    self.input.text = ''  # clear input
                    return True
                if key.enter:
                    return True
                if self.caps:
                    keycap = key.caption.translate(Uppercase)
                else:
                    keycap = key.caption
                self.input.addcharatcursor(keycap)
                self.paintkeys()
                return False

        self.paintkeys() 
        return False
Beispiel #17
0
    def loop_hit_death(self, g, r, canbehit, canhitplayer):
        self.timer += 1
        self.image = pygame.transform.flip(self.image, self.direction, 0)

        s = Rect(self.rect)
        if self.mode != 'death':
            if s.colliderect (g.player.rect):
                if canhitplayer:
                    g.player.touch(self)

        if canbehit:
            for b in g.bullets:
                if b.owner == 'player':
                    drect = (b.rect.x, b.rect.y)
                    if s.collidepoint(drect):
                        b.destroy()
                        self.health -= b.get_damage()
                        e = Effect(self.g, 'health', (self.rect.x, self.rect.y))
                        e.healthchange = -b.get_damage()
                        if self.mode != 'ouch':
                            self.birdhit.play()
                        self.mode = 'ouch'
                        self.btimer = 0
            #k = Rect(b.rect)
            #k.x -= g.view.x
            #k.y -= g.view.y
            #pygame.draw.rect(g.screen, (0,255,255), k)
        #s.x -= g.view.x
        #s.y -= g.view.y
        #pygame.draw.rect(g.screen, (255,0,255), s)
        

        # dead
        if self.health <= 0:
            if self.mode != 'death':
                self.mode = 'death'
                self.btimer = 0
 def mouse_down(self, point):
     for index, item in enumerate(self.items):
         item_rect = Rect(self.rect.x, self.rect.y + item.rect.y, item.rect.w, item.rect.h)
         if item_rect.collidepoint(point):
             self.select(index)
             break
Beispiel #19
0
def is_boat_collide_setpoint(
        setpoint_rectangle: Rect, location_coordinates: tuple[float,
                                                              float]) -> boat:
    return setpoint_rectangle.collidepoint(
        converter_utils.convert_coordinates(location_coordinates,
                                            Y_WINDOW_SIZE))
Beispiel #20
0
font2 = pygame.font.SysFont('Serif', 30)
score_font = pygame.font.SysFont('Serif', 20)
final_font = pygame.font.SysFont('Serif', 60)

# game over text
textSurface = myfont.render('GAME OVER!', False, white)
text2 = font2.render('evarywan s ded ur bad lol', False, white)

score = (population + morale) - diseased
scores = {"Population": population, "Diseased": diseased, "Morale": morale}
final_score = final_font.render("Score: " + str(score), False, (0, 153, 51))

ret_pos = (250, 500)

ret_position = Rect(220, 480, 400, 80)
ret_position.collidepoint(pygame.mouse.get_pos())

is_running = True
title = False
while is_running:

    ourDisplay.fill((0, 0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = event.pos
            if ret_position.collidepoint(mouse_pos):
                is_running = False
                title = True
Beispiel #21
0
class Player(Sprite):
    """ Player object. 

    """

    pos = (0, 0)
    health = 4
    healthmax = 4

    gravity = 0
    canjump = 0
    framecount = 0
    direction = 0
    looking = 0
    staylooking = 0
    animation = 0
    shotwait = 0
    shotcounter = 0
    imortal = 0  # after being hit by a enimy, this will be a timer down
    dx = 0
    snowwalk = 0
    hidden = 0
    jumpshoot = 0  # jumping while shooting
    maxspeed = SPEED_MAX
    jump_gravity = 15
    dieanimation = 0  # a special hack when you're drowing in after defeating robot

    def __init__(self, g, t):
        g.clayer[t.ty][t.tx] = 0
        self.rect = Rect(t.rect.x + 16 - g.view.x, t.rect.y - g.view.y, 32, 32)
        Sprite.__init__(self, g.images["player"], self.rect)
        self.renderoffset = (-13, 0)  # must be called after sprite init

        g.sprites.append(self)
        g.removeOnLeave.append(self)
        self.groups = g.string2groups("player")
        g.player = self
        g.infobox = 0
        self.orginalImage = self.image

        hitSoundFile = os.path.join("effects", "hit.wav")
        self.hitSound = pygame.mixer.Sound(hitSoundFile)
        hitSoundFile = os.path.join("effects", "ground.wav")
        self.hitground = pygame.mixer.Sound(hitSoundFile)
        hitSoundFile = os.path.join("effects", "jump.wav")
        self.jumpsound = pygame.mixer.Sound(hitSoundFile)

        if g.loadPosition != None:
            pop = g.tile_to_screen(g.loadPosition)
            self.rect.x = pop[0] + g.view.x
            self.rect.y = pop[1] + g.view.y
            g.loadPosition = None
        self.g = g
        self.health = g.saveData["health"]
        self.healthmax = g.saveData["healthmax"]
        self._rect.x, self._rect.y = self.rect.x, self.rect.y
        self.jumping = 0
        self.rect.width = 8
        # place the camera on the player
        if not g.intermission:
            if self.rect.x > g.view.width:
                g.view.x = self.rect.x - g.view.width / 2
            if self.rect.y > g.view.height:
                g.view.y = self.rect.y - g.view.height / 2

    # you get a skyberry
    def get_skyberry(self):
        # add to the weapon
        if "weapon" in self.g.saveData:
            if self.g.saveData["weapon"] >= 1:
                wpnstr = "shot" + str(self.g.saveData["weapon"]) + "_lvl"
                if self.g.saveData[wpnstr] == 10:
                    Effect(self.g, "msg", (self.rect.x, self.rect.y), "Level Up!")
                if self.g.saveData[wpnstr] == 20:
                    Effect(self.g, "msg", (self.rect.x, self.rect.y), "Level Up!")
                if self.g.saveData[wpnstr] >= 30:  # limit = 30
                    return
                self.g.saveData[wpnstr] += 1

    # touching an enemy
    def touch(self, e):
        if self.imortal == 0:
            self.g.hurt.play()
            self.imortal = 10
            self.health -= e.get_damage()
            ef = Effect(self.g, "health", (self.rect.x, self.rect.y))
            ef.healthchange = -e.get_damage()
            # drop some skyberries
            if "weapon" in self.g.saveData:
                if self.g.saveData["weapon"] >= 1:
                    wpnstr = "shot" + str(self.g.saveData["weapon"]) + "_lvl"
                    if self.g.saveData[wpnstr] > 1:
                        self.g.saveData[wpnstr] -= 1
                        if self.g.saveData[wpnstr] == 9:
                            Effect(self.g, "msg", (self.rect.x, self.rect.y), "Level Down")
                        if self.g.saveData[wpnstr] == 19:
                            Effect(self.g, "msg", (self.rect.x, self.rect.y), "Level Down")
                        sb = Inventory(self.g, "skyberry", (self.rect.x, self.rect.y))
                        sb.canget = 0
                        sb = Inventory(self.g, "skyberry", (self.rect.x, self.rect.y))
                        sb.canget = 0
                        sb = Inventory(self.g, "skyberry", (self.rect.x, self.rect.y))
                        sb.canget = 0

            self.g.player.gravity = 15
            self.g.player.jumping = 1
            if self.g.saveData["weapon"] != 0:
                shotType = "shot" + str(self.g.saveData["weapon"])
                self.g.saveData[shotType] -= 1
            self.g.saveData["health"] = self.health

    # upon each loop
    def loop(self, g, r):
        if g.dead == 1:
            self.image = self.orginalImage.subsurface((0, 0, 0, 0))
            return

        keys = pygame.key.get_pressed()
        dy = 0
        self.pos = g.screen_to_tile((g.player.rect.x - g.view.x + 8, g.player.rect.y - g.view.y + 16))
        faced = 0
        aimup, aimdown = 0, 0
        shooting = 0

        # move the player
        if g.intermission == 0:
            jumpkeydown = 0
            if keys[K_DOWN]:
                faced = 1
                if g.infobox:
                    self.staylooking = 1
                if self.jumpshoot:
                    aimdown = 1
            if keys[K_UP]:
                faced = 2
                # jump
                aimup = 1
            if keys[K_LEFT]:
                faced = 0
                self.staylooking = 0
                self.dx -= SPEED
                self.direction = 1
                if g.player.canjump:
                    self.framecount += 1
            if keys[K_RIGHT]:
                faced = 0
                self.staylooking = 0
                self.dx += SPEED
                self.direction = 0
                if g.player.canjump:
                    self.framecount += 1
            if keys[K_LEFT] and keys[K_RIGHT]:
                self.framecount = 0
            if keys[K_z]:
                if g.player.canjump == 1 and g.player.gravity == 0 and g.disable_fire == 0:
                    g.player.canjump = 0
                    g.player.gravity += self.jump_gravity
                    g.player.jumping = 1
                    self.jumpsound.play()
            if keys[K_x]:
                # firing code
                shooting = 1
                if g.level.weapon_gui == 0 and g.level.inventory_gui == 0:
                    if "weapon" in g.saveData and g.disable_fire == 0:
                        if self.shotcounter <= 0 and g.saveData["weapon"] > 0:
                            xoffset = (not self.direction) * 2
                            shottype = "shot" + str(g.saveData["weapon"])
                            sdirection = self.direction
                            if aimup:
                                sdirection = 2
                            if aimdown:
                                sdirection = 3
                            s = None
                            if shottype == "shot2":
                                s = Shot2(g, sdirection, (self.rect.x - xoffset, self.rect.y + 20))
                            elif shottype == "shot4":
                                s = Shot4(g, sdirection, (self.rect.x - xoffset, self.rect.y + 20))
                            else:
                                s = Shot(g, sdirection, (self.rect.x - xoffset, self.rect.y + 20), shottype)
                            s.invisible_timer = 1
                            self.shotcounter += s.get_reload_time()
            self.jumpshoot = 0
            if jumpkeydown == 0 and self.canjump == 0:
                self.jumpshoot = 1
            if g.disable_fire != 0:
                g.disable_fire += 1
                if g.disable_fire > 3:
                    g.disable_fire = 0
            # the gui disables firing
            # if not keys[K_z]:
            #    g.disable_fire = 0
            # if not keys[K_x]:
            #    g.disable_fire = 0
        # not walking
        if not keys[K_LEFT] and not keys[K_RIGHT]:
            self.framecount = 0

        # not going anywhere
        if keys[K_LEFT] and keys[K_RIGHT]:
            if self.dx > 0:
                self.dx -= SPEED
            if self.dx < 0:
                self.dx += SPEED
        if g.intermission:
            self.dx = 0

        if not keys[K_RIGHT] and self.dx > 0:
            self.dx -= SPEED
        if not keys[K_LEFT] and self.dx < 0:
            self.dx += SPEED

        if self.dx > self.maxspeed:
            self.dx = self.maxspeed
        if self.dx < -self.maxspeed:
            self.dx = -self.maxspeed

        # move camera with player
        if not g.intermission:
            if g.player.rect.x - g.view.x > SW - 200 and self.dx > 0:
                g.view.x += self.dx
            if g.player.rect.x - g.view.x < 200 and self.dx < 0:
                g.view.x += self.dx
            if g.player.rect.y - g.view.y > SH - 180:

                if self.maxspeed < dy - g.player.gravity:

                    g.view.y += dy - g.player.gravity
                else:
                    g.view.y += self.maxspeed
            if g.player.rect.y - g.view.y < 100:
                g.view.y -= self.maxspeed

        weaponvisible = 0
        if "weapon" in g.saveData:
            if g.saveData["weapon"] != 0:
                weaponvisible = 1

        # animation
        iw, ih = g.player.image.get_width(), g.player.image.get_height()
        if weaponvisible == 0 or self.dieanimation == 1:
            g.player.image = g.player.orginalImage.subsurface((iw * ((self.framecount / 3) % 5), 0, 32, 32))

            if g.following:
                # draw hand
                if g.connected == 1 and self.direction == 1:
                    g.player.image = pygame.Surface((32, 32), SRCALPHA)
                    g.player.image.blit(
                        g.player.orginalImage.subsurface((iw * ((self.framecount / 3) % 5), 6 * 32, 32, 32)), (0, 0)
                    )
                    g.player.image.blit(g.player.orginalImage.subsurface((2 * 32, 4 * 32, 32, 32)), (7, 0))
                    g.player.image = pygame.transform.flip(g.player.image, self.direction, 0)

            # looking forward
            if faced == 1 or self.staylooking:
                g.player.image = g.player.orginalImage.subsurface((5 * 32, 0, 32, 32))
            if faced == 2:
                g.player.image = g.player.orginalImage.subsurface((1 * 32, 32, 32, 32))
            # animations...
            if self.animation == 1:
                g.player.image = g.player.orginalImage.subsurface((6 * 32, 0, 32, 32))
            elif self.animation == 2:
                g.player.image = g.player.orginalImage.subsurface((7 * 32, 0, 32, 32))
            elif self.animation == 3:
                g.player.image = g.player.orginalImage.subsurface((0 * 32, 32, 32, 32))
            g.player.image = pygame.transform.flip(g.player.image, self.direction, 0)
        else:
            if self.direction == 0:
                g.player.image = g.player.orginalImage.subsurface((iw * ((self.framecount / 3) % 5), 2 * 32, 32, 32))
            else:
                if g.following:
                    g.player.image = pygame.Surface((32, 32), SRCALPHA)
                    g.player.image.blit(
                        g.player.orginalImage.subsurface((iw * ((self.framecount / 3) % 5), 5 * 32, 32, 32)), (0, 0)
                    )

                    # draw hand
                    if g.connected == 1 and self.direction == 1:
                        g.player.image.blit(g.player.orginalImage.subsurface((2 * 32, 4 * 32, 32, 32)), (7, 0))
                else:
                    g.player.image = g.player.orginalImage.subsurface(
                        (iw * ((self.framecount / 3) % 5), 3 * 32, 32, 32)
                    )
            # looking forward
            if (faced == 1 or self.staylooking) and not shooting and not self.jumping:
                if self.direction == 0:
                    g.player.image = g.player.orginalImage.subsurface((5 * 32, 2 * 32, 32, 32))
                else:
                    g.player.image = g.player.orginalImage.subsurface((5 * 32, 3 * 32, 32, 32))
            if faced == 2:
                if self.direction == 0:
                    g.player.image = g.player.orginalImage.subsurface((4 * 32, 1 * 32, 32, 32))
                else:
                    g.player.image = g.player.orginalImage.subsurface((5 * 32, 1 * 32, 32, 32))
            if self.jumping == 1:
                if self.direction == 0:
                    g.player.image = g.player.orginalImage.subsurface((6 * 32, 2 * 32, 32, 32))
                else:
                    g.player.image = g.player.orginalImage.subsurface((6 * 32, 3 * 32, 32, 32))
            if aimup:
                if self.direction:
                    self.image = g.player.orginalImage.subsurface((5 * 32, 1 * 32, 32, 32))
                else:
                    self.image = g.player.orginalImage.subsurface((4 * 32, 1 * 32, 32, 32))
            if aimdown:
                if self.direction:
                    self.image = g.player.orginalImage.subsurface((7 * 32, 1 * 32, 32, 32))
                else:
                    self.image = g.player.orginalImage.subsurface((6 * 32, 1 * 32, 32, 32))
        if g.player.gravity == 0:
            self.jumping = 0
        self.looking = faced
        g.infobox = 0

        if self.hidden == 1:
            self.image = self.orginalImage.subsurface((0, 0, 0, 0))

        # getting shot
        for b in g.bullets:
            if b.owner == "enemy":
                drect = (b.rect.x, b.rect.y)
                if self.rect.collidepoint(drect):
                    self.touch(b)

        # edge
        g.player.gravity -= GRAVITY
        if g.player.gravity < MAXVEL:
            g.player.gravity = MAXVEL
        self.rect.x += self.dx
        self.rect.y += dy - g.player.gravity
        # self.rect.clamp_ip(g.view)

        # dead ...
        if self.health <= 0 and not g.dead:
            g.dead = 1
            g.exp2.play()
        if self.imortal > 0:
            if self.imortal / 5 % 2 == 0:
                g.player.image = g.make_image_white(g.player.image)
            self.imortal -= 1

        # getting demoted
        if self.g.saveData["weapon"] > 1:
            shottype = "shot" + str(self.g.saveData["weapon"])
            if self.g.saveData[shottype] == 0:
                if self.g.saveData["weapon"] == 2:
                    self.g.saveData["weapon"] = 1
                elif self.g.saveData["weapon"] == 4:
                    self.g.saveData["weapon"] = 2
                elif self.g.saveData["weapon"] == 7:
                    self.g.saveData["weapon"] = 4
                else:
                    print "weapon not down graded"

        # reloading the gun
        if self.shotcounter > 0:
            self.shotcounter -= 1

    # hitting the ground
    def hit_ground(self):
        if self.gravity <= -14:
            self.hitground.play()
        if self.gravity <= -2:
            if self.snowwalk == 1:
                self.snowwalk = 0
                Effect(self.g, "snow", (self.rect.x - 8, self.rect.y + 8))
                Effect(self.g, "snow", (self.rect.x - 8, self.rect.y + 8))

    # adds some health to the player
    def addHealth(self, n):
        self.health += n
        ef = Effect(self.g, "health", (self.rect.x, self.rect.y - 10))
        ef.healthchange = n
        if self.health > self.healthmax:
            self.health = self.healthmax
        self.g.saveData["health"] = self.health
Beispiel #22
0
def translate_screen_to_ui_coordinates(
        ui_rect: Rect, screen_coordinates: Vec2) -> Optional[Vec2]:
    if ui_rect.collidepoint(screen_coordinates[0], screen_coordinates[1]):
        return screen_coordinates[0] - ui_rect.x, screen_coordinates[
            1] - ui_rect.y
Beispiel #23
0
class Label(MenuObjectWithText):

    text_str: str = None
    text_color: tuple = None
    is_text_underlined: bool = None  # Подчёркнут ли текст

    font: Font = None  # Шрифт, используемый для отрисовки текста
    font_size: int = None  # Размер шрифта
    text_surf: Surface = None  # Отрисовываемый текст
    text_size: tuple = None  # Размер места, занимаемого текстом

    alignment: int = None  # Выравнивание текста

    has_text_changed = None  # Изменился ли текст, чтобы его нужно было вновь render-ить?

    def __init__(self, window_surface: Surface, pos: tuple = None, text: str = None,
                 text_color: tuple = None, function=None, font_size: int = None, font: str = None,
                 alignment: int = None):
        self.window_surface = window_surface
        self.rect = Rect(0, 0, 100, 50)  # Стандартные размер и положение кнопки
        if pos is not None:
            self.set_pos(pos[0], pos[1], pos[2], pos[3])

        if text is not None:
            self.set_text(text)
        else:
            self.set_text("Label")  # Стандартный текст кнопки

        if text_color is not None:
            self.set_text_color(text_color)
        else:
            self.set_text_color(BLACK)  # Стандартный цвет текста кнопки

        if function is not None:
            self.add_function_onClick(function)
            self.is_text_underlined = True
        else:
            self.is_text_underlined = False

        if font_size is not None:
            self.set_font_size(font_size)
        else:
            self.set_font_size(16)

        if alignment is not None and alignment in ALIGNMENTS:
            self.alignment = alignment

        # Работа с текстом:
        self.set_font(self.font_size, font)  # Стандартный шрифт
        self.label_render_text()

    def set_text(self, text: str):
        if self.text_str is None or text != self.text_str:
            self.text_str = text
            self.has_text_changed = True

    def set_text_color(self, text_color: tuple):
        self.text_color = text_color
        self.has_text_changed = True

    def label_render_text(self):
        self.font.set_underline(self.is_text_underlined)
        super().render_text(self.text_str, self.text_color)

    def handle_event(self, event):
        """
        Обработка события кнопкой.
        """
        if event.type == MOUSEBUTTONUP:
            if self.function_onClick is not None and self.rect.collidepoint(event.pos[0], event.pos[1]):
                for fun in self.function_onClick:
                    fun()
                self.set_text_color(CLICKED_LINK_COLOR)

    def draw(self):
        if not self.alignment:
            self.window_surface.blit(self.text_surf,
                                     (self.rect.x + (self.rect.w / 2) - (self.text_size[0] / 2),
                                      self.rect.y + (self.rect.h / 2) - (self.text_size[1] / 2)))
        else:
            if self.alignment == LEFT_ALIGNMENT:
                # Выравнивание по левому краю
                self.window_surface.blit(self.text_surf,
                                         (self.rect.x,
                                          self.rect.y + (self.rect.h / 2) - (self.text_size[1] / 2)))

    def update(self):
        """
        Проверка на изменение текста. Происходит каждый такт игры.
        """
        if self.has_text_changed:
            self.label_render_text()
Beispiel #24
0
def mouse_in_area(rect: Rect, mouse_pos: ()):
    """Returns True if the rect collides with the mouse pointer location (if coordinates are the same)"""
    return rect.collidepoint(mouse_pos[0], mouse_pos[1])
Beispiel #25
0
class Controller:
    """The object that represents the input processing, logic and visuals

    Should be fully modular. May be dependent on other controllers, but
    nothing else.

    Accepts rectangle parameters. Do not pass the rectangle directly.
    """
    def __init__(self, x, y, width, height, controller_info):
        self.rectangle = Rect(x, y, width, height)
        self.children = []
        self.view = None
        self.parent = None
        self.mouse_pos = None
        self.events: EventList = None
        self.visible = True

        self._unpack_controller_info(controller_info)

    def _unpack_controller_info(self, controllerinfo):
        assert controllerinfo.config
        assert controllerinfo.publisher
        self.config = controllerinfo.config
        self.publisher = controllerinfo.publisher
        self.create_event_list_from(self.publisher)

    def create_event_list_from(self, publisher):
        self.events = publisher.create_event_list()
        for child in self.children:
            child.create_event_list_from(publisher)

    def topmost_controller_at(self, pos):
        local_pos = self.get_local_pos(pos)
        # latest controllers have highest priority (overlap earlier ones)
        for controller in reversed(self.get_visible_controllers()):
            if controller.overlaps_with(local_pos):
                return controller.topmost_controller_at(local_pos)
        # overlap is by rectangle which has its own x and y
        # therefore, compare overlap with parent pos instead of local post
        assert local_pos[0] >= 0 and local_pos[1] >= 0
        self.mouse_pos = local_pos
        return self

    def get_local_pos(self, pos):
        x, y = pos
        return x - self.rectangle.x, y - self.rectangle.y

    def receive_mouseclick(self, mouse_pos):
        controller = self.topmost_controller_at(mouse_pos)
        if controller:
            controller.handle_mouseclick()

    def receive_right_mouseclick(self, mouse_pos):
        controller = self.topmost_controller_at(mouse_pos)
        if controller:
            controller.handle_right_mouseclick()

    def receive_mouseover(self, mouse_pos):
        controller = self.topmost_controller_at(mouse_pos)
        if controller:
            controller.handle_mouseover()

    def receive_keypress(self, key):
        if not self.visible:
            return
        for controller in self.children:
            # right now all controllers listen to a keypress
            # only one controller should handle a keypress
            controller.receive_keypress(key)
        self.handle_keypress(key)

    def overlaps_with(self, mouse_pos):
        x, y = mouse_pos
        return self.rectangle.collidepoint(x, y)

    def attach_controller(self, controller):
        assert self.view != controller.view
        self.children.append(controller)
        controller.parent = self
        controller.view.parent = self.view
        self.view.add_child_view(controller.view)
        return controller

    def add_view(self, view_class, *args):
        self.view = view_class(self.rectangle, *args)
        self.view.initialize_background()
        return self.view

    def show(self):
        logging.info(f'Showing {self}')
        self._set_visibility(True)

    def hide(self):
        logging.info(f'Hiding {self}')
        self._set_visibility(False)

    def _set_visibility(self, visibility):
        self.visible = visibility
        if self.view:
            self.view.visible = visibility
            # for showing, just update view, for hiding, update parent view also
            if self.visible:
                self.view.queue_for_background_update()
            else:
                if self.parent and self.parent.view:
                    self.parent.view.queue_for_background_update()

    def update_view(self):
        if self.view:
            self.view.update_background()
        # for controller in self.get_visible_controllers():
        #     controller.update_view()

    def get_visible_controllers(self):
        visible_controllers = []
        for controller in self.children:
            if controller.visible:
                visible_controllers.append(controller)
        return visible_controllers

    def freeze_events(self):
        self.events.freeze()

    def unfreeze_events(self):
        self.events.unfreeze()

    def append_callback(self, callback, *args, name=None):
        assert callable(callback)
        self.events.subscribe()
        self.events.append(EventCallback(callback, *args, name=name))

    def append_event(self, event):
        assert self.events is not None
        self.events.subscribe()
        self.events.append(event)

    def click(self):
        """Shorthand, use in tests etc"""
        self.handle_mouseclick()

    def handle_keypress(self, key):
        """Actions a controller should do when key is pressed"""

    def handle_mouseclick(self):
        """Actions a controller should do on a left mouseclick"""

    def handle_right_mouseclick(self):
        """Actions a controller should do on a right mouseclick"""

    def handle_mouseover(self):
        """Actions a controller should do on a mouseover"""

    def __str__(self):
        return self.__class__.__name__

    def __repr__(self):
        return str(self)
Beispiel #26
0
class Client_game:
    def __init__(self, caption, width, height, back_image_filename, frame_rate,
                 checkers_count_line):
        self.background_image = pygame.image.load(back_image_filename)
        self.frame_rate = frame_rate
        self.game_over = False
        pygame.mixer.pre_init(44100, 16, 2, 4096)
        pygame.init()
        pygame.font.init()
        self.surface = pygame.display.set_mode((width, height))
        self.bounds = Rect(0, 0, width, height)
        self.state = ""
        pygame.display.set_caption(caption)
        self.clock = pygame.time.Clock()
        self.keydown_handlers = defaultdict(list)
        self.keyup_handlers = defaultdict(list)
        self.mouse_handlers = []
        self.mouse_handlers.append(self.handle_mouse_event)

        self.ky = int(height / 20)
        self.kx = int(width / 31)
        self.objects = dict()
        self.player_c = 0
        self.computer_c = 0
        if self.kx < self.ky:
            rad = self.kx
        else:
            rad = self.ky
        y = self.ky
        for i in range(0, 6):
            if i % 2 != 0:
                x = self.kx * 2
            else:
                x = self.kx * 5
            for j in range(0, 5):
                self.objects[(x,
                              y)] = Computer_checkers(x, y, rad, (255, 0, 0))
                x += self.kx * 6
                self.computer_c += 1
            y += self.ky
        y = height - self.ky
        for i in range(0, 6):
            if i % 2 != 0:
                x = self.kx * 2
            else:
                x = self.kx * 5
            for j in range(0, 5):
                self.objects[(x, y)] = Player_checkers(x, y, rad, (0, 0, 0))
                x += self.kx * 6
                self.player_c += 1
            y -= self.ky
        self.from_c = tuple()
        self.to_c = tuple()
        self.active_checker = None
        self.enemy_dict = dict()
        self.turn = "Player"

    def draw_hexagons(self):
        y1 = self.ky
        y2 = 0
        y3 = 0
        y4 = self.ky
        y5 = self.ky * 2
        y6 = self.ky * 2
        y7 = self.ky
        for j in range(0, 19):
            if j % 2 != 0:
                x1 = 0
                x2 = self.kx
                x3 = self.kx * 3
                x4 = self.kx * 4
                x5 = self.kx * 3
                x6 = self.kx
                x7 = 0
            else:
                x1 = self.kx * 3
                x2 = self.kx * 4
                x3 = self.kx * 6
                x4 = self.kx * 7
                x5 = self.kx * 6
                x6 = self.kx * 4
                x7 = self.kx * 3
            for i in range(0, 5):
                pygame.draw.line(self.surface, (0, 0, 0), (x1, y1), (x2, y2),
                                 5)
                pygame.draw.line(self.surface, (0, 0, 0), (x2, y2), (x3, y3),
                                 5)
                pygame.draw.line(self.surface, (0, 0, 0), (x3, y3), (x4, y4),
                                 5)
                pygame.draw.line(self.surface, (0, 0, 0), (x4, y4), (x5, y5),
                                 5)
                pygame.draw.line(self.surface, (0, 0, 0), (x5, y5), (x6, y6),
                                 5)
                pygame.draw.line(self.surface, (0, 0, 0), (x6, y6), (x7, y7),
                                 5)
                x1 += self.kx * 6
                x2 += self.kx * 6
                x3 += self.kx * 6
                x4 += self.kx * 6
                x5 += self.kx * 6
                x6 += self.kx * 6
                x7 += self.kx * 6
            y1 += self.ky
            y2 += self.ky
            y3 += self.ky
            y4 += self.ky
            y5 += self.ky
            y6 += self.ky
            y7 += self.ky

    def draw(self):
        """
        draws all the checkers on the field
        :return:
        """
        for o in self.objects.values():
            if o is not None:
                o.draw(self.surface)

    def handle_events(self):
        """
        handles the events of closing the game and clicking the mouse
        :return:
        """
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                for handler in self.mouse_handlers:
                    handler(event.type, event.pos)

    def handle_mouse_event(self, type, pos):
        """
        selects the method of the mouse action
        :param type: - action type
        :param pos: - click position
        :return:
        """
        if type == pygame.MOUSEBUTTONDOWN:
            self.handle_mouse_down(pos)

    def handle_mouse_down(self, pos):
        """
        first chooses the checker then moves it to the selected position
        :param pos: - click position
        :return:
        """
        if self.bounds.collidepoint(pos):
            self.check_to_enemy(
                "<class 'logic.Player_checkers.Player_checkers'>")
            x_pos, y_pos = self.get_true_mouthe_pos(pos)

            if str(type(self.objects.get(
                (x_pos, y_pos
                 )))) == "<class 'logic.Player_checkers.Player_checkers'>":
                self.active_checker = self.objects.get((x_pos, y_pos))
                return
            if self.active_checker is None:
                return
            cx_pos, cy_pos = self.active_checker.center
            if self.active_checker.checkers_type == "king" and (
                    math.fabs(x_pos - cx_pos) >= self.kx * 3
                    and math.fabs(y_pos - cy_pos) >= self.ky
                    and math.fabs(x_pos - cx_pos) //
                (self.kx * 3) == math.fabs(y_pos - cy_pos) // self.ky
                    or x_pos - cx_pos == 0
                    and math.fabs(y_pos - cy_pos) >= self.ky * 2):
                if len(self.enemy_dict) == 0:
                    if self.objects.get((x_pos, y_pos)) is None:
                        self.move_checker((x_pos - cx_pos) // 5,
                                          (y_pos - cy_pos) // 5, x_pos, cx_pos,
                                          y_pos, cy_pos)
                        self.turn = "Computer"
                    return
                gen_finder = self.find_enemy_for_king_on_path(
                    x_pos, y_pos, cx_pos, cy_pos)
                if self.enemy_dict.get(
                    (x_pos, y_pos)) is None and next(gen_finder):
                    self.move_checker((x_pos - cx_pos) // 5,
                                      (y_pos - cy_pos) // 5, x_pos, cx_pos,
                                      y_pos, cy_pos)
                    self.objects[next(gen_finder)] = None
                    self.computer_c -= 1
                    self.enemy_dict.clear()
                    self.check_to_enemy(
                        "<class 'logic.Player_checkers.Player_checkers'>")
                    if len(self.enemy_dict) == 0:
                        self.active_checker = None
                        self.turn = "Computer"
                    self.enemy_dict.clear()

            if math.fabs(x_pos - cx_pos) == self.kx * 3 and math.fabs(y_pos - cy_pos) == self.ky \
                    or x_pos - cx_pos == 0 and math.fabs(y_pos - cy_pos) == self.ky * 2:
                if len(self.enemy_dict) == 0:
                    if self.objects.get((x_pos, y_pos)) is None:
                        if y_pos - cy_pos <= 0:
                            self.move_checker((x_pos - cx_pos) // 5,
                                              (y_pos - cy_pos) // 5, x_pos,
                                              cx_pos, y_pos, cy_pos)
                            if y_pos <= self.ky * 2:
                                self.active_checker.color = (40, 40, 40)
                                self.active_checker.checkers_type = "king"
                            self.active_checker = None
                            self.turn = "Computer"
                    return
                if self.enemy_dict.get((x_pos, y_pos)) is not None:
                    if x_pos - cx_pos == 0:
                        new_x_pos = x_pos
                        new_y_pos = y_pos + self.ky * 2 * int(
                            (y_pos - cy_pos) // math.fabs(y_pos - cy_pos))
                    else:
                        new_x_pos = x_pos + self.kx * 3 * int(
                            (x_pos - cx_pos) // math.fabs(x_pos - cx_pos))
                        new_y_pos = y_pos + self.ky * int(
                            (y_pos - cy_pos) // math.fabs(y_pos - cy_pos))
                    if self.objects.get((new_x_pos, new_y_pos)) is None:
                        self.move_checker(2 * (x_pos - cx_pos) // 5,
                                          2 * (y_pos - cy_pos) // 5, new_x_pos,
                                          cx_pos, new_y_pos, cy_pos)
                        if new_y_pos <= self.ky * 2:
                            self.active_checker.color = (40, 40, 40)
                            self.active_checker.checkers_type = "king"
                        self.active_checker = None
                        self.objects[(x_pos, y_pos)] = None
                        self.computer_c -= 1
                        self.enemy_dict.clear()
                        self.check_to_enemy(
                            "<class 'logic.Player_checkers.Player_checkers'>")
                        if len(self.enemy_dict) == 0:
                            self.active_checker = None
                            self.turn = "Computer"
                        self.enemy_dict.clear()

    def get_true_mouthe_pos(self, pos):
        """
        calculates the coordinates of the checker that was clicked
        :param pos: - click position
        :return:
        """
        x_pos, y_pos = pos
        x_keys = [2, 5, 8, 11, 14, 17, 20, 23, 26, 29]
        x_left_count = 0
        x_right_count = 0
        x_left = x_pos
        x_right = x_pos
        while x_left % self.kx != 0:
            x_left -= 1
            x_left_count += 1
        while x_right % self.kx != 0:
            x_right += 1
            x_right_count += 1
        if x_left_count < x_right_count:
            x_pos = x_left
        else:
            x_pos = x_right
        if x_pos // self.kx - 1 in x_keys:
            x_pos -= self.kx
        if x_pos // self.kx + 1 in x_keys:
            x_pos += self.kx

        if x_pos // self.kx % 2 == 0:
            parity = 1
        else:
            parity = 0

        if parity != 1:
            while y_pos % self.ky != 0:
                y_pos -= 1
            if (y_pos // self.ky) % 2 == 0:
                y_pos += self.ky
        else:
            while y_pos % self.ky != 0:
                y_pos -= 1
            if (y_pos // self.ky) % 2 == 1:
                y_pos += self.ky
        return x_pos, y_pos

    def check_to_enemy(self, checker_type):
        """
        checks enemies nearby every checker of current player
        :param checker_type: - current player
        :return:
        """
        for pos, checker in self.objects.items():
            if str(type(checker)) == checker_type:
                pos_x, pos_y = pos
                if checker.checkers_type == "king":
                    self.check_enemy_for_king(pos_x, pos_y)
                else:
                    self.check_enemy_for_checker(pos_x, pos_y)

    def move_checker(self, kx, ky, x_pos, cx_pos, y_pos, cy_pos):
        """
        moves the checker to the selected position
        :param koef:
        :param x_pos: - to this position
        :param cx_pos: - from this position
        :param y_pos: - to this position
        :param cy_pos: - from this position
        :return:
        """
        self.active_checker.speed = (kx, ky)
        for i in range(0, 5):
            self.surface.blit(self.background_image, (0, 0))
            self.active_checker.update()
            self.draw_hexagons()
            self.draw()
            pygame.display.update()
        self.active_checker.speed = (0, 0)
        self.objects[(x_pos, y_pos)] = self.active_checker
        self.objects[(cx_pos, cy_pos)] = None
        self.from_c = (cx_pos, cy_pos)
        self.to_c = self.active_checker.center

    def find_enemy_for_king_on_path(self, x, y, cx, cy):
        """
        looking for enemies for checkers type king on line
        :param x: - completion point
        :param y: - completion point
        :param cx: - start point
        :param cy: - start point
        :return:
        """
        if x - cx == 0:
            kx = 0
            ky = 2 * math.fabs(y - cy) / (y - cy)
        else:
            kx = math.fabs(x - cx) / (x - cx)
            ky = math.fabs(y - cy) / (y - cy)
        x_pos = cx
        y_pos = cy
        enemy_flag = False
        checker_flag = False
        first_friend_flag = False
        pos_x, pos_y = (0, 0)
        while self.bounds.collidepoint((x_pos, y_pos)) and y_pos != y:
            x_pos += kx * self.kx * 3
            y_pos += ky * self.ky
            if type(self.objects.get(
                (x_pos, y_pos))) is type(self.active_checker):
                first_friend_flag = True
            if self.enemy_dict.get((x_pos, y_pos)) is not None:
                if cx < x_pos < x and cy < y_pos < y \
                        or cx > x_pos > x and cy < y_pos < y \
                        or cx < x_pos < x and cy > y_pos > y \
                        or cx > x_pos > x and cy > y_pos > y \
                        or cx == x and cy < y_pos < y \
                        or cx == x and cy > y_pos > y:
                    enemy_flag = True
                    pos_x = x_pos
                    pos_y = y_pos
                    if self.objects.get((pos_x + kx * self.kx * 3,
                                         pos_y + ky * self.ky)) is not None:
                        checker_flag = True
        if enemy_flag and not first_friend_flag and not checker_flag:
            yield True
            yield (pos_x, pos_y)
        else:
            yield False

    def check_enemy_for_checker(self, x_pos, y_pos):
        """
        looking for enemies for common type checker
        :param x_pos: - checker position
        :param y_pos: - checker position
        :return:
        """
        this_check_type = type(self.objects.get((x_pos, y_pos)))
        for i in range(-1, 2):
            for j in range(-1, 2):
                if i == 0 or j == 0:
                    continue
                possible_enemy = self.objects.get(
                    (x_pos + i * self.kx * 3, y_pos + j * self.ky))
                if type(
                        possible_enemy
                ) is not this_check_type and possible_enemy is not None:
                    if self.objects.get((x_pos + i * 2 * self.kx * 3,
                                         y_pos + j * 2 * self.ky)) is None:
                        if x_pos + i * 2 * self.kx * 3 in range(
                                1, 775) and y_pos + j * 2 * self.ky in range(
                                    1, 800):
                            self.enemy_dict[x_pos + i * self.kx * 3, y_pos +
                                            j * self.ky] = possible_enemy
        for i in range(-1, 2):
            if i == 0:
                continue
            possible_enemy = self.objects.get((x_pos, y_pos + i * self.ky * 2))
            if type(possible_enemy
                    ) is not this_check_type and possible_enemy is not None:
                if self.objects.get(
                    (x_pos, y_pos + i * 2 * self.ky * 2)) is None:
                    if y_pos + i * 2 * self.ky * 2 in range(1, 800):
                        self.enemy_dict[x_pos, y_pos +
                                        i * self.ky * 2] = possible_enemy

    def check_enemy_for_king(self, x, y):
        """
        looking for enemies for common type checker
        :param x_pos: - checker position
        :param y_pos: - checker position
        :return:
        """
        this_check_type = type(self.objects.get((x, y)))
        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            x_pos += self.kx * 3
            y_pos += self.ky
            if type(self.objects.get((x_pos, y_pos))) is this_check_type:
                break
            if type(self.objects.get(
                (x_pos, y_pos))) is not this_check_type and self.objects.get(
                    (x_pos, y_pos)) is not None:
                if self.objects.get(
                    (x_pos + self.kx * 3, y_pos + self.ky)) is None and (
                        self.objects.get(
                            (x_pos - self.kx * 3, y_pos - self.ky)) is None
                        or x_pos - self.kx * 3 == x
                        and y_pos - self.ky == y) and self.bounds.collidepoint(
                            (x_pos + self.kx * 3, y_pos + self.ky)):
                    self.enemy_dict[(x_pos, y_pos)] = self.objects.get(
                        (x_pos, y_pos))
                    break
        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            x_pos -= self.kx * 3
            y_pos += self.ky
            if type(self.objects.get((x_pos, y_pos))) is this_check_type:
                break
            if type(self.objects.get(
                (x_pos, y_pos))) is not this_check_type and self.objects.get(
                    (x_pos, y_pos)) is not None:
                if self.objects.get(
                    (x_pos - self.kx * 3, y_pos + self.ky)) is None and (
                        self.objects.get(
                            (x_pos + self.kx * 3, y_pos - self.ky)) is None
                        or x_pos + self.kx * 3 == x
                        and y_pos - self.ky == y) and self.bounds.collidepoint(
                            (x_pos - self.kx * 3, y_pos + self.ky)):
                    self.enemy_dict[(x_pos, y_pos)] = self.objects.get(
                        (x_pos, y_pos))
                    break
        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            x_pos -= self.kx * 3
            y_pos -= self.ky
            if type(self.objects.get((x_pos, y_pos))) is this_check_type:
                break
            if type(self.objects.get(
                (x_pos, y_pos))) is not this_check_type and self.objects.get(
                    (x_pos, y_pos)) is not None:
                if self.objects.get(
                    (x_pos - self.kx * 3, y_pos - self.ky)) is None and (
                        self.objects.get(
                            (x_pos + self.kx * 3, y_pos + self.ky)) is None
                        or x_pos + self.kx * 3 == x
                        and y_pos + self.ky == y) and self.bounds.collidepoint(
                            (x_pos - self.kx * 3, y_pos - self.ky)):
                    self.enemy_dict[(x_pos, y_pos)] = self.objects.get(
                        (x_pos, y_pos))
                    break
        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            x_pos += self.kx * 3
            y_pos -= self.ky
            if type(self.objects.get((x_pos, y_pos))) is this_check_type:
                break
            if type(self.objects.get(
                (x_pos, y_pos))) is not this_check_type and self.objects.get(
                    (x_pos, y_pos)) is not None:
                if self.objects.get(
                    (x_pos + self.kx * 3, y_pos - self.ky)) is None and (
                        self.objects.get(
                            (x_pos - self.kx * 3, y_pos + self.ky)) is None
                        or x_pos - self.kx * 3 == x
                        and y_pos + self.ky == y) and self.bounds.collidepoint(
                            (x_pos + self.kx * 3, y_pos - self.ky)):
                    self.enemy_dict[(x_pos, y_pos)] = self.objects.get(
                        (x_pos, y_pos))
                    break

        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            y_pos += 2 * self.ky
            if type(self.objects.get((x_pos, y_pos))) is this_check_type:
                break
            if type(self.objects.get(
                (x_pos, y_pos))) is not this_check_type and self.objects.get(
                    (x_pos, y_pos)) is not None:
                if self.objects.get((x_pos, y_pos + 2 * self.ky)) is None and (
                        self.objects.get(
                            (x_pos, y_pos - 2 * self.ky)) is None or
                        y_pos - 2 * self.ky == y) and self.bounds.collidepoint(
                            (x_pos, y_pos + 2 * self.ky)):
                    self.enemy_dict[(x_pos, y_pos)] = self.objects.get(
                        (x_pos, y_pos))
                    break

        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            y_pos -= 2 * self.ky
            if type(self.objects.get((x_pos, y_pos))) is this_check_type:
                break
            if type(self.objects.get(
                (x_pos, y_pos))) is not this_check_type and self.objects.get(
                    (x_pos, y_pos)) is not None:
                if self.objects.get((x_pos, y_pos - 2 * self.ky)) is None and (
                        self.objects.get(
                            (x_pos, y_pos + 2 * self.ky)) is None or
                        y_pos + 2 * self.ky == y) and self.bounds.collidepoint(
                            (x_pos, y_pos - 2 * self.ky)):
                    self.enemy_dict[(x_pos, y_pos)] = self.objects.get(
                        (x_pos, y_pos))
                    break

    def try_to_find_king(self, x, y, kx, ky):
        """
        looking for a king who can change your checker
        :return:
        """
        x_pos = x
        y_pos = y
        while self.bounds.collidepoint((x_pos, y_pos)):
            x_pos += kx * self.kx * 3
            y_pos += ky * self.ky
            if str(type(self.objects.get(
                (x_pos, y_pos
                 )))) == "<class 'logic.Computer_checkers.Computer_checkers'>":
                if self.objects[(x_pos, y_pos)].checkers_type == "king":
                    yield True
                    yield x_pos, y_pos
        yield False

    def another_player_move(self, pos):
        """
        makes a player move from the local network
        :param pos: - checker position that the player pushed
        :return:
        """
        to_x, to_y = pos
        from_x, from_y = self.active_checker.center
        self.move_checker((to_x - from_x) // 5, (to_y - from_y) // 5, to_x,
                          from_x, to_y, from_y)
        if to_x - from_x == 0:
            kx = 0
        else:
            kx = math.fabs(to_x - from_x) // (to_x - from_x)
        ky = math.fabs(to_y - from_y) // (to_y - from_y)
        while from_y != to_y:
            if self.objects.get((from_x, from_y)) is not None:
                self.objects[(from_x, from_y)] = None
            from_x += kx * self.kx * 3
            from_y += ky * self.ky
        self.active_checker = None

    def run(self):
        sock = socket.socket()
        host = 'localhost'
        port = 9090
        sock.connect((host, port))
        flag = True
        while True:
            if flag:
                data = sock.recv(100000)
                data_d = data.decode().split('/')
                from_d = data_d[0].split(',')
                from_x = 775 - int(from_d[0][1:])
                from_y = 800 - int(from_d[1][:len(from_d[1]) - 1])
                to_d = data_d[1].split(',')
                to_x = 775 - int(to_d[0][1:])
                to_y = 800 - int(to_d[1][:len(to_d[1]) - 1])
                print(data)
                self.active_checker = self.objects.get((from_x, from_y))
                self.another_player_move((to_x, to_y))
                self.from_c = tuple()
                self.to_c = tuple()
                if data_d[2] == '1':
                    flag = False
                self.surface.blit(self.background_image, (0, 0))
                self.draw()
                self.draw_hexagons()
                pygame.display.update()
            if not flag:
                self.handle_events()
                self.surface.blit(self.background_image, (0, 0))
                self.draw()
                self.draw_hexagons()
                pygame.display.update()
            if self.from_c != tuple():
                if self.turn == "Player":
                    sock.send((str(self.from_c) + '/' + str(self.to_c) + '/' +
                               "0").encode())
                if self.turn == "Computer":
                    sock.send((str(self.from_c) + '/' + str(self.to_c) + '/' +
                               '1').encode())
                    flag = True
                    self.turn = "Player"
                self.from_c = tuple()
                self.to_c = tuple()
            self.clock.tick(self.frame_rate)
Beispiel #27
0
class Unit(GameSprite):
    def __init__(self, x, y, kind, resourcemgr, team, mgr):
        super(Unit, self).__init__(x, y, kind, resourcemgr)
        self.team = team
        self.mgr = mgr
        set_unit_stats(self)
        self.rect = Rect(int(x), int(y), self.w, self.h)
        self.set_areas()
        self.area = self.areas[SELECT.NORM]
        self.health = self.max_health
        self.attack_time = 0
        self.shoot_time = 0
        self.x_speed = 0.0
        self.y_speed = 0.0
        self.x_target = None
        self.y_target = None
        self.target = None
        self.selected = False
        self.moving = False
        self.lazy_attacking = False
        self.mouse_over = False
        self.active_sounds = []
        self.camera_sounds = []

    def set_areas(self):
        self.areas = {}
        self.areas[SELECT.NORM] = Rect(0, 0, self.w, self.h)
        self.areas[SELECT.MOVING] = Rect(self.w, 0, self.w, self.h)
        self.areas[SELECT.FIRING] = Rect(0, self.h, self.w, self.h)
        self.areas[SELECT.DUNNO] = Rect(self.w, self.h, self.w, self.h)

    def set_speed(self, x, y):
        self.x_target = x - (self.w / 2.0)
        self.y_target = y - (self.h / 2.0)
        self.moving = True

        if self.x_target > self.x:
            self.x_speed = self.speed
        if self.x_target < self.x:
            self.x_speed = -self.speed
        if self.y_target > self.y:
            self.y_speed = self.speed
        if self.y_target < self.y:
            self.y_speed = -self.speed

    def reset_speed(self):
        self.moving = False
        self.x_target = None
        self.y_target = None
        self.x_speed = 0.0
        self.y_speed = 0.0

    def hurt(self, atk):
        self.health -= atk

    def is_dead(self):
        return self.health <= 0

    def play_sounds(self, camera):
        if self is self.mgr.active:
            for s in self.active_sounds:
                s.play()
        v = calculate_volume(self.rect, camera)
        if v > 0:
            for s in self.camera_sounds:
                s.set_volume(v)
                s.play()
        self.active_sounds = []
        self.camera_sounds = []

    def find_area(self):
        if self.moving:
            self.area = self.areas[SELECT.MOVING]
        elif self.shoot_time:
            if time.get_ticks() - self.shoot_time >= self.shoot_delay:
                self.shoot_time = 0
            else:
                self.area = self.areas[SELECT.FIRING]
        else:
            self.area = self.areas[SELECT.NORM]

    def draw_select_box(self, camera):
        if self.selected:
            self.resourcemgr.screen.lock()
            dx = self.w / 10
            dy = self.h / 10
            draw.lines(self.resourcemgr.screen, BLUE, False, (
                (self.rect.x - camera.rect.x + 3,
                    self.rect.y - camera.rect.y + 3 + dy),
                (self.rect.x - camera.rect.x + 3,
                    self.rect.y - camera.rect.y + 3),
                (self.rect.x - camera.rect.x + 3 + dx,
                    self.rect.y - camera.rect.y + 3),
            ), 2)
            draw.lines(self.resourcemgr.screen, BLUE, False, (
                (self.rect.x - camera.rect.x - 3 + self.w - dx,
                    self.rect.y - camera.rect.y + 3),
                (self.rect.x - camera.rect.x - 3 + self.w,
                    self.rect.y - camera.rect.y + 3),
                (self.rect.x - camera.rect.x - 3 + self.w,
                    self.rect.y - camera.rect.y + 3 + dy),
            ), 2)
            draw.lines(self.resourcemgr.screen, BLUE, False, (
                (self.rect.x - camera.rect.x - 3 + self.w,
                    self.rect.y - camera.rect.y - 3 + self.h - dy),
                (self.rect.x - camera.rect.x - 3 + self.w,
                    self.rect.y - camera.rect.y - 3 + self.h),
                (self.rect.x - camera.rect.x - 3 + self.w - dx,
                    self.rect.y - camera.rect.y - 3 + self.h),
            ), 2)
            draw.lines(self.resourcemgr.screen, BLUE, False, (
                (self.rect.x - camera.rect.x + 3 + dx,
                    self.rect.y - camera.rect.y - 3 + self.h),
                (self.rect.x - camera.rect.x + 3,
                    self.rect.y - camera.rect.y - 3 + self.h),
                (self.rect.x - camera.rect.x + 3,
                    self.rect.y - camera.rect.y - 3 + self.h - dy),
            ), 2)
            self.resourcemgr.screen.unlock()

    def draw_health_bar(self, camera):
        if self.selected or self.mouse_over:
            black_rect = Rect(self.rect.x - camera.rect.x,
                self.rect.y - camera.rect.y, self.w, 6)
            red_rect = Rect(self.rect.x - camera.rect.x + 1,
                self.rect.y - camera.rect.y + 1, self.w - 2, 4)
            green_rect = Rect(self.rect.x - camera.rect.x + 1,
                self.rect.y - camera.rect.y + 1,
                (self.w - 2) * (self.health / float(self.max_health)), 4)
            self.resourcemgr.screen.lock()
            draw.rect(self.resourcemgr.screen, BLACK, black_rect, 0)
            draw.rect(self.resourcemgr.screen, RED, red_rect, 0)
            draw.rect(self.resourcemgr.screen, GREEN, green_rect, 0)
            self.resourcemgr.screen.unlock()

    def die(self, camera):
        if self.is_dead():
            self.kill()
            v = calculate_volume(self.rect, camera)
            if v > 0:
                self.die_fx.set_volume(v)
                self.die_fx.play()

    def input(self, event, camera, mouse_rect, tilemgr):
        x, y = mouse.get_pos()
        x += camera.rect.x
        y += camera.rect.y
        self.mouse_over = self.rect.collidepoint(x, y)

        if event.type == MOUSEBUTTONUP:
            if event.button == MOUSE.LEFT:
                include = True
                if self.rect.colliderect(mouse_rect):
                    if self.team != self.mgr.team and \
                        len(self.mgr.selected) > 0:
                        include = False
                    elif self.team == self.mgr.team:
                        rem = []
                        for u in self.mgr.selected:
                            if u.team != self.mgr.team:
                                u.selected = False
                                rem.append(u)
                        self.mgr.selected.remove(*rem)

                        if self.has_flag(FLAGS.STRUCT):
                            for u in self.mgr.selected:
                                if u.has_flag(FLAGS.DUDE):
                                    include = False
                                    break
                        elif self.has_flag(FLAGS.DUDE):
                            rem = []
                            for u in self.mgr.selected:
                                if u.has_flag(FLAGS.STRUCT):
                                    u.selected = False
                                    rem.append(u)
                            self.mgr.selected.remove(*rem)
                else:
                    include = False

                if include:
                    self.selected = True
                    self.mgr.selected.add(self)
                else:
                    self.selected = False
                    self.mgr.selected.remove(self)
            elif self.team == self.mgr.team and event.button == MOUSE.RIGHT \
                and self.selected:
                self.lazy_attacking = False
                found = False
                if self.has_flag(FLAGS.CAN_FIRE):
                    for t in self.mgr.teams:
                        if t == self.team:
                            continue
                        for u in self.mgr.units[t]:
                            if u.rect.collidepoint(x, y):
                                self.target = u
                                found = True
                                break
                        if found:
                            self.active_sounds.append(self.target_fx)
                            break

                if self.has_flag(FLAGS.CAN_MOVE) and not found:
                    self.set_speed(x, y)
                    self.target = None
                    self.active_sounds.append(self.move_fx)

                if self.has_flag(FLAGS.CAN_BUILD) and not found:
                    unit = Unit(x - 25, y - 25, self.buildables[0],
                        self.resourcemgr, self.team, self.mgr)
                    if not unit.get_collisions(tilemgr.walls,
                        *self.mgr.units.values()):
                        self.mgr.add(unit)

    def logic(self, ticks, tilemgr):
        if self.has_flag(FLAGS.CAN_FIRE):
            if self.target is not None:
                if self.target.is_dead() or (self.lazy_attacking and distance(
                    self.x, self.y, self.target.x,
                    self.target.y) > self.range * 2.5):
                    self.lazy_attacking = False
                    self.target = None
                    self.reset_speed()
                elif distance(self.x, self.y, self.target.x,
                    self.target.y) <= self.range:
                    if self.moving:
                        self.reset_speed()
                    if time.get_ticks() - self.attack_time >= \
                        self.attack_delay:
                        self.shoot_time = time.get_ticks()
                        self.attack_time = time.get_ticks()
                        self.camera_sounds.append(self.fire_fx)
                        self.target.hurt(self.atk)
                else:
                    self.set_speed(self.target.x, self.target.y)
            elif not self.moving:
                found = False
                for t in self.mgr.teams:
                    if t == self.team:
                        continue
                    for u in self.mgr.units[t]:
                        if distance(self.x, self.y, u.x, u.y) <= \
                            self.range * 2:
                            self.target = u
                            self.lazy_attacking = True
                            found = True
                            break
                    if found:
                        break

        if self.has_flag(FLAGS.CAN_MOVE) and self.moving:
            x_part = self.x_speed * (ticks / 1000.0)
            y_part = self.y_speed * (ticks / 1000.0)
            x_old = self.x
            y_old = self.y
            rx_old = self.rect.x
            ry_old = self.rect.y
            x_delta = 0.0
            y_delta = 0.0

            if self.x_target:
                if abs(self.x_target - self.x) <= abs(x_part):
                    x_delta = self.x_target - self.x
                elif abs(self.y_target - self.y) > abs(y_part):
                    x_delta = x_part / sqrt(2.0)
                else:
                    x_delta = x_part
            self.x += x_delta
            self.rect.x = int(self.x)
            if self.get_collisions(tilemgr.walls, *self.mgr.units.values()):
                self.x = x_old
                self.rect.x = rx_old

            if self.y_target:
                if abs(self.y_target - self.y) <= abs(y_part):
                    y_delta = self.y_target - self.y
                elif abs(self.x_target - self.x) > abs(x_part):
                    y_delta = y_part / sqrt(2.0)
                else:
                    y_delta = y_part
            self.y += y_delta
            self.rect.y = int(self.y)
            if self.get_collisions(tilemgr.walls, *self.mgr.units.values()):
                self.y = y_old
                self.rect.y = ry_old

            if self.x_target == self.x and self.y_target == self.y:
                self.reset_speed()

    def render(self, camera=None):
        self.find_area()
        if not camera:
            self.resourcemgr.screen.blit(self.image, self.rect, self.area)
            self.draw_select_box(camera)
            self.draw_health_bar(camera)
        elif self.rect.colliderect(camera):
            pos = Rect(self.rect.x - camera.rect.x,
                self.rect.y - camera.rect.y, self.rect.w, self.rect.h)
            self.resourcemgr.screen.blit(self.image, pos, self.area)
            self.draw_select_box(camera)
            self.draw_health_bar(camera)
Beispiel #28
0
class Component:
    def __init__(self, size: Tuple[int, int], **kwargs):
        self.size = size
        self._rect = None
        self._style: Style = kwargs.get('style')
        self._style_hovered: Style = kwargs.get('style_hovered')
        self._is_hovered = False
        self._active_style: Style = self._style
        self._is_visible = True

    def update(self, elapsed_time: int):
        pass

    def set_pos(self, pos: Vector2):
        self._rect = Rect(pos, self.size)

    # TODO Have stricter control over size variable - make it private and always set it with this method?
    def set_size(self, size: Tuple[int, int]):
        self.size = size
        self._rect.size = size

    def handle_key_was_pressed(self, key):
        pass

    def handle_key_was_released(self, key):
        pass

    def handle_mouse_was_clicked(self, mouse_pos: Tuple[int, int]):
        self._assert_initialized()
        if self._is_visible and self._rect.collidepoint(
                mouse_pos[0], mouse_pos[1]):
            self._on_click(mouse_pos)

    def handle_mouse_was_released(self):
        pass

    def handle_mouse_motion(self, mouse_pos: Tuple[int, int]):
        self._assert_initialized()
        hover = self._rect.collidepoint(mouse_pos[0], mouse_pos[1])
        if self._is_hovered and not hover:
            self._active_style = self._style
            self._on_blur()
        elif not self._is_hovered and hover:
            if self._style_hovered:
                self._active_style = self._style_hovered
            self._on_hover(mouse_pos)
        self._is_hovered = hover

    def render(self, surface):
        self._assert_initialized()
        if self._is_visible:
            if self._active_style:
                if self._active_style.background_color:
                    pygame.draw.rect(surface,
                                     self._active_style.background_color,
                                     self._rect)
                elif self._active_style.background_surface:
                    surface.blit(self._active_style.background_surface,
                                 self._rect)
            self._render_contents(surface)
            if self._active_style and self._active_style.border_color:
                pygame.draw.rect(surface, self._active_style.border_color,
                                 self._rect, self._active_style.border_width)

    def set_visible(self, visible: bool):
        self._is_visible = visible

    def is_visible(self) -> bool:
        return self._is_visible

    def _render_contents(self, surface):
        pass

    def _on_click(self, mouse_pos: Optional[Tuple[int, int]]):
        pass

    # TODO Remove if not needed
    def _on_hover(self, mouse_pos: Tuple[int, int]):
        pass

    # TODO Remove if not needed
    def _on_blur(self):
        pass

    def _assert_initialized(self):
        if self._rect is None:
            raise Exception(
                "You must set the position of this component before interacting with it: %s"
                % self)
Beispiel #29
0
def is_point_in_rect(point: Tuple[int, int], rect: Rect):
    return rect.collidepoint(point[0], point[1])
Beispiel #30
0
class MFDButton(object):
    """
    Represents a UI button at the edge of the screen and controls the rendering and mouse collision detection of that
    button given its current text, enabled, and selected state.
    """

    text = None
    enabled = True
    selected = False
    always_render_background = False

    def __init__(self, text, selected=False, enabled=True):
        self.bounds = Rect(-1, -1, -1, -1)
        self.text = text
        self.selected = selected
        self.enabled = enabled
        self.draw_border = False

    def render(self, display, x_start, x_end, y, is_top):
        """
        Renders the button with its current state.
        :type display: The PiMFD.DisplayManager.DisplayManager that manages display settings
        :param x_start: The leftmost side of the button's bounds
        :param x_end: The rightmost side of the button's bounds
        :type is_top: bool True if this button is on the top of the screen, False if on the bottom.
        """

        if self.enabled:
            font_color = display.color_scheme.foreground
        else:
            font_color = display.color_scheme.disabled

        # Figure out background color - sometimes we'll want to render it on top of other content
        background = None
        if self.always_render_background:
            background = display.color_scheme.background

        label = self.text

        # If it's selected, use inverted colors
        if self.selected:
            background = font_color
            font_color = display.color_scheme.background
            label = ' ' + label + ' '  # Pad out the display so it appears wider with a background

        midpoint = ((x_end - x_start) / 2) + x_start

        pos = render_text_centered(display, display.fonts.normal, label, midpoint, y, font_color, background=background)

        if self.enabled:
            # Render tick marks
            line_length = 5
            if is_top:
                draw_vertical_line(display,
                                   display.color_scheme.foreground,
                                   midpoint,
                                   y - 2,
                                   y - 2 - line_length)

                top = y - 2 - line_length
                bottom = pos.bottom
            else:
                draw_vertical_line(display,
                                   display.color_scheme.foreground,
                                   midpoint,
                                   y + pos.height - 2,
                                   y + pos.height + line_length - 2)

                top = pos.top
                bottom = y + pos.height + line_length - 2
        else:
            top = pos.top
            bottom = pos.bottom

        # Update the bounds of the button for collision detection later
        self.bounds = Rect(x_start, top, x_end - x_start, bottom - top)

        # Render the bounds of the rectangle
        if self.draw_border:
            render_rectangle(display, display.color_scheme.foreground, self.bounds)

    def contains_point(self, pos):
        """
        Determines whether the bounds of this button contains the specified point. Bounds are defined as a general area
        represented by the button and not just rendered content.
        :param pos: The point to test
        :return: True if pos is inside the bounds of this button, otherwise False.
        """
        return self.bounds.collidepoint(pos)
Beispiel #31
0
class InputFieldWidget(Widget):
    """ widget where the user can enter text. 
    The widget loses focus when the user clicks somewhere else. 
    """

    def __init__(self, evManager, rect=None):
        Widget.__init__(self, evManager)
        # Widget init sets dirty to true, hence the actual rendering
        # will be done in InputFieldWidget.update(), called by the view renderer.

        self._em.reg_cb(NonprintableKeyEvent, self.on_invisiblekeypushed)
        self._em.reg_cb(UnicodeKeyPushedEvent, self.on_visiblekeypushed)
        self._em.reg_cb(DownClickEvent, self.on_downclick)

        self.text = ""
        self.font = Font(None, config_get_fontsize())

        if rect:
            self.rect = rect
        else:
            self.rect = Rect((0, 0), (100, config_get_fontsize() + 4))
            # 100px = default width,
            # 25px = font height, 4px = 1 px for each of border-bottom,
            # padding bottom, padding top, and border top.

        # rectangle to be drawn around the box as border
        border_rect = Rect((0, 0), self.rect.size)
        # draw and store unfocused empty box
        emptyboxImg = Surface(self.rect.size)
        self.unfocused_bgcolor = config_get_unfocusedinput_bgcolor()
        self.unfocused_txtcolor = config_get_unfocusedinput_txtcolor()
        emptyboxImg.fill(self.unfocused_bgcolor)
        pygame.draw.rect(emptyboxImg, self.unfocused_txtcolor, border_rect, 2)
        self.unfocused_emptyboxImg = emptyboxImg.convert_alpha()
        self.image = emptyboxImg
        # draw and store focused empty box
        emptyboxImg = Surface(self.rect.size)
        self.focused_bgcolor = config_get_focusedinput_bgcolor()
        self.focused_txtcolor = config_get_focusedinput_txtcolor()
        emptyboxImg.fill(self.focused_bgcolor)
        pygame.draw.rect(emptyboxImg, self.focused_txtcolor, border_rect, 2)
        self.focused_emptyboxImg = emptyboxImg.convert_alpha()

        self.textPos = (4, 2)  # 4px padding-left and 2px padding-top

    def update(self, duration):
        """ render the text in the box """
        if self.dirty == 0:
            return

        text = self.text
        if self.focused:
            text += "|"
            txtcolor = self.focused_txtcolor
            emptyboximg = self.focused_emptyboxImg
        else:
            txtcolor = self.unfocused_txtcolor
            emptyboximg = self.unfocused_emptyboxImg

        textImg = self.font.render(text, True, txtcolor)
        # cover the previous img instead of creating a new one
        # TODO: is bliting on existing faster than creating a new surface?
        self.image.blit(emptyboximg, (0, 0))
        self.image.blit(textImg, self.textPos)

        # self.dirty = 0

    def set_text(self, newtext):
        """ change the content of the text input field """
        self.text = newtext
        self.dirty = 1

    def submit_text(self):
        """ send the string typed, and reset the text input field """
        self.log.debug("Widget submit text: " + self.text)
        ev = SubmitChat(self.text)
        self.set_text("")
        self._em.post(ev)

    ###### CALLBACKS

    def on_downclick(self, event):
        """ Get focus if clicked, lose focus if something else is clicked """
        if self.rect.collidepoint(event.pos):  # box was clicked
            self.set_focus(True)
            self.dirty = 1
        elif self.focused:  # user clicked on something else
            self.set_focus(False)

    def on_invisiblekeypushed(self, event):
        """ Add/remove characters and 'submit' the string."""
        if self.focused:
            if event.key == K_BACKSPACE:  # erase last character
                newtxt = self.text[:-1]
                self.set_text(newtxt)
            elif event.key == K_RETURN:  # submit non-empty string
                if self.text:
                    self.submit_text()
                else:  # lose focus
                    self.set_focus(False)

        else:  # not focused => grab focus if K_RETURN pushed
            if event.key == K_RETURN:
                self.set_focus(True)

    def on_visiblekeypushed(self, event):
        """ Type characters inside the box. """
        if self.focused:
            # add visible characters at the end of existing string
            newtxt = self.text + event.unicode
            self.set_text(newtxt)
Beispiel #32
0
    def loop(self, g, r):
        enableflip = 1
        # reseting the frame count if not walking
        if self.walking == 0:
            self.framecount = 0
            
        # animation
        if self.type == None: # assistant ima
            self.image = self.orginalImage.subsurface((32 * ((self.framecount/2) % 4), 0, 32, 32))
            # hack! to get ima the only holding hand character
            if g.connected == 1 and self.direction == 0 and self.orginalImage.get_size() == (256, 128):
                self.image = self.orginalImage.subsurface((32 * ((self.framecount/2) % 4), 64, 32, 32))
            if self.faceup == 1:
                self.image = self.orginalImage.subsurface((32 * 4, 0, 32, 32))
            elif self.feeling == 'worried':
                self.image = self.orginalImage.subsurface((32 * 5, 0, 32, 32))
            elif self.feeling == 'pulled':
                self.image = self.orginalImage.subsurface((32 * 6, 0, 32, 32))
            elif self.feeling == 'coma':
                self.image = self.orginalImage.subsurface((32 * 7, 0, 32, 32))
            elif self.feeling == 'coma2':
                self.image = self.orginalImage.subsurface((32 * 7, 32, 32, 32))
        elif self.type == 'director':# director victora
            self.image = self.orginalImage.subsurface((32 * ((self.framecount/2) % 5), 0, 32, 32))
            if self.feeling == 'sit':
                self.image = self.orginalImage.subsurface((32 * 5, 0, 32, 32))
            elif self.feeling == 'sitangry':
                self.image = self.orginalImage.subsurface((32 * 6, 0, 32, 32))
            elif self.feeling == 'sitawake':
                self.image = self.orginalImage.subsurface((32 * 7, 0, 32, 32))
        elif self.type == 'robot':# robot 0
            self.image = self.orginalImage.subsurface((0, 0, 32, 32))
            if self.feeling == 'blink':
                self.image = self.orginalImage.subsurface((32, 0, 32, 32))
            elif self.feeling == 'happy':
                self.image = self.orginalImage.subsurface((64, 0, 32, 32))
            elif self.feeling == 'arms':
                self.image = self.orginalImage.subsurface((96, 0, 32, 32))
            elif self.feeling == 'attack':
                self.image = self.orginalImage.subsurface((96, 0, 32, 32))
            elif self.feeling == 'dead':
                self.image = self.orginalImage.subsurface((96, 32, 32, 32))
        elif self.type == 'mushroom':# mushroom king
            if self.dead:
                self.image = pygame.Surface((1, 1), SRCALPHA)
                return
            enableflip = 0
            self.timer += 1
            self.image = self.orginalImage.subsurface((256, 256, 256, 256))
            if self.feeling == 'walking':
                m = (self.timer / 3) % 3
                if m == 0:
                    self.image = self.orginalImage.subsurface((0, 0, 256, 256))
                elif m == 1:
                    self.image = self.orginalImage.subsurface((256, 0, 256, 256))
                elif m == 2:
                    self.image = self.orginalImage.subsurface((0, 256, 256, 256))
        elif self.type == 'doctor':# doctor robot
            if self.dead == 1:
                #self.image = pygame.Surface((1, 1), SRCALPHA)
                return
            self.image = pygame.Surface((256, 256), SRCALPHA)
            enableflip = 0
            self.timer += 1

            leftarmlength = self.attackleft
            rightarmlength = self.attackright
            rightarmspnning = 0
            if rightarmlength == 10:
                rightarmspnning = ((self.timer % 1000) - 600) / 40 + 1
            dead = 0
            if self.health <= 0:
                leftarmlength = 0
                rightarmlength = 0
                self.feeling = 'dead'
                self.image.blit(self.imagel, (0,0))
                dead = 1
            else:
                self.image.blit(self.imageh, (0,0))
            if self.feeling == 'walking':
                m = (self.timer / 2) % 2 == 0
                if m == 1:
                    self.image.blit(self.imagee, (0,0)) # wonky tracks 2
                else:
                    self.image.blit(self.imagef, (0,0)) # wonky tracks 1
            else:
                self.image.blit(self.imageg, (0,0)) # normal tracks

            # getting hit by a bullet
            s = Rect(self.rect)
            s.x += 50
            s.y += 40
            s.width -= 120
            s.height -= 140
            for b in g.bullets:
                if b.owner == 'player':
                    drect = (b.rect.x , b.rect.y )
                    if s.collidepoint(drect) and not dead and rightarmspnning == 0:
                        dmg = b.get_damage()
                        self.health -= dmg
                        e = Effect(self.g, 'health', (self.rect.x + 128, self.rect.y + 60))
                        e.healthchange = -dmg
                        self.hitme.play()
                        self.image.blit(self.imagek, (0,0)) # white flash hit
                        b.destroy()
                        if self.health <= 0:
                            self.timer = 0

            # blit the right arm
            if rightarmspnning == 0:
                if rightarmlength == 4 or leftarmlength == 4:
                    self.attack.play()
                if rightarmlength == 0 or rightarmlength == 2:
                    self.image.blit(self.imagec, (0,0))
                elif rightarmlength == 1 or rightarmlength == 3:
                    self.image.blit(self.imagei, (0,0))
                else:
                    self.image.blit(self.imagec, (0,(rightarmlength - 4) * 20))
                if rightarmlength >= 0 and rightarmlength <= 3:
                    rpos = (0,0)
                    armr = self.imagea
                elif rightarmlength == 4:
                    rpos = (-50,-65)
                    armr = pygame.transform.rotate(self.imagea, -27)
                elif rightarmlength == 5: # there's no way to rotate around a point in pygame.
                    rpos = (-55,-90)
                    armr = pygame.transform.rotate(self.imagea, -45)
                else: # there's no way to rotate around a point in pygame.
                    rpos = (-55,-90)
                    armr = pygame.transform.rotate(self.imagea, -50)
                self.image.blit(armr, rpos)
            else:
                # covering the cross from player fire
                if rightarmspnning == 1 or rightarmspnning >= 9:
                    armrd = pygame.transform.rotate(self.imagea, -10)
                    armrc = pygame.transform.rotate(self.imagec, -25)
                    self.image.blit(armrd, (-30, -25))
                    self.image.blit(armrc, (-60,-75))
                else:
                    armrd = pygame.transform.rotate(self.imagea, -20)
                    armrc = pygame.transform.rotate(self.imagec, -50)
                    self.image.blit(armrd, (-40, -50))
                    self.image.blit(armrc, (-80,-130))

            # blit the left arm
            if leftarmlength == 0 or leftarmlength == 2:
                self.image.blit(self.imaged, (0,0))
            elif leftarmlength == 1 or leftarmlength == 3:
                self.image.blit(self.imagej, (0,0))
            else:
                self.image.blit(self.imaged, (0,(leftarmlength - 4) * 18))
            if leftarmlength >= 0 and leftarmlength <= 3:
                rpos = (0,0)
                arml = self.imageb
            elif leftarmlength == 4:
                rpos = (-35,-60)
                arml = pygame.transform.rotate(self.imageb, 27)
            elif leftarmlength == 5:
                rpos = (-40,-80)
                arml = pygame.transform.rotate(self.imageb, 45)
            else:
                rpos = (-40,-80)
                arml = pygame.transform.rotate(self.imageb, 50)
            self.image.blit(arml, rpos)
            if self.attackright > 0:
                self.attackright += 1
                if self.attackright > 7:
                    self.attackright = 0
            if self.attackleft > 0:
                self.attackleft += 1
                if self.attackleft > 7:
                    self.attackleft = 0
        elif self.type == 'nurse': # the devil child of the doctor. special nurse
            if self.feeling == 'dead':
                self.image = self.orginalImage.subsurface((5 * 32, 0, 32, 32))
            elif self.feeling == 'look0':
                self.image = self.orginalImage.subsurface((6 * 32, 0, 32, 32))
            elif self.feeling == 'look1':
                self.image = self.orginalImage.subsurface((7 * 32, 0, 32, 32))
            else:
                self.image = self.orginalImage.subsurface((0, 0, 32, 32))
            if self.walking:
                self.image = self.orginalImage.subsurface((32 * (1 + (self.framecount/3) % 3), 0, 32, 32))
        elif self.type == 'fox':
            if self.lastframehidden != self.hidden and self.lastframehidden != -1:
                print 'out of frame animation effect'
                Effect(g, 'foxentrance', (self.rect.x + 32, self.rect.y + 8))
                self.teleport.play()
            self.lastframehidden = self.hidden
            if self.jumping:
                self.image = self.orginalImage.subsurface((96, 0, 96, 64))
            elif self.walking:
                self.image = self.orginalImage.subsurface((96 * ((self.framecount/3) % 2), 64, 96, 64))
            else:
                self.image = self.orginalImage.subsurface((0, 0, 96, 64))
                if self.feeling == 'sad':
                    self.image = self.orginalImage.subsurface((0, 128, 96, 64))
                elif self.feeling == 'shooting':
                    self.image = self.orginalImage.subsurface((96, 128, 96, 64))
                elif self.feeling == 'dead':
                    self.image = self.orginalImage.subsurface((96, 192, 96, 64))
                    
            if self.faceup == 1:
                self.image = self.orginalImage.subsurface((0, 192, 96, 64))
        elif self.type == 'backup':
            self.image = self.orginalImage.subsurface((0, 0, 32, 32))
            if self.dead:
                self.image = self.orginalImage.subsurface((196, 0, 32, 32))
        elif self.type == 'boat':
            return

        # if you look the way you are facing
        if enableflip:
            self.image = pygame.transform.flip(self.image, self.direction, 0)


        # AI Mode has been activated
        if self.attacking != 0:
            if self.type == 'mushroom':# robot 0
                self.mushroom_attack_loop()
            elif self.type == 'doctor':
                self.doctor_attack_loop()
            elif self.type == 'robot':
                self.robot_attack_loop()
            elif self.type == 'backup':
                self.backup_attack_loop()
            else:
                self.fox_attack_loop()
            return

        if self.dontwalk:
            return



        
        # if you're walking to a position
        p = (self.rect.x, self.rect.y)
        self.walking = 0
        if p != self.walktopos and self.walktopos != None:
            self.walking = 1
            self.framecount += 1
            if p[0] > self.walktopos[0] + self.walkspeed:
                self.rect.x -= self.walkspeed
            elif p[0] < self.walktopos[0] - self.walkspeed:
                self.rect.x += self.walkspeed
            else:
                self.rect.x = self.walktopos[0]
            if p[1] > self.walktopos[1] + self.walkspeed:
                self.rect.y -= self.walkspeed
            elif p[1] < self.walktopos[1] - self.walkspeed:
                self.rect.y += self.walkspeed
            else:
                self.rect.y = self.walktopos[1]

        if self.hidden == 1:
            self.image = self.orginalImage.subsurface((0, 0, 0, 0))
Beispiel #33
0
class ScrollContainer(AbstractContainer):
  SCROLLBAR_WIDTH = 15
  SCROLLBAR_MARGIN = 5

  def __init__(self, height: Any, children: List[Component], padding: int, margin: int, **kwargs):
    container_width = max(c.size[0] for c in children) \
                      + padding * 2 \
                      + ScrollContainer.SCROLLBAR_WIDTH \
                      + ScrollContainer.SCROLLBAR_MARGIN
    size = (container_width, height)
    super().__init__(size, children, **kwargs)
    sum_height = sum(c.size[1] for c in children) + padding * 2 + margin * (len(children) - 1)
    self._max_scroll = sum_height - height
    self._padding = padding
    self._margin = margin
    self._scroll_y = 0
    self._scrollbar = None
    self._scrollbar_top = None
    self._scrollbar_bottom = None
    self._scrolling_velocity = 0

  def scroll(self, dy: int):
    self._scroll_y = max(0, min(self._scroll_y + dy, self._max_scroll))
    self._update_children()

  def _render_contents(self, surface):
    s = Surface(self.size, pygame.SRCALPHA)
    for component in self._children:
      component.render(s)
    surface.blit(s, self._rect.topleft)
    pygame.draw.rect(surface, Color(150, 150, 150), self._scrollbar)
    height = 10
    up_arrow = [(self._scrollbar.centerx, self._scrollbar.top + 2),
                (self._scrollbar.left + 1, self._scrollbar.top + 2 + height),
                (self._scrollbar.right - 2, self._scrollbar.top + 2 + height)]
    pygame.draw.aalines(surface, Color(255, 255, 255), True, up_arrow)
    down_arrow = [(self._scrollbar.centerx, self._scrollbar.bottom - 2),
                  (self._scrollbar.left + 1, self._scrollbar.bottom - 2 - height),
                  (self._scrollbar.right - 2, self._scrollbar.bottom - 2 - height)]
    pygame.draw.aalines(surface, Color(255, 255, 255), True, down_arrow)

  def set_pos(self, pos: Vector2):
    super().set_pos(pos)
    self._update_children()
    self._scrollbar = Rect(
        self._rect.right - ScrollContainer.SCROLLBAR_WIDTH - ScrollContainer.SCROLLBAR_MARGIN,
        self._rect.top + ScrollContainer.SCROLLBAR_MARGIN,
        ScrollContainer.SCROLLBAR_WIDTH,
        self._rect.h - ScrollContainer.SCROLLBAR_MARGIN * 2)
    self._scrollbar_top = Rect(self._scrollbar.x, self._scrollbar.y, self._scrollbar.w, self._scrollbar.h // 2)
    self._scrollbar_bottom = Rect(self._scrollbar.x, self._scrollbar.y + self._scrollbar.h // 2, self._scrollbar.w,
                                  self._scrollbar.h // 2)

  def handle_mouse_motion(self, mouse_pos: Tuple[int, int]):
    super().handle_mouse_motion(mouse_pos)
    local_mouse_pos = (mouse_pos[0] - self._rect.x, mouse_pos[1] - self._rect.y)
    for component in self._children:
      component.handle_mouse_motion(local_mouse_pos)

  def _on_click(self, mouse_pos: Optional[Tuple[int, int]]):
    local_mouse_pos = (mouse_pos[0] - self._rect.x, mouse_pos[1] - self._rect.y)
    scroll_amount = 3
    if self._scrollbar_top.collidepoint(mouse_pos):
      self._scrolling_velocity = -scroll_amount
    if self._scrollbar_bottom.collidepoint(mouse_pos):
      self._scrolling_velocity = scroll_amount
    for component in self._children:
      component.handle_mouse_was_clicked(local_mouse_pos)

  def handle_mouse_was_released(self):
    super().handle_mouse_was_released()
    self._scrolling_velocity = 0

  def _update_children(self):
    pos = Vector2(self._padding, self._padding - self._scroll_y)
    for component in self._children:
      component.set_pos(pos)
      pos += (0, component.size[1] + self._margin)

  def update(self, elapsed_time: int):
    super().update(elapsed_time)
    self.scroll(self._scrolling_velocity)
Beispiel #34
0
class GameObject:
    def __init__(self, x, y, w, h, visible=True, speed=(0, 0)):
        self._bounds = Rect(x, y, w, h)
        self._visible = visible
        self._speed = speed

    @property
    def left(self):
        return self._bounds.left

    @property
    def right(self):
        return self._bounds.right

    @property
    def top(self):
        return self._bounds.top

    @property
    def bottom(self):
        return self._bounds.bottom

    @property
    def width(self):
        return self._bounds.width

    @property
    def height(self):
        return self._bounds.height

    @property
    def center(self):
        return self._bounds.center

    @property
    def centerx(self):
        return self._bounds.centerx

    @property
    def centery(self):
        return self._bounds.centery

    @property
    def visible(self):
        return self._visible

    def set_visible(self):
        self._visible = True

    def set_invisible(self):
        self._visible = False

    def in_bounds(self, pos):
        return self._bounds.collidepoint(pos)

    def draw(self, surface, dx=0, dy=0):
        pass

    def move(self, dx, dy):
        self._bounds = self._bounds.move(dx, dy)

    def update(self):
        pass
Beispiel #35
0
class TextBox(MenuObjectWithText):

    text_str: str = None  # Строка, которую хранит TextBox
    empty_text_str: str = None  # Строка, которую хранит TextBox, пока в него ничего не введено

    function_onEnter = None  # Функция, выполняемая при нажатии Enter-а
    arg_onEnter: str = None

    is_active = None  # Активен ли сейчас кнопка (можно ли на него нажать)
    is_selected = None  # Выбран ли сейчас TextBox

    def __init__(self, window_surface: Surface, pos: tuple = None, start_text: str = None,
                 empty_text: str = None, active: bool = None, selected: bool = None,
                 function_onEnter=None, arg_onEnter: object = None, font_size: int = None, font: str = None):
        self.window_surface = window_surface

        self.rect = Rect(0, 0, 100, 50)  # Стандартные размер и положение TextBox
        if pos is not None:
            self.set_pos(pos[0], pos[1], pos[2], pos[3])

        if start_text is not None:
            self.set_text(start_text)
        else:
            self.set_text("")  # Стандартный текст TextBox - пустой

        if empty_text is not None:
            self.empty_text_str = empty_text
        else:
            self.empty_text_str = ""  # Текст подсказки пустой по умолчанию

        if selected is not None:
            self.set_selected(selected)
        else:
            self.is_selected = False

        if active is not None:
            self.set_active(active)
        else:
            self.is_active = True  # Стандартная кнопка активна

        if function_onEnter is not None:
            self.set_function_onEnter(function_onEnter)
        else:
            self.set_function_onEnter(lambda: print(self.text_str))

        if font_size is not None:
            self.set_font_size(font_size)
        else:
            self.set_font_size(16)

        if arg_onEnter is not None:
            self.arg_onEnter = arg_onEnter

        # Работа с текстом:
        if font is not None and font in fonts:
            path = get_script_dir() + fonts[font]
            self.font = Font(path, self.font_size)
        else:
            self.font = Font(None, self.font_size)
        self.textbox_render_text()

    def set_active(self, active: bool):
        self.is_active = active

    def set_selected(self, selected: bool):
        self.is_selected = selected
        self.has_text_changed = True

    def set_text(self, text: str):
        self.text_str = text
        self.has_text_changed = True

    def textbox_render_text(self):
        if self.text_str.__len__() > 0 or self.is_selected:
            # Если что-то напечатано или поле выбрано:
            super().render_text(self.text_str, BLACK)
        else:
            # Если поле пустое и не выбрано
            super().render_text(self.empty_text_str, DARK_GREY)

    def set_function_onEnter(self, function):
        self.function_onEnter = function

    def draw(self):
        if self.is_active:
            # Если активен:
            if self.is_selected:
                # Если выделен
                self.window_surface.fill(WHITE, self.rect)
            else:
                # Если не выделен
                self.window_surface.fill(VERY_LIGHT_GREY, self.rect)
        else:
            # Если не активен
            self.window_surface.fill(LIGHT_GREY, self.rect)
        self.window_surface.blit(self.text_surf,
                                 (self.rect.x,
                                  self.rect.y + (self.rect.h / 2) - (self.text_size[1] / 2)))

    def handle_event(self, event):
        if self.is_active:
            if event.type == MOUSEBUTTONUP:
                if self.rect.collidepoint(event.pos[0], event.pos[1]):
                    self.set_selected(True)
                else:
                    self.set_selected(False)
            if self.is_selected and event.type == KEYDOWN:
                if event.key == K_RETURN:
                    if self.arg_onEnter is not None:
                        self.function_onEnter(self.arg_onEnter)
                    else:
                        self.function_onEnter()
                elif event.key == K_BACKSPACE:
                    self.text_str = self.text_str[:-1]
                else:
                    self.text_str += event.unicode
                self.has_text_changed = True

    def update(self):
        if self.has_text_changed:
            self.textbox_render_text()