##知识点 分析
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’,将呈现未知字符。通常是一个矩形。相反,需要自己处理新行。
返回的表面将具有容纳文本所需的尺寸。(与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) #返回一个在5和CELLWIDTH - 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): # 绘制垂直线,范围:0到WINDOWWIDTH-1,CELLSIZE次,即单元格的框框
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()
代码源自:
贪吃蛇
代码