主游戏逻辑
在这一步中,我们将实现《飞扬的小鸟》的主游戏逻辑。
def mainGame(movementInfo):
score = playerIndex = loopIter = 0
playerIndexGen = movementInfo["playerIndexGen"]
playerx, playery = int(SCREENWIDTH * 0.2), movementInfo["playery"]
basex = movementInfo["basex"]
baseShift = IMAGES["base"].get_width() - IMAGES["background"].get_width()
## 获取2个新管道以添加到上管道和下管道列表中
newPipe1 = getRandomPipe()
newPipe2 = getRandomPipe()
## 上管道列表
upperPipes = [
{"x": SCREENWIDTH + 200, "y": newPipe1[0]["y"]},
{"x": SCREENWIDTH + 200 + (SCREENWIDTH / 2), "y": newPipe2[0]["y"]},
]
## 下管道列表
lowerPipes = [
{"x": SCREENWIDTH + 200, "y": newPipe1[1]["y"]},
{"x": SCREENWIDTH + 200 + (SCREENWIDTH / 2), "y": newPipe2[1]["y"]},
]
dt = FPSCLOCK.tick(FPS) / 1000
pipeVelX = -128 * dt
## 玩家速度、最大速度、向下加速度、拍打时的加速度
playerVelY = -9 ## 玩家沿Y轴的速度,默认与玩家拍打时相同
playerMaxVelY = 10 ## 沿Y轴的最大速度,最大下降速度
playerMinVelY = -8 ## 沿Y轴的最小速度,最大上升速度
playerAccY = 1 ## 玩家向下的加速度
playerRot = 45 ## 玩家的旋转角度
playerVelRot = 3 ## 角速度
playerRotThr = 20 ## 旋转阈值
playerFlapAcc = -9 ## 玩家拍打时的速度
playerFlapped = False ## 玩家拍打时为True
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
if playery > -2 * IMAGES["player"][0].get_height():
playerVelY = playerFlapAcc
playerFlapped = True
## 在此处检查碰撞
crashTest = checkCrash(
{"x": playerx, "y": playery, "index": playerIndex}, upperPipes, lowerPipes
)
if crashTest[0]:
return {
"y": playery,
"groundCrash": crashTest[1],
"basex": basex,
"upperPipes": upperPipes,
"lowerPipes": lowerPipes,
"score": score,
"playerVelY": playerVelY,
"playerRot": playerRot,
}
## 检查得分
playerMidPos = playerx + IMAGES["player"][0].get_width() / 2
for pipe in upperPipes:
pipeMidPos = pipe["x"] + IMAGES["pipe"][0].get_width() / 2
if pipeMidPos <= playerMidPos < pipeMidPos + 4:
score += 1
## playerIndex和basex变化
if (loopIter + 1) % 3 == 0:
playerIndex = next(playerIndexGen)
loopIter = (loopIter + 1) % 30
basex = -((-basex + 100) % baseShift)
## 旋转玩家
if playerRot > -90:
playerRot -= playerVelRot
## 玩家的移动
if playerVelY < playerMaxVelY and not playerFlapped:
playerVelY += playerAccY
if playerFlapped:
playerFlapped = False
## 更多旋转以覆盖阈值(在可见旋转中计算)
playerRot = 45
playerHeight = IMAGES["player"][playerIndex].get_height()
playery += min(playerVelY, BASEY - playery - playerHeight)
## 将管道向左移动
for uPipe, lPipe in zip(upperPipes, lowerPipes):
uPipe["x"] += pipeVelX
lPipe["x"] += pipeVelX
## 当第一个管道即将接触屏幕左侧时添加新管道
if 3 > len(upperPipes) > 0 and 0 < upperPipes[0]["x"] < 5:
newPipe = getRandomPipe()
upperPipes.append(newPipe[0])
lowerPipes.append(newPipe[1])
## 如果第一个管道超出屏幕范围,则将其移除
if len(upperPipes) > 0 and upperPipes[0]["x"] < -IMAGES["pipe"][0].get_width():
upperPipes.pop(0)
lowerPipes.pop(0)
## 绘制精灵
SCREEN.blit(IMAGES["background"], (0, 0))
for uPipe, lPipe in zip(upperPipes, lowerPipes):
SCREEN.blit(IMAGES["pipe"][0], (uPipe["x"], uPipe["y"]))
SCREEN.blit(IMAGES["pipe"][1], (lPipe["x"], lPipe["y"]))
SCREEN.blit(IMAGES["base"], (basex, BASEY))
## 显示得分,以便玩家覆盖得分
showScore(score)
## 玩家旋转有一个阈值
visibleRot = playerRotThr
if playerRot <= playerRotThr:
visibleRot = playerRot
playerSurface = pygame.transform.rotate(
IMAGES["player"][playerIndex], visibleRot
)
SCREEN.blit(playerSurface, (playerx, playery))
pygame.display.update()
FPSCLOCK.tick(FPS)
- 我们定义了
mainGame
函数,其中包含《飞扬的小鸟》游戏的核心逻辑。
- 该函数处理用户输入、更新游戏状态、检查碰撞并记录得分。
- 游戏循环持续运行,更新游戏的显示和逻辑。
- 通过按键事件(空格键或向上箭头)处理玩家控制。
- 该函数还检查与管道和地面的碰撞、更新得分并管理小鸟的动画。
- 游戏循环持续进行,直到玩家碰撞或退出游戏。