如何为Python Pygame游戏添加碰撞检测、积分系统与计分板功能
解决方案
1. 矩形与圆形碰撞检测实现
核心判断逻辑如下:
- 先定位矩形上距离圆形圆心最近的坐标点:将圆心的x坐标限制在矩形左右边界之间、y坐标限制在矩形上下边界之间,得到的点就是矩形上离圆心最近的点
- 计算该点到圆心的欧氏距离,若距离小于等于圆的半径,即可判定为碰撞
2. 碰撞加积分逻辑
遍历食物列表时同步做碰撞检测,检测到碰撞后将对应食物从列表中移除,同时积分变量加1即可。注意不要正序遍历原列表并删除元素,建议用新列表存储未被收集的食物避免遍历异常。
3. 积分系统与可视化计分板
通过pygame内置的font模块实现:
- 初始化pygame后提前加载字体,设置字号和显示颜色
- 每帧游戏循环中,用
render方法将当前积分转换为Surface对象 - 调用
blit方法将文本Surface绘制到屏幕固定位置(比如左上角)即可
修改后的完整可运行代码
import pygame import random import math pygame.init() # 初始化计分板字体,使用系统黑体,字号28 pygame.font.init() score_font = pygame.font.SysFont("simhei", 28) y = 0 x = 0 point = 0 is_blue = True WHITE = (255, 255, 255) clock = pygame.time.Clock() screen = pygame.display.set_mode([500, 500]) # 统一配置参数避免硬编码 FOOD_RADIUS = 5 PLAYER_SIZE = 30 food_list = [] time_interval = 3000 next_food_time = pygame.time.get_ticks() done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: is_blue = not is_blue pygame.display.set_caption("Collect the balls to win!") pressed = pygame.key.get_pressed() if pressed[pygame.K_UP]: y -= 3 if pressed[pygame.K_DOWN]: y += 3 if pressed[pygame.K_LEFT]: x -= 3 if pressed[pygame.K_RIGHT]: x += 3 # 玩家边界限制 if x <= -1: x = 0 if x >= 500 - PLAYER_SIZE: x = 500 - PLAYER_SIZE if y <= -1: y = 0 if y >= 500 - PLAYER_SIZE: y = 500 - PLAYER_SIZE # 定时生成食物 current_time = pygame.time.get_ticks() if current_time > next_food_time and len(food_list) < 10: next_food_time += time_interval # 生成位置避免食物超出屏幕边界 food_list.append((random.randint(FOOD_RADIUS, 500 - FOOD_RADIUS), random.randint(FOOD_RADIUS, 500 - FOOD_RADIUS))) # 碰撞检测 + 积分更新 new_food_list = [] player_rect = pygame.Rect(x, y, PLAYER_SIZE, PLAYER_SIZE) for food_pos in food_list: fx, fy = food_pos # 计算矩形上离圆心最近的点 closest_x = max(player_rect.left, min(fx, player_rect.right)) closest_y = max(player_rect.top, min(fy, player_rect.bottom)) # 计算两点距离 distance = math.hypot(fx - closest_x, fy - closest_y) if distance <= FOOD_RADIUS: point += 1 else: new_food_list.append(food_pos) food_list = new_food_list # 画面渲染 screen.fill((0, 0, 0)) if is_blue: color = (0, 128, 255) else: color = (255, 100, 0) pygame.draw.rect(screen, color, player_rect) for food_pos in food_list: pygame.draw.circle(screen, WHITE, food_pos, FOOD_RADIUS) # 渲染计分板 score_text = score_font.render(f"当前积分: {point}", True, WHITE) screen.blit(score_text, (10, 10)) pygame.display.flip() clock.tick(144) pygame.quit()
内容的提问来源于stack exchange,提问作者bruh3436
相关产品推荐
相关产品推荐

