python成长记:写一个自己的超简单贪吃蛇游戏

本人系python小白,这是我的第一篇博客,一路摸爬滚打,终于入了门。花了两天琢磨,写了这个超简单的容易理解的贪吃蛇游戏,给大家分享自己的理解吧。

简介:

1,老方法用pygame库来画背景,蛇,食物等等。

2,sys库控制程序窗口

3,random库来取随机数处理食物生成问题。

4,time库让游戏结束时短暂停顿后自动结束程序。

详解:

第一步:毋庸置疑肯定就是导入库

import pygame
import sys
import random
import time

第二步:创建游戏窗口等准备部分

pygame.init()    # 初始化pygame库
size = (640, 480)   # 设置窗口大小
screen = pygame.display.set_mode(size)   # 初始化窗口
pygame.display.set_caption("The PPSnake")  # 设置的窗口名称
snake_body = [[100, 100]]  # 贪吃蛇初始长度只有一节(蛇头),提供是的坐标(x轴,y轴)
font = pygame.font.SysFont("SIMYOU.TTF", 80)  # 由于会涉及到分数,所以设置字体格式
clock = pygame.time.Clock()     # 控制运行速度,增加游戏乐趣,随着蛇的长度越长,速度越快
food_flag = 1  # 食物存在的标志
food_position = [300, 300]    # 食物最初的位置
direction = ''  # 存下方向变量

第三步:主循环搭建好

while True:

    clock.tick(2*len(snake_body)+9)  # 设置游戏速度,蛇长度越长,游戏速度越快

    # 监视键盘事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()  #退出游戏
            sys.exit()  #退出程序

        # 贪吃蛇移动方向标志
        elif event.type == pygame.KEYDOWN:
            if event.key == K_UP and direction != 'DOWN':
                direction = 'UP'
            if event.key == K_DOWN and direction != 'UP':
                direction = 'DOWN'
            if event.key == K_LEFT and direction != 'RIGHT':
                direction = 'LEFT'
            if event.key == K_RIGHT and direction != 'LEFT':
                direction = 'RIGHT'

    # snake移动
    snake_move(snake_body)

    # 判断食物存在
    food_flag = food_judge(screen, food_position, food_flag)

    # 判断食物是否被吃
    food_eat(food_position, snake_body)

    # 绘制分数
    draw_score(screen, snake_body, font)

    # 判断游戏结束, 只要蛇头超出屏幕就结束游戏
    if snake_body[0][0] > screen.get_width() or snake_body[0][0] < 0:
        GameOver(screen, font)
    elif snake_body[0][1] > screen.get_height() or snake_body[0][0] < 0:
        GameOver(screen, font)

    # 这里的判断方法很特别,而且也很方便我自己认为,因为蛇在屏幕上是由一个一个正方形小格子构成
    # 所以头咬到自己的身体至少说明蛇是5个正方形以上,因此我们从snak_body中从第4个元素起开始
    # 查找,只要会咬到,蛇头的坐标就肯定出现在后面的列表中
    elif snake_body[0] in snake_body[4:]:
        GameOver(screen, font)

    # 窗口背景色
    screen.fill((125, 125, 125))

    # 绘制贪吃蛇
    draw_snake(screen, snake_body)

    # 绘制食物
    draw_food(screen, food_position)

第四步:实现各个功能

(1)snake移动:这里运用也比较巧妙,通过删除蛇的尾巴,和将要移动的方向,来找到新蛇头

                              的位置,然后通过列表操作,加入新的蛇头的坐标。这样就实现了蛇的移动,

                              而且又没有改变蛇的长度。(只要拿起笔算一算蛇的坐标很容易就理解了)

def snake_move(snake_body):     # 因为靠蛇的首尾部分来实现移动,所以把蛇的长度传入函数中
    global direction            # direction是最初设置的存方向的变量,这里声明为全局变量
    if direction == 'UP':
        x = snake_body[0][0]
        y = snake_body[0][1] - 10
        snake_body.insert(0, [x, y])  # 加入新的蛇头
        snake_body.pop(-1)        # 删除尾巴
    if direction == 'DOWN':
        x = snake_body[0][0]
        y = snake_body[0][1] + 10
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)
    if direction == 'LEFT':
        x = snake_body[0][0] - 10
        y = snake_body[0][1]
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)
    if direction == 'RIGHT':
        x = snake_body[0][0] + 10
        y = snake_body[0][1]
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)

(2)food_eat部分:因为要判断食物是否被吃,也就是要判断蛇头与食物的位置是否重合,

                                      所以把food_position(食物的位置), snake_body传入到函数中。这

                                       里蛇吃到食物后变长也运用比较巧妙,记录下即将被删除的尾巴坐标,

                                       判断吃到食物,然后就重新添加回到列表,这样自然就变长了一个长度

def food_eat(food_position, snake_body):
    global food_flag       # food_flag食物存在标志初始准备定义的,这里声明为全局变量
    # 判断食物是否被吃
    if food_position[0] == snake_body[0][0] and food_position[1] == snake_body[0][1]:
        # 被吃后设置食物标志为0
        food_flag = 0
        # 记下即将被删除尾巴的坐标,然后给加回来用于增加一个长度
        x = snake_body[-1][0]
        y = snake_body[-1][1]
        snake_body.insert(-1, [x, y])

(3)food_judge部分:首先判断是否食物存在,若不存在就用random库中的randint()函数重新

                                      生成食物的位置,然后再画出食物,并把食物标志设置为1表示存在。

# 判断食物存在
if food_flag == 0:
    # 重新生成食物并设置标志为1
    food_position[0] = int(10 * random.randint(0, 64))
    food_position[1] = int(10 * random.randint(4, 32))
    pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))
    food_flag = 1
    return food_flag

(4)draw_snake部分:因为在屏幕上画出蛇,所以传入screen,snake_body两个参数到函数。

                                       for循环遍历组成蛇的格子的坐标,screen屏幕,(255,255,255)是

                                       蛇的颜色,i[0],i[1]是坐标,10,10是10*10像素的格子。

def draw_snake(screen, snake_body):
    for i in snake_body:
        pygame.draw.rect(screen, (255, 255, 255), (i[0], i[1], 10, 10))

(5)draw_food部分: 同理(4)

def draw_food(screen, food_position):
    pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))

(6)draw_score部分:

def draw_score(screen, snake_body, font):
    # 绘制分数
    score_surf = font.render("%s" % (len(snake_body) - 1), True, (0, 0, 0))  # 创建字体对象
    score_rect = score_surf.get_rect()  # 获得字体对象的外接矩形
    score_rect.midtop = (320, 0)  # 设置矩形的位置
    screen.blit(score_surf, score_rect)  # 画出字体对象
    pygame.display.flip()   # 更新屏幕

(7)GameOver部分:

def GameOver(screen, font):  同理(6)
    # 绘制游戏结束
    Gameover_surf = font.render("Game Over", True, (0, 0, 0))
    Gameover_rect = Gameover_surf.get_rect()
    Gameover_rect.midtop = (320, 240)
    screen.blit(Gameover_surf, Gameover_rect)
    pygame.display.flip()   
    time.sleep(3)   # 暂停3后退出
    pygame.quit()
    sys.exit()

最后:代码如下

import pygame
import sys
import random
import time
from pygame import K_LEFT, K_DOWN, K_UP, K_RIGHT

pygame.init()    # 初始化pygame库
size = (640, 480)   # 窗口大小
screen = pygame.display.set_mode(size)   # 初始化窗口
pygame.display.set_caption("The PPSnake")  # 窗口名称
snake_body = [[100, 100]]  # 贪吃蛇初始长度
font = pygame.font.SysFont("SIMYOU.TTF", 80)  # 设置字体格式
clock = pygame.time.Clock()     # 控制运行速度
food_flag = 1  # 食物存在到标志
food_position = [300, 300]    # 食物最初的位置
direction = ''  # 方向

def snake_move(snake_body):
    global direction
    if direction == 'UP':
        x = snake_body[0][0]
        y = snake_body[0][1] - 10
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)
    if direction == 'DOWN':
        x = snake_body[0][0]
        y = snake_body[0][1] + 10
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)
    if direction == 'LEFT':
        x = snake_body[0][0] - 10
        y = snake_body[0][1]
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)
    if direction == 'RIGHT':
        x = snake_body[0][0] + 10
        y = snake_body[0][1]
        snake_body.insert(0, [x, y])
        snake_body.pop(-1)

def food_eat(food_position, snake_body):
    global food_flag
    # 判断食物是否被吃
    if food_position[0] == snake_body[0][0] and food_position[1] == snake_body[0][1]:
        # 被吃后设置标志为0
        food_flag = 0
        # 记下即将被删除尾巴的坐标,然后给加回来用于增加一个长度
        x = snake_body[-1][0]
        y = snake_body[-1][1]
        snake_body.insert(-1, [x, y])

def food_judge(screen, food_position, food_flag):
    # 判断食物存在
    if food_flag == 0:
        # 重新生成食物并设置标志为1
        food_position[0] = int(10 * random.randint(0, 64))
        food_position[1] = int(10 * random.randint(4, 32))
        pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))
        food_flag = 1
        return food_flag

def draw_snake(screen, snake_body):
    for i in snake_body:
        pygame.draw.rect(screen, (255, 255, 255), (i[0], i[1], 10, 10))

def draw_food(screen, food_position):
    pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))

def draw_score(screen, snake_body, font):
    # 绘制分数
    score_surf = font.render("%s" % (len(snake_body) - 1), True, (0, 0, 0))  # 创建字体对象
    score_rect = score_surf.get_rect()  # 获得字体对象的外接矩形
    score_rect.midtop = (320, 0)  # 设置矩形的位置
    screen.blit(score_surf, score_rect)  # 画出字体对象
    pygame.display.flip()

def GameOver(screen, font):
    # 绘制游戏结束
    Gameover_surf = font.render("Game Over", True, (0, 0, 0))
    Gameover_rect = Gameover_surf.get_rect()
    Gameover_rect.midtop = (320, 240)
    screen.blit(Gameover_surf, Gameover_rect)
    pygame.display.flip()
    time.sleep(3)   # 暂停3后退出
    pygame.quit()
    sys.exit()

while True:

    clock.tick(2*len(snake_body)+9)  # 设置每秒运行的次数控制游戏速度

    # 监视键盘事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # 贪吃蛇移动方向标志
        elif event.type == pygame.KEYDOWN:
            if event.key == K_UP and direction != 'DOWN':
                direction = 'UP'
            if event.key == K_DOWN and direction != 'UP':
                direction = 'DOWN'
            if event.key == K_LEFT and direction != 'RIGHT':
                direction = 'LEFT'
            if event.key == K_RIGHT and direction != 'LEFT':
                direction = 'RIGHT'

    # snake移动
    snake_move(snake_body)

    # 判断食物存在
    food_flag = food_judge(screen, food_position, food_flag)

    # 判断食物是否被吃
    food_eat(food_position, snake_body)

    # 绘制分数
    draw_score(screen, snake_body, font)

    # 判断游戏结束
    if snake_body[0][0] > screen.get_width() or snake_body[0][0] < 0:
        GameOver(screen, font)
    elif snake_body[0][1] > screen.get_height() or snake_body[0][0] < 0:
        GameOver(screen, font)
    elif snake_body[0] in snake_body[4:]:
        GameOver(screen, font)

    # 窗口背景色
    screen.fill((125, 125, 125))

    # 绘制贪吃蛇
    draw_snake(screen, snake_body)

    # 绘制食物
    draw_food(screen, food_position)

后记:本人系初学者小白,尽自己最大努力写了这篇博客,这也是第一篇博客,希望自己的能力越来越好,对于代码能够挥刀自如,也希望用CSDN能够见证自己的成长。

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唯有深海与我同眠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值