|
|
# 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() |