贪吃蛇python代码分析

##知识点 分析
1,pygame.time.Clock.tick()
tick(framerate=0) -> milliseconds
作用:更新帧显示速率(即图像移动速度),限制游戏的运行速度,若clock.tick(40),则程序运行速度<=每秒40帧。一般放在图像更新函数update后

2,字体模块中的pygame.font.Font()
Font(filename, size) -> Font
Font(object, size) -> Font
pygame.font.SysFont() :可从系统加载字体,在windows/Font下
none:使用pygame带有内置的默认字体
pygame.font.Font(‘freesansbold.ttf’, 18) #freesansbold字体,.ttf字体文件格式

3,from pygame.locals import * :引入pygame中的所有常量
pygame.locals模块包含pygame使用的各种常量,会自动放置在PyGame模块名称空间中。但是,应用程序可以使用模块中仅包含带有from pygame.locals import*的pygame常量(pygame中定义的常量)。

4,pygame.font.Font.render()
render(text, antialias, color, background=None) -> Surface
text:
在新Surface上绘制文本,pygame不提供直接在现有surface上绘制文本,相反,必须使用font.render()创建文本的图像(表面),然后将此图像快速放到另一个surface上
文本只能是单行:不呈现换行符。空字符(“x00”)会引发类型错误。
在这里插入图片描述
在这里插入图片描述
接受unicode和char(byte)字符串。对于Unicode字符串,只识别ucs-2字符(“u0001”到“uffff”)。任何更大的值都会引发一个unicode错误。
如果呈现’\n’,将呈现未知字符。通常是一个矩形。相反,需要自己处理新行
贪吃蛇python代码分析_第1张图片
返回的表面将具有容纳文本所需的尺寸。(与FONT.SIZE()返回的相同)。如果为文本传递空字符串,将返回一个宽度为一个像素和字体高度的空白表面

antialias:平滑的边缘(true),false表示带有锯齿
background:用于文本背景的颜色(新创建的surface的颜色)。如果没有背景通过,文本之外的区域将是透明的。

5,pygame.transform.rotate()
rotate(Surface, angle) -> Surface
旋转图像
angle:表示度数,可以是任意浮点数,正角度逆时针,逆角度顺时针。
除非以90度的增量旋转,否则图像将被填充得更大以保持新的大小。如果图像有像素alphas,填充区域将是透明的。否则,pygame将选择与表面颜色键或左上角像素值匹配的颜色。

6,pygame.Surface.blit()
blit(source, dest, area=None, special_flags=0) -> Rect
将一个图像绘制到另一个图像上

7,pygame.event.get()
get(eventtype=None) -> Eventlist
get(eventtype=None, pump=True) -> Eventlist
punp=true:调用pygame.event.pump()内部进程pygame事件处理程序。
作用:获取所有消息并将其从队列中删除。如果给定了类型或类型序列,则只会从队列中删除这些消息。

8,pygame.key
模块包含处理键盘的功能.

9,pygame.display.update()
update(rectangle=None) -> None
update(rectangle_list) -> None
类似于软件显示的pygame.display.flip()的优化版本。它只允许更新屏幕的一部分,而不允许更新整个区域。如果没有传递任何参数,它将更新整个表面积,如pygame.display.flip()。

10,pygame.draw.line()
line(surface, color, start_pos, end_pos, width) -> Rect
line(surface, color, start_pos, end_pos, width=1) -> Rect
在给定的曲面上绘制一条直线。没有端盖。粗线的两端是方形的。
width:线条厚度。如果宽度大于等于1,则用于线条厚度(默认值为1)。如果宽度小于1,则不会绘制任何内容。
start_pos, end_pos:起末位置 (x, y)

11,pygame.Rect()
Rect(left, top, width, height) -> Rect
Rect((left, top), (width, height)) -> Rect
Rect(object) -> Rect
用于存储直角坐标的PyGame对象

12,pygame.draw.rect()
rect(surface, color, rect) -> Rect
rect(surface, color, rect, width=0) -> Rect
绘制矩形

13,if name == ‘main’:
name :当前模块名
当模块被直接运行时,代码块将被运行,模块名为 main,当模块被导入时,代码块不被运行。即自己眼中还是main,别人眼中则_name_不再是_main_,是你的名字。

14,assert断言:测试表示式,true的话ok,false就会触发异常

代码

import random, pygame
from pygame.locals import *
#import pygame.locals

FPS = 10 #循环频率()
WINDOWWIDTH = 640 #窗口宽度
WINDOWHEIGHT = 480 #窗口高度
CELLSIZE = 20 #单元格大小,即正方形边长
assert WINDOWWIDTH % CELLSIZE == 0, "窗口宽度必须是单元格大小的倍数,防止有空余"
assert WINDOWHEIGHT % CELLSIZE == 0, "窗口高度必须是单元格大小的倍数"
CELLWIDTH = int(WINDOWWIDTH / CELLSIZE) #单元格个数
CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE)

#             R    G    B
WHITE     = (255, 255, 255) #白
BLACK     = (  0,   0,   0) #黑
RED       = (255,   0,   0) #红
GREEN     = (  0, 255,   0) #绿
DARKGREEN = (  0, 155,   0) #深绿
DARKGRAY  = ( 40,  40,  40) #深灰
BGCOLOR = BLACK #背景颜色:黑

UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'

HEAD = 0 # 头部,列表

def main():
    global FPSCLOCK, DISPLAYSURF, BASICFONT #可一个一个套进去
    pygame.init()
    #创建游戏时钟对象,控制游戏循环频率
    FPSCLOCK = pygame.time.Clock()
    #设置游戏窗口
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) #显示界面
    #BASICFONT = pygame.font.SysFont('sylfaen.ttf', 18) #系统的
    #BASICFONT = pygame.font.SysFont('Open Sans.ttf', 18) #创建字体对象
    BASICFONT = pygame.font.Font('freesansbold.ttf', 18) 
    pygame.display.set_caption('Wormy')
    #绘制图像初始位置
    showStartScreen()
    #游戏循环
    while True:
        #检测用户交互+更新所有图像位置
        runGame()
        #更新屏幕显示
        showGameOverScreen()


def runGame():
    # 设置随机起点
    startx = random.randint(5, CELLWIDTH - 6) #返回一个在5CELLWIDTH - 6之间的随机整数
    starty = random.randint(5, CELLHEIGHT - 6) #控制蛇出现在距top和bottom有一定距离
    wormCoords = [{
     'x': startx,     'y': starty}, #头部位置  字典列表
                  {
     'x': startx - 1, 'y': starty}, #第二节 水平
                  {
     'x': startx - 2, 'y': starty}] #第三节
    direction = RIGHT #蛇的初始方向

    # 在一个随机的地方开始苹果(红块)
    apple = getRandomLocation()

    while True: # 主游戏循环
        for event in pygame.event.get(): # 事件处理
            if event.type == QUIT:
                pygame.quit()
            elif event.type == KEYDOWN:
                #<- or A 向左,当现在方向不是左时
                if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
                    direction = LEFT
                elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
                    direction = RIGHT
                elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
                    direction = UP
                elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
                    direction = DOWN
                elif event.key == K_ESCAPE:#esc退出
                    pygame.quit()

        # 检查蛇是否击中自身或边缘
        #['x'] == -1是左边缘,['x'] == CELLWIDTH是右,['y'] == -1是上,['y'] == CELLHEIGHT是下,意味着撞墙后会少掉一节
        if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == CELLWIDTH or wormCoords[HEAD]['y'] == -1 or wormCoords[HEAD]['y'] == CELLHEIGHT:
            return # game over
        #查看除头部外,其他与头部x,y是否重合(击中自身)
        for wormBody in wormCoords[1:]:
            if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
                return # game over

        # 检查蛇是否吃过
        if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']: #蛇移动到苹果位置
            # 不要取下蛇的尾段,吃到时,移动产生的一段作为新的
            apple = getRandomLocation() # 在某个地方放一个新苹果
        else:
            del wormCoords[-1] # 未吃的时候,移动一格拆下一段蛇尾段,因为蛇的移动是通过加一段实现的

        #通过向蛇移动的方向添加一个段来移动蛇
        if direction == UP:
            newHead = {
     'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1}
        elif direction == DOWN:
            newHead = {
     'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1}
        elif direction == LEFT:
            newHead = {
     'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']}
        elif direction == RIGHT:
            newHead = {
     'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']}
        wormCoords.insert(0, newHead) #在0位置插入新头部
        DISPLAYSURF.fill(BGCOLOR) #用背景色填充屏幕
        drawGrid() #给单元格的外边框加色
        drawWorm(wormCoords)
        drawApple(apple)
        drawScore(len(wormCoords) - 3)
        pygame.display.update()
        # 设置主循环刷新帧频
        FPSCLOCK.tick(FPS)

def drawPressKeyMsg():
    pressKeySurf = BASICFONT.render('Press a key to play.', True, RED) #换个颜色会发现在右下角
    pressKeyRect = pressKeySurf.get_rect()
    #top, left, bottom, right
    #center, centerx, centery
    #topleft,bottomleft,topright,bottomright
    #midtop,midleft,midbottom,midright
    pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30) 
    DISPLAYSURF.blit(pressKeySurf, pressKeyRect)


def checkForKeyPress():
    if len(pygame.event.get(QUIT)) > 0:
        pygame.quit()

    keyUpEvents = pygame.event.get(KEYUP)#接收任意按键  列表
    if len(keyUpEvents) == 0:
        return None
    if keyUpEvents[0].key == K_ESCAPE:#初始按ESC退出
        pygame.quit()
    return keyUpEvents[0].key #按下键了,后续清空列表,开始游戏


def showStartScreen():
    titleFont = pygame.font.SysFont('freesansbold.ttf', 100)
    titleSurf1 = titleFont.render('Snake!!', True, WHITE, DARKGREEN) #底层 
    titleSurf2 = titleFont.render('Snake!!', True, GREEN) #外层

    degrees1 = 0 #水平 初始位置
    degrees2 = 0
    while True:
        DISPLAYSURF.fill(BGCOLOR) #用背景色填充屏幕
        rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1)
        rotatedRect1 = rotatedSurf1.get_rect()
        rotatedRect1.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2) #水平居中垂直居中
        DISPLAYSURF.blit(rotatedSurf1, rotatedRect1) 

        rotatedSurf2 = pygame.transform.rotate(titleSurf2, degrees2)
        rotatedRect2 = rotatedSurf2.get_rect()
        rotatedRect2.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
        DISPLAYSURF.blit(rotatedSurf2, rotatedRect2)

        drawPressKeyMsg()

        if checkForKeyPress():
            pygame.event.get() # 清除事件队列
            return #跳出循环
        pygame.display.update()
        FPSCLOCK.tick(FPS)# 设置刷新帧频,每帧调用一次,计算每次的毫秒数
        degrees1 += 3 # 每帧旋转3,每帧:一个循环
        degrees2 += 7 # 每帧旋转7度


def getRandomLocation():
    return {
     'x': random.randint(0, CELLWIDTH - 1), 'y': random.randint(0, CELLHEIGHT - 1)} #在全屏幕内找个位置


def showGameOverScreen():
    gameOverFont = pygame.font.Font('freesansbold.ttf', 150)
    gameSurf = gameOverFont.render('Game', True, WHITE)
    overSurf = gameOverFont.render('Over', True, WHITE)
    gameRect = gameSurf.get_rect()
    overRect = overSurf.get_rect()
    gameRect.midtop = (WINDOWWIDTH / 2, 10)
    overRect.midtop = (WINDOWWIDTH / 2, gameRect.height + 10 + 25)

    DISPLAYSURF.blit(gameSurf, gameRect)
    DISPLAYSURF.blit(overSurf, overRect)
    drawPressKeyMsg()
    pygame.display.update()
    pygame.time.wait(500)
    checkForKeyPress() # 清除事件队列中的所有按键

    while True:
        if checkForKeyPress():
            pygame.event.get() # 清除事件队列
            return

def drawScore(score):
    scoreSurf = BASICFONT.render('Score: %s' % (score), True, WHITE) #% (score) ->%d 整型
    scoreRect = scoreSurf.get_rect()#获取屏幕位置作参照
    scoreRect.topleft = (WINDOWWIDTH - 120, 10)
    DISPLAYSURF.blit(scoreSurf, scoreRect)


def drawWorm(wormCoords):
    for coord in wormCoords:
        x = coord['x'] * CELLSIZE #第几个的位置*单位宽度
        y = coord['y'] * CELLSIZE
        wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE) #Rect(left, top, width, height) -> Rect 获取位置
        pygame.draw.rect(DISPLAYSURF, DARKGREEN, wormSegmentRect) #绘制蛇
        wormInnerSegmentRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8) #内节矩形,即两层颜色的蛇
        pygame.draw.rect(DISPLAYSURF, GREEN, wormInnerSegmentRect)


def drawApple(coord):#只有一个格不需要遍历
    x = coord['x'] * CELLSIZE
    y = coord['y'] * CELLSIZE
    appleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
    pygame.draw.rect(DISPLAYSURF, RED, appleRect)


def drawGrid():
    for x in range(0, WINDOWWIDTH, CELLSIZE): # 绘制垂直线,范围:0WINDOWWIDTH-1CELLSIZE次,即单元格的框框
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, WINDOWHEIGHT))
    for y in range(0, WINDOWHEIGHT, CELLSIZE): # 绘制水平线
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (WINDOWWIDTH, y))


if __name__ == '__main__':
    main()

代码源自:
贪吃蛇
代码

你可能感兴趣的:(python,python,小游戏,分析)