You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:27:02