当马里奥移动时,会发现金币也跟随着移动,一直位于马里奥的头顶,如图7‑5所示。

图7‑5马里奥行走后的金币
这是因为金币的显示位置在代码中是固定的,所以金币始终显示在屏幕的特定位置,它的坐标实际是屏幕坐标。我们希望金币能随着屏幕滚动而移动,并最终移出屏幕不再可见。滚屏动作现在是更新马里奥后触发的,代码如下所示:
07\02\mario\Mario.py
|
# 显示马里奥 self.screen.blit(self.image, self.rect)
# 滚动地图 if self.currentState.getScrollMap(): Globals.game.scrollMap(self.walkStep) |
在scrollMap()方法中,会改变屏幕的显示范围,随后在下一帧会根据新范围重新绘制地图,从而实现地图滚动的效果。然而,由于金币是单独创建的,不在地图文件中,它是一个游离于地图之外的物体,因此地图的重绘不会影响到金币。
我们需要将金币管理起来,使用一个数组来存储多个金币对象,代码如下所示:
07\02\Game.py
|
# 多个金币 from item.FlashingCoinAnimation import FlashingCoinAnimation self.itemArray = [FlashingCoinAnimation(100, 100), FlashingCoinAnimation(260, 110), FlashingCoinAnimation(400, 60)] |
在重绘地图后,只需更新数组中所有物体的坐标,即可实现物体随屏幕滚动。不过,在修改代码进行坐标转换的过程中,我们发现金币与地图中的砖块、水管类似,都需要两个坐标:一个地图坐标和一个屏幕坐标。实际上,金币类中的坐标可以被视为地图坐标,表示金币在整个地图中的位置,绘制时转换为屏幕坐标即可。由于scrollMap()方法会更新mapViewFrom值,因此下一帧金币的屏幕坐标自然就变化了,金币类本身不需要进行额外操作。
修改后的金币代码如下所示:
07\02\item\FlashingCoinAnimation.py
|
from pygame import Rect from game_globals.Globals import Globals from game_globals.constants import MAP_BLOCK_SIZE, SCREEN_WIDTH from utils.utils import mapToScreen
# 闪烁金币动画 class FlashingCoinAnimation(object): # 帧动画 frames = [Globals.itemImageCache.flashingCoinImg1, Globals.itemImageCache.flashingCoinImg1, Globals.itemImageCache.flashingCoinImg2, Globals.itemImageCache.flashingCoinImg3, Globals.itemImageCache.flashingCoinImg4]
# 构造方法,记录初始坐标 def __init__(self, x, y): self.rect = Rect(x, y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE) # 地图坐标 self.frameDuration = 100 # 每帧显示时间,单位为毫秒 self.frameIndex = 0 # 当前帧的下标 self.elapsedTime = 0 # 时间差累计
# 更新动画 def update(self, keys, deltaTime): # 转换为屏幕坐标,并判断是否在显示范围内 screenRect = mapToScreen(self.rect) if screenRect[0] + MAP_BLOCK_SIZE > 0 and screenRect[0] < SCREEN_WIDTH:
# 时间差累计 self.elapsedTime += deltaTime
# 切换动画图片 if self.elapsedTime > self.frameDuration: self.elapsedTime -= self.frameDuration # 减去差值 self.frameIndex += 1 if self.frameIndex >= len(self.frames): self.frameIndex = 0
# 显示图片 Globals.screen.blit(self.frames[self.frameIndex], screenRect) |
运行程序,画面如图7‑6所示。

图7‑6多个金币
滚动屏幕后,可以看到金币也随着移动了,如图7‑7所示。

图7‑7随着屏幕滚动的金币