import pygame
import random
import math
# 初始化
pygame.init()
WIDTH, HEIGHT = 600, 670
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pac-Man")
CLOCK = pygame.time.Clock()
# 颜色定义
LIGHT_BLUE = (173, 216, 230)
BEIGE = (245, 245, 220)
YELLOW = (255, 255, 0)
BLACK = (0, 0, 0)
BLUE = (33, 33, 255)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
CYAN = (0, 255, 255)
PINK = (255, 184, 255)
ORANGE = (255, 184, 82)
# 游戏状态
MENU = 0
PLAYING = 1
GAME_OVER = 2
current_state = MENU
# 迷宫布局
maze = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1],
[1,2,1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,2,1],
[1,2,1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,2,1],
[1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1],
[1,2,1,1,2,1,2,1,1,1,1,1,2,1,2,1,1,2,1],
[1,2,2,2,2,1,2,2,2,1,2,2,2,1,2,2,2,2,1],
[1,1,1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,1,1],
[0,0,0,1,2,1,2,2,2,2,2,2,2,1,2,1,0,0,0],
[1,1,1,1,2,1,2,1,1,0,1,1,2,1,2,1,1,1,1],
[2,2,2,2,2,2,2,1,0,0,0,1,2,2,2,2,2,2,2],
[1,1,1,1,2,1,2,1,1,0,1,1,2,1,2,1,1,1,1],
[0,0,0,1,2,1,2,2,2,2,2,2,2,1,2,1,0,0,0],
[1,1,1,1,2,1,2,1,1,1,1,1,2,1,2,1,1,1,1],
[1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1],
[1,2,1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,2,1],
[1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1],
[1,1,2,2,2,1,2,1,1,1,1,1,2,1,2,2,2,1,1],
[1,2,2,1,1,1,2,2,2,1,2,2,2,1,1,1,2,2,1],
[1,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]
class Pacman:
def __init__(self):
self.x = 9.0
self.y = 15.0
self.speed = 0.15
self.direction = 0
self.mouth_angle = 0
self.mouth_direction = 1
self.score = 0
self.hitbox = pygame.Rect(0, 0, 20, 20)
def update_hitbox(self):
self.hitbox.center = (self.x*30+15, self.y*30+15)
def move(self):
self.mouth_angle += self.mouth_direction * 6
if self.mouth_angle > 35 or self.mouth_angle < 0:
self.mouth_direction *= -1
next_x = self.x
next_y = self.y
dir_map = {
1: (0, -self.speed), # 上
2: (0, self.speed), # 下
3: (-self.speed, 0), # 左
4: (self.speed, 0) # 右
}
dx, dy = dir_map.get(self.direction, (0, 0))
# 精确碰撞检测
if dx != 0:
test_y = self.y
for offset in [-0.4, 0, 0.4]:
if not self.check_collision(self.x + dx, test_y + offset):
next_x += dx
break
if dy != 0:
test_x = self.x
for offset in [-0.4, 0, 0.4]:
if not self.check_collision(test_x + offset, self.y + dy):
next_y += dy
break
self.x = next_x
self.y = next_y
self.update_hitbox()
# 吃豆子
if maze[int(self.y)][int(self.x)] == 2:
maze[int(self.y)][int(self.x)] = 0
self.score += 10
def check_collision(self, x, y):
if x < 0.4 or x >= 19.6 or y < 0.4 or y >= 20.6:
return True
grid_x = int(round(x))
grid_y = int(round(y))
try:
return maze[grid_y][grid_x] == 1
except IndexError:
return True
def draw(self):
direction_angle = {
1: 90, 2: 270, 3: 180, 4: 0
}.get(self.direction, 0)
start_angle = math.radians(direction_angle + self.mouth_angle)
end_angle = math.radians(direction_angle - self.mouth_angle)
pygame.draw.arc(SCREEN, YELLOW,
(self.x*30+3, self.y*30+3, 24, 24),
start_angle, end_angle, 12)
class Ghost:
def __init__(self, color, start_pos):
self.x, self.y = start_pos
self.color = color
self.direction = random.choice([1,2,3,4])
self.eye_direction = 4
self.speed = 0.08
self.hitbox = pygame.Rect(0, 0, 20, 20)
def update_hitbox(self):
self.hitbox.center = (self.x*30+15, self.y*30+15)
def move(self):
original_dir = self.direction
if random.random() < 0.15:
self.direction = random.choice([1,2,3,4])
dx, dy = 0, 0
dir_map = {
1: (0, -self.speed),
2: (0, self.speed),
3: (-self.speed, 0),
4: (self.speed, 0)
}
dx, dy = dir_map[self.direction]
if not self.check_collision(self.x + dx, self.y + dy):
self.x += dx
self.y += dy
else:
self.direction = random.choice([1,2,3,4])
self.eye_direction = self.direction
self.update_hitbox()
def check_collision(self, x, y):
grid_x = int(round(x))
grid_y = int(round(y))
try:
return maze[grid_y][grid_x] == 1
except IndexError:
return True
def draw(self):
pygame.draw.circle(SCREEN, self.color,
(int(self.x*30+15), int(self.y*30+15)), 14)
eye_pos = {
1: (0, -4), 2: (0, 4),
3: (-4, 0), 4: (4, 0)
}[self.eye_direction]
pygame.draw.circle(SCREEN, WHITE,
(int(self.x*30+15)+eye_pos[0],
int(self.y*30+15)+eye_pos[1]), 5)
pygame.draw.circle(SCREEN, BLUE,
(int(self.x*30+15)+eye_pos[0],
int(self.y*30+15)+eye_pos[1]), 3)
def draw_maze():
for y in range(len(maze)):
for x in range(len(maze[y])):
if maze[y][x] == 1:
pygame.draw.rect(SCREEN, BLUE,
(x*30, y*30, 30, 30), 2)
elif maze[y][x] == 2:
pygame.draw.circle(SCREEN, WHITE,
(x*30+15, y*30+15), 3)
def draw_gradient_background():
for i in range(HEIGHT):
ratio = i / HEIGHT
r = int(LIGHT_BLUE[0] * (1 - ratio) + BEIGE[0] * ratio)
g = int(LIGHT_BLUE[1] * (1 - ratio) + BEIGE[1] * ratio)
b = int(LIGHT_BLUE[2] * (1 - ratio) + BEIGE[2] * ratio)
pygame.draw.line(SCREEN, (r, g, b), (0, i), (WIDTH, i))
def show_menu():
SCREEN.fill(LIGHT_BLUE)
draw_gradient_background()
title_font = pygame.font.SysFont('arial', 64, True)
title_text = title_font.render("PAC-MAN", True, BLUE)
SCREEN.blit(title_text, (WIDTH//2-120, HEIGHT//2-120))
mouse_pos = pygame.mouse.get_pos()
btn_font = pygame.font.SysFont('arial', 32)
# 开始按钮
start_btn = pygame.Rect(WIDTH//2-100, HEIGHT//2+50, 200, 50)
btn_color = (100, 200, 100) if start_btn.collidepoint(mouse_pos) else (50, 150, 50)
pygame.draw.rect(SCREEN, btn_color, start_btn, border_radius=25)
btn_text = btn_font.render("Start Game", True, WHITE)
SCREEN.blit(btn_text, (WIDTH//2-80, HEIGHT//2+60))
# 退出按钮
quit_btn = pygame.Rect(WIDTH//2-100, HEIGHT//2+120, 200, 50)
btn_color = (200, 100, 100) if quit_btn.collidepoint(mouse_pos) else (150, 50, 50)
pygame.draw.rect(SCREEN, btn_color, quit_btn, border_radius=25)
btn_text = btn_font.render("Quit Game", True, WHITE)
SCREEN.blit(btn_text, (WIDTH//2-75, HEIGHT//2+130))
pygame.display.update()
return start_btn, quit_btn
def game_loop():
global current_state
pacman = Pacman()
ghosts = [
Ghost(RED, (9, 7)),
Ghost(CYAN, (9, 9)),
Ghost(PINK, (10, 7)),
Ghost(ORANGE, (10, 9))
]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
if current_state == MENU:
if event.type == pygame.MOUSEBUTTONDOWN:
start_btn, quit_btn = show_menu()
if start_btn.collidepoint(event.pos):
current_state = PLAYING
elif quit_btn.collidepoint(event.pos):
pygame.quit()
return
elif current_state == PLAYING:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
pacman.direction = 1
elif event.key == pygame.K_DOWN:
pacman.direction = 2
elif event.key == pygame.K_LEFT:
pacman.direction = 3
elif event.key == pygame.K_RIGHT:
pacman.direction = 4
if current_state == MENU:
show_menu()
elif current_state == PLAYING:
SCREEN.fill(BLACK)
draw_maze()
pacman.move()
pacman.draw()
for ghost in ghosts:
ghost.move()
ghost.draw()
if ghost.hitbox.colliderect(pacman.hitbox):
current_state = GAME_OVER
# 显示分数
font = pygame.font.SysFont('Arial', 24)
score_text = font.render(f'Score: {pacman.score}', True, WHITE)
SCREEN.blit(score_text, (10, HEIGHT-40))
pygame.display.update()
CLOCK.tick(60)
elif current_state == GAME_OVER:
SCREEN.fill(BLACK)
font = pygame.font.SysFont('Arial', 48)
text = font.render('GAME OVER', True, RED)
SCREEN.blit(text, (WIDTH//2-120, HEIGHT//2-24))
pygame.display.update()
if __name__ == "__main__":
game_loop()这个代码中小球无法出来修改代码修正这个问题其他不变