Python-pygame-实现功能超赞的贪吃蛇游戏 可绘制地图

大一暑假闲时练手作品,全为自主原创无任何参考,咱也不知道这么原始的绘图方式算好算赖

实现的功能有:
·贪吃蛇基本游戏功能,·可选有无墙,·生成大食物 ·速度变化(有上限) ·得分减少
·地图选择功能 ·自定义速度功能  ·记录最高分功能 ·玩家绘制地图功能!
游戏主页游戏效果
绘制地图

实现代码:

运行需要pygame,可在cmd中使用下列命令安装

>>> pip install pygame

这里就不详细分类说明了, 每个功能都是独立的类或方法 基本都有注释,可以参考学习,也可以复制来玩玩。

原创源码,转载请注明。

import pygame
import random
import sys
import pygame.freetype
import re
import datetime

pygame.init()  # 初始化py_game模块
fl = pygame.freetype.Font("C://Windows//Fonts//simsun.ttc", 30)     # 加载字体 此行报错把路径修改为本地字体路径
screen = pygame.display.set_mode((1186, 668))   # 界面大小
pygame.display.set_caption("贪吃蛇v-0.2.0")   # 修改名称
clock = pygame.time.Clock()     # 游戏时钟
GOLD = 255, 251, 0          # 颜色设定 可更换喜欢的颜色,稍加修改可以变成?色
RED = pygame.Color('red')
WHITE = 255, 255, 255


class Snake:
    body_list = []  # 记录蛇身位置的列表
    center_1 = None  # 小食物中心
    center_2 = None  # 大食物中心
    center_2_key = False  # 大食物控制钥匙
    big_time = None
    score = 0       # 分数记录
    long = 0        # 蛇身记录
    fs = 0          # 最终得分
    WALL = False    # 墙 不存在

    def __init__(self):
        self.r = 5  # 食物半径
        self.FOOD_SIZE = 21

        self.old_pop = None  # 尾巴列表
        self.switch = (0, 0)  # 防止撞头开关
        self.big_food_time_1 = None  # 大豆豆时间
        self.eat_big_food_key = 0  # 大豆豆增长钥匙
        Snake.body_list = []  # 记录蛇身位置的列表
        Snake.center_1 = None  # 小食物中心
        Snake.center_2 = None  # 大食物中心
        Snake.center_2_key = False  # 大食物控制钥匙
        Snake.big_time = None
        Snake.score = 0  # 分数记录
        Snake.long = 7  # 蛇的长度
        self.SNAKE_SIZE = 21  # 每一块?的大小
        self.x_speech = 0
        self.y_speech = 0
        self.speech = (0, 0)
        self.head_rect = [15, 12]  # 蛇头的相对位置
        self.__draw_head()  # 绘制蛇头
        for p in range(Snake.long):  # 绘制蛇身
            if p != 0:
                pygame.draw.rect(screen, WHITE, (
                    81 + (self.head_rect[0] - p) * self.SNAKE_SIZE + 1, 66 + self.head_rect[1] * self.SNAKE_SIZE + 1,
                    self.SNAKE_SIZE - 1,
                    self.SNAKE_SIZE - 1))
                Snake.body_list.append((self.head_rect[0] - p, self.head_rect[1]))

    def Speech(self, p, switch_1):
        if switch_1 == 0:
            self.switch = self.speech
            switch_1 = 1
        if p.type == pygame.KEYDOWN:
            if p.key == pygame.K_UP:
                if self.speech != (0, 1) and self.switch != (0, 1):
                    self.y_speech = -1
                    self.x_speech = 0
            elif p.key == pygame.K_DOWN:
                if self.speech != (0, -1) and self.switch != (0, -1):
                    self.y_speech = 1
                    self.x_speech = 0
            elif p.key == pygame.K_RIGHT:
                if self.speech != (-1, 0) and self.switch != (-1, 0):
                    self.x_speech = 1
                    self.y_speech = 0
            elif p.key == pygame.K_LEFT:
                if self.speech != (1, 0) and self.switch != (1, 0) and self.speech != (0, 0):
                    self.x_speech = -1
                    self.y_speech = 0
        self.speech = (self.x_speech, self.y_speech)
        return switch_1

    def move(self):

        if self.x_speech or self.y_speech != 0:
            Snake.body_list = [(self.head_rect[0], self.head_rect[1])] + Snake.body_list
            self.__draw_body()

        # 位置移动区块
        self.head_rect[0] += self.speech[0]
        self.head_rect[1] += self.speech[1]
        self.__wall()           # 墙面传送
        self.__draw_head()      # 绘制蛇头

        # 判断蛇头吃豆豆
        if self.head_rect == list(Snake.center_1):
            Snake.long += 1
            self.draw_new_food()
            Snake.score += 10
            if self.eat_big_food_key > 0:
                self.old_pop = Snake.body_list.pop()
                self.eat_big_food_key += 1
            else:
                pygame.draw.rect(screen, WHITE, (
                    81 + Snake.body_list[Snake.long - 2][0] * self.SNAKE_SIZE + 1,
                    66 + Snake.body_list[Snake.long - 2][1] * self.SNAKE_SIZE + 1,
                    self.SNAKE_SIZE - 1, self.SNAKE_SIZE - 1))  # 身体增长
        elif self.x_speech or self.y_speech != 0:
            self.old_pop = Snake.body_list.pop()
            self.draw_new_food(False)

        if Snake.center_2_key:  # 大豆豆的时间控制 与 吃到大豆豆的变化
            if self.head_rect == list(Snake.center_2):
                Snake.long += 3  # 长度+3
                Snake.score += 50  # 分数+50
                self.eat_big_food_key = 3  # 大豆豆增长钥匙
                Snake.center_2 = None  # 清空大豆豆列表
                Snake.center_2_key = False
                fl.render_to(screen, (560, 80), str(8 - Snake.big_time), (0, 0, 0), size=40)
                fl.render_to(screen, (560, 80), str(9 - Snake.big_time), (0, 0, 0), size=40)
            self.big_food_time()

        if self.eat_big_food_key > 0:
            Snake.body_list.append(self.old_pop)
            self.eat_big_food_key -= 1
            pygame.draw.rect(screen, WHITE, (
                81 + Snake.body_list[Snake.long - 2 - self.eat_big_food_key][0] * self.SNAKE_SIZE + 1,
                66 + Snake.body_list[Snake.long - 2 - self.eat_big_food_key][1] * self.SNAKE_SIZE + 1,
                self.SNAKE_SIZE - 1, self.SNAKE_SIZE - 1))

        # 判断头吃身体
        if tuple(self.head_rect) in Snake.body_list:
            self.speech = (0, 0)
            self.x_speech = self.y_speech = 0
            # 游戏结束
            return 1

        # 判断头撞地形
        if AllMap.map_list[AllMap.numb] is not None:
            if tuple(self.head_rect) in AllMap.map_list[AllMap.numb]:
                self.speech = (0, 0)
                self.x_speech = self.y_speech = 0
                return 1

    def __draw_head(self):
        pygame.draw.rect(screen, RED, (
            81 + self.head_rect[0] * self.SNAKE_SIZE + 1, 66 + self.head_rect[1] * self.SNAKE_SIZE + 1,
            self.SNAKE_SIZE - 1,
            self.SNAKE_SIZE - 1))

    def __draw_body(self):
        # 覆盖老蛇头
        pygame.draw.rect(screen, WHITE, (
            81 + Snake.body_list[0][0] * self.SNAKE_SIZE + 1, 66 + Snake.body_list[0][1] * self.SNAKE_SIZE + 1,
            self.SNAKE_SIZE - 1,
            self.SNAKE_SIZE - 1))

        # 删除蛇尾
        if self.eat_big_food_key <= 0:
            pygame.draw.rect(screen, (0, 0, 0), (
                81 + Snake.body_list[Snake.long - 1][0] * self.SNAKE_SIZE + 1,
                66 + Snake.body_list[Snake.long - 1][1] * self.SNAKE_SIZE + 1,
                self.SNAKE_SIZE, self.SNAKE_SIZE))

    @staticmethod
    def __Center():
        """随机生成豆豆位置"""
        center = (random.randint(0, 24), random.randint(0, 24))  # 随机生成食物的相对位置
        # 判断随机数是否与蛇身重合,并处理
        while True:
            if center in Snake.body_list:
                center = (random.randint(0, 24), random.randint(0, 24))
            elif center == Snake.center_1 or center == Snake.center_2:
                center = (random.randint(0, 24), random.randint(0, 24))
            elif AllMap.map_list[AllMap.numb] is not None and center in AllMap.map_list[AllMap.numb]:
                center = (random.randint(0, 24), random.randint(0, 24))
            else:
                return center

    def draw_new_food(self, key=True):
        if key:
            Snake.center_1 = Snake.__Center()
        pygame.draw.circle(screen, WHITE,
                           (81 + Snake.center_1[0] * self.FOOD_SIZE + 11, 66 + Snake.center_1[1] * self.FOOD_SIZE + 11),
                           self.r)

        if Snake.long % 12 == 0 and key:
            Snake.center_2 = Snake.__Center()
            pygame.draw.circle(screen, GOLD,
                               (81 + Snake.center_2[0] * self.FOOD_SIZE + 11,
                                66 + Snake.center_2[1] * self.FOOD_SIZE + 11),
                               self.r + 2)
            Snake.center_2_key = True
            self.big_food_time_1 = int(pygame.time.get_ticks() / 1000)

    def big_food_time(self):
        time_2 = int(pygame.time.get_ticks() / 1000)
        Snake.big_time = time_2 - self.big_food_time_1
        if time_2 - self.big_food_time_1 >= 8:
            pygame.draw.circle(screen, (0, 0, 0),
                               (81 + Snake.center_2[0] * self.FOOD_SIZE + 11,
                                66 + Snake.center_2[1] * self.FOOD_SIZE + 11),
                               self.r + 2)
            fl.render_to(screen, (560, 80), '1', (0, 0, 0), size=40)
            Snake.center_2 = None
            Snake.center_2_key = False

    def __wall(self):
        """判断是否有墙及传送"""
        if Snake.WALL:
            if self.head_rect[0] == 25 or self.head_rect[0] == -1 or self.head_rect[1] == 25 or self.head_rect[1] == -1:  # 判断撞墙
                over()
        else:
            if self.head_rect[0] == 25:  # 墙面传送
                self.head_rect[0] = 0
            elif self.head_rect[1] == 25:
                self.head_rect[1] = 0
            elif self.head_rect[0] == -1:
                self.head_rect[0] = 24
            elif self.head_rect[1] == -1:
                self.head_rect[1] = 24


class GameSpeed:

    game_fps_min_speed = 5
    game_fps_high_speed = 10
    game_fps_max_speed = 24


class AllMap:
    GAME_WINDOW_NO = (80, 65, 529, 529)
    GAME_WINDOW_HA = (78, 63, 532, 532)
    WALL = False        # 无墙
    map_list = [None,
                ((2, 2), (2, 4), (2, 5), (2, 1
  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值