def initialization(): """инициализация нужных файлов игры""" pygame.init() Viewer.init() Display.init(width=settings.WINDOW_WIDTH, height=settings.WINDOW_HEIGHT, framerate=settings.FRAMERATE) Menu.init() Skins.init() Map.init(width=settings.MAP_WIDTH, height=settings.MAP_HEIGHT)
class MainMenu(object): def __init__(self, stdscreen, player, parent): self.parent = parent self.args = parent.args self.screen = stdscreen self.player = player self.map_generator = None self.menu_items = (MenuItem('New Player', self.recreate_player, 0), MenuItem('Select Class', self.class_select, 1), MenuItem('Set Attributes', self.attr_select, 2), MenuItem('Start Game', self.go, 3), MenuItem('Options', self.opt_menu, 4)) self.populate_menu() self.main_menu.display() def recreate_player(self): self.parent.player = self.player = Player() self.main_menu.msg_bar('[*] Player refreshed') self.main_menu.draw_charinfo() def go(self): game = MapWindow(self.screen, self.parent) # game.post_init() return game.display() def opt_menu(self): menu = OptionMenu(self.screen, self) menu.post_init() return menu.display() def class_select(self): menu = ClassSelection(self.screen, self) menu.post_init() return menu.display() def attr_select(self): if self.player.player_class is None: self.main_menu.current_msg = 'Select a Class first!' self.main_menu.msg_bar() return menu = AttributeSelection(self.screen, self) menu.post_init() return menu.display() def populate_menu(self): item_list = [] for item in self.menu_items: item_list.append(item) self.main_menu = Menu(self.screen, self) self.main_menu.post_init(item_list)
def __menu(self): print("entering __menu") menu = Menu(self.graphics, ("play", "how to play", "exit")) state_to_return = "EXIT" goon = True while goon: # events for event in pygame.event.get(): if event.type == QUIT: goon = False menu.event(event) # updates menu.update() choice = menu.get_clicked_button_txt() if choice == "play": state_to_return = "GAME" goon = False if choice == "how to play": state_to_return = "HOWTOPLAY" goon = False #if choice == "credits": # state_to_return = "CREDITS" # goon = False if choice == "exit": state_to_return = "EXIT" goon = False # draws finalrender = pygame.Surface((c.WINDOW_WIDTH, c.WINDOW_HEIGHT)) finalrender.blit(menu.draw(), (0, 0)) self.screen.blit( pygame.transform.scale(finalrender, (c.WINDOW_WIDTH, c.WINDOW_HEIGHT)), (0, 0)) pygame.display.flip() self.clock.tick(30) print("exiting __menu") return state_to_return
SCREEN_SIZE = (1080, 720) SCREEN_COLOR = (255, 255, 255) screen = pygame.display.set_mode(SCREEN_SIZE) # screen = pygame.display.set_mode(SCREEN_SIZE, pygame.FULLSCREEN, pygame.RESIZABLE) # 60 frames per second clock = pygame.time.Clock() FPS = 60 # Debug mode on DEBUG = True DEBUG_FONT = pygame.font.SysFont("arial", 16) menu = Menu() # player pl = Player((540, 500)) keydict = [ pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN, pygame.K_LSHIFT ] player_group = pygame.sprite.Group() player_group.add(pl) level = "hometown" bg = level_list[level] music = bg.music_path save_data = {"level": level, "pos": pl.get_rect(), "save_iteration": 0}
from game.menu import Menu if __name__ == '__main__': menu = Menu() menu.init_menu()
# Caméra from view.skins import Skins # Skins pygame.init() # Initialisation de pygame Camera.init() # Initialisation de la caméra Display.init(width=config.WINDOW_WIDTH, height=config.WINDOW_HEIGHT, framerate=config.FRAMERATE) # Initialisation de la fenêtre Menu.init() # Initialisation du menu Skins.init() # Initialisation et chargement des skins Map.init(width=config.MAP_WIDTH, height=config.MAP_HEIGHT) # Initialisation du terrain de jeu Game.run() # Lancement du jeu pygame.quit() # Fermeture de pygame
from game.menu import Menu from game.base import Construct menu = Menu() menu.start() draft_player = Construct(menu.race, menu.gender, menu.name) player = draft_player.player_build() print(player)
def __init__(self): """ initialize game window """ pg.init() pg.mixer.init() self.clock = pg.time.Clock() if FULLSCREEN: self.screen = pg.display.set_mode((WIDTH, HEIGHT), pg.FULLSCREEN) else: self.screen = pg.display.set_mode((WIDTH, HEIGHT)) pg.display.set_caption(TITLE) self.font_name = pg.font.match_font(FONT_NAME) self.running = True self.playing = True self.has_won = False self.lives = PLAYER_LIVES self.coin_counter = 0 self.dead = True self.frame_count = 0 self.total_seconds = 0 self.dir = path.dirname(__file__) # init sprite Groups self.all_sprites = pg.sprite.Group() self.platforms = pg.sprite.Group() self.death_tiles = pg.sprite.Group() self.checkpoints = pg.sprite.Group() self.ai_borders = pg.sprite.Group() self.coins = pg.sprite.Group() self.sprites_on_screen = pg.sprite.Group() self.jump_pads = pg.sprite.Group() self.enemies = pg.sprite.Group() self.sprites_on_screen = pg.sprite.Group() self.finishes = pg.sprite.Group() # map self.player = None self.map = None self.player_start = None self.player_spawn = None self.total_world_shift = 0 self.checkpoint_shift = 0 self.checkpoint_coin_counter = 0 self.shift_factor = 999 self.last_checkpoint_rect = None self.map_quick_load = False # menu self.menu = Menu(self.screen) # sounds self.sound_counter = 0 self.coin_sound = rM.getSound("coin.wav") self.checkpoint_sound = rM.getSound("Checkpoint.wav") self.die_sound = rM.getSound("steve_hurt.wav") self.win_sound = rM.getSound("finish.wav") self.lose_sound = rM.getSound("game-over.wav") # overlayed text info self.overlay_seconds = 0 self.overlay_coins = 0 self.overlay_lives = 0 self.overlay_map_name = None # rendered text info self.rendered_seconds = None self.rendered_coins = None self.rendered_lives = None self.rendered_map_name = None
class Game: """ platformer game """ # Initialization of Game, high scores, map tiles and a new level def __init__(self): """ initialize game window """ pg.init() pg.mixer.init() self.clock = pg.time.Clock() if FULLSCREEN: self.screen = pg.display.set_mode((WIDTH, HEIGHT), pg.FULLSCREEN) else: self.screen = pg.display.set_mode((WIDTH, HEIGHT)) pg.display.set_caption(TITLE) self.font_name = pg.font.match_font(FONT_NAME) self.running = True self.playing = True self.has_won = False self.lives = PLAYER_LIVES self.coin_counter = 0 self.dead = True self.frame_count = 0 self.total_seconds = 0 self.dir = path.dirname(__file__) # init sprite Groups self.all_sprites = pg.sprite.Group() self.platforms = pg.sprite.Group() self.death_tiles = pg.sprite.Group() self.checkpoints = pg.sprite.Group() self.ai_borders = pg.sprite.Group() self.coins = pg.sprite.Group() self.sprites_on_screen = pg.sprite.Group() self.jump_pads = pg.sprite.Group() self.enemies = pg.sprite.Group() self.sprites_on_screen = pg.sprite.Group() self.finishes = pg.sprite.Group() # map self.player = None self.map = None self.player_start = None self.player_spawn = None self.total_world_shift = 0 self.checkpoint_shift = 0 self.checkpoint_coin_counter = 0 self.shift_factor = 999 self.last_checkpoint_rect = None self.map_quick_load = False # menu self.menu = Menu(self.screen) # sounds self.sound_counter = 0 self.coin_sound = rM.getSound("coin.wav") self.checkpoint_sound = rM.getSound("Checkpoint.wav") self.die_sound = rM.getSound("steve_hurt.wav") self.win_sound = rM.getSound("finish.wav") self.lose_sound = rM.getSound("game-over.wav") # overlayed text info self.overlay_seconds = 0 self.overlay_coins = 0 self.overlay_lives = 0 self.overlay_map_name = None # rendered text info self.rendered_seconds = None self.rendered_coins = None self.rendered_lives = None self.rendered_map_name = None def init_map(self, map_tiles): """ Initialized all sprites from the level """ style = int(self.map.MAP_STYLE) print("map style: " + str(style)) for t in map_tiles: # ghost if t.tile_id == 69: e = Ghost(self, t.x, t.y, t.tile_id, self.map.ENEMY_SPEED, style) self.death_tiles.add(e) self.enemies.add(e) self.all_sprites.add(e) # android elif t.tile_id == 65: e = GroundCrawler(self, t.x, t.y, t.tile_id, self.map.ENEMY_SPEED, style) self.death_tiles.add(e) self.enemies.add(e) self.all_sprites.add(e) # player elif t.tile_id == 80: self.player_spawn = (t.x, t.y) # jump pad elif t.tile_id == 74: p = Platform(t.x, t.y, t.tile_id, 1, style) self.platforms.add(p) self.all_sprites.add(p) self.jump_pads.add(p) # laser elif t.tile_id == 76: l = Laser(self, t.x, t.y, t.tile_id) self.platforms.add(l) self.all_sprites.add(l) # finish elif t.tile_id == 112: f = Platform(t.x, t.y, t.tile_id, 1, style) self.finishes.add(f) self.all_sprites.add(f) # checkpoint elif t.tile_id == 67: c = Platform(t.x, t.y, t.tile_id, 1, style) self.checkpoints.add(c) self.all_sprites.add(c) # Moving platform elif t.tile_id == 77: print("tiledata:" + str(t.data)) c = MovingPlatform(self, t.x, t.y, t.tile_id, t.data, style) self.platforms.add(c) self.all_sprites.add(c) # AI border elif t.tile_id == 124: a = Platform(t.x, t.y, t.tile_id, 1, style) self.ai_borders.add(a) self.all_sprites.add(a) # death tile elif t.tile_id in colorMap.death_tiles: d = Platform(t.x, t.y, t.tile_id, 1, style) self.death_tiles.add(d) self.all_sprites.add(d) # coin elif t.tile_id == 99: c = Coin(t.x, t.y) self.coins.add(c) self.all_sprites.add(c) # invisible tile elif t.tile_id == 33: i = Platform(t.x, t.y, t.tile_id, 1, style) self.all_sprites.add(i) # floor filler tile without collision elif t.tile_id == 120: f = Platform(t.x, t.y, t.tile_id, 1, style) self.all_sprites.add(f) elif t.tile_id == 83: s = Platform(t.x, t.y, t.tile_id, 1, style) self.all_sprites.add(s) # the rest is assumed to be a platforms else: # print("WARNING: Creating platform for unknown tile_id: " + str(t.tile_id)) p = Platform(t.x, t.y, t.tile_id, 1, style) self.platforms.add(p) self.all_sprites.add(p) def new(self, level, play_music): """ start new game, player lives set """ if self.map is None: self.all_sprites.empty() self.platforms.empty() self.death_tiles.empty() self.checkpoints.empty() self.ai_borders.empty() self.coins.empty() self.sprites_on_screen.empty() self.jump_pads.empty() self.enemies.empty() self.finishes.empty() self.map = Map(level) self.init_map(self.map.getTiles()) if self.map.FFT_HIGH is None: self.map.FFT_HIGH = settings.DEFAULT_FFT_HIGH if self.map.FFT_LOW is None: self.map.FFT_LOW = settings.DEFAULT_FFT_LOW if play_music: rM.loadMusic(self.map.BACKGROUND_MUSIC) pg.mixer.music.play(-1) player_properties = [ self.map.PLAYER_ACC, self.map.PLAYER_FRICTION, self.map.PLAYER_GRAV, self.map.PLAYER_JUMP ] # if player has not reached a checkpoint, place on starting position if self.player_start is None: if self.player_spawn is None: self.player_spawn = (WIDTH / 2, HEIGHT / 2) self.player_start = self.player_spawn for sprite in self.all_sprites: sprite.rect.right += (self.checkpoint_shift - self.total_world_shift) self.total_world_shift = self.checkpoint_shift if self.player is None: self.player = Player(self, player_properties, TILESIZE, TILESIZE * 3 / 2) self.all_sprites.add(self.player) else: self.player.vel.y = 0 self.player.vel.x = 0 self.player.set_start(self.player_start) self.map_quick_load = True self.run() # Game loop; run to call events, update and draw def run(self): """ game loop """ self.playing = True while self.playing: old_time = time.time() * 1000 self.events() if PROFILING: print("handling events took " + str(int(time.time() * 1000 - old_time)) + " milliseconds") old_time = time.time() * 1000 self.update() if PROFILING: print("updating took " + str(int(time.time() * 1000 - old_time)) + " milliseconds") old_time = time.time() * 1000 if self.frame_count % 2 == 0: self.draw() if PROFILING: print("drawing took " + str(int(time.time() * 1000 - old_time)) + " milliseconds\n") self.clock.tick(FPS) if self.dead: self.update() self.draw() pg.mixer.Sound.play(self.die_sound) time.sleep(1) self.dead = False def events(self): """ game loop - handling events """ for event in pg.event.get(): # check for close window event if event.type == pg.QUIT: self.quit() elif event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.quit() elif event.key == pg.K_SPACE: self.player.jump() """ # Handle FPGA jump input if self.map.FFT_LOW <= self.spiController.fft <= self.map.FFT_HIGH and self.spiController.rms >= settings.RMS_JUMP_THRESHOLD: self.player.jump(self.spiController.rms / settings.RMS_JUMP_DIVSOR) """ def update(self): """ update all the things! """ # game loop updates self.all_sprites.update() # check all die conditions if (self.player.rect.top > HEIGHT or pg.sprite.spritecollide( self.player, self.death_tiles, False)): # start level again if you have enough lives left, otherwise stop playing self.has_won = False self.playing = False self.coin_counter = self.checkpoint_coin_counter self.shift_factor = 999 self.dead = True # check coin collision hits = pg.sprite.spritecollide(self.player, self.coins, True) if hits: pg.mixer.Sound.play(self.coin_sound) self.coin_counter += 1 # check win conditions hits = pg.sprite.spritecollide(self.player, self.finishes, True) if hits: self.has_won = True self.playing = False self.checkpoint_coin_counter = self.coin_counter self.dead = False # check checkpoint collision hits = pg.sprite.spritecollide(self.player, self.checkpoints, False) if hits: checkpoint_pos = (hits[0].rect.x, hits[0].rect.y) # if this was not last visited checkpoint, only then play sound if self.last_checkpoint_rect != hits[0].rect: pg.mixer.Sound.play(self.checkpoint_sound) self.last_checkpoint_rect = hits[0].rect self.player_start = checkpoint_pos self.checkpoint_shift = self.total_world_shift self.checkpoint_coin_counter = self.coin_counter UPS = 5 # updates per second; checking sprites on screen if self.map_quick_load or self.frame_count % (FPS // UPS) == 0: self.map_quick_load = False self.set_sprites_on_screen() if self.frame_count % FPS == 0: self.total_seconds = self.frame_count / FPS self.frame_count += 1 def draw(self): """ game loop - drawing """ old_time = time.time() self.screen.blit(self.map.bgImage, (0, 0)) if PROFILING: print(" background took " + str(int((time.time() - old_time) * 1000)) + " milliseconds") old_time = time.time() self.sprites_on_screen.draw(self.screen) if PROFILING: print(" sprites took " + str(int((time.time() - old_time) * 1000)) + " milliseconds") old_time = time.time() # for the overlayed text, check if a new render has to be made, otherwise use the exisiting text surface if DRAW_TEXT: if self.rendered_lives is None or self.lives != self.overlay_lives: self.overlay_lives = self.lives self.rendered_lives = self.render_text( "Lives: " + str(self.lives), 24, colorMap.BLACK) self.draw_text_surface(self.rendered_lives, WIDTH - 60, 20) if self.rendered_coins is None or self.coin_counter != self.overlay_coins: self.overlay_coins = self.coin_counter self.rendered_coins = self.render_text( "Coins: " + str(self.coin_counter), 24, colorMap.BLACK) self.draw_text_surface(self.rendered_coins, 60, 20) if self.rendered_seconds is None or self.total_seconds != self.overlay_seconds: self.overlay_seconds = self.total_seconds self.rendered_seconds = self.render_text( format_timer(self.total_seconds), 24, colorMap.BLACK) self.draw_text_surface(self.rendered_seconds, WIDTH / 2, HEIGHT - 40) if self.rendered_map_name is None or self.map.mapName != self.overlay_map_name: self.overlay_map_name = self.map.mapName self.rendered_map_name = self.render_text( self.map.mapName, 24, colorMap.BLACK) self.draw_text_surface(self.rendered_map_name, WIDTH / 2, 20) if PROFILING: print(" text took " + str(int((time.time() - old_time) * 1000)) + " milliseconds") old_time = time.time() pg.display.flip() if PROFILING: print(" update took " + str(int((time.time() - old_time) * 1000)) + " milliseconds") def quit(self): """ stops the game """ if self.playing: self.playing = False self.running = False # Methods regarding drawing to / updating the screen surface def draw_text_surface(self, text_surface, x, y): """ draw text to the screen at position x, y """ text_rect = text_surface.get_rect() text_rect.midtop = (x, y) self.screen.blit(text_surface, text_rect) def render_text(self, text, size, color): """ renders text to a surface """ """ CPU INTENSIVE """ if PROFILING: print("RENDERING: " + text) font = pg.font.Font(self.font_name, size) text_surface = font.render(text, True, color) return text_surface def shift_world(self, shift_x): """ shift everything opposite of the change in x of the player """ if self.player.rect.right > WIDTH * 2 / 3 and shift_x > 0: for sprite in self.all_sprites: sprite.rect.right -= shift_x self.total_world_shift -= shift_x elif self.player.rect.left < WIDTH / 3 and shift_x < 0: for sprite in self.all_sprites: sprite.rect.left -= shift_x self.total_world_shift -= shift_x def set_sprites_on_screen(self): """ sets sprites_on_screen to only include sprites that are on screen """ """ this update is only done after a world shift of 10 tiles """ shift_factor = self.total_world_shift // (TILESIZE * 10) if shift_factor != self.shift_factor: self.shift_factor = shift_factor self.sprites_on_screen.empty() for sprite in self.all_sprites: if sprite.rect.left < (WIDTH + TILESIZE * 15) and sprite.rect.right > ( 0 - TILESIZE * 15): self.sprites_on_screen.add(sprite) # Used to play (a series of) levels def reset_level(self): """ resets constants to start a fresh game """ self.player_start = None self.player_spawn = None self.total_world_shift = 0 self.checkpoint_shift = 0 self.checkpoint_coin_counter = 0 self.map = None self.player = None self.shift_factor = 999 self.lives = PLAYER_LIVES self.last_checkpoint_rect = None def play_level(self, level, lives, playlist_name, is_last, play_music): """ plays a specific level until win or no lives left """ self.lives = lives while self.lives >= 1 and self.running: self.new(level, play_music) if self.has_won: break self.lives -= 1 # todo: add score to top of screen and go/win screen if self.running: if self.has_won: print("YOU WON!") if is_last: pg.mixer.music.stop() pg.mixer.Sound.play(self.win_sound) if not self.menu.finish(is_last, playlist_name, self.frame_count // 60, self.checkpoint_coin_counter): self.quit() return True else: print("YOU LOSE!") pg.mixer.music.stop() pg.mixer.Sound.play(self.lose_sound) if not self.menu.gameOver(): self.quit() return False def play_playlist(self, playlist_index): """ plays a specific playlist until all levels completed or no lives left """ level_index = 1 level_amount = len(PLAYLIST[playlist_index]) - 1 playlist_name = PLAYLIST[playlist_index][0] self.reset_level() while (level_index <= level_amount and g.play_level( PLAYLIST[playlist_index][level_index], g.lives, playlist_name, level_index == level_amount, level_index == 1)): self.reset_level() level_index += 1 # todo: method for saving score and reset score in reset_level self.lives = PLAYER_LIVES self.coin_counter = 0 self.frame_count = 0
from game.director import Director from game.input_service import Input_Service from game.output_service import Output_Service from asciimatics.screen import Screen from game.menu import Menu def main(screen, player: str): input_service = Input_Service(screen) output_service = Output_Service(screen) director = Director(input_service, output_service, player) results = director.start_game() return results menu = Menu() play_game = menu.main_menu() while play_game: results = Screen.wrapper(main, arguments=[menu.player]) menu.game_over(results) play_game = menu.main_menu()
def populate_menu(self): item_list = [] for item in self.menu_items: item_list.append(item) self.main_menu = Menu(self.screen, self) self.main_menu.post_init(item_list)
from game.menu import Menu import pygame as pg from game import settings import time pg.init() pg.mixer.init() screen = pg.display.set_mode( (settings.WIDTH, settings.HEIGHT)) # (0, pg.FULLSCREEN)[FULLSCREEN] pg.display.set_caption(settings.TITLE) m = Menu(screen) m.finish(True, "test playlist", 50, 1)
def run(cls): """Запуск игры""" while not cls.finished: cls.handleKeys() mx, my = pygame.mouse.get_pos() mouse_pos = vector(mx, my) mouse_pressed = pygame.mouse.get_pressed()[0] Menu.state = GameState.MENU if cls.state == GameState.MENU: Display.draw_start_img( pygame.image.load("data/game_images/start1.png"), vector(0, 0)) Display.draw_start_img( pygame.image.load("data/game_images/f12.png"), vector(50, 0)) Display.draw_start_img( pygame.image.load("data/game_images/esc.png"), vector(0, 50)) Display.draw_start_img( pygame.image.load("data/game_images/space.png"), vector(50, 50)) Menu.update(mouse_pos, mouse_pressed) if Menu.can_play: cls.state = GameState.GAME if Menu.can_quit: cls.finished = True Menu.display() if Menu.can_play: Display.set_cursor() elif cls.state == GameState.END: Menu.update(mouse_pos, mouse_pressed) if not Map.end: Map.update() if Menu.can_play: cls.state = GameState.GAME Display.end = False Map.end = False if Menu.can_quit: cls.finished = True Map.display() Menu.display() if Menu.can_play: Display.set_cursor() elif cls.state == GameState.WIN: Menu.update(mouse_pos, mouse_pressed) if Menu.can_play: cls.state = GameState.GAME Display.end = False Map.end = False if Menu.can_quit: cls.finished = True Menu.display() if Menu.can_play: Display.set_cursor() elif cls.state == GameState.GAME: Map.set_mouse(mouse_pos / Display.zoom_factor) Map.update() Map.display() if Map.is_player_alive(): if Map.end: cls.state = GameState.WIN Menu.apply_state(GameState.WIN) else: cls.state = GameState.END Menu.apply_state(GameState.END) Display.update_frame()
def run(cls) -> None: """Méthode principale permettant de faire tourner le jeu""" cls.finished = False cls.keytime = {} cls.state = GameState.MENU while not cls.finished: cls.ESC_MAX_FRAMECOUNT = Display.real_framerate * 0.25 # On veut quitter après 0.25 secondes cls.handleKeys() mx, my = pygame.mouse.get_pos() mouse_pos = Vect2d(mx, my) # Position de la souris mouse_pressed = pygame.mouse.get_pressed()[0] # Clic ou non Menu.state = GameState.MENU if cls.state == GameState.MENU: # Affichage du menu Menu.update(mouse_pos, mouse_pressed) if Menu.can_play: # Si l'on veut rejouer cls.state = GameState.GAME if Menu.can_quit: # Si l'on veut quitter cls.finished = True Menu.display() if Menu.can_play: # Si l'on veut rejouer on remet le curseur normal Display.setCursorArrow() elif cls.state == GameState.END: # Partie perdue Menu.update(mouse_pos, mouse_pressed) if not Map.game_finished: # On update la map tant que la partie n'est pas terminée pour de bon # afin de faire jouer les IA Map.update() if Menu.can_play: cls.state = GameState.GAME if Menu.can_quit: cls.finished = True Map.display() Menu.display() # Affichage du menu et de l'effet de transparence au dessus de la map if Menu.can_play: Display.setCursorArrow() elif cls.state == GameState.WIN: # Victoire Menu.update(mouse_pos, mouse_pressed) if Menu.can_play: cls.state = GameState.GAME if Menu.can_quit: cls.finished = True Menu.display() if Menu.can_play: Display.setCursorArrow() elif cls.state == GameState.GAME: # Jeu en cours Map.setMousePos(mouse_pos / Display.zoom_factor) # On envoie la position de la souris à la map Map.update() Map.display() if Map.isPlayerAlive(): if Map.game_finished: cls.state = GameState.WIN Menu.applyState(GameState.WIN) else: cls.state = GameState.END Menu.applyState(GameState.END) else: raise ValueError("État inconnu") alpha = cls.keytime.get(pygame.K_ESCAPE, 0) / cls.ESC_MAX_FRAMECOUNT * 255 Display.drawText("Quitter...", Vect2d(50, 25), color=(255, 0, 0, alpha), size=16, base_pos=Vect2d(0, 0)) # Affichage du "Quitter" rouge en haut à gauche proportionnellement au temps d'appui de la touche ESC Display.updateFrame()