前文内容请移步:
在本小节实现runGame的代码
八
在runGame中主要是响应键盘的操作。还是在代码中来一一讲解
'''
关卡的游戏主循环
'''
def runGame(screen, gamelevel):
clock = pygame.time.Clock()
gamedisplay = gameDisplay(screen)
gamedisplay.loadLevelMap(gamelevel)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quitGame()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
next_pos = gamedisplay.worker.getNextPos('left')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('left')
else:
box = gamedisplay.gamemap.getTheBoxByPos(*next_pos)
if box:
next_pos = box.getNextPos('left')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('left')
box.move('left')
break
if event.key == pygame.K_RIGHT:
next_pos = gamedisplay.worker.getNextPos('right')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('right')
else:
box = gamedisplay.gamemap.getTheBoxByPos(*next_pos)
if box:
next_pos = box.getNextPos('right')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('right')
box.move('right')
break
if event.key == pygame.K_DOWN:
next_pos = gamedisplay.worker.getNextPos('down')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('down')
else:
box = gamedisplay.gamemap.getTheBoxByPos(*next_pos)
if box:
next_pos = box.getNextPos('down')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('down')
box.move('down')
break
if event.key == pygame.K_UP:
next_pos = gamedisplay.worker.getNextPos('up')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('up')
else:
box = gamedisplay.gamemap.getTheBoxByPos(*next_pos)
if box:
next_pos = box.getNextPos('up')
if gamedisplay.gamemap.isCanPushPos(*next_pos):
gamedisplay.worker.move('up')
box.move('up')
break
if event.key == pygame.K_r:
gamedisplay.initCurGame()
gamedisplay.loadLevelMap(gamelevel)
gamedisplay.draw(gamedisplay.worker, gamedisplay.gamemap)
if gamedisplay.gamemap.curLevelCompleted():
return
pygame.display.flip()
clock.tick(100)
注解:
1、套娃的过程中,最外面的是gameDisplay,所以先实例化一个gameDisplay,叫做gamedisplay
2、利用传入的参数gamelevel加载该关卡地图loadLevelMap
3、开始消息循环,用到的主要是键盘事件,就是上下左右,r键,响应一次,就调用gamedisplay的draw函数重绘一次游戏页面
4、用gamemap的curLevelCompleted函数判断该关卡是否过关,过关就return,到main里面的switchGame,由用户选择“下一关”还是“退出”。
5、flip显示出来
以向左来为例简要讲解一下移动处理过程:
3.1 首先getNextPos函数获取下一个位置next_pos,
3.2如果这个位置工人worker可以到达,则移动这个工人worker
3.3如果工人worker不能移动,就有两种可能:
3.3.1该方向上下一个位置的箱子可以在该方向上移动:此时,先getTheBoxByPos找到next_pos上的箱子对象,再获取该箱子在该方向上的下一个位置,如果箱子可以到达,则移动该箱子及工人
3.3.2 如果不满足条件,则不能move
至此,讲解完成。
当然,大家会看到,runGame消息循环中有大量代码重复。故可以改成:
'''
关卡的游戏主循环
'''
def myMove(_gamedisplay,_direction):
next_pos = _gamedisplay.worker.getNextPos(_direction)
if _gamedisplay.gamemap.isCanPushPos(*next_pos):
_gamedisplay.worker.move(_direction)
else:
box = _gamedisplay.gamemap.getTheBoxByPos(*next_pos)
if box:
next_pos = box.getNextPos(_direction)
if _gamedisplay.gamemap.isCanPushPos(*next_pos):
_gamedisplay.worker.move(_direction)
box.move(_direction)
def runGame(screen, gamelevel):
clock = pygame.time.Clock()
gamedisplay = gameDisplay(screen)
gamedisplay.loadLevelMap(gamelevel)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quitGame()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
myMove(gamedisplay,'left')
break
if event.key == pygame.K_RIGHT:
myMove(gamedisplay,'right')
break
if event.key == pygame.K_DOWN:
myMove(gamedisplay,'down')
break
if event.key == pygame.K_UP:
myMove(gamedisplay,'up')
break
if event.key == pygame.K_r:
gamedisplay.initCurGame()
gamedisplay.loadLevelMap(gamelevel)
gamedisplay.draw(gamedisplay.worker, gamedisplay.gamemap)
if gamedisplay.gamemap.curLevelCompleted():
return
pygame.display.flip()
clock.tick(100)
九
关卡文件就是使用普通的文本编辑器就可以了,注意其对应的关系。
w:推箱子的工人
*:墙
#:箱子
o:目的地
十
大家一关关过后,到最后一关都过去了,会发现先弹出switchGame的界面,点击后才显示“恭喜通关!”,体验不是很好,聪明的你自行解决一下这个问题~~~
“源码面前,了无秘密” --- 侯捷《STL源码剖析》