当前位置:   article > 正文

pygame小游戏——贪吃蛇_pygame snake

pygame snake

前言

贪吃蛇(也叫做贪食蛇)游戏是一款休闲益智类游戏,既简单又耐玩,唯一的目标就是做这条gai上最长(pang)的蛇(zhu)

玩贪吃蛇最考验的就是走位(简称蛇皮走位),各种漂移过人,唉,就是玩儿!

在这里插入图片描述

基本设置

# 基本设置
lattice_wh = 20
snake_color = (84, 255, 159)
snake_head_color = (123, 104, 238)
food_color = (255, 64, 64)
  • 1
  • 2
  • 3
  • 4
  • 5

绘制屏幕

# 绘制屏幕
pygame.init()
screen = pygame.display.set_mode((25*lattice_wh, 25*lattice_wh))
pygame.display.set_caption("贪吃蛇")

# 帧率,每秒刷新屏幕次数
FPS = 10
# 帧率变化系数
level = 1.5
# 时间对象
FPSCLOCK = pygame.time.Clock()
# 游戏结束标志
game_over = 0
# 前进方向
direction = 0
# 进食数量
num = 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

蛇类

# 蛇
class Snake():
    def __init__(self, snake_color, snake_head_color, x, y, lattice_wh):
        self.color = snake_color
        self.head_color = snake_head_color
        # 左上顶点坐标
        self.pos = (x, y)
        self.lattice_wh = lattice_wh
      	# 绘制蛇体
        self.rect = pygame.rect.Rect(x, y, self.lattice_wh, self.lattice_wh)
        # 左上顶点坐标变化
        self.pos_change = {
            # 上移
            1:(0, -self.lattice_wh),
            # 下移
            2:(0, self.lattice_wh),
            # 左移
            3:(-self.lattice_wh, 0),
            # 右移
            4:(self.lattice_wh, 0)
        }
	
    def move(self, direction):
        self.rect.x += self.pos_change[direction][0]
        self.rect.y += self.pos_change[direction][1]

    def forecast(self, direction):
        return (self.rect.x+self.pos_change[direction][0], self.rect.y+self.pos_change[direction][1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

食物类

# 食物
class Food():
    def __init__(self, food_color, screen, lattice_wh, x, y):
        self.screen = screen
        self.color = food_color
        self.lattice_wh = lattice_wh
        # 半径
        self.radius = lattice_wh/2
        self.x, self.y = x, y

    def draw(self):
        # 圆心
        pos = (self.x+self.lattice_wh/2, self.y+self.lattice_wh/2)
        # 绘制食物
        pygame.draw.circle(self.screen, self.color, pos, self.radius, int(self.radius))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

初始状态

# 贪吃蛇
snakes = list()
snakes.append(Snake(snake_color, snake_head_color, lattice_wh, 24*lattice_wh, lattice_wh))
snakes.append(Snake(snake_color, snake_head_color, 0, 24*lattice_wh, lattice_wh))

# 食物
food = create_food(food_color, screen, lattice_wh, snakes)

# 游戏状态
game_stats = [game_over, direction, num, food]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

生成食物

# 生成食物
def create_food(food_color, screen, lattice_wh, snakes):
    # 食物是否生成成功
    create_success = 0
    # 食物位置坐标
    food_x, food_y = 0, 0
    while not create_success:
        food_x, food_y = randint(0, 24), randint(0, 24)
        food_x *= lattice_wh
        food_y *= lattice_wh
        # 检查食物位置是否与贪吃蛇位置重合
        for snake in snakes:
            if (food_x, food_y) != (snake.rect.x, snake.rect.y):
                create_success = 1
                break
    # 在指定位置生成食物
    food = Food(food_color, screen, lattice_wh, food_x, food_y)
    return food
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

响应键鼠

# 响应键鼠
def check_events(game_stats):
    for event in pygame.event.get():
        # 退出游戏
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        # 控制移动方向,注意不能直接反向移动
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP and game_stats[1] != 2:
                game_stats[1] = 1
            elif event.key == pygame.K_DOWN and game_stats[1] != 1:
                game_stats[1] = 2
            elif event.key == pygame.K_LEFT and game_stats[1] != 4:
                game_stats[1] = 3
            elif event.key == pygame.K_RIGHT and game_stats[1] != 3:
                game_stats[1] = 4
            else:
                game_stats[1] = game_stats[1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

更新屏幕

# 更新屏幕
def update(screen, lattice_wh, snakes, game_stats):
    screen.fill((255, 255, 255))
    # 绘制蛇头
    pygame.draw.rect(screen, snakes[0].head_color, snakes[0].rect)
    # 绘制蛇身
    for i in range(1, len(snakes)):
        pygame.draw.rect(screen, snakes[i].color, snakes[i].rect)
    # 绘制横线
    for i in range(25):
        pygame.draw.line(screen, (105, 105, 105), (0, lattice_wh*i), (500, lattice_wh*i))
    # 绘制竖线
    for i in range(25):
        pygame.draw.line(screen, (105, 105, 105), (lattice_wh*i, 0), (lattice_wh*i, 500))
    # 绘制食物
    game_stats[3].draw()
    # 更新屏幕
    pygame.display.flip()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

移动进食

# 移动进食
def going(screen, game_stats, snakes, snake_head_color, snake_color, food_color, lattice_wh):
    if not game_stats[1]:
        return
    # 蛇头下一前进位置
    (x, y) = snakes[0].forecast(game_stats[1])
    # 检查是否触碰边界
    if x == -lattice_wh or x == 25*lattice_wh or y == -lattice_wh or y == 25*lattice_wh:
        game_stats[0] = 1
        return
    # 检查是否触碰食物
    if (x, y) == (game_stats[3].x, game_stats[3].y):
        # 更新蛇头
        new_head = Snake(snake_color, snake_head_color, x, y, lattice_wh)
        snakes.insert(0, new_head)
        # 更新分数
        game_stats[2] += 1
        # 重新生成食物
        game_stats[3] = create_food(food_color, screen, lattice_wh, snakes)
        return
    # 检查是否触碰蛇身
    for snake in snakes:
        if (x, y) == (snake.rect.x, snake.rect.y):
            game_stats[0] = 1
            return
    # 更新所有蛇身位置
    for i in range(len(snakes)-1, 0, -1):
        snakes[i].rect.x = snakes[i-1].rect.x
        snakes[i].rect.y = snakes[i-1].rect.y
    # 更新蛇头位置
    snakes[0].move(game_stats[1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

游戏入口

# 游戏入口
while not game_stats[0]:
    update(screen, lattice_wh, snakes, game_stats)
    check_events(game_stats)
    going(screen, game_stats, snakes, snake_head_color, snake_color, food_color, lattice_wh)
    FPSCLOCK.tick(FPS * level ** num if FPS * level ** num < 60 else 60)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

snake.py

import pygame

# 蛇
class Snake():
    def __init__(self, snake_color, snake_head_color, x, y, lattice_wh):
        self.color = snake_color
        self.head_color = snake_head_color
        # 左上顶点坐标
        self.pos = (x, y)
        self.lattice_wh = lattice_wh
        # 绘制蛇体
        self.rect = pygame.rect.Rect(x, y, self.lattice_wh, self.lattice_wh)
        # 左上顶点坐标变化
        self.pos_change = {
            # 上移
            1:(0, -self.lattice_wh),
            # 下移
            2:(0, self.lattice_wh),
            # 左移
            3:(-self.lattice_wh, 0),
            # 右移
            4:(self.lattice_wh, 0)
        }

    # 移动
    def move(self, direction):
        self.rect.x += self.pos_change[direction][0]
        self.rect.y += self.pos_change[direction][1]

    # 下一前进位置
    def forecast(self, direction):
        return (self.rect.x+self.pos_change[direction][0], self.rect.y+self.pos_change[direction][1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

food.py

import pygame

# 食物
class Food():
    def __init__(self, food_color, screen, lattice_wh, x, y):
        self.screen = screen
        self.color = food_color
        self.lattice_wh = lattice_wh
        # 半径
        self.radius = lattice_wh/2
        self.x, self.y = x, y

    def draw(self):
        # 圆心
        pos = (self.x+self.lattice_wh/2, self.y+self.lattice_wh/2)
        # 绘制食物
        pygame.draw.circle(self.screen, self.color, pos, self.radius, int(self.radius))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

function.py

import pygame
import sys
from random import randint
from food import Food
from snake import Snake

# 生成食物
def create_food(food_color, screen, lattice_wh, snakes):
    # 食物是否生成成功
    create_success = 0
    # 食物位置坐标
    food_x, food_y = 0, 0
    while not create_success:
        food_x, food_y = randint(0, 24), randint(0, 24)
        food_x *= lattice_wh
        food_y *= lattice_wh
        # 检查食物位置是否与贪吃蛇位置重合
        for snake in snakes:
            if (food_x, food_y) != (snake.rect.x, snake.rect.y):
                create_success = 1
                break
    # 在指定位置生成食物
    food = Food(food_color, screen, lattice_wh, food_x, food_y)
    return food

# 响应事件
def check_events(game_stats):
    for event in pygame.event.get():
        # 退出游戏
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        # 控制移动方向,注意不能直接反向移动
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP and game_stats[1] != 2:
                game_stats[1] = 1
            elif event.key == pygame.K_DOWN and game_stats[1] != 1:
                game_stats[1] = 2
            elif event.key == pygame.K_LEFT and game_stats[1] != 4:
                game_stats[1] = 3
            elif event.key == pygame.K_RIGHT and game_stats[1] != 3:
                game_stats[1] = 4
            else:
                game_stats[1] = game_stats[1]

# 更新屏幕
def update(screen, lattice_wh, snakes, game_stats):
    screen.fill((255, 255, 255))
    # 绘制蛇头
    pygame.draw.rect(screen, snakes[0].head_color, snakes[0].rect)
    # 绘制蛇身
    for i in range(1, len(snakes)):
        pygame.draw.rect(screen, snakes[i].color, snakes[i].rect)
    # 绘制横线
    for i in range(25):
        pygame.draw.line(screen, (105, 105, 105), (0, lattice_wh*i), (500, lattice_wh*i))
    # 绘制竖线
    for i in range(25):
        pygame.draw.line(screen, (105, 105, 105), (lattice_wh*i, 0), (lattice_wh*i, 500))
    # 绘制食物
    game_stats[3].draw()
    # 更新屏幕
    pygame.display.flip()

# 移动进食
def going(screen, game_stats, snakes, snake_head_color, snake_color, food_color, lattice_wh):
    if not game_stats[1]:
        return
    # 蛇头下一前进位置
    (x, y) = snakes[0].forecast(game_stats[1])
    # 检查是否触碰边界
    if x == -lattice_wh or x == 25*lattice_wh or y == -lattice_wh or y == 25*lattice_wh:
        game_stats[0] = 1
        return
    # 检查是否触碰食物
    if (x, y) == (game_stats[3].x, game_stats[3].y):
        # 更新蛇头
        new_head = Snake(snake_color, snake_head_color, x, y, lattice_wh)
        snakes.insert(0, new_head)
        # 更新分数
        game_stats[2] += 1
        # 重新生成食物
        game_stats[3] = create_food(food_color, screen, lattice_wh, snakes)
        return
    # 检查是否触碰蛇身
    for snake in snakes:
        if (x, y) == (snake.rect.x, snake.rect.y):
            game_stats[0] = 1
            return
    # 更新所有蛇身位置
    for i in range(len(snakes)-1, 0, -1):
        snakes[i].rect.x = snakes[i-1].rect.x
        snakes[i].rect.y = snakes[i-1].rect.y
    # 更新蛇头位置
    snakes[0].move(game_stats[1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

main.py

import pygame
from function import *
from snake import Snake

# 基本设置
lattice_wh = 20
snake_color = (84, 255, 159)
snake_head_color = (123, 104, 238)
food_color = (255, 64, 64)

# 绘制屏幕
pygame.init()
screen = pygame.display.set_mode((25*lattice_wh, 25*lattice_wh))
pygame.display.set_caption("贪吃蛇")

# 帧率,每秒刷新屏幕次数
FPS = 10
# 帧率变化系数
level = 1.5
# 时间对象
FPSCLOCK = pygame.time.Clock()

# 游戏结束标志
game_over = 0

# 前进方向
direction = 0
# 进食数量
num = 0

# 贪吃蛇
snakes = list()
snakes.append(Snake(snake_color, snake_head_color, lattice_wh, 24*lattice_wh, lattice_wh))
snakes.append(Snake(snake_color, snake_head_color, 0, 24*lattice_wh, lattice_wh))

# 食物
food = create_food(food_color, screen, lattice_wh, snakes)

# 游戏状态
game_stats = [game_over, direction, num, food]

# 游戏入口
while not game_stats[0]:
    update(screen, lattice_wh, snakes, game_stats)
    check_events(game_stats)
    going(screen, game_stats, snakes, snake_head_color, snake_color, food_color, lattice_wh)
    FPSCLOCK.tick(FPS * level ** num if FPS * level ** num < 60 else 60)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

敲黑板!!!在控制蛇的移动方向时,易忽略蛇不能直接反向移动这一问题;另外,在生成食物时,要检查食物的位置与蛇的位置是否重合,如果两者位置重合,此时需要生成新的食物。

python小游戏——井字棋:https://blog.csdn.net/KissMoon_/article/details/117437893

凉梦空间

欢迎你进入我的个人博客网站参观交流:https://www.liangmeng.xyz

在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号