# Function:吃豆人小游戏 import os #用于获取当前目录、更改目录、创建文件和目录等 import sys #提供了有关 Python 解释器和系统的信息 import pygame #用于创建游戏窗口、加载图像、播放声音等 import Levels #模块包含游戏关卡的信息,例如关卡的地图、敌人的位置等 import login BLACK = (0, 0, 0) WHITE = (255, 255, 255) BLUE = (0, 0, 255) GREEN = (0, 255, 0) RED = (255, 0, 0) YELLOW = (255, 255, 0) PURPLE = (255, 0, 255) SKYBLUE = (0, 191, 255) #os.path.join:将多个路径片段连接成一个完整路径 #os.getcwd():获取当前工作目录 BGMPATH = os.path.join(os.getcwd(), 'resources/sounds/bg.mp3') #背景音乐 ICONPATH = os.path.join(os.getcwd(), 'resources/images/icon.png') #背景图 FONTPATH = os.path.join(os.getcwd(), 'resources/font/ALGER.TTF') #truetype字体文件 HEROPATH = os.path.join(os.getcwd(), 'resources/images/pacman.png') #吃豆人形象 BlinkyPATH = os.path.join(os.getcwd(), 'resources/images/Blinky.png') #怪物形象 ClydePATH = os.path.join(os.getcwd(), 'resources/images/Clyde.png') InkyPATH = os.path.join(os.getcwd(), 'resources/images/Inky.png') PinkyPATH = os.path.join(os.getcwd(), 'resources/images/Pinky.png') def startLevelGame(level, screen, font): clock = pygame.time.Clock() SCORE = 0 wall_sprites = level.setupWalls(SKYBLUE) #从levels读取墙壁 gate_sprites = level.setupGate(WHITE) #门... hero_sprites, ghost_sprites = level.setupPlayers(HEROPATH, [BlinkyPATH, ClydePATH, InkyPATH, PinkyPATH]) food_sprites = level.setupFood(YELLOW, WHITE) is_clearance = False #设置关卡通关标志为否 while True: #监听方向键,更新玩家移动速度和方向 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() #关闭pygame sys.exit() #退出程序 if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: for hero in hero_sprites: hero.changeSpeed([-1, 0]) hero.is_move = True elif event.key == pygame.K_RIGHT: for hero in hero_sprites: hero.changeSpeed([1, 0]) hero.is_move = True elif event.key == pygame.K_UP: for hero in hero_sprites: hero.changeSpeed([0, -1]) hero.is_move = True elif event.key == pygame.K_DOWN: for hero in hero_sprites: hero.changeSpeed([0, 1]) hero.is_move = True if event.type == pygame.KEYUP: if (event.key == pygame.K_LEFT) or (event.key == pygame.K_RIGHT) or (event.key == pygame.K_UP) or (event.key == pygame.K_DOWN): hero.is_move = False screen.fill(BLACK) #清空屏幕并填充黑色背景 for hero in hero_sprites: hero.update(wall_sprites, gate_sprites) hero_sprites.draw(screen) for hero in hero_sprites: food_eaten = pygame.sprite.spritecollide(hero, food_sprites, True) SCORE += len(food_eaten) #检测吃豆子并更新得分 wall_sprites.draw(screen) gate_sprites.draw(screen) food_sprites.draw(screen) for ghost in ghost_sprites: # 幽灵随机运动(效果不好且有BUG) ''' res = ghost.update(wall_sprites, None) while not res: ghost.changeSpeed(ghost.randomDirection()) res = ghost.update(wall_sprites, None) ''' # 指定幽灵运动路径 if ghost.tracks_loc[1] < ghost.tracks[ghost.tracks_loc[0]][2]: ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2]) ghost.tracks_loc[1] += 1 else: if ghost.tracks_loc[0] < len(ghost.tracks) - 1: ghost.tracks_loc[0] += 1 elif ghost.role_name == 'Clyde': ghost.tracks_loc[0] = 2 else: ghost.tracks_loc[0] = 0 ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2]) ghost.tracks_loc[1] = 0 if ghost.tracks_loc[1] < ghost.tracks[ghost.tracks_loc[0]][2]: ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2]) else: if ghost.tracks_loc[0] < len(ghost.tracks) - 1: loc0 = ghost.tracks_loc[0] + 1 elif ghost.role_name == 'Clyde': loc0 = 2 else: loc0 = 0 ghost.changeSpeed(ghost.tracks[loc0][0: 2]) ghost.update(wall_sprites, None) ghost_sprites.draw(screen) score_text = font.render("Score: %s" % SCORE, True, RED) screen.blit(score_text, [10, 10]) if len(food_sprites) == 0: is_clearance = True #豆子吃完,游戏通关 break if pygame.sprite.groupcollide(hero_sprites, ghost_sprites, False, False): is_clearance = False #玩家撞到幽灵,游戏结束 break pygame.display.flip() clock.tick(10) return is_clearance def showText(screen, font, is_clearance, flag=False): clock = pygame.time.Clock() msg = 'Game Over!' if not is_clearance else 'Congratulations, you won!' positions = [[235, 233], [65, 303], [170, 333]] if not is_clearance else [[145, 233], [65, 303], [170, 333]] surface = pygame.Surface((400, 200)) #创建一个透明的surface稍微遮挡后面的背景 surface.set_alpha(10) surface.fill((128, 128, 128)) screen.blit(surface, (100, 200)) texts = [font.render(msg, True, WHITE), font.render('Press ENTER to continue or play again.', True, WHITE), font.render('Press ESCAPE to quit.', True, WHITE)] while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() pygame.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: if is_clearance: if not flag: return else: main(initialize()) else: main(initialize()) elif event.key == pygame.K_ESCAPE: sys.exit() pygame.quit() for idx, (text, position) in enumerate(zip(texts, positions)): screen.blit(text, position) pygame.display.flip() clock.tick(10) def initialize(): pygame.init() icon_image = pygame.image.load(ICONPATH) pygame.display.set_icon(icon_image) screen = pygame.display.set_mode([606, 606]) pygame.display.set_caption('吃豆人') return screen def login(): # 导入登录界面 import login # 显示登录界面 login.window.mainloop() '''主函数''' def main(screen): pygame.mixer.init() pygame.mixer.music.load(BGMPATH) pygame.mixer.music.play(-1, 0.0) pygame.font.init() font_small = pygame.font.Font(FONTPATH, 18) font_big = pygame.font.Font(FONTPATH, 24) for num_level in range(1, Levels.NUMLEVELS+1): if num_level == 1: level = Levels.Level1() is_clearance = startLevelGame(level, screen, font_small) if num_level == Levels.NUMLEVELS: showText(screen, font_big, is_clearance, True) else: showText(screen, font_big, is_clearance) '''test''' if __name__ == '__main__': main(initialize()) login() if is_login_success: # type: ignore main()