IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 一个正在开发中的 Python3 贪吃蛇游戏 -> 正文阅读

[Python知识库]一个正在开发中的 Python3 贪吃蛇游戏

前言

最近正在练习使用 pygame, 感觉这东西真的是功能强大、用途广泛。前几天用 pygame,写了一个 Console 程序,看起来很极客(实际上很弱智),今天觉得可以写一个简易的贪吃蛇程序。

游戏界面

游戏界面其中,浅绿色的部分是水果(吃了之后蛇的长度 +1),深绿色的部分是蛇身(蛇头和蛇尾一个样,懒得处理了),暗绿色的部分是墙。

snake.py

贪吃蛇游戏的主程序。

# Author : GGN_2015
# Content: 贪吃蛇游戏

from game_method import *
import random # 生成随机位置
import time

# 棋盘相关的常量, (棋盘是左右上下循环的)
BOARD_EMPTY = 0 # 空位置
BOARD_SNAKE = 1 # 棋盘上蛇占据的位置
BOARD_WALL  = 2 # 棋盘上墙占据的位置
BOARD_FRUIT = 3 # 水果

chessboard = {} # 棋盘存储空间
WIDTH  = 20
HEIGHT = 20 # 棋盘的宽度和高度,下标为 (高度-1, 宽度-1)
for i in range(0, HEIGHT):
    for j in range(0, WIDTH):
        chessboard[(i, j)] = BOARD_EMPTY # 初始化将棋盘清空

RESOLUTION = (1920, 1080) # 屏幕分辨率 

REDIUS = int((RESOLUTION[1] - 50) / HEIGHT / 2) - 2 # 半径算法,各种圆的半径

SNAKE_BODY = [] # 描述蛇身每个位置的坐标
INIT_LEN = 4

for i in range(0, INIT_LEN):
    SNAKE_BODY.append((int(HEIGHT/2), int(WIDTH/2) + i)) # 初始蛇身长度为 4, 左头 [0], 右尾 [len - 1]

DIRX = {} # 方向向下的坐标轴
DIRY = {} # 方向向右的坐标轴

DIRX['LEFT']  =  0
DIRX['RIGHT'] =  0
DIRX['UP']    = -1
DIRX['DOWN']  =  1 # 描述蛇移动时 X 坐标的改变情况

DIRY['LEFT']  = -1
DIRY['RIGHT'] =  1
DIRY['UP']    =  0
DIRY['DOWN']  =  0 # 描述蛇移动时 Y 坐标的改变情况

DIRECTION = 'LEFT' # 描述蛇移动的方向

def NextHead(): # 通过当前蛇头计算新的蛇头坐标(空间是循环的)
    NowHead  = SNAKE_BODY[0]
    nextHead = ((NowHead[0] + DIRX[DIRECTION]) % HEIGHT, (NowHead[1] + DIRY[DIRECTION]) % WIDTH)
    return nextHead

def Crash(): # 检测是否会发生蛇头碰撞
    return chessboard[NextHead()] != BOARD_EMPTY and chessboard[NextHead()] != BOARD_FRUIT

def Grow():
    return chessboard[NextHead()] == BOARD_FRUIT # 蛇身长度增长

Window = screen(Title = "Snake Game", FullScreen = True, Resolution = RESOLUTION)
Window.Fill((0, 0, 0)) # BLACK 纯色填充

def Modify(R, G, B, rate):
    return (int(R*rate), int(G*rate), int(B*rate))

# LINECOLOR = (127, 127, 127)
LINECOLOR = Modify(34, 252, 43, 0.10)

"""
def GetColor(BOARD_TYPE): # 获得某种区块对应的颜色
    if BOARD_TYPE == BOARD_EMPTY: return (  0,   0,   0)
    if BOARD_TYPE == BOARD_FRUIT: return (255,  50,  50)
    if BOARD_TYPE == BOARD_SNAKE: return ( 50,  50, 255)
    if BOARD_TYPE == BOARD_WALL : return (127, 127, 127)
    return (0, 255, 0) # Error color
"""

def GetColor(BOARD_TYPE): # 获得某种区块对应的颜色极客配色
    if BOARD_TYPE == BOARD_EMPTY: return Modify(34, 252, 43, 0.00)
    if BOARD_TYPE == BOARD_FRUIT: return Modify(34, 252, 43, 1.00)
    if BOARD_TYPE == BOARD_SNAKE: return Modify(34, 252, 43, 0.50)
    if BOARD_TYPE == BOARD_WALL : return Modify(34, 252, 43, 0.10)
    return (0, 255, 0) # Error color

def ShowChessBoard(): # 在屏幕上显示棋盘

    D = (RESOLUTION[1] - 50) / HEIGHT # 棋盘方格的边长

    for i in range(0, HEIGHT + 1): # 画横线
        pygame.draw.line(Window.Screen, LINECOLOR, (0, D*i), (RESOLUTION[1] - 50, D*i), 3)
    for i in range(0, WIDTH + 1): # 画竖线
        pygame.draw.line(Window.Screen, LINECOLOR, (D*i, 0), (D*i, RESOLUTION[1] - 50), 3)

    for i in range(0, HEIGHT):
        for j in range(0, WIDTH): # 清空蛇的坐标
            if chessboard[(i, j)] == BOARD_SNAKE:
                chessboard[(i, j)] = BOARD_EMPTY

    for pos in SNAKE_BODY:
        chessboard[pos] = BOARD_SNAKE # 重新设置蛇身坐标

    for i in range(0, HEIGHT):
        for j in range(0, WIDTH): # 枚举坐标系中的每一个位置
            pos = (D*j + int(D/2), D*i + int(D/2))
            pygame.draw.circle(Window.Screen, GetColor(chessboard[(i, j)]), pos, int(D/2) - 4)


def dir(EventKey): # 通过按键得到方向字符串
    if   EventKey ==  K_LEFT: return 'LEFT'
    elif EventKey == K_RIGHT: return 'RIGHT'
    elif EventKey ==    K_UP: return 'UP'
    else: return 'DOWN'

SPEED = 0.2 # 每 SPEED 秒前进一步

def RandFruit():
    posList = []
    for i in range(0, HEIGHT):
        for j in range(0, WIDTH): # 枚举坐标系中的每一个位置
            if chessboard[(i, j)] == BOARD_EMPTY:
                posList.append((i, j))
    if len(posList) > 0:
        id = random.randint(0, len(posList) - 1) # 随机选择一个位置
        chessboard[posList[id]] = BOARD_FRUIT

Message = "Paused ..." # 状态信息
state  = text(Window, Message = Message) # 显示状态信息
length = text(Window)

if __name__ == "__main__": # 启动游戏

    running = False # 表示🐍是否在运动 (游戏结束或暂停时🐍不运动)
    BeginTime = time.time() # 游戏开始的时间 (暂停后重新记录)

    ShowChessBoard() # 试图初次绘制棋盘
    RandFruit()

    for i in range(0, HEIGHT):
        for j in range(0, WIDTH):
            if chessboard[(i, j)] == BOARD_EMPTY and (i, j) != NextHead():
                if random.randint(0, 100) < 10:
                    chessboard[(i, j)] = BOARD_WALL

    while True: # 
        for event in pygame.event.get(): # 获取事件序列
            if event.type == pygame.QUIT: # 退出事件
                exit()

            elif event.type == KEYDOWN: # 键盘按键事件
                if event.key == K_ESCAPE: # 按下ESC
                    # Window.ChangeFullScreen() # 翻转全屏状态
                    exit() # 按下 ESC 直接退出

                elif event.key == K_SPACE and Message != "You Dead!": # 按空格键暂停/继续
                    running = not running
                    BeginTime = time.time() # 重新计时
                    if running:
                        Message = "Running ..."
                    else:
                        Message = "Paused ..."

                if running: # 在蛇运行时检测方向键是否按下
                    if event.key == K_LEFT or event.key == K_RIGHT: # 向左右转向
                        if DIRECTION != 'LEFT' and DIRECTION != 'RIGHT':
                            DIRECTION = dir(event.key)

                    elif event.key == K_UP or event.key == K_DOWN: # 向上下转向
                        if DIRECTION != 'UP' and DIRECTION != 'DOWN':
                            DIRECTION = dir(event.key)

        if running:
            if time.time() - BeginTime >= SPEED: # 移动一次
                if Crash():
                    running = False # 停止运行
                    Message = "You Dead!"
                elif Grow():
                    SNAKE_BODY = [NextHead()] + SNAKE_BODY
                    chessboard[SNAKE_BODY[0]] = BOARD_SNAKE # 设置新的头部
                    RandFruit() # 随机生成水果
                else:
                    SNAKE_BODY = [NextHead()] + SNAKE_BODY
                    del SNAKE_BODY[len(SNAKE_BODY) - 1] # 删除尾部
                BeginTime = time.time() # 重新计时

        Window.Fill((0, 0, 0))

        state.ChangeMessage(Message + " ESC to exit, SPACE to pause.") # 显示状态信息
        state.Show((RESOLUTION[1] + 20, 20))

        length.ChangeMessage("Length: " + str(len(SNAKE_BODY))) # 显示长度信息
        length.Show((RESOLUTION[1] + 20, 42))

        ShowChessBoard() # 每次都重新绘制
        pygame.display.flip()

game_method.py

须和 snake.py 放在同一目录下。

# Author: GGN_2015
# Content: 整理了一些使用 pygame 实现游戏界面的方法

# 使用 pygame 游戏库
import pygame
from pygame.locals import *

# 引用 exit 函数
from sys import exit

class screen(object): # 绘图屏幕类

    def __init__(self, Title = "GGN PyGame Template", FullScreen = True, Resolution = (1920,1080)):
        self.Title = Title
        self.FullScreen = FullScreen
        self.Resolution = Resolution # 分辨率

        pygame.display.set_caption(Title) # 设置标题

        if self.FullScreen:
            self.Screen = pygame.display.set_mode(Resolution, FULLSCREEN, 32) # 设置全屏区域
        else:
            self.Screen = pygame.display.set_mode(Resolution, 0, 32) # 设置非全屏区域

    def ChangeFullScreen(self): # 修改全屏状态
        self.FullScreen = not self.FullScreen
        if self.FullScreen:
            self.Screen = pygame.display.set_mode(self.Resolution, FULLSCREEN, 32) # 设置全屏区域
        else:
            self.Screen = pygame.display.set_mode(self.Resolution, 0, 32) # 设置非全屏区域

    def ChangeTitle(self, NewTitle): # 修改标题
        self.Title = NewTitle
        pygame.display.set_caption(Title)

    def Fill(self, Color = (0, 0, 0)): # 纯色填充
        self.Screen.fill(Color)


class text(object): # 在游戏中运行背景透明的文本框

    def __init__(self, Screen, FontName = "consolas", CharSize = 20, Message = "", Color = (34, 252, 43)):
        # 初始化文本框

        self.Visible  = True # 默认显示

        self.Screen   = Screen.Screen # 绘图屏幕

        self.FontName = FontName
        self.CharSize = CharSize
        self.Message  = Message
        self.Color    = Color

        self.Font = pygame.font.SysFont(self.FontName, self.CharSize) # 使用系统字体
        self.Text = self.Font.render(self.Message, True, self.Color) # 文本框

    def ChangeMessage(self, NewMessage): # 更改文字的内容
        self.Message = NewMessage
        self.Text = self.Font.render(NewMessage, True, self.Color) # 文本框

    def SetVisible(self, NewVisible = True): # 设置是否可见
        self.Visible  = NewVisible

    def Show(self, Position = (0, 0)): # 在屏幕上显示内容 Position 是相对于左上角的坐标
        if self.Visible:
            self.Screen.blit(self.Text, Position)

pygame.init() # 游戏初始化
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-07-11 16:36:07  更:2021-07-11 16:36:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 15:08:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码