游戏分享:手把手教你用Python编写推星星
游戏(六)
2017.12.10
来让我们开始今天的学习吧
注意要善用列表噢
396.#置入背景色
397.DISPLAYSURF.fill(BGCOLOR)
398.
399.#置入标题图片
400.DISPLAYSURF.blit(IMAGESDICT['title'],titleRect)
401.
402.#置入并定位文本
403.for i in range(len(instructionText)):
404.instSurf=BASICFONT.render(instructionText[i],1,TEXTCOLOR) 405.instRect=instSurf.get_rect()
406.topCoord+=10#行距10像素
407.instRect.top=topCoord
408.instRect.centerx=HALF_WINWIDTH
409.topCoord+=instRect.height#调整行高
410.DISPLAYSURF.blit(instSurf,instRect)
400行驶将图片置入表层显示对象。而403行的for循环将传递,定位并置入每个教学字符串至instructionText循环中。
topCoord变量将随着409行中的文本大小而改变数值,并在每一行隔开10个像素间距(406行)
412.while True:#初始界面循环
413.for event in pygame.event.get():
414.if event.type==QUIT:
415.terminate()
416.elif event.type==KEYDOWN:
417.if event.key==K_ESCAPE:
418.terminate()
419.return#玩家按下了ESC
420.
421.#在屏幕上显示DISPLAYSURF里的内容
422.pygame.display.update()
423.FPSCLOCK.tick()
412行有个关于startScreen()的循环,它将处理程序是否应关闭或返回至startScreen()函数。直到玩家做出操作后,循环会持续调用
pygame.display.update()和FPSCLOCK.tick()来使屏幕上显示初始界面
“地图”数据结构
地图数据结构是有由一系列简单的2D列表组成,分别代表了地图上元素的XY坐标。列表中的值都是单字符串,代表了地图上的元素。
·'#'–木墙
·'x'–角落墙
·'@'–玩家初始位置
·'.'–星标方块
·'$'–星星初始位置
·'+'–玩家初始位置与星标方块
·'*'–星星初始位置与星标方块
·''–.关卡外草地方块
·'o'–关卡内地板方块(这是一个小写o)
·'1'–草地方块上的石头装饰
·'2'–小树装饰
·'3'–大树装饰
·'4'–奇怪的树装饰
426.def readLevelsFile(filename):
427.assert os.path.exists(filename),'Cannot find the level file:%s'% (filename)
os.path.exists()函数将会反馈True如果文件确实存在。反之则为False
428.mapFile=open(filename,'r')
429.#每一关必须以空行结尾
430.content=mapFile.readlines()+['\r\n']
431.mapFile.close()
432.
433.levels=[]#关卡列表
434.levelNum=0
435.mapTextLines=[]#单个关卡地图
436.mapObj=[]#mapTextLines里的关卡对象
关卡对象储存在mapFile里,所有关于关卡的文本对象都将作为字符串列表储存在content变量里,并且以在结尾处空行。(空行的原因将在稍后解释)关卡对象创建后将储存在levels列表里。
levelNum变量将持续监测关卡文件里有多少关卡。mapTextLines列表是一个从content列表中提取的单个地图字符串列表。
437.for lineNum in range(len(content)):
438.#加工关卡内文本行
439.line=content[lineNum].rstrip('\r\n')
437行的for循环将审阅关卡文件里的每一行。行数将储存在lineNum里,而每行文本字符串将储存在line里,任何新行字符串末尾的字符将被移除。
441.if';'in line:
442.#忽略;行这是关卡文件里的评论
443.line=line[:line.find(';')]
地图文件里,任何在分号后的文本与评论一样将被忽略,这就和#在python里的作用一样。为了确保我们的代码不会认为评论是地图的一部分,line变量将只包括分号前的内容。(这一步知识改变content列表里的字符串而不是硬盘里的关卡文件)
445.if line!='':
446.#这行代码是地图的一部分
447.mapTextLines.append(line)
在地图文件里有各个关卡的地图。mapTextLines列表将包含地图文件内已被读取的关卡文本。只要当前关卡存在,当前line就会被添加到mapTextLines的底部
448.elif line==''and len(mapTextLines)>0:
449.#空行表示单个关卡地图到此为止
450.#将mapTextLines中的文本转换为关卡对象
当地图文件中出现一个空行,那表明当前关卡的地图已经处理完毕。而之后的文本将是在本关后的其他关卡的地图。
452.#找到地图中最长的一排方块
453.maxWidth=-1
454.for i in range(len(mapTextLines)):
455.if len(mapTextLines[i])>maxWidth:
456.maxWidth=len(mapTextLines[i])
所有在mapTextLines中的字符串必须是相同长度的,这样才能组建一个矩形,所以长度短的方块行必须填补空格来与最长的方块行达到相同的长度。
这个for循环将检查mapTextLines中每一行字符串,并在找到最长方块行的同时更新maxWidth。在循环结束后,maxWidth变量将设置为mapTextLines中长度最长的字符串
457.#A给短的方块行添加空格
458.#保证地图为矩形
459.for i in range(len(mapTextLines)):
460.mapTextLines[i]+=''*(maxWidth-len(mapTextLines[i]))
459行的for循环将再次检查mapTextLines中的字符串。这次将给每一行都添加空方块来达到最大长度。
462.#将mapTextLines转换为地图对象
463.for x in range(len(mapTextLines[0])):
464.mapObj.append([])
465.for y in range(len(mapTextLines)):
466.for x in range(maxWidth):
467.mapObj[x].append(mapTextLines[y][x])
mapTextLines储存的是字符串列表(列表中的每个字符串代表一行方块,而每个字符串中的字符又代表了另一列的字符。)而地图对象必须包含每个单字符串的XY坐标。所以463行的for循环给mapObj添加了一个空列表来储存mapTextLines中每一列的坐标。
465,466行的嵌套for循环将通过这些列表中的单字符串来表示地图上每个方块的坐标。这步操作创建了推星星所使用的地图对象。