pygame框架之贪吃蛇(140行规范代码)

贪吃蛇

Posted by LuochuanAD on April 14, 2024

前言

最近学到pygame框架,就想利用Python的语法特性,来规范写一个贪吃蛇游戏

此版本贪吃蛇特点

充分利用Python的语法特性,具有可读性高的特点,方便为以后写其他Python项目打下一个好的代码风格

Demo的gif动画如下

思路分析:

一, 我希望python中所有默认的配置都在同一个类中

class SnakeGameConf():
    SCREEN_WIDTH = 800                 屏幕宽度
    SCREEN_HEIGHT = 800		     屏幕高度
    FPS = 3						     帧度(也即速度)
    BG_COLOR = (255, 255, 255)       屏幕背景颜色(白色)
    SNAKE_COLOR = (0, 255, 255)     贪吃蛇颜色
    SNAKE_BODY = [[100,100],[80, 100],[60,100],[40,100],[20,100]]  贪吃蛇初始身体
    FOOD_COlOR = (255, 0, 0)			食物颜色
    FOOD_SIZE = 20					食物大小
    FOOD_POSITION = [300, 300]        食物初始位置
    SCORE = 0						得分
    FOOD_TOTAL = 1                         食物出现次数(也是当前关卡数)
    BUTTON_RECT = pygame.Rect(300,SCREEN_HEIGHT/2+100,200,50)                                  重新开始按钮的位置大小

二, 建立蛇类和食物类

class Snake(pygame.sprite.Sprite):
    def __init__(self): 初始化贪吃蛇当前的方向 和 初始身体大小
        ......
    def drawSnake(self,body,Screen): 在屏幕绘制新的蛇的身体
        for i in body:
            pygame.draw.rect(Screen, SnakeGameConf.SNAKE_COLOR, Rect(i[0],i[1], SnakeGameConf.FOOD_SIZE,SnakeGameConf.FOOD_SIZE))
    def changeDirection(self, direction):  通过键盘上下左右改变蛇的的方向
       ......
    def addNode(self): 在移动过程中增加蛇头的坐标
       ......
    def deleteNode(self):在移动过程中删除蛇尾的坐标
        ......
    def snakeMove(self): 蛇移动
        self.addNode()
        self.deleteNode()
    def isDead(self): 蛇死亡的条件
        # 贪吃蛇碰到四周边界,或自己身体,死
        ......
class Food(pygame.sprite.Sprite):
    def __init__(self):初始化食物的位置
        ......
    def drawFood(self,foodLocation,Screen): 在屏幕上绘制食物
        ......
    def removeFood(self): 将食物坐标移出屏幕外,代表已被蛇吃了
        ......
    def set(self,snakeLocation): 随机设置食物的位置
        

三, 建立UI类(用于显示文字或按钮等)

class UISettings():
    def show_text(self, screen, pos, text, color, font_bold = False, font_size = 60, font_italic = False): 显示文字
        cur_font = pygame.font.SysFont('宋体', font_size)
        cur_font.set_bold(font_bold)
        cur_font.set_italic(font_italic)
        text_fmt = cur_font.render(text, 1, color)
        screen.blit(text_fmt, pos)
    def show_button(self, screen,rect, button_color, text,text_color,text_font):显示按钮
        text = pygame.font.Font(None,text_font).render(text,True,text_color)
        text_rect = text.get_rect(center=rect.center)
        pygame.draw.rect(screen,button_color,rect)
        screen.blit(text,text_rect)

四, main()方法(用于执行主程序)

def main():
    ......
    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                snake.changeDirection(event.key)
            if event.type == MOUSEBUTTONDOWN:
                if snakeconf.BUTTON_RECT.collidepoint(pygame.mouse.get_pos()):
                    '''重新开始,重置默认参数'''
                    snake.curDirection = pygame.K_RIGHT
                    snake.body = snakeconf.SNAKE_BODY[:]
                    snakeconf.SCORE = 0
                    snakeconf.FOOD_TOTAL = 0
                    snakeconf.FPS = 3
        screen.fill(snakeconf.BG_COLOR)
        if snake.isDead():  
         '''死亡时,显示提示和重新开始按钮'''
            	......
        else:
            snake.snakeMove()
            snakeconf.SCORE += 1
            snake.drawSnake(snake.body, screen)
            
        '''判断是否吃到食物'''
        if snake.body[0] == snakeconf.FOOD_POSITION:
           ......
            snakeconf.FPS += 3  无限关卡,每次速度加3
        food.drawFood(food.rect, screen)
        uisettings.show_text(screen,[20,SnakeGameConf.SCREEN_HEIGHT-50],'Level: '+ str(snakeconf.FOOD_TOTAL) +'  Scors: '+str(snakeconf.SCORE), 'pink',True,50,True)
        pygame.display.update()
        clock.tick(snakeconf.FPS)

if __name__ == '__main__': main()

Github项目链接:

https://github.com/LuochuanAD/PythonProject/blob/main/SnakeGame/standardGame.py

个人反思:

1, 使用pygame来开发2D游戏是足够的,但是加载图片等素材时,还有帧率(流畅度)是不够的. 但是能够用Pygame来开发游戏的永远是靠创意.

2, 我在用pygame开发贪吃蛇时, 发现代码的底层就是在计算坐标. python这门语言真的适合来做数据相关的工作,算法是Python的核心功能.