def draw(self, x, y, size=32): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() if self.x < mouse[0] < self.x + self.width and self.y < mouse[ 1] < self.y + self.height: image = self.image[self.ind_image // self.count_img] self.glow_transparency += glow_v / fps self.glow_transparency = min(self.glow_transparency, 255) if self.glow: self.glow.set_alpha(self.glow_transparency) if self.ind_image != self.count_img**2 - 1: self.ind_image += 1 if click[0] and self.func: self.func() else: image = self.image[self.ind_image // self.count_img] if self.ind_image != 0: self.ind_image -= 1 self.glow_transparency -= glow_v / fps self.glow_transparency = max(self.glow_transparency, 0) if self.glow: self.glow.set_alpha(self.glow_transparency) if self.glow: display.blit(self.glow, (self.x, self.y)) display.blit(image, (self.x, self.y)) drawing_text(self.text, (x, y), (220, 220, 220), size)
def update(self): if self.reverse: self.cur_frame += self.k if self.cur_frame > len(self.frames) - 0.8 or self.cur_frame < 0: self.k *= -1 else: self.cur_frame = (self.cur_frame + self.k) % len(self.frames) self.image = self.frames[int(self.cur_frame)] display.blit(self.image, (self.rect.x, self.rect.y))
def drawing_text(text, cords, font_color=pygame.Color('black'), font_size=30, font_type=None, bold=False, italic=False): font_type = pygame.font.Font(font_type, font_size) font_type.set_bold(bold) font_type.set_italic(italic) text = font_type.render(text, True, font_color) display.blit(text, cords) return text
def update_sliders(self): # обновление длинных нот time = self.time_now if self.sliders: while abs(self.sliders[-1][1] - time) <= 1000 / fps: # добавление новых длинных нот k = self.sliders.pop() self.sliders_active.append((Slider(k[0], k[4], k[3]), k)) if not self.sliders: break for i in range(len(self.sliders_failed) - 1, -1, -1): # обновление пропущенных длинных нот sprite, slider = self.sliders_failed[i] display.blit(sprite.image, sprite.rect) sprite.update() if time >= slider[-2]: self.sliders_failed.pop(i) for i in range(len(self.sliders_pressed) - 1, -1, -1): # обновление нажатых длинных нот if self.sliders_pressed[i] != -1: sprite, slider = self.sliders_pressed[i] display.blit(sprite.image, sprite.rect) sprite.update() for i in range(len(self.sliders_near) - 1, -1, -1): # обновление активных для нажатия sprite, slider = self.sliders_near[i] # длинных нот display.blit(sprite.image, sprite.rect) sprite.update() if slider[-1] - time <= -self.od_50: self.marks.append([0, 0]) self.sliders_failed.append(self.sliders_near.pop(i)) for i in range(len(self.sliders_active) - 1, -1, -1): # обновление активных длинных нот sprite, slider = self.sliders_active[i] display.blit(sprite.image, sprite.rect) sprite.update() if slider[-1] - time <= self.od_50: self.sliders_near.append(self.sliders_active.pop(i))
def draw(self, x, y, size=32): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() if self.x < mouse[0] < self.x + self.width and self.y < mouse[ 1] < self.y + self.height: image = self.image_on if click[0]: self.func() else: image = self.image_off display.blit(image, (self.x, self.y)) drawing_text(self.text, x, y, (0, 0, 0), size)
def drawing_text(text, cords, font_color=pygame.Color('black'), font_size=30, font_type='rizumu.ttf', bold=False, italic=False): # функция для отрисовки текста, также возвращает surface с текстом font_type = pygame.font.Font(fonts[font_type], font_size) font_type.set_bold(bold) font_type.set_italic(italic) text = font_type.render(text, True, font_color) display.blit(text, cords) return text
def draw(self): display.blit(pygame.image.load('image/StartMenu.jpg'), (0, 0)) drawing_text('Выберите персонажа', 345, 70, font_color=pygame.Color('white'), font_size=40) name = self.list_chr[self.ind_chr][0] drawing_text(name, (1185 - len(name) * 40) // 2, 140, font_color=pygame.Color('grey'), font_size=40) for i in range(2): name, cords = self.list_chr[i] display.blit(pygame.image.load(f'image/{name}_0.png'), cords) if i != self.ind_chr: x, y = pygame.mouse.get_pos() if cords[0] < x < cords[0] + 96 and cords[ 1] < y < cords[1] + 120: display.blit( pygame.image.load('image/select_square_1.png'), cords) else: display.blit(pygame.image.load('image/select_square_0.png'), cords) self.confirm_button.draw(0, 0)
def render(self): # анимация перехода между экранами if self.background: display.blit(self.background, (0, 0)) if self.transition_back: self.frame -= 1 img = pygame.transform.flip( AnimationTransition.transition_img[self.frame], True, False) if self.frame == 0: self.frame = -1 self.reverse() else: self.frame += 1 img = AnimationTransition.transition_img[self.frame] if self.frame == 35: self.reverse() display.blit(img, (0, 0))
def show_marks(self): # отрисовка оценок за ноты flag = False # переменная нужна для того, чтобы отображалось только одна оценка for i, elem in enumerate(self.marks): mark, time = elem if self.activate_ability: # условие для способностей персонажей - Flandre и Remilia if self.character == 3 and (mark == 200 or mark == 100) or \ self.character == 0 and (mark == 50 or mark == 0): mark = 300 coord = (st_x + 10, 300) # координаты отрисовки оценки if not flag: if mark == 0: image = hit0 # Miss elif mark == 50: image = hit50 # Bad elif mark == 100: image = hit100 # Good elif mark == 200: image = hit200 # Great elif mark == 300: image = hit300 # Perfect elif mark == 301: image = hit301 # Marvelous image.set_alpha(255 * ((250 - self.marks[i][1] + 1) / 250)) # эффект пропадания оценки display.blit(image, coord) # отрисовка оценки self.marks[i][1] += 1000 / fps if self.marks[i][1] >= 250: # проверка, если оценка почти пропала m = self.marks.pop(i)[0] # получение значение оценки self.count_marks[m] += 1 # подсчет кол-ва каждой оценки self.score += m * self.coefficient # увелечение общего счета игрока if m == 0: # если был пропуск if self.character != 2: self.combo = 0 # комбо обнуляется elif self.combo > 100: # если выбран персонаж Reimu и комбо > 100 self.combo = 0 # то комбо не собьется else: self.combo += 1 # увелечение комбо if self.character == 4 and m != 300 and m != 301: # если выбран персонаж Sakuya # и оценка не была 'Marvelous' или 'Perfect', то комбо обнуляется self.combo = 0 if self.combo > self.max_combo: self.max_combo = self.combo # обновление значения максимального комбо if m == 301: # так как 'Marvelous' - это 301, а дает 320, то дополнительно self.score += 19 * self.coefficient # дается 19 flag = True
def render(self): display.blit(background, (0, 0)) # отрисовка заднего фона # отрисовка кнопок изменения громкости self.exit_btn.draw(0, 0) self.volume_up_btn.draw(0, 0) self.volume_down_btn.draw(0, 0) # отрисовка надписи и значения 'music volume' display.blit(music_volume_image, (60, 110)) drawing_text(str(int(self.music_volume)), (680, 120), font_color=(255, 255, 255), font_size=72, font_type='corp_round_v1.ttf') # отрисовка кнопок изменения скорости нот self.speed_up_btn.draw(0, 0) self.speed_down_btn.draw(0, 0) # отрисовка надписи и значения 'scroll speed' display.blit(scroll_speed_image, (60, 260)) drawing_text(str(self.scroll_speed) + ' px', (680, 270), font_color=(255, 255, 255), font_size=72, font_type='corp_round_v1.ttf') # отрисовка кнопки подтверждения изменений self.confrim_btn.draw(0, 0)
def show_points(self): # отрисовка статистики игрока score = str(self.score) # общий счет игрока score = '0' * (10 - len(score)) + score # добавление нулей если число меньше миллиарда display.blit(self.score_surface, (670, 30)) # обновление области общего счета drawing_text(score, (670, 40), pygame.Color('white'), font_size=40, font_type='corp_round_v1.ttf') # отрисовка общего счета sum_marks = sum(self.count_marks.values()) # кол-во всех полученных оценок if sum_marks != 0: # подсчет точности описан в файле ReadMe.txt self.accuracy = (self.score - 19 * self.count_marks[301]) / (sum_marks * 300) * 100 if self.accuracy > 100: self.accuracy = 100 display.blit(self.acc_surface, (670, 90)) # обновление точности drawing_text(str(('%.2f' % self.accuracy)) + ' %', (670, 100), pygame.Color('white'), font_size=40, font_type='corp_round_v1.ttf') # отрисовка точности display.blit(self.combo_surface, (670, 150)) # обновление комба игрока drawing_text(str(self.combo) + 'x', (670, 160), pygame.Color('white'), font_size=40, font_type='corp_round_v1.ttf') # отрисовка комба # отрисовка полоски способности персонажа if self.character == 0 or self.character == 1 or self.character == 3: if self.activate_ability: # если способность персонажа активна self.ability_score += 50 # уменьшается полоска способности if self.ability_score == 10000: self.activate_ability = False # способность отключается elif self.ability_score > 0: # способность накапливаться пока не заполнена self.ability_score -= 5 # заполняется способность медленне, чем тратиться(в 10 раз) self.ability_sprite.update() # обновление полоски способности персонажа pygame.draw.rect(display, (37, 25, 45), (672, 232, 371 * self.ability_score // 10000, 24)) # отрисовка не заполненой области
def update_notes(self): # обновление одиночных нот time = self.time_now if self.notes: while abs(self.notes[-1][1] - time) <= 1000 / fps: # добавление новых одиночных нот k = self.notes.pop() self.notes_active.append((Note(k[0]), k)) if not self.notes: break for i in range(len(self.notes_near) - 1, -1, -1): # обновление активных для нажатия нот sprite, note = self.notes_near[i] display.blit(sprite.image, sprite.rect) sprite.update() if note[-1] - time <= -self.od_50: self.marks.append([0, 0]) self.notes_near.pop(i) for i in range(len(self.notes_active) - 1, -1, -1): # обновление активных одиночных нот sprite, note = self.notes_active[i] display.blit(sprite.image, sprite.rect) sprite.update() if note[-1] - time <= self.od_50: self.notes_near.append(self.notes_active.pop(i))
def render(self): display.blit(menu_background[0], (0, 0)) # отрисовка изображений заднего фона display.blit(menu_background[1], (0, 620)) display.blit(menu_background[2], (0, 0)) chr = character_list[self.ind_chr] # спрайт отображаемого персонажа if self.ind_chr == self.character: # отрисовка круга выбранного персонажа pygame.draw.circle(display, (212, 84, 182), (565, 385), 220) chr.update() text, cords = self.names_chr[ self.ind_chr] # имя и координаты имени персонажа drawing_text(text, cords, font_color=pygame.Color('White'), font_size=70) # отрисовка имени text = character_ability[ self.ind_chr] # описание способности персонажа for i in range( len(text) ): # отрисовка описание способности персонажа(тень текста) drawing_text(text[i], (240 - 10 * i + 2, 600 + 30 * i + 2), font_size=30, font_color=pygame.Color('Black')) for i in range( len(text) ): # отрисовка описание способности персонажа(основной текст) drawing_text(text[i], (240 - 10 * i, 600 + 30 * i), font_color=pygame.Color('White'), font_size=30) # отрисовка кнопок self.exit_btn.draw(0, 0) # выход к экрану выбора карт self.confirm_btn.draw(0, 0) # подтвердить выбранного персонажа self.left_button.draw(0, 0) # прошлый персонаж self.right_button.draw(0, 0) # следующий персонаж
def draw(self): display.blit(pygame.image.load('image/StartMenu.jpg'), (0, 0)) self.start_btn.draw(460, 210) self.continue_btn.draw(415, 340) self.exit_btn.draw(510, 470)
if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: x, y = event.pos if x < 600 and y < 450: spn = float(params['spn'].split(',')[0]) map_x, map_y = [float(i) for i in params['ll'].split(',')] new_x, new_y = ( (x - 300) / 600 * 2.55 * spn + map_x), (-y + 450 / 2) / 450 * spn * 1.2 + map_y params['pt'] = f'{new_x},{new_y},pmwtm1' params['type'] = 'geo' save_map_image(map_file, params) elif event.button == 3: x, y = event.pos if x < 600 and y < 450: spn = float(params['spn'].split(',')[0]) map_x, map_y = [float(i) for i in params['ll'].split(',')] new_x, new_y = ( (x - 300) / 600 * 2.55 * spn + map_x), (-y + 450 / 2) / 450 * spn * 1.2 + map_y params['type'] = 'biz' params['pt'] = f'{new_x},{new_y},pmwtm1' save_map_image(map_file, params) display.blit(pygame.image.load(map_file), (0, 0)) change_view_btn.draw(710, 25) change_place_btn.draw(680, 115) cancel_place_btn.draw(632, 205, size=27) info_btn.draw(675, 295) pygame.display.flip() clock.tick(fps)
def drawing_text(text, x, y, font_color=pygame.Color('black'), font_size=30): font_type = pygame.font.Font('lost.ttf', font_size) text = font_type.render(text, True, font_color) display.blit(text, (x, y))
def render_map(self): # отрисовка карты во время обратного отсчета display.fill((0, 0, 0)) display.blit(self.map_background, (0, 0)) display.blit(self.map_keys[0], (st_x, 0)) for notes in self.map_objects[0]: # отрисовка одиночных нот if len(notes) == 1: sprite = notes[0][0] display.blit(sprite.image, sprite.rect) elif len(notes) > 1: for note in notes: sprite = note[0] display.blit(sprite.image, sprite.rect) for slider in self.map_objects[1]: # отрисовка длинных нот for obj in slider: try: sprite = obj[0] display.blit(sprite.image, sprite.rect) except (AttributeError, TypeError): pass key0d_image, key1d_image = self.map_keys[1:] display.blit(key0d_image, (st_x + 30, 617)) display.blit(key1d_image, (st_x + 30 + 45, 617)) display.blit(key1d_image, (st_x + 30 + 45 * 2, 617)) display.blit(key0d_image, (st_x + 30 + 45 * 3, 617))
def render_pause(self): # отрисовка экрана паузы display.blit(background_image, (0, 0)) self.continue_btn.draw(0, 0) self.restart_btn.draw(0, 0) self.back_btn.draw(0, 0)
def render(self): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() display.blit(self.menu_background, (0, 0)) display.blit(back_mask, (0, 0)) for i, elem in enumerate(self.maps): x, y, map = elem if 1020 >= y >= -60: # отрисовка карты на экране if 500 <= mouse[0] and y <= mouse[1] <= y + 80 and mouse[ 1] <= 720 - 96: # отрисовка, если на карту наведен курсор # сдвиг прямоугольника карты влево self.maps[i][0] -= shift_v / fps self.maps[i][0] = min(self.maps[i][0], 500) self.maps[i][0] = max(470, self.maps[i][0]) display.blit(song_rect_active, (x, y)) if click[0]: # если курсор нажали # смена активной карты self.maps[self.active_map][0] += 30 self.active_map = i map = self.maps[self.active_map][2] self.menu_background = map.background self.maps[i][0] -= 30 self.maps[i][0] = min(self.maps[i][0], 500) self.maps[i][0] = max(470, self.maps[i][0]) pygame.mixer.music.load( f'maps/{map.dir}/{map.general["AudioFilename"]}') pygame.mixer.music.set_volume( 0.1 * int(settings_values['music_volume'])) pygame.mixer.music.play(-1) else: # отрисовка карты если курсор на нее не наведен if i != self.active_map: # сдвиг карты влево self.maps[i][0] += shift_v / fps self.maps[i][0] = min(self.maps[i][0], 500) self.maps[i][0] = max(470, self.maps[i][0]) display.blit(song_rect, (x, y)) song_background = map.small_background display.blit(song_background, (x, y)) title, artist, creator, version = map.title, map.artist, map.creator, map.version # отрисовка текста об карте с сохранением изображений текста if title in self.cache: display.blit(self.cache[title], (x + 130, y + 10)) else: self.cache[title] = drawing_text(title, (x + 130, y + 10), font_color=pygame.Color( 255, 255, 255), font_size=20) if artist in self.cache: display.blit(self.cache[artist], (x + 130, y + 32)) else: self.cache[artist] = drawing_text(artist, (x + 130, y + 32), font_color=pygame.Color( 200, 200, 200), font_size=15, italic=True) if version in self.cache: display.blit(self.cache[version], (x + 130, y + 50)) else: self.cache[version] = drawing_text(version, (x + 130, y + 50), font_color=pygame.Color( 255, 255, 255), font_size=23) # отрисовка кнопок, полосок меню display.blit(menu_back_plus, (0, 620)) display.blit(menu_plus, (0, 0)) self.play_btn.draw(0, 0) self.exit_btn.draw(0, 0) self.play_btn.draw(0, 0) self.chr_btn.draw(0, 0) self.settings_btn.draw(0, 0) # удаление из словаря с рекордами рекорда, если для какой-то карты их больше 6 if int(self.maps[self.active_map][2].map_id) in self.records: while len(self.records[int( self.maps[self.active_map][2].map_id)]) > 6: self.records[int(self.maps[self.active_map][2].map_id)].pop() records = self.records[int(self.maps[self.active_map][2].map_id)] else: records = [] for y, elem in enumerate(records): # отрисовка рекорда elem_id, map_id, mapset_id, score, accuracy, combo, date, time = elem y *= 90 y += 100 display.blit(records_rect, (-200, y)) display.blit(date, (10, y + 10)) display.blit(score, (10, y + 30)) display.blit(accuracy, (300, y + 60)) display.blit(combo, (10, y + 50))
def render(self): display.blit(background, (0, 0)) display.blit(self.rank, (775, 110)) # отрисовка точности игрока drawing_text(self.accuracy, (790, 400), (255, 255, 255), 60, font_type='corp_round_v1.ttf') display.blit(miss, (0, 40)) drawing_text(self.marks[0], (65, 100), (200, 0, 0), 50, font_type='corp_round_v1.ttf') # отрисовка набранных оценок display.blit(bad, (290, 40)) drawing_text(self.marks[1], (355, 100), (230, 0, 150), 50, font_type='corp_round_v1.ttf') display.blit(good, (0, 170)) drawing_text(self.marks[2], (65, 230), (0, 185, 230), 50, font_type='corp_round_v1.ttf') display.blit(great, (290, 170)) drawing_text(self.marks[3], (355, 230), (0, 230, 30), 50, font_type='corp_round_v1.ttf') display.blit(perfect, (0, 320)) drawing_text(self.marks[4], (65, 390), (255, 255, 75), 50, font_type='corp_round_v1.ttf') display.blit(marvelous, (290, 315)) drawing_text(self.marks[5], (355, 390), (235, 250, 255), 50, font_type='corp_round_v1.ttf') # отрисовка максимального комбо игрока drawing_text(self.count_combo, (210, 520), (255, 255, 255), 50, font_type='corp_round_v1.ttf') score_width = len(self.score) * 25 x = 890 - score_width // 2 drawing_text(self.score, (x, 530), (255, 255, 255), 50, font_type='corp_round_v1.ttf') self.back_btn.draw(0, 0) self.restart_btn.draw(0, 0)
def render(self): self.time_now = (pygame.time.get_ticks() - self.time) # обновление игрового поля display.fill((0, 0, 0), (st_x + 30, 0, 45 * 4, 720)) display.blit(stage_image, (st_x, 0)) keys = pygame.key.get_pressed() # получение всех прожатых на клавиатуре клавиш for key in range(4): if keys[keyboard[key]]: # линия на кторой была нажата клавиша, становится яркой display.blit(stage_light_image, (st_x + 30 + 45 * key, 617 - 737)) if self.notes or self.notes_near or self.notes_active: self.update_notes() # обновление всех одиночных нот if self.sliders or self.sliders_pressed[0] != -1 or self.sliders_pressed[1] != -1 or \ self.sliders_pressed[2] != -1 or self.sliders_pressed[3] != -1 or \ self.sliders_near or self.sliders_active or self.sliders_failed: self.update_sliders() # обновление всех длинных нот if self.activate_ability and self.character == 1: self.destroy_sliders() # если выбран персонаж 'Marisa' и была использована способность self.destroy_notes() # то уничтожаются все одиночные и все длинные ноты else: # проверка нажатия клавиш, когда длинная нота рядом # одиночные ноты проверяются в функции 'handle_keys_notes' в цикле 'play_map'(main.py) self.handle_keys_sliders() # отрисовка оценок display.fill((0, 0, 0), (st_x + 30, 700, 45 * 4, 20)) self.show_marks() self.show_points() # отрисовка общего счета, точности и комбо игрока # обновление спрайта персонажа display.blit(self.surface_chr, (600, 300)) if self.activate_ability: # отрисовка активированной способности персонажа if self.character == 1 and self.character_ability.k < 0 and \ self.character_ability.cur_frame < 1: # эта проверка созданна для персонажа self.character_stand.update() # Marisa, чтобы она сделала только 2 оборота else: self.character_ability.update() else: self.character_stand.update() # отрисовка обычного состояния персонажа # отрисовка нажатых и не нажатых клавиш if keys[pygame.K_d]: display.blit(key0d_image, (st_x + 30, 617)) else: display.blit(key0_image, (st_x + 30, 617)) if keys[pygame.K_f]: display.blit(key1d_image, (st_x + 30 + 45, 617)) else: display.blit(key1_image, (st_x + 30 + 45, 617)) if keys[pygame.K_j]: display.blit(key1d_image, (st_x + 30 + 45 * 2, 617)) else: display.blit(key1_image, (st_x + 30 + 45 * 2, 617)) if keys[pygame.K_k]: display.blit(key0d_image, (st_x + 30 + 45 * 3, 617)) else: display.blit(key0_image, (st_x + 30 + 45 * 3, 617)) if self.ability_score == 0: # активация способности персонажа if keys[pygame.K_SPACE]: # по нажатию на пробел self.activate_ability = True for key in range(4): # отрисовка вспышек self.lightnings[key] -= 20 if self.lightnings[key] >= 0: lightning = lightning_image lightning.set_alpha(self.lightnings[key]) display.blit(lightning, ( st_x + 30 + 45 * key + 45 // 2 - lightning.get_width() // 2, 617 - lightning.get_height() // 2))
def __init__(self, map): global v, time_uprise settings_values = load_settings() # загрузка настроек игрока v = int(settings_values['scroll_speed']) # обновление значения скорости игрока time_uprise = ((720 - 130) / v * 1000) // 1 # обновление времени начала движения нот self.map = map[2] self.score = 0 # общий счет игрока self.accuracy = 100 # точность нажатий игрока self.max_combo = 0 # максимальное комбо игрока self.combo = 0 # комбо игрока # настройка времени для получения соответсвующей оценки od = float(self.map.OD) # время, за которое нужно нажать на ноту для какой-то оценки self.od_max = 16.5 * 2 self.od_300 = (64 - (od * 3)) * 2 self.od_200 = (97 - (od * 3)) * 2 self.od_100 = (127 - (od * 3)) * 2 self.od_50 = (151 - (od * 3)) * 2 self.marks = [] # подсчет кол-ва всех оценок self.count_marks = {0: 0, 50: 0, 100: 0, 200: 0, 300: 0, 301: 0} # создания списков для отслеживания состояния одиночных нот self.notes_near = [] # нота находится в области нажатий игрока self.notes_active = [] # нота присутсвует на игровом поле self.notes = [i.copy() for i in self.map.objects if i[2] == 1] # все ноты карты for i in range(len(self.notes)): # заполнения массива 'self.notes' self.notes[i].append(self.notes[i][1]) self.notes[i][1] -= time_uprise # преобразование массива для удобства отслеживания нот self.notes.sort(key=lambda x: x[1], reverse=True) while self.notes[-1][1] <= 0: self.notes.pop() # создания списков для отслеживания состояния длинных нот(или по другому slider) self.sliders_active = [] # длинная нота находится в области нажатий игрока self.sliders_near = [] # длинная нота присутсвует на игровом поле self.sliders_pressed = [-1, -1, -1, -1] # массив для хранения нажатых слайдеров self.sliders_pressed_ms = [-1, -1, -1, -1] # массив для отслеживания кол-ва времен # потраченного на прожатие слайдера self.sliders_failed = [] # пропущенная или ненажатая длинная нота self.sliders = [i.copy() for i in self.map.objects if i[2] == 128] # все длинные ноты for i in range(len(self.sliders)): # заполнения массива 'self.sliders' self.sliders[i].append(self.sliders[i][1]) self.sliders[i][1] -= time_uprise # преобразование массива для удобства отслеживания длинных нот self.sliders.sort(key=lambda x: x[1], reverse=True) while self.sliders[-1][1] < 0: self.sliders.pop() self.end_time = max((self.notes[0][4], self.sliders[0][3])) + 1500 # время оканчания карты self.map.background.set_alpha(100) # задней фон карты display.fill((0, 0, 0)) display.blit(self.map.background, (0, 0)) # загрузка музыки карты pygame.mixer.music.load(f'maps/{self.map.dir}/{self.map.general["AudioFilename"]}') pygame.mixer.music.set_volume(0.1 * int(settings_values['music_volume'])) pygame.mixer.music.play(1) # создание изображения для обновления значения общего счета игрока score_surface = self.map.background.subsurface((670, 30, 290, 50)) self.score_surface = pygame.surface.Surface((290, 50)) self.score_surface.fill((0, 0, 0)) score_surface.set_alpha(100) self.score_surface.blit(score_surface, (0, 0)) # создание изображения для обновления значения точности попадания игрока acc_surface = self.map.background.subsurface((670, 90, 200, 50)) self.acc_surface = pygame.surface.Surface((200, 50)) self.acc_surface.fill((0, 0, 0)) acc_surface.set_alpha(100) self.acc_surface.blit(acc_surface, (0, 0)) # создание изображения для обновления значения комбо игрока combo_surface = self.map.background.subsurface((670, 150, 150, 50)) self.combo_surface = pygame.surface.Surface((150, 50)) self.combo_surface.fill((0, 0, 0)) combo_surface.set_alpha(100) self.combo_surface.blit(combo_surface, (0, 0)) # анимация заполненой способности персонажа self.ability_sprite = AnimatedSprite('ability_bar/ability_bar', 17, 645, 230, 15) self.ability_score = 10000 # значение при котором способность можно буде использовать self.activate_ability = False # переменная для отслеживания активации способности self.character = int(settings_values['character']) # персонаж # создание изображения для обновления персонажа surface_chr = self.map.background.subsurface((600, 300, 500, 355)) self.surface_chr = pygame.surface.Surface((500, 355)) self.surface_chr.fill((0, 0, 0)) surface_chr.set_alpha(100) self.surface_chr.blit(surface_chr, (0, 0)) # коэффициэнт очков игрока if self.character == 4: # множитель будет 1.5, если выбран персонаж 'Sakuya' self.coefficient = 1.5 else: # множитель будет 1 у всех персонажей, кроме 'Sakuya' self.coefficient = 1 self.character_stand = AnimatedSprite(*character_dict[self.character]) # анимация персонажа if self.character != 2 and self.character != 4: # анимация способности персонажа(если есть) self.character_ability = AnimatedSprite(*ability_dict[self.character]) # массив для отслеживания, на каких линиях нужно сделать вспышки self.lightnings = [-1, -1, -1, -1] self.time = pygame.time.get_ticks() # время начала игры