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)
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]
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
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)
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
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
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
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)
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()
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)
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
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
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))
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
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
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
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()
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])
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)
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)
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)
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)
def is_point_in_rect(point: Tuple[int, int], rect: Rect): return rect.collidepoint(point[0], point[1])
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)
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)
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))
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)
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
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()