(六)Rect、浮点位置与对象修改
1. 用矩形属性表达位置关系
# 项目文件:demos/rect_ops.py
# move 交回新Rect,move_ip修改原对象;共享名称会一起看到原对象的变化。
import pygame
player = pygame.Rect(20, 30, 40, 20)
print(player.right, player.bottom, player.center)
moved = player.move(10, -5)
print(player.topleft, moved.topleft)
same = player
player.move_ip(5, 0)
print(same.topleft, player.topleft)
player.clamp_ip(pygame.Rect(0, 0, 50, 40))
print(player.topleft, player.right, player.bottom)首先输出 60 50 (40, 40),对应右侧结束位置、下侧结束位置和中心。move 取得新矩形,原对象仍位于 (20, 30);move_ip 修改原对象,共享的 same 也看到 (25, 30)。最后把它放入宽 50、高 40 的区域,得到 (10, 20),右侧与下侧结束位置分别为 50、40。
修改 center、topleft、right 等属性也会改变对应位置,而不是在矩形里维护几份互不关联的坐标。第四章的共享引用在这里仍然成立;需要独立副本时用 rect.copy(),不要把再次赋值当作复制。Rect 接口
2. 小数位移单独累积
# 项目文件:demos/rect_float.py
# 每次写回整数坐标会丢掉小数累积;独立浮点位置保留每步0.4像素。
import pygame
bad = pygame.Rect(0, 0, 48, 36)
x, pixels = 0.0, []
for _ in range(6):
bad.x += 0.4
x += 0.4
pixels.append(round(x))
print("仅Rect", bad.x)
print("浮点位置", f"{x:.1f}", "绘制位置", pixels)仅使用 Rect 的结果为 0;独立浮点位置累计为 2.4,六次绘制位置依次为 [0, 1, 1, 2, 2, 2]。每步 0.4 都写回整数属性时,分数部分没能累积;浮点 x 则保存这一步还没有形成完整像素的移动,后续会继续加上去。
完整游戏同样让模型保存浮点 x、y,显示精灵的 Rect 再通过 round 取得屏幕位置。逻辑位置与显示位置各自负责自己的精度。