设计三个文件:
1.main.py
作为运行游戏的主程序
2.settings.py
在此设置游戏的各种参数
3.game_functions.py
游戏运行需要的各种自定义函数
4.字体为华文中宋“STZHONGS.TTF”,可在windows下面的fonts中找
有不对之处,请多指教
1.main.py
'''
创建于 2020年10月10日
作者:追风者
'''
import pygame
import game_functions as gf
from settings import Settings
# 创建游戏各设置参数对象
sn_settings = Settings()
# 计算小格与窗口是否倍数关系,不是倍数关系游戏不执行。
assert sn_settings.screen_width % sn_settings.Cell_Size == 0, "窗口宽度必须是小格子的倍数!"
assert sn_settings.screen_height % sn_settings.Cell_Size == 0, "窗口高度必须是小格子的倍数!"
# 定义主函数
def main(sn_settings):
# 定义全局变量
global SnakespeedCLOCK, SCREEN, BASICFONT
pygame.init()
SnakespeedCLOCK = pygame.time.Clock()
SCREEN = pygame.display.set_mode((sn_settings.screen_width, sn_settings.screen_height))
BASICFONT = pygame.font.Font('STZHONGS.TTF', 24)
pygame.display.set_caption('贪食蛇')
gf.showStartScreen(sn_settings,SCREEN,SnakespeedCLOCK,BASICFONT)
while True:
gf.runGame(sn_settings,SCREEN,BASICFONT,SnakespeedCLOCK)
gf.showGameOverScreen(sn_settings,SCREEN,BASICFONT)
if __name__ == '__main__':
try:
main(sn_settings)
except SystemExit:
pass
2.settings.py
class Settings():
"""存储所有设置"""
def __init__(self):
# 颜色定义
self.WHITE = (255, 255, 255)
self.BLACK = (0, 0, 0)
self.RED = (255, 0, 0)
self.GREEN = (0, 255, 0)
self.DARK_GREEN = (0, 155, 0)
self.DARK_GRAY = (40, 40, 40)
self.YELLOW = (255, 255, 0)
self.RED_DARK = (150, 0, 0)
self.BLUE = (0, 0, 255)
self.BLUE_DARK = (0, 0, 150)
# 屏的设置
self.screen_width = 1200
self.screen_height = 600
self.BGCOLOR = self.BLACK
self.Grid_BGCOLOR = self.DARK_GREEN
# 键盘的设置
self.UP = 'up'
self.DOWN = 'down'
self.LEFT = 'left'
self.RIGHT = 'right'
#蛇的设置
self.Snakespeed = 5
self.HEAD = 0
# 食物的设置
self.Apple_BGCOLOR = self.YELLOW
self.Cell_Size = 20 # 食物正方形边长
self.Cell_W = int(self.screen_width / self.Cell_Size)
self.Cell_H = int(self.screen_height / self.Cell_Size)
3.game_functions.py
import random
import pygame
import sys
from pygame.locals import *
from settings import Settings
def showStartScreen(sn_settings,SCREEN,SnakespeedCLOCK,BASICFONT):
titleFont = pygame.font.Font('STZHONGS.TTF', 80)
titleSurf1 = titleFont.render('贪食蛇', True, sn_settings.WHITE, sn_settings.DARK_GREEN)
degrees = 0
while True:
SCREEN.fill(sn_settings.BGCOLOR)
rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees)
rotatedRect1 = rotatedSurf1.get_rect()
rotatedRect1.center = (sn_settings.screen_width /2, sn_settings.screen_height /2)
SCREEN.blit(rotatedSurf1, rotatedRect1)
drawPressKeyMsg(BASICFONT,SCREEN,sn_settings)
if checkForKeyPress():
pygame.event.get() # 清除事件队列
return
pygame.display.update()
SnakespeedCLOCK.tick(sn_settings.Snakespeed)
degrees += 3 # 每次以3度速度旋转
def drawPressKeyMsg(BASICFONT,SCREEN,sn_settings):
pressKeySurf = BASICFONT.render('按任意键开始游戏!', True, sn_settings.WHITE)
author = BASICFONT.render('设计 by 追风者 ', True, sn_settings.WHITE)
# dr_image = pygame.image.load("image/dr.png")
# dr_rect = dr_image.get_rect()
# dr_rect.centerx = SCREEN.get_rect().centerx -200
# dr_rect.bottom = SCREEN.get_rect().bottom -50
#
# lx_image = pygame.image.load("image/lx.png")
# lx_rect = dr_image.get_rect()
# lx_rect.centerx = SCREEN.get_rect().centerx
# lx_rect.bottom = SCREEN.get_rect().bottom - 50
#
# le_image = pygame.image.load("image/le.png")
# le_rect = dr_image.get_rect()
# le_rect.centerx = SCREEN.get_rect().centerx + 200
# le_rect.bottom = SCREEN.get_rect().bottom - 50
# SCREEN.blit(dr_image, dr_rect)
# SCREEN.blit(lx_image, lx_rect)
# SCREEN.blit(le_image, le_rect)
pressKeyRect = pressKeySurf.get_rect()
authorRect = author.get_rect()
pressKeyRect.topleft = (sn_settings.screen_width - 300, sn_settings.screen_height - 60)
authorRect.topleft = (sn_settings.screen_width - 280, sn_settings.screen_height - 30)
SCREEN.blit(pressKeySurf, pressKeyRect)
SCREEN.blit(author, authorRect)
def checkForKeyPress():
if len(pygame.event.get(QUIT)) > 0:
terminate()
keyUpEvents = pygame.event.get(KEYUP)
if len(keyUpEvents) == 0:
return None
if keyUpEvents[0].key == K_ESCAPE:
terminate()
return keyUpEvents[0].key
def runGame(sn_settings,SCREEN,BASICFONT,SnakespeedCLOCK):
# 设置蛇的一个随机位置
startx = random.randint(5, sn_settings.Cell_W - 6)
starty = random.randint(5, sn_settings.Cell_H - 6)
wormCoords = [{'x': startx, 'y': starty},
{'x': startx - 1, 'y': starty},
{'x': startx - 2, 'y': starty}]
direction = sn_settings.RIGHT
# 设置一个食物的随机位置.
apple = getRandomLocation(sn_settings)
while True: # 游戏主循环
for event in pygame.event.get(): # 键盘事件
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN:
if (event.key == K_LEFT) and direction != sn_settings.RIGHT:
direction = sn_settings.LEFT
elif (event.key == K_RIGHT) and direction != sn_settings.LEFT:
direction = sn_settings.RIGHT
elif (event.key == K_UP) and direction != sn_settings.DOWN:
direction = sn_settings.UP
elif (event.key == K_DOWN) and direction != sn_settings.UP:
direction = sn_settings.DOWN
elif event.key == K_ESCAPE or event.key == K_q:
terminate()
# 检查蛇是否碰到窗口边缘
if wormCoords[sn_settings.HEAD]['x'] == -1 \
or wormCoords[sn_settings.HEAD]['x'] == sn_settings.Cell_W \
or wormCoords[sn_settings.HEAD]['y'] == -1 \
or wormCoords[sn_settings.HEAD]['y'] == sn_settings.Cell_H:
return # 游戏结束
for wormBody in wormCoords[1:]:
if wormBody['x'] == wormCoords[sn_settings.HEAD]['x'] \
and wormBody['y'] == wormCoords[sn_settings.HEAD]['y']:
return # 游戏结束
# 检查蛇是不是吃到一个食物
if wormCoords[sn_settings.HEAD]['x'] == apple['x'] \
and wormCoords[sn_settings.HEAD]['y'] == apple['y']:
apple = getRandomLocation(sn_settings) # 放一个新的食物
else:
del wormCoords[-1]
# 移动蛇头
if direction == sn_settings.UP:
newHead = {'x': wormCoords[sn_settings.HEAD]['x'],
'y': wormCoords[sn_settings.HEAD]['y'] - 1}
elif direction == sn_settings.DOWN:
newHead = {'x': wormCoords[sn_settings.HEAD]['x'],
'y': wormCoords[sn_settings.HEAD]['y'] + 1}
elif direction == sn_settings.LEFT:
newHead = {'x': wormCoords[sn_settings.HEAD][
'x'] - 1, 'y': wormCoords[sn_settings.HEAD]['y']}
elif direction == sn_settings.RIGHT:
newHead = {'x': wormCoords[sn_settings.HEAD][
'x'] + 1, 'y': wormCoords[sn_settings.HEAD]['y']}
wormCoords.insert(0, newHead)
SCREEN.fill(sn_settings.BGCOLOR)
drawGrid(sn_settings,SCREEN)
drawWorm(wormCoords,sn_settings,SCREEN)
drawApple(apple,sn_settings,SCREEN)
drawScore((len(wormCoords) - 3),BASICFONT,sn_settings,SCREEN)
pygame.display.update()
SnakespeedCLOCK.tick(sn_settings.Snakespeed)
def getRandomLocation(sn_settings):
return {'x': random.randint(0, sn_settings.Cell_W - 1), 'y': random.randint(0, sn_settings.Cell_H - 1)}
def drawGrid(sn_settings,SCREEN):
for x in range(0, sn_settings.screen_width, sn_settings.Cell_Size): # 画垂直线
pygame.draw.line(SCREEN, sn_settings.Grid_BGCOLOR, (x, 0), (x, sn_settings.screen_height))
for y in range(0, sn_settings.screen_height, sn_settings.Cell_Size): # 画水平线
pygame.draw.line(SCREEN, sn_settings.Grid_BGCOLOR, (0, y), (sn_settings.screen_width, y))
def drawWorm(wormCoords,sn_settings,SCREEN):
for coord in wormCoords:
x = coord['x'] * sn_settings.Cell_Size
y = coord['y'] * sn_settings.Cell_Size
wormSegmentRect = pygame.Rect(x, y, sn_settings.Cell_Size, sn_settings.Cell_Size)
pygame.draw.rect(SCREEN, sn_settings.DARK_GREEN, wormSegmentRect)
wormInnerSegmentRect = pygame.Rect(
x + 4, y + 4, sn_settings.Cell_Size - 8, sn_settings.Cell_Size - 8)
pygame.draw.rect(SCREEN, sn_settings.GREEN, wormInnerSegmentRect)
def drawApple(coord,sn_settings,SCREEN):
x = coord['x'] * sn_settings.Cell_Size
y = coord['y'] * sn_settings.Cell_Size
appleRect = pygame.Rect(x, y, sn_settings.Cell_Size, sn_settings.Cell_Size)
pygame.draw.rect(SCREEN, sn_settings.Apple_BGCOLOR, appleRect)
def drawScore(score,BASICFONT,sn_settings,SCREEN):
scoreSurf = BASICFONT.render('得分: %s' % (score), True, sn_settings.WHITE)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (sn_settings.screen_width - 120, 10)
SCREEN.blit(scoreSurf, scoreRect)
def showGameOverScreen(sn_settings,SCREEN,BASICFONT):
gameOverFont = pygame.font.Font('STZHONGS.TTF', 50)
gameSurf = gameOverFont.render('游戏结束', True, sn_settings.WHITE)
# overSurf = gameOverFont.render('Over', True, sn_settings.WHITE)
gameRect = gameSurf.get_rect()
# overRect = overSurf.get_rect()
gameRect.midtop = (sn_settings.screen_width / 2, (sn_settings.screen_height - 50) / 2)
# overRect.midtop = (sn_settings.screen_width / 2, gameRect.height + 10 + 25)
SCREEN.blit(gameSurf, gameRect)
# SCREEN.blit(overSurf, overRect)
drawPressKeyMsg(BASICFONT,SCREEN,sn_settings)
pygame.display.update()
pygame.time.wait(500)
checkForKeyPress() # clear out any key presses in the event queue
while True:
if checkForKeyPress():
pygame.event.get() # clear event queue
return
def terminate():
pygame.quit()
sys.exit()