class Explode: enemy = None explode = None screen = None camera = None def __init__(self, x, y): self.x, self.y = round(x), round(y) self.anim = PygAnimation([[img, 50] for img in images['explosion']]) self.anim.play() self.rect = Rect(self.x - 64, self.y - 64, 128, 128) self.sound = sounds['explode'] self.sound.play() def render(self): self.anim.blit(Explode.screen, Explode.camera.get_pos(self.x - 64, self.y - 64)) for n in Explode.enemy: if sprite.collide_rect(self, n): n.hp -= 1 if self.anim.currentFrameNum == 15: Explode.explode.remove(self)
def __init__(self, enemy_coords, name, walking_radius=3*82, detect_radius=5*82, isActive=False, isStaying=True): # КОГДА Я НАЧАЛ ПИСАТЬ КОММЕНТАРИЙ Я ПОНЯЛ, ЧТО ПАССИВНЫМ ВРАГАМ # ВООБЩЕ НЕ СТОИТ ЗНАТЬ ПРО ТО, ЧТО ОНИ МОГУТ СТУКАТЬСЯ О ПОЛ, # НО, Т.К. МЫ НЕ БУДЕМ ИСПОЛЬЗОВАТЬ ЕЁ, ТО В ЦЕЛОМ НОРМ self.ALIVE_IMAGES = PygAnimation([(join(Enemies, f'{name}.png'), DELAY), (join(Enemies, f'{name}_ani.png'), DELAY)]) self.DEAD_IMAGE = load(join(Enemies, f'{name}_dead.png')) self.HIT_IMAGE = load(join(Enemies, f'{name}_hit.png')) self.isAlive = True self.isActive = isActive self.isStaying = isStaying # self.isRight = True # self.isMoving = False self.isUndergo = False # self.walking_radius = walking_radius self.detect_radius = detect_radius self.x0y0 = enemy_coords Model.__init__(self, enemy_coords, self.DEAD_IMAGE, 5)
def __init__(self, x, y): self.x, self.y = round(x), round(y) self.anim = PygAnimation([[img, 50] for img in images['explosion']]) self.anim.play() self.rect = Rect(self.x - 64, self.y - 64, 128, 128) self.sound = sounds['explode'] self.sound.play()
class Bird: def __init__(self, x, y, direction_left): # -Настройки- self.dx = 10 self.dy = 0 self.hp = 0.5 # ----------- if direction_left: self.dx *= -1 self.x, self.y = x, y self.Visible = True self.rect = pygame.Rect(x, y, 45, 59) image = pygame.image.load( r'data\textures\bird.png').convert_alpha() frames = [] if direction_left is False: image = pygame.transform.flip(image, True, False) for x in range(0, 22): frames.append([image.subsurface(x * 45, 0, 45, 59), 50]) self.anim_left = PygAnimation(frames) self.anim_left.play() def render(self, game): # Перемещение self.x += self.dx self.rect.center = self.x, self.y if abs(self.x - game.hero.x) >= SIZE[0] * 12: # Границы существования game.animals['bird'].remove(self) else: self.Visible = False if (game.camera.x - 45 < self.rect.x < game.camera.x + SIZE[0] + 5) and \ (game.camera.y - 59 < self.rect.y < game.camera.y + SIZE[1] + 5): self.Visible = True # Количество жизней if self.hp <= 0: for count in range(1, randint(2, 4)): game.pickup.append( PickUp(self.x - randint(-10, 10), self.y, 'fowl')) game.animals['bird'].remove(self) self.draw(game) def draw(self, game): self.anim_left.blit(game.screen, game.camera.get_pos(self.rect.x, self.rect.y))
class Monster(sprite.Sprite): def __init__(self, x, y, left, up, maxLengthLeft, maxLengthUp): sprite.Sprite.__init__(self) self.image = Surface((MONSTER_WIDTH, MONSTER_HEIGHT)) self.image.fill(Color(MONSTER_COLOR)) self.rect = Rect(x, y, MONSTER_WIDTH, MONSTER_HEIGHT) self.image.set_colorkey(Color(MONSTER_COLOR)) # начальные координаты self.startX = x self.startY = y self.maxLengthLeft = maxLengthLeft # максимальное расстояние, которое может пройти в одну сторону self.maxLengthUp = maxLengthUp # максимальное расстояние, которое может пройти в одну сторону, вертикаль self.xvel = left # cкорость передвижения по горизонтали, 0 - стоит на месте self.yvel = up # скорость движения по вертикали, 0 - не двигается boltAnim = [] for anim in ANIMATION_MONSTERHORYSONTAL: boltAnim.append((anim, 0.3)) self.boltAnim = PygAnimation(boltAnim) self.boltAnim.play() def update(self, platforms): # по принципу героя self.image.fill(Color(MONSTER_COLOR)) self.boltAnim.blit(self.image, (0, 0)) self.rect.y += self.yvel self.rect.x += self.xvel self.collide(platforms) if (abs(self.startX - self.rect.x) > self.maxLengthLeft): self.xvel = -self.xvel # если прошли максимальное растояние, то идеи в обратную сторону if (abs(self.startY - self.rect.y) > self.maxLengthUp): self.yvel = -self.yvel # если прошли максимальное растояние, то идеи в обратную сторону, вертикаль def collide(self, platforms): # если с чем-то или кем-то столкнулись, то поворачиваем в обратную сторону for p in platforms: if sprite.collide_rect(self, p) and self != p: self.xvel = -self.xvel self.yvel = -self.yvel
class Bird(Sprite): def __init__(self, xpos, ypos, image): Sprite.__init__(self) self.yvel = 0 self.up = False self.wasup = False self.end = False self.score = 0 x = load("bird/skeleton-animation_00.png") h, w = x.get_size() self.image = Surface((h, w)) self.rect = self.image.get_rect() self.rect.x = xpos self.rect.y = ypos self.image.set_colorkey(COLOR) animations = [] for anim in ANIMATION: animations.append((anim, ANIMATION_DELAY)) self.anim = PygAnimation(animations) self.anim.play() def draw(self, screen): screen.blit(self.image, (self.rect.x, self.rect.y)) def update(self): timer = Clock() self.image.fill(COLOR) self.anim.blit(self.image, (0, 0)) if self.up: self.yvel = -JUMP self.up = False self.wasup = True elif not self.wasup: self.yvel += GRAVITY else: self.wasup = False #pygame.time.delay(30) self.rect.y += self.yvel self.rect.x += SPEED if (self.rect.y < 0): self.rect.y = 0 if self.rect.y >= 400: self.end = True
def __init__(self, xpos, ypos, image): Sprite.__init__(self) self.yvel = 0 self.up = False self.wasup = False self.end = False self.score = 0 x = load("bird/skeleton-animation_00.png") h, w = x.get_size() self.image = Surface((h, w)) self.rect = self.image.get_rect() self.rect.x = xpos self.rect.y = ypos self.image.set_colorkey(COLOR) animations = [] for anim in ANIMATION: animations.append((anim, ANIMATION_DELAY)) self.anim = PygAnimation(animations) self.anim.play()
def __init__(self, x, y): # -Настройки- self.hp = 5 # ----------- self.Ground = False self.move_left = False self.to_jump = False self.Visible = True self.dx = self.dy = 0 resource = pygame.image.load( r'data\textures\zombie.png').convert_alpha() self.rect = pygame.Rect(x, y, 22, 38) self.anim_r = PygAnimation( [[resource.subsurface(x * 22, 0, 22, 38), 50] for x in range(0, 9)]) self.anim_r.play() self.anim_l = PygAnimation( [[resource.subsurface(x * 22, 38, 22, 38), 50] for x in range(0, 9)]) self.anim_l.play()
def __init__(self, x, y, direction_left): # -Настройки- self.dx = 10 self.dy = 0 self.hp = 0.5 # ----------- if direction_left: self.dx *= -1 self.x, self.y = x, y self.Visible = True self.rect = pygame.Rect(x, y, 45, 59) image = pygame.image.load( r'data\textures\bird.png').convert_alpha() frames = [] if direction_left is False: image = pygame.transform.flip(image, True, False) for x in range(0, 22): frames.append([image.subsurface(x * 45, 0, 45, 59), 50]) self.anim_left = PygAnimation(frames) self.anim_left.play()
def __init__(self, x, y): super().__init__(x, y) self.image = pygame.image.load('data/img/lander0.png').convert_alpha() self.second_stage = False img = pygame.image.load('data/img/fire.png').convert_alpha() self.fire = PygAnimation([[ img.subsurface(img.get_width() // 10 * x, img.get_height() // 6 * y, img.get_width() // 10, img.get_height() // 6), 10 ] for y in range(0, 6) for x in range(0, 10)]) self.fire.play() self.rcs = PygAnimation([[ pygame.transform.scale( img.subsurface(img.get_width() // 10 * x, img.get_height() // 6 * y, img.get_width() // 10, img.get_height() // 6), (10, 10)), 10 ] for y in range(0, 6) for x in range(0, 10)]) self.rcs.play() self.rcsMode = 0
def __init__(self, player_x, player_y): # -Настройки- self.Move = 0.5 self.Max_Speed = 2.5 self.Jump = 8 self.reach = 75 self.block_damage = 1 self.damage = 0.2 self.hp = self.hp0 = 10 self.hunger = 10 self.inventory = [None] * 20 self.cooldown = self.cooldown0 = 8 self.bow_cooldown = self.bow_cooldown0 = 16 self.spawn_point = [] # ----------- self.x, self.y = player_x, player_y self.dx = self.dy = 0 self.Ground = False self.ladder = False self.left = self.right = self.up = self.down = self.left_click = self.right_click = \ self.k_up = self.k_down = self.k_left = self.k_right = self.q = False self.anim_l = False self.cursor = [0, 0] self.hp_img = pygame.image.load(r'data\textures\icons.png').convert_alpha().subsurface(9, 0, 9, 9) self.hunger_img = pygame.image.load(r'data\textures\icons.png').convert_alpha().subsurface(18, 0, 9, 9) self.armor_img = pygame.image.load(r'data\textures\icons.png').convert_alpha().subsurface(0, 0, 9, 9) self.craft_available = [] self.furnace_available = [] self.inventory_menu_pos = 1 self.menu_pos = 1 resource = pygame.image.load(r'data\textures\player.png').convert_alpha() self.rect = pygame.Rect(player_x, player_y, 22, 49) self.walk_r = PygAnimation([[resource.subsurface((count * 22, 0, 22, 49)), 100] for count in range(0, 7)]) self.walk_r.play() self.walk_l = PygAnimation([[resource.subsurface((count * 22, 49, 22, 49)), 100] for count in range(0, 7)]) self.walk_l.play() self.stay_r = PygAnimation([[resource.subsurface((0, 98, 22, 49)), 100]]) self.stay_r.play() self.stay_l = PygAnimation([[resource.subsurface((22, 98, 22, 49)), 100]]) self.stay_l.play()
def __init__(self, x, y, left, up, maxLengthLeft, maxLengthUp): sprite.Sprite.__init__(self) self.image = Surface((MONSTER_WIDTH, MONSTER_HEIGHT)) self.image.fill(Color(MONSTER_COLOR)) self.rect = Rect(x, y, MONSTER_WIDTH, MONSTER_HEIGHT) self.image.set_colorkey(Color(MONSTER_COLOR)) # начальные координаты self.startX = x self.startY = y self.maxLengthLeft = maxLengthLeft # максимальное расстояние, которое может пройти в одну сторону self.maxLengthUp = maxLengthUp # максимальное расстояние, которое может пройти в одну сторону, вертикаль self.xvel = left # cкорость передвижения по горизонтали, 0 - стоит на месте self.yvel = up # скорость движения по вертикали, 0 - не двигается boltAnim = [] for anim in ANIMATION_MONSTERHORYSONTAL: boltAnim.append((anim, 0.3)) self.boltAnim = PygAnimation(boltAnim) self.boltAnim.play()
def __init__(self, x, y): Sprite.__init__(self) self.xvel = 0 self.yvel = 0 self.on_ground = False self.start_pos = x, y self.image = Surface((40, 40)) self.image.fill(COLOR) self.rect = Rect(x, y, 40, 40) self.image.set_colorkey(COLOR) self.jump_sound = Sound('sounds/jump.ogg') self.punch_sound = Sound('sounds/punch.ogg') self.anim_stay = PygAnimation(ANIM_STAY) self.anim_right = PygAnimation(ANIM_RIGHT) self.anim_left = PygAnimation(ANIM_LEFT) self.anim_jump = PygAnimation(ANIM_JUMP) self.anim_stay.play() self.anim_left.play() self.anim_right.play() self.anim_jump.play() self.anim_stay.blit(self.image, (0, 0)) self.win = False self.lose_reload = 0
def __init__(self, path_to_image, animations, coords, play_sounds): super().__init__() self.health = 100 self.path_to_image = path_to_image self.stay_animation = PygAnimation([animations[0]]) self.move_animation = PygAnimation(animations[:2]) self.dead_animation = PygAnimation([animations[2]]) self.rect = self.image.get_rect() self.rect.x = coords[0] self.rect.y = coords[1] self.play_sounds = play_sounds self.direction = 1 self.dead_time = 0 self.distance = 0 self.speed = 10 self.damage = 10 self.push = 30 self.push_sound = Sound(PUSH_SOUND) self.on_ground = True self._play_animations()
def __init__(self): super().__init__() self.image_path = PLAYER_IMAGE self.stay_and_left_animation = PygAnimation([(PLAYER_IMAGE, ANIMATION_DELAY)]) self.fall_animation = PygAnimation([(PLAYER_FALLING_IMAGE, ANIMATION_DELAY)]) self.right_animation = PygAnimation([(PLAYER_RIGHT_IMAGE, ANIMATION_DELAY)]) self.health_image = pygame.image.load(HEALTH_IMAGE) self.rect = self.image.get_rect() self.on_ground = True self.is_jumping = False self.jump_power = JUMP_POWER self.speed = 30 self.health = 100 self.max_distance = 0 self.down_speed = 25 self.set_start_coords(START_PLAYER_POSITION_X, START_PLAYER_POSITION_Y) self._play_animations()
def __init__(self, x, y): # --Настройки-- self.Max_Speed = 1 self.hp = Cthulhu.hp # ------------- self.x, self.y = x, y self.dx = self.dy = 0 # Creating animation resource = pygame.image.load( r'data\textures\cthulhu.png').convert_alpha() frames = [[ resource.subsurface(resource.get_width() // 8 * x, resource.get_height() // 3 * y, resource.get_width() // 8, resource.get_height() // 3), 100 ] for y in range(0, 3) for x in range(0, 8)] self.anim_walk = PygAnimation(frames[:8]) self.anim_rotate = PygAnimation(frames[16:18] + frames[20:21] + frames[18:20]) self.anim_attack = PygAnimation(frames[8:16]) self.anim_walk.play() self.anim_rotate.play() self.anim_attack.play() self.anim_l = False self.rotating = False self.rect = self.anim_walk.getRect() self.attack = False self.Visible = False self.throw_worms = False self.cooldown = self.cooldown0 = 250 self.distance = 0 self.aim = [0, 0] self.zombie_count = 10 self.distance_min = 250
class MainCharacter(Sprite): """ Class with player characteristics, animations and etc :self.image_path (str) - path to image sprite; :self.stay_and_left_animation (PygAnimation) - animations of stay and left movement; :self.fall_animation (PygAnimation) - animations of falling player :self.right_animation (PygAnimation) - animations of right movement; :self.rect (pygame.Rect) - rect of player (player is a rect with point of view of game) :self.on_ground (bool) - Is player on ground? :self.jump_power (int) - amount of pixels that character will move by :self.down_speed (int) - speed of falling; :self.image (pygame.image) - image of player; :self.coordinates (tuple) - coordinate of player on xy-axis """ def __init__(self): super().__init__() self.image_path = PLAYER_IMAGE self.stay_and_left_animation = PygAnimation([(PLAYER_IMAGE, ANIMATION_DELAY)]) self.fall_animation = PygAnimation([(PLAYER_FALLING_IMAGE, ANIMATION_DELAY)]) self.right_animation = PygAnimation([(PLAYER_RIGHT_IMAGE, ANIMATION_DELAY)]) self.health_image = pygame.image.load(HEALTH_IMAGE) self.rect = self.image.get_rect() self.on_ground = True self.is_jumping = False self.jump_power = JUMP_POWER self.speed = 30 self.health = 100 self.max_distance = 0 self.down_speed = 25 self.set_start_coords(START_PLAYER_POSITION_X, START_PLAYER_POSITION_Y) self._play_animations() @property def image(self): return pygame.image.load(self.image_path) @property def coordinates(self): return self.rect.x, self.rect.y @property def region(self): return self.coordinates[0] // 1000 @property def is_dead(self): return self.health <= 0 or self.coordinates[1] >= STOP_FALLING def set_start_coords(self, x, y): """ Set start coords :param x: (int) - x-axis; :param y: (int) - y-axis; :return: None """ self.rect.x = x self.rect.y = y def move(self, screen, camera, left_stop, level_objects): """ Method for processing player movements :param screen: (pygame.Surface) - screen where image will be drew :param camera: (Camera) - big rect that follows for player :param left_stop (int) - the leftmost region (as a rule it equals curr_region - 1) :param level_objects (pygame.sprite.Group) - Group with level blocks sprites :return: None """ permissions = self._check_collision(level_objects) pressed_keys = pygame.key.get_pressed() if pressed_keys[K_UP] and permissions['up']: self.is_jumping = True elif pressed_keys[K_RIGHT] and permissions['right']: if self.on_ground is True: self.right_animation.blit(screen, camera.apply(self)) self.rect.x += self.speed self.max_distance += self.speed self.rect.x = max(self.rect.x % 3584, 512) elif pressed_keys[K_LEFT] and permissions['left']: if self.on_ground is True: self.stay_and_left_animation.blit(screen, camera.apply(self)) if self.rect.x >= left_stop * 1024 + 150: self.rect.x -= self.speed self.max_distance -= self.speed else: if self.on_ground: self.stay_and_left_animation.blit(screen, camera.apply(self)) if self.is_jumping: self._jumping(screen, camera, permissions['top_collision']) else: self._gravity(screen, camera) def _check_collision(self, level_objects): """ Check collision with player and its side :param level_objects: (pygame.sprite.Group) - Group with level blocks sprites :return: (dict) - dict with permissions to moves. """ moves = { 'right': True, 'left': True, 'up': False, 'top_collision': False } self.on_ground = False for object_ in level_objects: if object_.rect.colliderect(self.rect): if object_.rect.centerx > self.rect.centerx and object_.rect.centery - self.rect.centery < 100: moves['right'] = False if str(object_) == 'Mob': object_.push_object(self) elif object_.rect.centerx < self.rect.centerx and object_.rect.centery - self.rect.centery < 100: moves['left'] = False if str(object_) == 'Mob': object_.push_object(self) if object_.rect.centery > self.rect.centery: moves['up'] = True self.on_ground = True else: moves['top_collision'] = True return moves def _jumping(self, screen, camera, top_collision): """ If this method was called it means that player is flying (self.on_ground = False) :param screen: (pygame.Surface) - screen where image will be drew :param camera: (Camera) - big rect that follows for player :param top_collision (bool) - if True player collides with top block :return: None """ if self.jump_power > 0 and top_collision is False: self.fall_animation.blit(screen, camera.apply(self)) self.rect.y -= self.jump_power self.jump_power -= GRAVITY_POWER else: self.is_jumping = False def _gravity(self, screen, camera): """ Check if the character is on the ground or not. If false it means that character is falling :param screen: (pygame.Surface) - screen where image will be drew :param camera: (Camera) - big rect that follows for player :return: None """ if not self.on_ground: self.fall_animation.blit(screen, camera.apply(self)) self.rect.y += self.down_speed else: self.jump_power = min(JUMP_POWER, self.jump_power + ENERGY_RECOVERY) def _play_animations(self): """ Method for loading and playing animations It is enough to call method once :return: None """ self.stay_and_left_animation.play() self.right_animation.play() self.fall_animation.play()
# Вынесли для большей гибкости проекта # Используемая графика: # Переходим в папку, где лежат анимации персонажа units = dirname(__file__) Game = split(units)[-2] CUT = split(Game)[-2] Images = join(CUT, 'Images') Character = join(Images, 'Character(82 x 75)') # Спрайты движения DELAY = 150 # [DELAY] = ms WALK_RIGHT = PygAnimation([(join(Character, 'walk1_right.png'), DELAY), (join(Character, 'walk2_right.png'), DELAY)], loop=True) WALK_LEFT = PygAnimation([(join(Character, 'walk1_left.png'), DELAY), (join(Character, 'walk2_left.png'), DELAY)]) DANCE = PygAnimation([(join(Character, 'walk2_right.png'), DELAY), (join(Character, 'walk1_left.png'), DELAY), (join(Character, 'walk2_left.png'), DELAY), (join(Character, 'jump_right.png'), DELAY), (join(Character, 'walk1_right.png'), DELAY), (join(Character, 'walk2_right.png'), DELAY), (join(Character, 'happy_right.png'), DELAY), (join(Character, 'climb1(83 x 79).png'), DELAY), (join(Character, 'climb2(83 x 79).png'), DELAY), (join(Character, 'climb1(83 x 79).png'), DELAY),
def __init__(self, x=0, y=0, width=0, height=0, keys=[], type='', animation_koef=0, animation_right='', animation_left='', animation_jump='', animation_jump_right='', animation_jump_left='', side=False, power=0, lifes=0, time_flower_activity=0, time_mushroom_activity=0, left=False, right=False, up=False, on_ground=False, xvel=0, yvel=0, move_speed=0, jump_power=0, gravity=0, fire_ability=False, flower_ability=False): super().__init__(x, y, width, height, left, right, up, on_ground, xvel, yvel, move_speed, gravity, lifes) self.__type = type self.__side = side self.__power = power self.__time_flower_activity = time_flower_activity self.__time_mushroom_activity = time_mushroom_activity self.__fire_ability = fire_ability self.__flower_ability = flower_ability self.__jump_power = jump_power self.__key_up = keys[0] self.__key_left = keys[1] self.__key_right = keys[2] self.__key_fire = keys[3] self.image.set_colorkey(Color("#888888")) # self.image = pygame.image.load(s) animations = [] for anim in animation_right: animations.append((anim, animation_koef)) self.do_right = PygAnimation(animations) self.do_right.play() animations = [] for anim in animation_left: animations.append((anim, animation_koef)) self.do_left = PygAnimation(animations) self.do_left.play() self.do_stay_right = PygAnimation([(animation_right[0], animation_koef) ]) self.do_stay_right.play() self.do_stay_right.blit(self.image, (0, 0)) self.do_stay_left = PygAnimation([(animation_left[0], animation_koef)]) self.do_stay_left.play() self.do_stay_left.blit(self.image, (0, 0)) self.do_jump_left = PygAnimation([(animation_jump_left, animation_koef) ]) self.do_jump_left.play() self.do_jump_right = PygAnimation([(animation_jump_right, animation_koef)]) self.do_jump_right.play() self.do_jump = PygAnimation([(animation_jump, animation_koef)]) self.do_jump.play()
class Hero(Character): def __init__(self, x=0, y=0, width=0, height=0, keys=[], type='', animation_koef=0, animation_right='', animation_left='', animation_jump='', animation_jump_right='', animation_jump_left='', side=False, power=0, lifes=0, time_flower_activity=0, time_mushroom_activity=0, left=False, right=False, up=False, on_ground=False, xvel=0, yvel=0, move_speed=0, jump_power=0, gravity=0, fire_ability=False, flower_ability=False): super().__init__(x, y, width, height, left, right, up, on_ground, xvel, yvel, move_speed, gravity, lifes) self.__type = type self.__side = side self.__power = power self.__time_flower_activity = time_flower_activity self.__time_mushroom_activity = time_mushroom_activity self.__fire_ability = fire_ability self.__flower_ability = flower_ability self.__jump_power = jump_power self.__key_up = keys[0] self.__key_left = keys[1] self.__key_right = keys[2] self.__key_fire = keys[3] self.image.set_colorkey(Color("#888888")) # self.image = pygame.image.load(s) animations = [] for anim in animation_right: animations.append((anim, animation_koef)) self.do_right = PygAnimation(animations) self.do_right.play() animations = [] for anim in animation_left: animations.append((anim, animation_koef)) self.do_left = PygAnimation(animations) self.do_left.play() self.do_stay_right = PygAnimation([(animation_right[0], animation_koef) ]) self.do_stay_right.play() self.do_stay_right.blit(self.image, (0, 0)) self.do_stay_left = PygAnimation([(animation_left[0], animation_koef)]) self.do_stay_left.play() self.do_stay_left.blit(self.image, (0, 0)) self.do_jump_left = PygAnimation([(animation_jump_left, animation_koef) ]) self.do_jump_left.play() self.do_jump_right = PygAnimation([(animation_jump_right, animation_koef)]) self.do_jump_right.play() self.do_jump = PygAnimation([(animation_jump, animation_koef)]) self.do_jump.play() @property def type(self): return self.__type @property def fire_ability(self): return self.__fire_ability @fire_ability.setter def fire_ability(self, value): self.__fire_ability = value @property def flower_ability(self): return self.__flower_ability @flower_ability.setter def flower_ability(self, value): self.__flower_ability = value @property def jump_power(self): return self.__jump_power @jump_power.setter def jump_power(self, value): self.__jump_power = value @property def power(self): return self.__power @power.setter def power(self, value): self.__power = value @property def side(self): return self.__side @side.setter def side(self, value): self.__side = value @property def time_flower_activity(self): return self.__time_flower_activity @time_flower_activity.setter def time_flower_activity(self, value=0): self.__time_flower_activity = value @property def time_mushroom_activity(self): return self.__time_mushroom_activity @time_mushroom_activity.setter def time_mushroom_activity(self, value=0): self.__time_mushroom_activity = value @property def key_fire(self): return self.__key_fire @key_fire.setter def key_fire(self, value): self.__key_fire = value @property def key_up(self): return self.__key_up @key_up.setter def key_up(self, value): self.__key_up = value @property def key_left(self): return self.__key_left @key_left.setter def key_left(self, value): self.__key_left = value @property def key_right(self): return self.__key_right @key_right.setter def key_right(self, value): self.__key_right = value def move_to_start(self): self.rect.x = self.x self.rect.y = self.y def get_super_jump(self, value=0): self.jump_power = int(self.jump_power * value) self.flower_ability = True def get_simple_jump(self, value=16): self.jump_power = value self.flower_ability = False def set_fire_ability(self): self.fire_ability = False def update(self): if self.up: if self.on_ground: self.yvel = -self.jump_power self.image.fill(Color('#888888')) self.do_jump.blit(self.image, (0, 0)) if self.left: self.xvel = -self.move_speed self.image.fill(Color('#888888')) if self.up: self.do_jump_left.blit(self.image, (0, 0)) else: self.do_left.blit(self.image, (0, 0)) if self.right: self.xvel = self.move_speed self.image.fill(Color('#888888')) if self.up: self.do_jump_right.blit(self.image, (0, 0)) else: self.do_right.blit(self.image, (0, 0)) if not (self.left or self.right): self.xvel = 0 if not self.up: self.image.fill(Color('#888888')) if self.side: self.do_stay_left.blit(self.image, (0, 0)) else: self.do_stay_right.blit(self.image, (0, 0)) if not self.on_ground: self.yvel += self.gravity self.on_ground = False def update_bonus(self): if self.flower_ability: if self.time_flower_activity == 0: self.get_simple_jump() else: self.time_flower_activity -= 0.25 if self.fire_ability: if self.time_mushroom_activity == 0: self.set_fire_ability() else: self.time_mushroom_activity -= 0.25
class Mob(Sprite): """ Class for creating game mobs Args: path_to_image (str) - path to image mob; animations (list) - list with paths to animations mobs; coords (tuple) - start coordinates of mob play_sounds (bool) - if True there will be certain sounds """ def __init__(self, path_to_image, animations, coords, play_sounds): super().__init__() self.health = 100 self.path_to_image = path_to_image self.stay_animation = PygAnimation([animations[0]]) self.move_animation = PygAnimation(animations[:2]) self.dead_animation = PygAnimation([animations[2]]) self.rect = self.image.get_rect() self.rect.x = coords[0] self.rect.y = coords[1] self.play_sounds = play_sounds self.direction = 1 self.dead_time = 0 self.distance = 0 self.speed = 10 self.damage = 10 self.push = 30 self.push_sound = Sound(PUSH_SOUND) self.on_ground = True self._play_animations() @property def image(self): return pygame.image.load(self.path_to_image) @property def coordinates(self): return self.rect.x, self.rect.y def _play_animations(self): """ Method for loading and playing animations It is enough to call method once :return: None """ self.stay_animation.play() self.move_animation.play() self.dead_animation.play() def push_object(self, object_): """ If has collision between mob and object_ (for example, player), mob will pushes object by self.push :param object_: pygame.sprite object :return: None """ object_.health -= self.damage check = False if self.direction == 1 and object_.rect.x > self.rect.x: object_.rect.x += self.push check = True elif self.direction == -1 and object_.rect.x < self.rect.x: object_.rect.x -= self.push check = True if check and self.play_sounds: self.push_sound.play() def live(self, screen, camera, level_objects): """ Life cycle of mob. If mod is dead it will returns True :param screen: (pygame.Surface) - screen where image will be drew :param camera: (Camera) - big rect that follows for player :param level_objects: (pygame.sprite.Group) - Group with level blocks sprites or mobs :return: (bool) """ permissions = self._check_collision(level_objects) if permissions['is_dead']: self.dead_time = time() return True curr_distance = self.direction * self.speed if self.direction == 1 and permissions['right']: self.rect.x += curr_distance elif self.direction == -1 and permissions['left']: self.rect.x += curr_distance else: curr_distance = 0 self.distance += abs(curr_distance) if self.distance >= STOP_MOVEMENT: self.direction *= -1 self.distance = 0 if curr_distance != 0: self.move_animation.blit(screen, camera.apply(self)) else: self.stay_animation.blit(screen, camera.apply(self)) self._gravity() if self.coordinates[1] >= STOP_FALLING: self.dead_time = time() return True return False def _gravity(self): """ If there is no surface it means that mob is falling :return: None """ if not self.on_ground: self.rect.y += GRAVITY_POWER def _check_collision(self, level_objects): """ Checks collision with mob and finds side of collision :param level_objects: (pygame.sprite.Group) - Group with level blocks sprites :return: (dict) - dict with permissions to moves. """ moves = {'right': True, 'left': True, 'up': False, 'is_dead': False} self.on_ground = False for object_ in level_objects: if self != object_ and object_.rect.colliderect(self.rect): # 100 if object_.rect.centerx > self.rect.centerx and object_.rect.centery - self.rect.centery < 30: moves['right'] = False if str(object_) == 'Mob': self.push_object(object_) elif object_.rect.centerx < self.rect.centerx and object_.rect.centery - self.rect.centery < 30: moves['left'] = False if str(object_) == 'Mob': self.push_object(object_) if object_.rect.centery > self.rect.centery: moves['up'] = True self.on_ground = True else: if str(object_) == 'Mob': moves['is_dead'] = True return moves def __str__(self): return 'Mob' def die(self, screen, camera): """ If mob is dead this method will be called. 10 seconds for showing death animations :param screen: (pygame.Surface) - screen where image will be drew :param camera: (Camera) - big rect that follows for player :return: (bool) """ self.damage = 0 self.push = 0 self.health = 0 self.dead_animation.blit(screen, camera.apply(self)) curr_time = time() if curr_time - self.dead_time >= TIME_TO_SHOW_DEATH_ANIMATION: return True return False
class Player: gravity = 1 def __init__(self, player_x, player_y): # -Настройки- self.Move = 0.5 self.Max_Speed = 2.5 self.Jump = 8 self.reach = 75 self.block_damage = 1 self.damage = 0.2 self.hp = self.hp0 = 10 self.hunger = 10 self.inventory = [None] * 20 self.cooldown = self.cooldown0 = 8 self.bow_cooldown = self.bow_cooldown0 = 16 self.spawn_point = [] # ----------- self.x, self.y = player_x, player_y self.dx = self.dy = 0 self.Ground = False self.ladder = False self.left = self.right = self.up = self.down = self.left_click = self.right_click = \ self.k_up = self.k_down = self.k_left = self.k_right = self.q = False self.anim_l = False self.cursor = [0, 0] self.hp_img = pygame.image.load(r'data\textures\icons.png').convert_alpha().subsurface(9, 0, 9, 9) self.hunger_img = pygame.image.load(r'data\textures\icons.png').convert_alpha().subsurface(18, 0, 9, 9) self.armor_img = pygame.image.load(r'data\textures\icons.png').convert_alpha().subsurface(0, 0, 9, 9) self.craft_available = [] self.furnace_available = [] self.inventory_menu_pos = 1 self.menu_pos = 1 resource = pygame.image.load(r'data\textures\player.png').convert_alpha() self.rect = pygame.Rect(player_x, player_y, 22, 49) self.walk_r = PygAnimation([[resource.subsurface((count * 22, 0, 22, 49)), 100] for count in range(0, 7)]) self.walk_r.play() self.walk_l = PygAnimation([[resource.subsurface((count * 22, 49, 22, 49)), 100] for count in range(0, 7)]) self.walk_l.play() self.stay_r = PygAnimation([[resource.subsurface((0, 98, 22, 49)), 100]]) self.stay_r.play() self.stay_l = PygAnimation([[resource.subsurface((22, 98, 22, 49)), 100]]) self.stay_l.play() def render(self, game): # Обработка нажатий клавиш self.key_event(game) # Счётчики if self.cooldown < self.cooldown0: self.cooldown -= 1 if self.cooldown <= 0: self.cooldown = self.cooldown0 if self.bow_cooldown0 < self.bow_cooldown: self.bow_cooldown0 -= 1 if self.bow_cooldown0 <= 0: self.bow_cooldown0 = self.bow_cooldown # Мышь self.cursor = pygame.mouse.get_pos() # Количество жизней, голод и броня if self.hp0 > 10: if (0 < self.hp <= self.hp0 - 0.015) and (self.hunger - 0.005 > 0): self.hp += 0.015 self.hunger -= 0.005 else: if (0 < self.hp <= self.hp0 - 0.005) and (self.hunger - 0.005 > 0): self.hp += 0.005 self.hunger -= 0.005 if self.hunger > 10: self.hunger = 10 elif self.hunger > 0: self.hunger -= 0.0005 else: self.hp -= 0.001 _hp = 0 for item in [i for i in self.inventory if i]: if item[0] == 'iron_helmet': _hp += 3 elif item[0] == 'iron_chestplate': _hp += 3 elif item[0] == 'iron_leggings': _hp += 2 elif item[0] == 'iron_boots': _hp += 2 self.hp0 = 10 + _hp if self.hp > self.hp0: self.hp = self.hp0 del _hp # Лестница if self.ladder: self.dy = 0 if self.up: self.dy -= self.Jump - 1 if self.down: self.dy += self.Max_Speed if (self.up is False) and (self.down is False): if self.dy + self.Move < 0: self.dy += self.Move elif self.dy - self.Move > 0: self.dy -= self.Move else: self.dy = 0 # Границы мира if (self.x <= 0) and (self.dx < 0): self.dx = 0 if (self.x + 22 >= F_SIZE[0]) and (self.dx > 0): self.dx = 0 if (self.y + 49 >= F_SIZE[1]) and (self.dy > 0): self.dy = 0 # Гравитация if (self.Ground is False) and (self.ladder is False): self.dy += Player.gravity self.Ground = False self.ladder = False # Торможение if (self.left is False) and (self.right is False): if self.dx + self.Move < 0: self.dx += self.Move elif self.dx - self.Move > 0: self.dx -= self.Move else: self.dx = 0 if self.dx > self.Max_Speed: self.dx -= self.Move elif self.dx < -self.Max_Speed: self.dx += self.Move self.draw(game) # Перемещение self.x += self.dx self.y += self.dy # Столкновение self.rect.x = self.x self.collision(self.dx, 0, game.block, game.wall, game.enemy) self.rect.y = self.y self.collision(0, self.dy, game.block, game.wall, game.enemy) def collision(self, dx, dy, block, wall, enemy): collide_objects = [n for n in block if n.Visible and (n.Collision or n.name == 'ladder' or n.name == 'chest')] + \ [en for en in enemy if type(en) not in [Eye, EyeServant, Cthulhu, Worm]] + \ [w for w in wall if not w.explored] for n in pygame.Rect.collidelistall(self.rect, collide_objects): if (collide_objects[n] in block) and (collide_objects[n].name == 'ladder'): self.ladder = True else: collide_objects[n].explored = True if collide_objects[n] in block and collide_objects[n].name == 'chest': continue if collide_objects[n] in wall: continue if dx > 0: self.rect.right = collide_objects[n].rect.left self.dx = 0 self.x = self.rect.x elif dx < 0: self.rect.left = collide_objects[n].rect.right self.dx = 0 self.x = self.rect.x if dy > 0: self.rect.bottom = collide_objects[n].rect.top self.y = self.rect.y if self.dy > 12: self.hp -= self.dy // 3 self.Ground = True self.dy = 0 elif dy < 0: self.rect.top = collide_objects[n].rect.bottom self.dy = 0 self.y = self.rect.y def draw(self, game): # Отображение if self.dx > 0: self.walk_r.blit(game.screen, game.camera.get_pos(self.x, self.y)) self.anim_l = False elif self.dx < 0: self.walk_l.blit(game.screen, game.camera.get_pos(self.x, self.y)) self.anim_l = True elif self.anim_l: self.stay_l.blit(game.screen, game.camera.get_pos(self.x, self.y)) else: self.stay_r.blit(game.screen, game.camera.get_pos(self.x, self.y)) def key_event(self, game): if self.left: if self.dx - self.Move >= -self.Max_Speed: self.dx -= self.Move if self.right: if self.dx + self.Move <= self.Max_Speed: self.dx += self.Move if self.up: if self.Ground and self.ladder is False: self.dy -= self.Jump if self.left_click: xx, yy = game.camera.get_pos(self.rect.centerx, self.rect.centery) if self.inventory[self.inventory_menu_pos - 1]: if self.inventory[self.inventory_menu_pos - 1][0] == 'bow' and \ self.bow_cooldown0 == self.bow_cooldown: self.bow_cooldown0 -= 1 if self.remove_item(self.inventory, ['arrow', 1]): game.arrow.append(Arrow(self.rect.centerx, self.rect.centery, self.cursor[0] + game.camera.x, self.cursor[1] + game.camera.y)) return if sqrt(pow(self.cursor[0] - xx, 2) + pow(self.cursor[1] - yy, 2)) <= self.reach: for e in game.enemy: _x, _y = game.camera.get_pos(e.rect.x, e.rect.y) if (_x < self.cursor[0] < _x + e.rect.width) and (_y < self.cursor[1] < _y + e.rect.height): _dx = 8 e.hp -= self.damage if self.inventory[self.inventory_menu_pos - 1]: if self.inventory[self.inventory_menu_pos - 1][0] == 'wooden_sword': e.hp -= 0.4 _dx += 2 elif self.inventory[self.inventory_menu_pos - 1][0] == 'stone_sword': e.hp -= 0.8 _dx += 4 elif self.inventory[self.inventory_menu_pos - 1][0] == 'iron_sword': e.hp -= 1.2 _dx += 6 elif self.inventory[self.inventory_menu_pos - 1][0] == 'golden_sword': e.hp -= 1.6 _dx += 8 elif self.inventory[self.inventory_menu_pos - 1][0] == 'diamond_sword': e.hp -= 2 _dx += 10 if type(e) not in [Eye, EyeServant, Cthulhu, Worm]: if self.x < e.rect.x: e.dx += _dx else: e.dx -= _dx e.dy -= 5 del _dx break del _x, _y else: for a in game.animals['pig'] + game.animals['sheep']: _x, _y = game.camera.get_pos(a.rect.x, a.rect.y) if (_x < self.cursor[0] < _x + a.rect.width) and (_y < self.cursor[1] < _y + a.rect.height): if (a in game.animals['sheep']) and (self.inventory[self.inventory_menu_pos - 1]) and \ (self.inventory[self.inventory_menu_pos - 1][0] == 'scissors'): if a.grow_time0 == Sheep.grow_time: a.grow_time0 -= 1 break _dx = 8 a.hp -= self.damage if self.inventory[self.inventory_menu_pos - 1]: if self.inventory[self.inventory_menu_pos - 1][0] == 'wooden_sword': a.hp -= self.damage * 2 _dx += 2 elif self.inventory[self.inventory_menu_pos - 1][0] == 'stone_sword': a.hp -= self.damage * 4 _dx += 4 elif self.inventory[self.inventory_menu_pos - 1][0] == 'iron_sword': a.hp -= self.damage * 6 _dx += 6 elif self.inventory[self.inventory_menu_pos - 1][0] == 'golden_sword': a.hp -= self.damage * 8 _dx += 8 elif self.inventory[self.inventory_menu_pos - 1][0] == 'diamond_sword': a.hp -= self.damage * 10 _dx += 10 if self.x < a.rect.x: a.dx += _dx else: a.dx -= _dx a.dy -= 5 del _dx break del _x, _y else: for n in game.block: if n.Visible and n.explored: _x, _y = game.camera.get_pos(n.rect.x, n.rect.y) if (_x + 1 <= self.cursor[0] <= _x + 24) and (_y + 1 <= self.cursor[1] <= _y + 24): if (n.name != 'bedrock') and (n.name != 'altar'): n.hp0 -= self.block_damage if self.inventory[self.inventory_menu_pos - 1]: _name = self.inventory[self.inventory_menu_pos - 1][0] if n.name in axe_damage: if _name == 'wooden_axe': n.hp0 -= self.block_damage * 0.7 elif _name == 'stone_axe': n.hp0 -= self.block_damage * 1.1 elif _name == 'iron_axe': n.hp0 -= self.block_damage * 1.5 elif _name == 'golden_axe': n.hp0 -= self.block_damage * 1.9 elif _name == 'diamond_axe': n.hp0 -= self.block_damage * 2.3 if n.name in pickaxe_damage: if _name == 'wooden_pickaxe': n.hp0 -= self.block_damage * 0.7 elif _name == 'stone_pickaxe': n.hp0 -= self.block_damage * 1.4 elif _name == 'iron_pickaxe': n.hp0 -= self.block_damage * 2.1 elif _name == 'golden_pickaxe': n.hp0 -= self.block_damage * 2.8 elif _name == 'diamond_pickaxe': n.hp0 -= self.block_damage * 3.5 if n.name in shovel_damage: if _name == 'wooden_shovel': n.hp0 -= self.block_damage * 0.7 elif _name == 'stone_shovel': n.hp0 -= self.block_damage * 1.4 elif _name == 'iron_shovel': n.hp0 -= self.block_damage * 2.1 elif _name == 'golden_shovel': n.hp0 -= self.block_damage * 2.8 elif _name == 'diamond_shovel': n.hp0 -= self.block_damage * 3.5 break del _x, _y else: for n in game.wall: if n.Visible: _x, _y = game.camera.get_pos(n.x, n.y) if (_x + 1 <= self.cursor[0] <= _x + 24) and (_y + 1 <= self.cursor[1] <= _y + 24): if self.inventory[self.inventory_menu_pos - 1]: if self.inventory[self.inventory_menu_pos - 1][0] == 'wooden_hammer': n.hp -= self.block_damage * 1.7 elif self.inventory[self.inventory_menu_pos - 1][0] == 'stone_hammer': n.hp -= self.block_damage * 2.4 elif self.inventory[self.inventory_menu_pos - 1][0] == 'iron_hammer': n.hp -= self.block_damage * 3.1 elif self.inventory[self.inventory_menu_pos - 1][0] == 'golden_hammer': n.hp -= self.block_damage * 3.8 elif self.inventory[self.inventory_menu_pos - 1][0] == 'diamond_hammer': n.hp -= self.block_damage * 4.5 if n.hp <= 0: game.wall.remove(n) break if self.right_click: xx, yy = game.camera.get_pos(self.rect.centerx, self.rect.centery) if sqrt(pow(self.cursor[0] - xx, 2) + pow(self.cursor[1] - yy, 2)) <= self.reach: go = True _x = round((self.cursor[0] + game.camera.x - 12) / 25) * 25 _y = round((self.cursor[1] + game.camera.y - 12) / 25) * 25 if (self.x - 25 < _x < self.x + 21) and (self.y - 25 < _y < self.y + 49): go = False _name = '' if self.inventory[self.inventory_menu_pos - 1]: if self.inventory[self.inventory_menu_pos - 1][1] <= 0: go = False else: _name = self.inventory[self.inventory_menu_pos - 1][0] if _name == 'bread': self.inventory[self.inventory_menu_pos - 1][1] -= 1 go = False self.hunger += 2 elif _name == 'mushroom_stew': self.inventory[self.inventory_menu_pos - 1][1] -= 1 go = False self.hunger += 3 elif _name in ['cooked_porkchop', 'cooked_fowl', 'cooked_mutton']: self.inventory[self.inventory_menu_pos - 1][1] -= 1 go = False self.hunger += 4 elif _name[-3:] == 'axe' or _name[-7:] == 'pickaxe' or _name[-6:] == 'shovel' or \ _name[-5:] == 'sword' or _name[-6:] == 'hammer' or _name == 'grown_wheat' or \ _name[-8:] == 'porkchop' or _name == 'arrow' or _name == 'bow' or _name[-4:] == 'fowl' or \ _name[-5:] == 'ingot' or _name == 'diamond' or _name == 'iron_helmet' or \ _name == 'iron_chestplate' or _name == 'iron_leggings' or _name == 'iron_boots' or \ _name == 'eye_call' or _name[-6:] == 'mutton' or _name == 'thread' or _name == 'stick' or \ _name == 'scissors' or _name == 'coal': go = False for n in game.block: if n.Visible: if (n.name == 'door') and (n.rect.x == _x) and (_y - 25 <= n.rect.y <= _y): go = False if n.Collision: n.Collision = False elif n.Collision is False: if pygame.sprite.collide_rect(self, n) == 0: n.Collision = True if (n.name == 'bed') and (_x - 25 <= n.rect.x <= _x) and (n.rect.y == _y): go = False if ((n.name == 'trapdoor') or (n.name == 'fence')) and (n.rect.x == _x) and (_y == n.rect.y): go = False if n.Collision: n.Collision = False elif n.Collision is False: if pygame.sprite.collide_rect(self, n) == 0: n.Collision = True if (n.rect.x == _x) and (n.rect.y == _y): go = False if (n.name == 'altar') and (_name == 'eye_call'): self.remove_item(self.inventory, ['eye_call', 1]) game.enemy.append(Eye(self.x - 800, self.y - 800)) go = False if n.name == 'chest': game.inventory(n.content) if (_name == 'door') and (n.rect.x == _x) and (_y <= n.rect.y <= _y + 49): go = False if (_name == 'bed') and (n.rect.x == _x + 25) and (n.rect.y == _y): go = False if _name[-4:] == 'wall': for n in game.wall: if n.Visible: if (n.x == _x) and (n.y == _y): go = False break for e in game.enemy: if (e.rect.x - 25 < _x < e.rect.x + 3) and (e.rect.y - 25 < _y < e.rect.y + 63): go = False if (_name == 'sapling') or (_name == 'wheat_seed'): for q in game.block: if q.Visible: if (_x == q.rect.x) and (_y + 25 == q.rect.y) and ( (q.name == 'dirt') or (q.name == 'grass')): break else: go = False if _name == 'wheat_seed': for q in game.animals['sheep'] + game.animals['pig']: q_x, q_y = game.camera.get_pos(q.rect.x, q.rect.y) if q_x < self.cursor[0] < q_x + q.rect.width and \ q_y < self.cursor[1] < q_y + q.rect.height and q.active_cooldown == 0 and \ q.active == type(q).active_time: go = False q.active = 0 self.inventory[self.inventory_menu_pos - 1][1] -= 1 break if _name == 'mushroom': for q in game.block: if q.Visible and q.Collision: if (_x == q.rect.x) and (_y + 25 == q.rect.y): break else: go = False if go: if _name == 'bed': self.spawn_point.append([_x, _y - 25]) if _name[-4:] == 'wall': self.inventory[self.inventory_menu_pos - 1][1] -= 1 game.wall.append(Wall(_x, _y, self.inventory[self.inventory_menu_pos - 1][0], explored=True)) elif _name != '': self.inventory[self.inventory_menu_pos - 1][1] -= 1 if self.inventory[self.inventory_menu_pos - 1][0] != 'wheat_seed': game.block.append(Block(_x, _y, self.inventory[self.inventory_menu_pos - 1][0], explored=True)) else: game.block.append(Block(_x, _y, 'wheat', explored=True)) del _x, _y, _name, go if self.k_up: if self.furnace_available: if self.menu_pos <= len(self.furnace_available): if self.add_item(self.inventory, self.furnace_available[self.menu_pos - 1][0]): for rem_item in self.furnace_available[self.menu_pos - 1][1]: self.remove_item(self.inventory, rem_item) else: if self.menu_pos <= len(self.craft_available): if self.add_item(self.inventory, self.craft_available[self.menu_pos - 1][0]): for rem_item in self.craft_available[self.menu_pos - 1][1]: self.remove_item(self.inventory, rem_item) self.k_up = False if self.k_down: self.k_down = False if self.k_left: self.menu_pos -= 1 self.k_left = False if self.k_right: self.menu_pos += 1 self.k_right = False if self.q: if self.inventory[self.inventory_menu_pos - 1]: if pygame.key.get_mods() == 1: self.inventory[self.inventory_menu_pos - 1][1] -= 50 else: self.inventory[self.inventory_menu_pos - 1][1] -= 1 self.q = False def add_item(self, inventory, item): for z in inventory: if z and z[0] == item[0]: z[1] += item[1] return True for index, cell in enumerate(inventory): if not cell: inventory[index] = item[:] return True return False def remove_item(self, inventory, item): for i in inventory: if i and i[0] == item[0]: if i[1] >= item[1]: i[1] -= item[1] return True return False
class enemy(Model): ''' Enemy class for CUT Класс определяющий поведение врага, его взаимодействие с персонажем ''' def __init__(self, enemy_coords, name, walking_radius=3*82, detect_radius=5*82, isActive=False, isStaying=True): # КОГДА Я НАЧАЛ ПИСАТЬ КОММЕНТАРИЙ Я ПОНЯЛ, ЧТО ПАССИВНЫМ ВРАГАМ # ВООБЩЕ НЕ СТОИТ ЗНАТЬ ПРО ТО, ЧТО ОНИ МОГУТ СТУКАТЬСЯ О ПОЛ, # НО, Т.К. МЫ НЕ БУДЕМ ИСПОЛЬЗОВАТЬ ЕЁ, ТО В ЦЕЛОМ НОРМ self.ALIVE_IMAGES = PygAnimation([(join(Enemies, f'{name}.png'), DELAY), (join(Enemies, f'{name}_ani.png'), DELAY)]) self.DEAD_IMAGE = load(join(Enemies, f'{name}_dead.png')) self.HIT_IMAGE = load(join(Enemies, f'{name}_hit.png')) self.isAlive = True self.isActive = isActive self.isStaying = isStaying # self.isRight = True # self.isMoving = False self.isUndergo = False # self.walking_radius = walking_radius self.detect_radius = detect_radius self.x0y0 = enemy_coords Model.__init__(self, enemy_coords, self.DEAD_IMAGE, 5) def draw(self, win, xy): if self.isAlive: self.ALIVE_IMAGES.play() self.ALIVE_IMAGES.blit(win, xy) else: win.blit(self.DEAD_IMAGE, xy) # def update(self, char, environment): # if (abs(self.rect.center - self.x0y0[0]) < self.walking_radius) and self.isRight: # self.rect.x += self.velocity[0] # elif not self.isRight: # self.rect.x -= self.velocity[0] # else: # self.isRight = ~self.isRight # # if abs(self.rect.center + char.rect.center) < self.detect_radius: # self.isUndergo = True # def passive_attack(self, env): def detect(self, char): if abs(char.rect.center[0] - self.x0y0[0]) < self.detect_radius and self.rect.center[1] + 41 >= char.rect.center[1]: # стоит добавить проверку на высоту self.isUndergo = True else: self.isUndergo = False def hit(self, char): if collide_rect(self, char): # ТУТ НАДО ВЫЗЫВАТЬ DUCK_IMAGE # И МЕНЮ (09.12.2019, 20:19) char.isDuck = True
def __init__(self, level_number, background, landscape, px, py, model, block_size=82, bx=-600, by=-700): self.background = background self.landscape = landscape self.model = model self.level_number = level_number self.character_coords = [px, py] # Описание используемой графики, # она привязана к уровню (landscape), а в папках указан размер SIZE self.block_size = block_size self.BACKGROUND_IMAGE = load( join(Images, f'Background\\backgroundColor{self.background}.png')).convert( ) self.br = self.BACKGROUND_IMAGE.get_rect() self.PLATFORM_IMAGE_DICT = { '_': load( join( Images, f'Ground\\{landscape}\\{landscape}Mid{str(self.block_size)}.png' )), '=': load( join( Images, f'Ground\\{landscape}\\{landscape}Half{str(self.block_size)}.png' )), '<': load( join( Images, f'Ground\\{landscape}\\{landscape}Half_left{str(self.block_size)}.png' )), '-': load( join( Images, f'Ground\\{landscape}\\{landscape}Half_mid{str(self.block_size)}.png' )), '>': load( join( Images, f'Ground\\{landscape}\\{landscape}Half_right{str(self.block_size)}.png' )), '~': load(join(Images, f'Tiles\\lavaTop_high.png')), } # красивые ключи, так оставим self.ITEMS_IMAGE_DICT = { 'B': ('Blue key', load(join(Images, f'Items\\keyBlue{str(self.block_size)}.png'))), 'R': ('Red key', load(join(Images, f'Items\\keyRed{str(self.block_size)}.png'))), 'G': ('Green key', load(join(Images, f'Items\\keyGreen{str(self.block_size)}.png'))), 'Y': ('Yellow key', load(join(Images, f'Items\\keyYellow{str(self.block_size)}.png'))), 'j': ('Yellow gem', load(join(Images, f'Items\\gemYellow.png'))) } self.DOORS_IMAGE_DICT = { 'b': ('Blue', load(join(Images, 'Tiles\\Blue_doorClosed.png'))), 'r': ('Red', load(join(Images, 'Tiles\\Red_doorClosed.png'))), 'g': ('Green', load(join(Images, 'Tiles\\Green_doorClosed.png'))), 'y': ('Yellow', load(join(Images, 'Tiles\\Yellow_doorClosed.png'))), 'o': ('oo_', load(join(Images, 'Tiles\\opened_door.png'))) } DELAY = 150 self.flagYellow = PygAnimation([ (join(Images, 'Items\\flagYellow82.png'), DELAY), (join(Images, 'Items\\flagYellow282.png'), DELAY) ]) self.flagYellow_down = load( join(Images, 'Items\\flagYellow_down82.png')) # Конец описания графики # чтобы красиво двигать фон self.bx, self.by = bx, by # Инициализация и объединение всех объектов на уровне # Для упрощённой рисовки уровня self.whole_group = Group() # Для отработки логики на уровнях self.platforms_group = Group() self.items_group = Group() self.doors_group = Group() self.o_doors_group = Group() self.enemies_group = Group() # self.flags_group = Group() # на этом примере я покажу как улучшить (?) x = y = 0 for row in self.model: for col in row: if col in self.PLATFORM_IMAGE_DICT.keys(): pl = design(x, y, self.PLATFORM_IMAGE_DICT[col]) self.platforms_group.add(pl) self.whole_group.add(pl) elif col in self.ITEMS_IMAGE_DICT.keys(): it = design(x, y, self.ITEMS_IMAGE_DICT[col][1], self.ITEMS_IMAGE_DICT[col][0]) self.items_group.add(it) self.whole_group.add(it) elif col in self.DOORS_IMAGE_DICT.keys(): # наверное здесь стоит записывать, на каком она уровне стоит # тем более мы его зачем-то знаем do = design(x, y - 82, self.DOORS_IMAGE_DICT[col][1], self.DOORS_IMAGE_DICT[col][0]) self.doors_group.add(do) self.whole_group.add(do) elif col == 'f': it = design(x, y, self.flagYellow_down, 'f', True, self.flagYellow) self.whole_group.add(it) elif col == 's': saw = enemy([x, y + 52], 'spinnerHalf') # С КООРДИНАТОЙ ТАК ПОТОМУ, # ЧТО САМИ КАРТИНКИ ПИЛЫ МЕНЬШЕ self.enemies_group.add(saw) self.whole_group.add(saw) # ЕСЛИ ТАК ПЫТАТЬСЯ РИСОВАТЬ, ТО У НИХ НЕТ .IMAGE И ЭТО # ПРОБЛЕМА ПОТОМУ, ЧТО МЫ ХОТИМ НЕ ПРОСТО ОДНУ ПИКЧУ # РИСОВАТЬ, А АНИМАЦИЮ И ЧТОБЫ ОН МЕРТВЫЙ БЫЛ И ВООБЩЕ # ХОТЯ КСТАТИ КАК ТОЛЬКО ОН ПОМРЁТ МОЖНО ЗАКИНУТЬ ЕГО # ВО 'ВСЁ_ГРУППУ' И ОН БУДЕТ ТАК ПУТЕШЕСТВОВАТЬ(!) # # РЕШЕНИЕ: ПРОСТО СДЕЛАТЬ УСЛОВИЕ В ПРОХОДЕ ПО ВСЕМ # ЭЛЕМЕНТАМ НА ПОПАДАНИЕ В ПОДГРУПППЫ elif col == 'L': lava_snake = enemy([x + 15, y - 50], 'snakeLava', isActive=True) self.enemies_group.add(lava_snake) self.whole_group.add(lava_snake) # elif col == 'i': # spider = enemy([x, y + 30], 'spider') # self.enemies_group.add(spider) # self.whole_group.add(spider) x += self.block_size y += self.block_size x = 0 ' Конец инициализации платформ '
class Zombie: move = 2 gravity = 1 jump = 8 damage = 0.1 def __init__(self, x, y): # -Настройки- self.hp = 5 # ----------- self.Ground = False self.move_left = False self.to_jump = False self.Visible = True self.dx = self.dy = 0 resource = pygame.image.load( r'data\textures\zombie.png').convert_alpha() self.rect = pygame.Rect(x, y, 22, 38) self.anim_r = PygAnimation( [[resource.subsurface(x * 22, 0, 22, 38), 50] for x in range(0, 9)]) self.anim_r.play() self.anim_l = PygAnimation( [[resource.subsurface(x * 22, 38, 22, 38), 50] for x in range(0, 9)]) self.anim_l.play() def render(self, game): # Движение к цели if game.hero.x > self.rect.x: if self.dx + Zombie.move <= Zombie.move: self.dx += Zombie.move else: self.dx = Zombie.move self.move_left = False elif game.hero.x < self.rect.x: if self.dx - Zombie.move >= -Zombie.move: self.dx -= Zombie.move else: self.dx = -Zombie.move self.move_left = True if self.to_jump: self.dy -= Zombie.jump self.to_jump = False # Границы if abs(self.rect.x - game.hero.x) > SIZE[0] * 1.5 or abs( self.rect.y - game.hero.y) > SIZE[1] * 1.5: game.enemy.remove(self) # Гравитация if self.Ground is False: self.dy += Zombie.gravity else: self.Ground = False # Количество жизней if self.hp <= 0: rand_choice = randint(1, 100) if 1 == rand_choice: game.pickup.append( PickUp(self.rect.centerx, self.rect.centery, 'mushroom')) if 2 == rand_choice: game.pickup.append( PickUp(self.rect.centerx, self.rect.centery, 'bread')) if 3 == rand_choice: game.pickup.append( PickUp(self.rect.centerx, self.rect.centery, 'iron_helmet')) if 4 == rand_choice: game.pickup.append( PickUp(self.rect.centerx, self.rect.centery, 'wheat_seed')) if 5 == rand_choice: game.pickup.append( PickUp(self.rect.centerx, self.rect.centery, 'bread')) if 6 == rand_choice: game.pickup.append( PickUp(self.rect.centerx, self.rect.centery, 'iron_pickaxe')) del rand_choice game.enemy.remove(self) # Перемещение self.rect.y += self.dy self.collision(0, self.dy, game.block, game.hero) self.rect.x += self.dx self.collision(self.dx, 0, game.block, game.hero) if (game.camera.x - 22 < self.rect.x < game.camera.x + SIZE[0] + 5) and \ (game.camera.y - 38 < self.rect.y < game.camera.y + SIZE[1] + 5): self.Visible = True self.draw(game) else: self.Visible = False def draw(self, game): if self.move_left: self.anim_l.blit(game.screen, game.camera.get_pos(self.rect.x, self.rect.y)) else: self.anim_r.blit(game.screen, game.camera.get_pos(self.rect.x, self.rect.y)) def collision(self, dx, dy, block, hero): collide_objects = [n for n in block if n.Visible and n.Collision ] + [hero] for n in pygame.Rect.collidelistall(self.rect, collide_objects): if collide_objects[n] == hero.rect: hero.hp -= Zombie.damage if dx: self.dx = 0 if collide_objects[n] in block and self.Ground: self.to_jump = True if collide_objects[n].rect.y < self.rect.y: self.to_jump = False if dx > 0: self.rect.right = collide_objects[n].rect.left self.dx = 0 elif dx < 0: self.rect.left = collide_objects[n].rect.right self.dx = 0 if dy > 0: self.rect.bottom = collide_objects[n].rect.top self.dy = 0 if collide_objects[n] in block: self.Ground = True if self.dy > 12: self.hp -= self.dy // 8 elif dy < 0: self.rect.top = collide_objects[n].rect.bottom self.dy = 0
class Ship(Entity): def __init__(self, x, y): super().__init__(x, y) self.image = pygame.image.load('data/img/lander0.png').convert_alpha() self.second_stage = False img = pygame.image.load('data/img/fire.png').convert_alpha() self.fire = PygAnimation([[ img.subsurface(img.get_width() // 10 * x, img.get_height() // 6 * y, img.get_width() // 10, img.get_height() // 6), 10 ] for y in range(0, 6) for x in range(0, 10)]) self.fire.play() self.rcs = PygAnimation([[ pygame.transform.scale( img.subsurface(img.get_width() // 10 * x, img.get_height() // 6 * y, img.get_width() // 10, img.get_height() // 6), (10, 10)), 10 ] for y in range(0, 6) for x in range(0, 10)]) self.rcs.play() self.rcsMode = 0 def draw(self, window): if self.up and (self.fuel > 0): img = pygame.transform.rotate(self.fire.getCurrentFrame(), 270 - self.angle) window.blit( img, Camera.get_pos( self.x - img.get_width() / 2 - 25 * cos(radians(self.angle)), self.y - img.get_height() / 2 - 25 * sin(radians(self.angle)))) if self.left or self.right: if self.left: img = pygame.transform.rotate(self.rcs.getCurrentFrame(), -self.angle) x = self.x - img.get_width() / 2 + 12 * cos( radians(self.angle + 90)) y = self.y - img.get_height() / 2 + 12 * sin( radians(self.angle + 90)) x += 2.5 * cos(radians(self.angle)) y += 2.5 * sin(radians(self.angle)) elif self.right: img = pygame.transform.rotate(self.rcs.getCurrentFrame(), 180 - self.angle) x = self.x - img.get_width() / 2 + 12 * cos( radians(self.angle - 90)) y = self.y - img.get_height() / 2 + 12 * sin( radians(self.angle - 90)) x += 5 * cos(radians(self.angle)) y += 5 * sin(radians(self.angle)) window.blit(img, Camera.get_pos(x, y)) img = pygame.transform.rotate(self.image, 270 - self.angle) pygame.draw.line( window, (255, 0, 255), Camera.get_pos(self.x, self.y), Camera.get_pos(self.x + self.dx * 5, self.y + self.dy * 5)) window.blit( img, Camera.get_pos(self.x - img.get_width() / 2, self.y - img.get_height() / 2)) def render(self): def distance(angle): v1 = self.dx, self.dy v2 = cos(angle), sin(angle) a = atan2(v1[0] * v2[1] - v1[1] * v2[0], v1[0] * v2[0] + v1[1] * v2[1]) return a # RCS Mode if self.rcsMode == 1: # Stabilization self.left = self.right = False if self.da > .1: self.left = True elif self.da < -.1: self.right = True else: if abs(self.da) < .8: self.da = 0 elif self.rcsMode == 2 or self.rcsMode == 3: if self.rcsMode == 2: # Prograde diff = distance(radians(self.angle)) elif self.rcsMode == 3: # Retrograde diff = distance(radians(self.angle) + pi) self.left = self.right = False if diff > .1: if self.da > -1: self.left = True elif diff < -.1: if self.da < 1: self.right = True else: if abs(self.da) < 1: self.da = 0 super().render()
class Cthulhu: move = .1 hp = 100 def __init__(self, x, y): # --Настройки-- self.Max_Speed = 1 self.hp = Cthulhu.hp # ------------- self.x, self.y = x, y self.dx = self.dy = 0 # Creating animation resource = pygame.image.load( r'data\textures\cthulhu.png').convert_alpha() frames = [[ resource.subsurface(resource.get_width() // 8 * x, resource.get_height() // 3 * y, resource.get_width() // 8, resource.get_height() // 3), 100 ] for y in range(0, 3) for x in range(0, 8)] self.anim_walk = PygAnimation(frames[:8]) self.anim_rotate = PygAnimation(frames[16:18] + frames[20:21] + frames[18:20]) self.anim_attack = PygAnimation(frames[8:16]) self.anim_walk.play() self.anim_rotate.play() self.anim_attack.play() self.anim_l = False self.rotating = False self.rect = self.anim_walk.getRect() self.attack = False self.Visible = False self.throw_worms = False self.cooldown = self.cooldown0 = 250 self.distance = 0 self.aim = [0, 0] self.zombie_count = 10 self.distance_min = 250 def render(self, game): # Движение к цели self.aim = game.hero.rect.center if self.rect.centery < self.aim[1] - Cthulhu.move: self.dy += Cthulhu.move elif self.rect.centery > self.aim[1] + Cthulhu.move: self.dy -= Cthulhu.move if self.rect.centerx < self.aim[0]: if self.anim_l: self.rotating = True self.anim_l = False self.dx += Cthulhu.move elif self.rect.centerx > self.aim[0]: if not self.anim_l: self.rotating = True self.anim_l = True self.dx -= Cthulhu.move # Соблюдение дистанции self.distance = sqrt( pow(self.aim[0] - self.x, 2) + pow(self.aim[1] - self.y, 2)) if self.distance <= self.distance_min: if self.anim_l: self.dx += Cthulhu.move * 10 else: self.dx -= Cthulhu.move * 10 # Контроль скорости if self.dx > self.Max_Speed: self.dx = self.Max_Speed elif self.dx < -self.Max_Speed: self.dx = -self.Max_Speed if self.dy > self.Max_Speed: self.dy = self.Max_Speed elif self.dy < -self.Max_Speed: self.dy = -self.Max_Speed # Атака if self.attack: self.distance_min = 60 else: self.distance_min = 250 if self.hp > 50: if 1 == randint(1, 200): game.enemy.append( Worm(game.hero.rect.centerx, game.hero.rect.centery + SIZE[1])) if self.attack: self.Max_Speed = 5 else: self.Max_Speed = 3 else: if not self.throw_worms: i = 0 for x in range(round(self.x), round(self.x + 500), 60): game.enemy.append( Worm(x, game.hero.rect.centery + SIZE[1] + i * 100)) i += 1 i = 0 for x in range(round(self.x), round(self.x - 500), -60): game.enemy.append( Worm(x, game.hero.rect.centery + SIZE[1] + i * 100)) i += 1 game.time = 180 self.throw_worms = True if 1 == randint(1, 50): game.enemy.append( Worm(game.hero.rect.centerx, game.hero.rect.centery + SIZE[1])) if self.zombie_count > 0: if 1 == randint(1, 40): self.zombie_count -= 1 game.add_zombie() if self.attack: self.Max_Speed = 7 else: self.Max_Speed = 5 if self.attack: if self.rect.colliderect(game.hero.rect): if self.hp > 50: game.hero.hp -= 2 game.hero.dx += self.dx * 5 game.hero.dy -= self.dy * 5 else: game.hero.hp -= 4 game.hero.dx += self.dx * 7 game.hero.dy -= self.dy * 7 self.attack = False if self.cooldown0 <= self.cooldown: self.cooldown0 -= 1 if self.cooldown0 <= 0: self.attack = True if self.hp > 30: self.cooldown = randint(100, 250) else: self.cooldown = randint(30, 100) self.cooldown0 = self.cooldown # Жизни юнита if self.hp <= 0: for n in range(0, 12): game.pickup.append( PickUp( randint( round(self.rect.centerx) - 50, round(self.rect.centerx) + 50), randint( round(self.rect.centery) - 50, round(self.rect.centery) + 50), 'diamond')) game.enemy.remove(self) if (game.camera.x - 70 < self.rect.x < game.camera.x + SIZE[0] + 10) and \ (game.camera.y - 100 < self.rect.y < game.camera.y + SIZE[1] + 20): self.Visible = True self.draw(game) else: self.Visible = False # Движение self.x += self.dx self.y += self.dy self.rect.center = self.x, self.y def draw(self, game): if self.rotating: if self.anim_l: game.screen.blit( pygame.transform.flip( self.anim_rotate.getCurrentFrame(), True, False), game.camera.get_pos(self.x - self.rect.w / 2, self.y - self.rect.h / 2)) else: self.anim_rotate.blit( game.screen, game.camera.get_pos(self.x - self.rect.w / 2, self.y - self.rect.h / 2)) else: if self.anim_l: if self.attack: game.screen.blit( pygame.transform.flip( self.anim_attack.getCurrentFrame(), True, False), game.camera.get_pos(self.x - self.rect.w / 2, self.y - self.rect.h / 2)) else: game.screen.blit( pygame.transform.flip( self.anim_walk.getCurrentFrame(), True, False), game.camera.get_pos(self.x - self.rect.w / 2, self.y - self.rect.h / 2)) else: if self.attack: self.anim_attack.blit( game.screen, game.camera.get_pos(self.x - self.rect.w / 2, self.y - self.rect.h / 2)) else: self.anim_walk.blit( game.screen, game.camera.get_pos(self.x - self.rect.w / 2, self.y - self.rect.h / 2)) if self.anim_rotate.currentFrameNum == self.anim_rotate.numFrames - 1: self.rotating = False
class Player(Sprite): def __init__(self, x, y): Sprite.__init__(self) self.xvel = 0 self.yvel = 0 self.on_ground = False self.start_pos = x, y self.image = Surface((40, 40)) self.image.fill(COLOR) self.rect = Rect(x, y, 40, 40) self.image.set_colorkey(COLOR) self.jump_sound = Sound('sounds/jump.ogg') self.punch_sound = Sound('sounds/punch.ogg') self.anim_stay = PygAnimation(ANIM_STAY) self.anim_right = PygAnimation(ANIM_RIGHT) self.anim_left = PygAnimation(ANIM_LEFT) self.anim_jump = PygAnimation(ANIM_JUMP) self.anim_stay.play() self.anim_left.play() self.anim_right.play() self.anim_jump.play() self.anim_stay.blit(self.image, (0, 0)) self.win = False self.lose_reload = 0 def update(self, left, right, up, platforms): self.image.fill(COLOR) if right: self.xvel = MOVE_SPEED self.anim_right.blit(self.image, (0, 0)) elif left: self.xvel = -MOVE_SPEED self.anim_left.blit(self.image, (0, 0)) else: self.xvel = 0 if not up: self.anim_stay.blit(self.image, (0, 0)) if up: self.image.fill(COLOR) self.anim_jump.blit(self.image, (0, 0)) else: self.anim_jump.rewind() if up and self.on_ground: self.yvel = -JUMP_POWER self.jump_sound.play() if not self.on_ground: self.yvel += GRAVITY if self.yvel + GRAVITY < MAX_GRAVITY else 0 self.on_ground = False self.rect.y += self.yvel self.collide(0, self.yvel, platforms) self.rect.x += self.xvel # переносим свои положение на xvel self.collide(self.xvel, 0, platforms) def draw(self, surface): surface.blit(self.image, self.rect.topleft) def collide(self, xvel, yvel, platforms): for platform in platforms: if self.rect.colliderect(platform.rect): if platform.state == 'upper': self.yvel = -JUMP_POWER * 5 continue if xvel > 0: self.rect.right = platform.rect.left if xvel < 0: self.rect.left = platform.rect.right if yvel > 0: self.rect.bottom = platform.rect.top self.on_ground = True self.yvel = 0 if yvel < 0: self.rect.top = platform.rect.bottom self.yvel = 0 if platform.state == 'trap': platforms.remove(platform) self.punch_sound.play() if platform.state == 'enemy': self.rect.x, self.rect.y = self.start_pos self.lose_reload = 60 if platform.state == 'target': self.win = True