def __init__(self, screen, item, pos_x, pos_y, icon=""): self.screen = screen self.display_height = self.screen.get_height() / 2 self.display_width = self.screen.get_width() self.font_size = self.screen.get_height() / 10 self.title_size = self.display_height self.pos_x = pos_x self.pos_y = pos_y self.item = item self.input_text = '' self.input_format = '%s' # Player-Bild self.player_icon = None if icon != '': image = pygame.image.load(os.path.join('icons', '%s.png' % icon)) self.player_icon = pygame.transform.smoothscale( image, (image.get_rect().width * self.display_height / image.get_rect().height, self.display_height)) self.player_icon_position = (self.display_width / 2 - self.player_icon.get_rect().width / 2, self.pos_y) # Input-Zeile self.input_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.font_size) self.input = Label(self.input_format % self.input_text, self.input_font, (68, 68, 68), (255, 255, 255)) self.input.set_position( self.display_width / 2 + self.pos_x - self.input.width / 2, self.pos_y + self.display_height / 2 - self.input.height / 2)
def __init__(self, screen, race_length, diameter, actions): self.race_status = 'READY' self.actions = actions self.screen = screen self.screen_width = self.screen.get_rect().width self.screen_height = self.screen.get_rect().height self.font_size = self.screen_height / 9 self.font = pygame.font.Font('fonts/UbuntuMono.ttf', self.font_size) self.information_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.font_size * 3 / 7) self.race_length = race_length self.diameter = diameter # Leeres Array für Player, wird in Unterklassen belegt self.players = [] # Informations-Label self.information_label = Label(u'Return zum Starten …', self.information_font, (68, 68, 68), (255, 255, 255)) self.information_label.set_position( (self.screen_width / 2) - (self.information_label.width / 2), (self.screen_height - self.information_label.height)) # Countdown self.countdown = Countdown(self.screen, {'success': self.start})
def __init__(self, screen, race_lengths, results, actions, current_item=3): self.screen = screen self.screen_width = self.screen.get_rect().width self.screen_height = self.screen.get_rect().height self.actions = actions self.title_font_size = self.screen_height / 12 self.title_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.title_font_size) self.title_format = 'Highscore %dm' self.item_format = '%s %s %s %s' self.item_offset = 0 self.results = results self.race_lengths = race_lengths self.current_race_length = current_item self.highscore_title = Label( self.title_format % self.race_lengths[self.current_race_length], self.title_font, (68, 68, 68), (255, 255, 255) ) self.highscore_title.set_position( (self.screen_width / 2) - (self.highscore_title.width / 2), 0 ) self.highscore_height = self.screen_height - self.highscore_title.height self.item_font_size = self.highscore_height / 12 self.item_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.item_font_size) self.item_surface = None self.current_highscore_items = None self.fill_item_surface()
def __init__(self, screen, pos_x, pos_y, font, diameter): self.screen = screen self.screen_width = screen.get_rect().width self.screen_height = screen.get_rect().height self.format = '%7.2fkm/h' self.avg_format = u'ø%6.2fkm/h' self.value = 0.0 self.label_text = self.format % self.value self.pos_x = pos_x self.pos_y = pos_y self.font_size = self.screen_height / 9 self.font = font self.prev_time = int(round(time.time() * 1000)) self.diameter = diameter self.label = Label(self.format % 0.0, self.font, (68, 68, 68), (255, 255, 255), (0, 0), 'speed-grey') self.label.set_position( self.pos_x + self.screen_width - self.label.width - self.screen_width / 60, self.pos_y + self.screen_width / 60) self.current_ticks = 0
class Speedo(): def __init__(self, screen, pos_x, pos_y, font, diameter): self.screen = screen self.screen_width = screen.get_rect().width self.screen_height = screen.get_rect().height self.format = '%7.2fkm/h' self.avg_format = u'ø%6.2fkm/h' self.value = 0.0 self.label_text = self.format % self.value self.pos_x = pos_x self.pos_y = pos_y self.font_size = self.screen_height / 9 self.font = font self.prev_time = int(round(time.time() * 1000)) self.diameter = diameter self.label = Label(self.format % 0.0, self.font, (68, 68, 68), (255, 255, 255), (0, 0), 'speed-grey') self.label.set_position( self.pos_x + self.screen_width - self.label.width - self.screen_width / 60, self.pos_y + self.screen_width / 60) self.current_ticks = 0 def update(self): self.label.set_text(self.get_current_speed()) def render(self): self.screen.blit(self.label.label, self.label.position) def get_current_speed(self): current_time = int(round(time.time() * 1000)) value = (self.format % 0.0) if self.prev_time is not None and current_time - self.prev_time < 1000: value = self.format % self.value return value def set_current_speed(self, ticks): self.current_ticks += ticks if self.current_ticks > 8: current_time = int(round(time.time() * 1000)) self.value = (self.current_ticks * self.diameter * 36.0) / (current_time - self.prev_time) self.current_ticks = 0 self.prev_time = current_time def set_avg_speed(self, speed): self.label.set_text(self.avg_format % speed)
class PreGameItem(): def __init__(self, screen, item, pos_x, pos_y, icon=""): self.screen = screen self.display_height = self.screen.get_height() / 2 self.display_width = self.screen.get_width() self.font_size = self.screen.get_height() / 10 self.title_size = self.display_height self.pos_x = pos_x self.pos_y = pos_y self.item = item self.input_text = '' self.input_format = '%s' # Player-Bild self.player_icon = None if icon != '': image = pygame.image.load(os.path.join('icons', '%s.png' % icon)) self.player_icon = pygame.transform.smoothscale( image, (image.get_rect().width * self.display_height / image.get_rect().height, self.display_height)) self.player_icon_position = (self.display_width / 2 - self.player_icon.get_rect().width / 2, self.pos_y) # Input-Zeile self.input_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.font_size) self.input = Label(self.input_format % self.input_text, self.input_font, (68, 68, 68), (255, 255, 255)) self.input.set_position( self.display_width / 2 + self.pos_x - self.input.width / 2, self.pos_y + self.display_height / 2 - self.input.height / 2) def activate_input(self): self.input_format = '%s_' def deactivate_input(self): self.input_format = '%s' def append_key(self, key): if len(self.input_text) < 12: self.input_text += key def delete_last_char(self): self.input_text = self.input_text[:-1] def update(self, deltat): self.input.set_text(self.input_format % self.input_text) self.input.set_position( self.display_width / 2 + self.pos_x - self.input.width / 2, self.pos_y + self.display_height / 2 - self.input.height / 2) def render(self, deltat): self.screen.blit(self.player_icon, self.player_icon_position) self.screen.blit(self.input.label, self.input.position) def activate(self): self.input.set_font_color((68, 68, 68)) self.input.set_background_color((255, 255, 255)) def deactivate(self): self.input.set_font_color((68, 68, 68)) self.input.set_background_color((255, 255, 255))
class Race(): def __init__(self, screen, race_length, diameter, actions): self.race_status = 'READY' self.actions = actions self.screen = screen self.screen_width = self.screen.get_rect().width self.screen_height = self.screen.get_rect().height self.font_size = self.screen_height / 9 self.font = pygame.font.Font('fonts/UbuntuMono.ttf', self.font_size) self.information_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.font_size * 3 / 7) self.race_length = race_length self.diameter = diameter # Leeres Array für Player, wird in Unterklassen belegt self.players = [] # Informations-Label self.information_label = Label(u'Return zum Starten …', self.information_font, (68, 68, 68), (255, 255, 255)) self.information_label.set_position( (self.screen_width / 2) - (self.information_label.width / 2), (self.screen_height - self.information_label.height)) # Countdown self.countdown = Countdown(self.screen, {'success': self.start}) def update(self, deltat): for player in self.players: player.update(deltat) if self.race_status == 'COUNTDOWN': self.countdown.update(deltat) if self.race_status == 'RUNNING': if self.players[0].finished and self.players[1].finished: self.finish_race() elif self.players[0].finished: self.players[0].set_winner() elif self.players[1].finished: self.players[1].set_winner() def render(self, deltat): # Player rendern for player in self.players: player.render(deltat) # Info-Label rendern if self.race_status == 'READY': self.screen.blit(self.information_label.label, self.information_label.position) elif self.race_status == 'COUNTDOWN': self.countdown.render(deltat) elif self.race_status == 'FINISHED': self.screen.blit(self.information_label.label, self.information_label.position) def set_race_status(self, status): self.race_status = status def handle_input_data(self, event): # Anfangs-Status if self.race_status == 'READY': if event.key == pygame.K_RETURN: self.information_label.set_text(' ') self.set_race_status('COUNTDOWN') self.countdown.start() if self.race_status == 'FINISHED': if event.key == pygame.K_RETURN: self.actions['success']() # Countdown-Status elif self.race_status == 'COUNTDOWN': if event.key == pygame.K_ESCAPE: self.countdown.stop() self.race_status = 'READY' self.information_label.set_text(u'Return zum Starten …') self.information_label.set_position( (self.screen_width / 2) - (self.information_label.width / 2), (self.screen_height - self.information_label.height)) # sonstige Status else: if event.key == pygame.K_ESCAPE: self.actions['cancel']() def start(self): self.set_race_status('RUNNING') start_time = time.time() # Startzeiten an Player übermitteln for player in self.players: player.running = True player.set_start_time(start_time) def interrupt_countdown(self, interrupter): self.countdown.stop() self.race_status = 'READY' format = u'Fehlstart von %s (Return für Neustart …)' self.information_label.set_text(format % interrupter.name) self.information_label.set_position( (self.screen_width / 2) - (self.information_label.width / 2), (self.screen_height - self.information_label.height)) def finish_race(self): self.information_label.set_text(u'Weiter mit Return …') self.information_label.set_position( (self.screen_width / 2) - (self.information_label.width / 2), (self.screen_height - self.information_label.height)) self.set_race_status('FINISHED')
class Highscore(): def __init__(self, screen, race_lengths, results, actions, current_item=3): self.screen = screen self.screen_width = self.screen.get_rect().width self.screen_height = self.screen.get_rect().height self.actions = actions self.title_font_size = self.screen_height / 12 self.title_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.title_font_size) self.title_format = 'Highscore %dm' self.item_format = '%s %s %s %s' self.item_offset = 0 self.results = results self.race_lengths = race_lengths self.current_race_length = current_item self.highscore_title = Label( self.title_format % self.race_lengths[self.current_race_length], self.title_font, (68, 68, 68), (255, 255, 255) ) self.highscore_title.set_position( (self.screen_width / 2) - (self.highscore_title.width / 2), 0 ) self.highscore_height = self.screen_height - self.highscore_title.height self.item_font_size = self.highscore_height / 12 self.item_font = pygame.font.Font('fonts/UbuntuMono.ttf', self.item_font_size) self.item_surface = None self.current_highscore_items = None self.fill_item_surface() def render(self, deltat): self.screen.blit(self.item_surface, ( self.screen_width / 2 - self.item_surface.get_rect().width / 2, self.highscore_title.height )) self.screen.blit(self.highscore_title.label, self.highscore_title.position) def fill_item_surface(self): self.current_highscore_items = self.get_highscore_for_length() self.item_surface = Surface((self.screen_width, self.highscore_height)) self.item_surface.fill((68, 68, 68)) last_item = self.item_offset + 10 if len(self.current_highscore_items) + 10 < len(self.current_highscore_items) else len(self.current_highscore_items) position = 0 for i in range(self.item_offset, last_item): player = self.current_highscore_items[i] highscore_item = self.item_font.render( self.item_format % ( str(i + 1).rjust(2), player['name'].ljust(12), helpers.format_time(player['time']).rjust(7), helpers.format_speed(player['speed']).rjust(10) ), 1, (255, 255, 255) ) pos_x = (self.screen_width / 2) - (highscore_item.get_rect().width / 2) pos_y = position * highscore_item.get_rect().height + highscore_item.get_rect().height / 2 self.item_surface.blit(highscore_item, (pos_x, pos_y)) position += 1 def handle_keypress(self, event): if event.key == pygame.K_ESCAPE: self.actions['cancel']() elif event.key == pygame.K_RIGHT: if self.current_race_length + 1 < len(self.race_lengths): self.item_offset = 0 self.current_race_length += 1 self.fill_item_surface() self.highscore_title.set_text(self.title_format % self.race_lengths[self.current_race_length]) self.highscore_title.set_position( (self.screen_width / 2) - (self.highscore_title.width / 2), 0 ) elif event.key == pygame.K_LEFT: if self.current_race_length > 0: self.item_offset = 0 self.current_race_length -= 1 self.fill_item_surface() self.highscore_title.set_text(self.title_format % self.race_lengths[self.current_race_length]) self.highscore_title.set_position( (self.screen_width / 2) - (self.highscore_title.width / 2), 0 ) self.fill_item_surface() elif event.key == pygame.K_UP: self.item_offset -= 1 if self.item_offset > 0 else 0 self.fill_item_surface() elif event.key == pygame.K_DOWN: if self.item_offset + 1 < len(self.current_highscore_items) - 10: self.item_offset += 1 self.fill_item_surface() def get_highscore_for_length(self): return self.results[str(self.race_lengths[self.current_race_length])]
def __init__(self, screen, name, color, pos_x, pos_y, race_length, diameter, background=''): self.screen = screen self.screen_width = screen.get_rect().width self.screen_height = screen.get_rect().height self.font = pygame.font.Font('fonts/UbuntuMono.ttf', self.screen_height / 12) self.race_length = race_length self.diameter = diameter self.color = color self.name = name self.pos_x = pos_x self.pos_y = pos_y self.event_count = 0 self.full_ticks = (self.race_length * 100) / self.diameter self.running = False self.finished = False self.start_time = time.time() self.current_time_text = self.format_time(self.get_current_time()) self.finish_time = None self.avg_speed = None # Namenslabel self.name_label = Label(self.name, self.font, self.color, (255, 255, 255), (0, 0)) self.name_label.set_position(self.pos_x + self.screen_width / 60, self.pos_y + self.screen_width / 60) # Label für Gewinner self.winner_label = Label('Winner', self.font, (68, 68, 68), (255, 255, 255)) self.winner_label.set_position( self.pos_x + self.screen_width / 60, self.pos_y + 2 * self.screen_width / 60 + self.name_label.height) self.winner = False self.show_winner = False self.winner_ticker = 600 # Time self.time_label = Label(self.current_time_text, self.font, (68, 68, 68), (255, 255, 255), (0, 0), 'time-grey') self.time_label.set_position( self.pos_x + self.screen_width - self.time_label.width - self.screen_width / 60, self.pos_y + self.time_label.height + self.screen_width / 60 + self.screen_width / 60) # Progress self.progress_bar = Progress(self.screen, self.color, pos_x, pos_y, background) # Speedo self.speedo = Speedo(self.screen, self.pos_x, self.pos_y, self.font, self.diameter)
class Player(): def __init__(self, screen, name, color, pos_x, pos_y, race_length, diameter, background=''): self.screen = screen self.screen_width = screen.get_rect().width self.screen_height = screen.get_rect().height self.font = pygame.font.Font('fonts/UbuntuMono.ttf', self.screen_height / 12) self.race_length = race_length self.diameter = diameter self.color = color self.name = name self.pos_x = pos_x self.pos_y = pos_y self.event_count = 0 self.full_ticks = (self.race_length * 100) / self.diameter self.running = False self.finished = False self.start_time = time.time() self.current_time_text = self.format_time(self.get_current_time()) self.finish_time = None self.avg_speed = None # Namenslabel self.name_label = Label(self.name, self.font, self.color, (255, 255, 255), (0, 0)) self.name_label.set_position(self.pos_x + self.screen_width / 60, self.pos_y + self.screen_width / 60) # Label für Gewinner self.winner_label = Label('Winner', self.font, (68, 68, 68), (255, 255, 255)) self.winner_label.set_position( self.pos_x + self.screen_width / 60, self.pos_y + 2 * self.screen_width / 60 + self.name_label.height) self.winner = False self.show_winner = False self.winner_ticker = 600 # Time self.time_label = Label(self.current_time_text, self.font, (68, 68, 68), (255, 255, 255), (0, 0), 'time-grey') self.time_label.set_position( self.pos_x + self.screen_width - self.time_label.width - self.screen_width / 60, self.pos_y + self.time_label.height + self.screen_width / 60 + self.screen_width / 60) # Progress self.progress_bar = Progress(self.screen, self.color, pos_x, pos_y, background) # Speedo self.speedo = Speedo(self.screen, self.pos_x, self.pos_y, self.font, self.diameter) def update(self, deltat): self.progress_bar.set_progress(self.event_count * 1.0 / self.full_ticks) if self.running: self.time_label.set_text(self.format_time(self.get_current_time())) if not self.finished: self.speedo.update() if self.winner: if self.winner_ticker > 500: self.show_winner = not self.show_winner self.winner_ticker = 0 else: self.winner_ticker += deltat def render(self, deltat): self.progress_bar.render() self.screen.blit(self.name_label.label, self.name_label.position) self.screen.blit(self.time_label.label, self.time_label.position) self.speedo.render() if self.show_winner: self.screen.blit(self.winner_label.label, self.winner_label.position) def handle_progress(self, ticks): if self.running: if self.event_count < self.full_ticks: self.event_count += ticks else: self.finish_time = self.get_current_time() self.running = False self.finished = True self.avg_speed = (self.race_length * 3.6) / self.finish_time self.speedo.set_avg_speed(self.avg_speed) self.time_label.set_text(self.format_time(self.finish_time)) self.speedo.set_current_speed(ticks) def set_start_time(self, start_time): self.start_time = start_time def get_current_time(self): return time.time() - self.start_time def format_time(self, timer): seconds = int(timer) milli_seconds = int(modf(timer)[0] * 100) return ('%0d.%02ds' % (seconds, milli_seconds)).rjust(11) def set_winner(self): self.winner = True