python实现简单贪吃蛇

news2024/11/28 10:57:01
import math
import pygame
import time
import numpy as np
# 此模块包含游戏所需的常量
from pygame.locals import *

# 设置棋盘的长宽
BOARDWIDTH = 90
BOARDHEIGHT = 50
# 分数
score = 0

# 豆子
class Food(object):

    def __init__(self):
        self.item = (4, 5)
    # 画出食物
    def _draw(self, screen, i, j):
        color = 255, 255, 0
        radius = 10
        width = 0
        position = 10 + 20 * i, 10 + 20 * j
        pygame.draw.circle(screen, color, position, radius, width)
    # 随机产生食物
    def update(self, screen, enlarge, snack):
        if enlarge:
            self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2)
            while self.item in snack.item:
                self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2)
        self._draw(screen, self.item[0], self.item[1])
# 贪吃蛇
class Snack(object):
    def __init__(self):
        # 开始的蛇形
        self.item = [(11, 25), (10, 25), (9, 25), (8, 25), (7, 25), (6, 25), (5, 25), (4, 25), (3, 25), (2, 25), (1, 25)]
        self.x = 0.0001
        self.y = 0

    def move(self, enlarge):
        if not enlarge:
            self.item.pop()
        # 新蛇头的坐标为旧蛇头坐标加上移动方向的位移
        head = (self.item[0][0] + self.x, self.item[0][1] + self.y)
        # 将新的蛇头坐标插入在 list 最前面
        self.item.insert(0, head)

    def eat_food(self, food):
        global score
        # snack_x,snack_y 蛇头坐标
        # food_x, food_y 食物坐标
        snack_x, snack_y = self.item[0]
        food_x, food_y = food.item
        # 比较蛇头坐标与食物坐标
        if (math.fabs(snack_x - food_x) < 1) and (math.fabs(snack_y - food_y) < 1):
            score += 88888
            return 1
        else:
            return 0

    def toward(self, x, y):
        # 改变蛇头朝向
        if self.x * x >= 0 and self.y * y >= 0:
            self.x = x
            self.y = y

    def get_head(self):
        # 获取蛇头坐标
        return self.item[0]

    def draw(self, screen):
        # 贪吃蛇
        radius = 25
        width = 30
        color = 10, 255, 255
        position = 10 + 20 * self.item[0][0], 10 + 20 * self.item[0][1]
        pygame.draw.circle(screen, color, position, radius, width)
        # 蛇身为实心圆
        radius = 15
        width = 30
        color = 255, 255, 0
        for i, j in self.item[1:]:
            position = 10 + 20 * i, 10 + 20 * j
            pygame.draw.circle(screen, color, position, radius, width)

# 初始界面
def init_board(screen):
    board_width = BOARDWIDTH
    board_height = BOARDHEIGHT
    color = 10, 255, 255
    width = 0
    # width:x, height:y
    # 左右边框占用了 X: 0 35*20
    for i in range(board_width):
        pos = i * 20, 0, 20, 20
        pygame.draw.rect(screen, color, pos, width)
        pos = i * 20, (board_height - 1) * 20, 20, 20
        pygame.draw.rect(screen, color, pos, width)
    # 上下边框占用了 Y: 0 *20
    for i in range(board_height - 1):
        pos = 0, 20 + i * 20, 20, 20
        pygame.draw.rect(screen, color, pos, width)
        pos = (board_width - 1) * 20, 20 + i * 20, 20, 20
        pygame.draw.rect(screen, color, pos, width)


# 游戏失败
def game_over(snack):
    broad_x, broad_y = snack.get_head()
    flag = 0
    old = len(snack.item)
    new = len(set(snack.item))
    # 游戏失败
    # 咬到自身
    if new < old:
        flag = 1
    # 撞到边框
    if broad_x >= BOARDWIDTH or broad_x <= 0 or math.fabs(broad_x - BOARDWIDTH) < 5:
        flag = 1
    if broad_y >= BOARDHEIGHT or broad_y <= 0 or math.fabs(broad_y - BOARDHEIGHT) < 5:
        flag = 1
    if flag:
        return True
    else:
        return False


# 打印字符
def print_text(screen, font, x, y, text, color=(155, 0, 0)):
    # 在屏幕上打印字符
    # text是需要打印的文本,color为字体颜色
    # (x,y)是文本在屏幕上的位置
    imgText = font.render(text, True, color)
    screen.blit(imgText, (x, y))


# 按键
def press(keys, snack):
    global score
    # K_w 为 pygame.locals 中的常量
    # keys[K_w] 返回 True or False
    # 上移
    if keys[K_w] or keys[K_UP]:
        snack.toward(0, -0.1)
    # 下移
    elif keys[K_s] or keys[K_DOWN]:
        snack.toward(0, 0.1)
    # 左移
    elif keys[K_a] or keys[K_LEFT]:
        snack.toward(-0.1, 0)
    # 右移
    elif keys[K_d] or keys[K_RIGHT]:
        snack.toward(0.1, 0)
    # 重置游戏
    elif keys[K_SPACE]:
        score = 0
        main()
    # 退出游戏
    elif keys[K_ESCAPE]:
        exit()


# 游戏初始化
def game_init():
    # pygame 初始化
    pygame.init()
    # 设置游戏界面大小
    screen = pygame.display.set_mode((BOARDWIDTH * 20, BOARDHEIGHT * 20))
    return screen


# 开始游戏
def game(screen):
    snack = Snack()
    food = Food()
    font = pygame.font.SysFont('SimHei', 70)
    is_fail = 0
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()

        # 填充屏幕
        screen.fill((0, 0, 200))
        init_board(screen=screen)
        # 获得用户按键命令
        keys = pygame.key.get_pressed()
        press(keys, snack)
        # 游戏失败打印提示
        if is_fail:
            font = pygame.font.Font(None, 50)
            font2 = pygame.font.Font(None, 100)
            font3 = pygame.font.Font(None, 30)
            print_text(screen, font, 700, 570, text)
            print_text(screen, font2, 700, 400, "GAME OVER!")
            print_text(screen, font3, 700, 500, "Press 'SPACE' to play again ")
            print_text(screen, font3, 700, 530, "Press 'ESC' to exit the game")
        # 游戏主进程
        if not is_fail:
            enlarge = snack.eat_food(food)
            text = u"score: {}".format(score)
            print_text(screen, font, 0, 0, text)
            food.update(screen, enlarge, snack)
            snack.move(enlarge)
            is_fail = game_over(snack=snack)
            snack.draw(screen)
        # 游戏刷新
        pygame.display.update()
        time.sleep(0.002)


# 主程序
def main():
    screen = game_init()
    game(screen)


if __name__ == '__main__':
    main()


在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/719836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qtav源码包编译(qt5.15+msvc2019)、使用vlc media player串流生成rtsp的url并且在qml客户端中通过qtav打开

QTAV源码包编译 下载源码 下载依赖库&#xff08;里面有ffmepg等内容&#xff09; https://sourceforge.net/projects/qtav/files/depends/QtAV-depends-windows-x86x64.7z/download下载源码包 https://github.com/wang-bin/QtAV更新子模块 cd QtAV && git submod…

vmware postgresql大杂烩

Vmware 窗口过界&#xff1a; https://blog.csdn.net/u014139753/article/details/111603882 vmware, ubuntu 安装&#xff1a; https://zhuanlan.zhihu.com/p/141033713 https://blog.csdn.net/weixin_41805734/article/details/120698714 centos安装&#xff1a; https://w…

【Go】短信内链接拉起小程序

一、 需求场景 (1) 业务方&#xff0c;要求给用户发送的短信内含有可以拉起我们的小程序指定位置的链接&#xff1b; 【XXX】尊敬的客户&#xff0c;您好&#xff0c;由于您XX&#xff0c;请微信XX小程序-微信授权登录-个人中心去XX&#xff0c;如已操作请忽略&#xff0c;[…

Jenkins2.346新建项目时没有Maven项目选项解决办法

解决办法&#xff1a;需要安装Maven Integration 系统管理-->管理插件-->可选插件-->过滤输入框中输入搜索关键字&#xff1a; Maven Integration&#xff0c;下载好后安装。

Mysql:创建和管理表(全面详解)

创建和管理表 前言一、基础知识1、一条数据存储的过程2、标识符命名规则3、MySQL中的数据类型 二、创建和管理数据库1、创建数据库2、使用数据库3、修改数据库4、删除数据库 三、创建表1、创建方式12、创建方式23、查看数据表结构 四、修改表1、追加一个列2、修改一个列3、重命…

MySQL存储引擎(InnoDB、MyISAM、Memory面试题)

1.1 MySQL体系结构 1). 连接层 最上层是一些客户端和链接服务&#xff0c;包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证安全接入的…

暑期学JavaScript【第六天】

一、正则表达式 边界符 ^&#xff1a;表示以后面字符开头 $&#xff1a;表示以前方字符结尾量词 *:前面的字符至少出现0次 :前面的字符至少出现1次 ?:前面的字符出现0/1次 {n}:重复n次 {n,}:至少重复n次 {n,m}:重复n~m次字符类 [ ]:代表字符集合 /^[a-z]$/[ ^ ] 取反 [^a-…

leetcode 257. 二叉树的所有路径

2023.7.5 这题需要用到递归回溯&#xff0c;也是我第一次接触回溯这个概念。 大致思路是&#xff1a; 在reversal函数中&#xff0c;首先将当前节点的值加入到路径path中。然后判断当前节点是否为叶子节点&#xff0c;即没有左右子节点。如果是叶子节点&#xff0c;将路径转化…

nnUNet保姆级使用教程!从环境配置到训练与推理(新手必看)

文章目录 写在前面nnUNet是什么&#xff1f;一、配置虚拟环境二、安装nnUNet框架1.安装nnUNet这一步我遇到的两个问题&#xff1a; 2.安装隐藏层hiddenlayer&#xff08;可选&#xff09; 三、数据集准备nnUNet对于你要训练的数据是有严格要求的&#xff0c;这第一点就体现在我…

apple pencil值不值得购买?ipad可以用的手写笔推荐

现在市面的电容笔品牌鱼龙混杂&#xff0c;我们很在选购中很容易就踩坑&#xff0c;例如买到一些书写会频繁出现断触的&#xff0c;或者防误触功能会失灵。所以我们在选购中务必要擦亮双眼。而对于一些将ipad作为一种学习工具的人而言&#xff0c;电容笔已经是iPad中不可或缺的…

【C++】vector基本用法介绍

vector简单介绍 前言vector原型vector常用函数接口介绍vector的构造、析构、赋值构造析构 修改类的函数push_backinsertfind 函数 eraseswap 关于容量的函数max_sizesort vector\<char\> 和 string的区别vector\<数据类型\> 结束 前言 首先&#xff0c;vector的用…

vue watch

Vue.js已在全球开发人员中广受欢迎&#xff0c;这归功于其灵活的响应式系统和丰富的开发工具。本文将深入解析Vue中的Watch特性&#xff0c;我们将了解其功能&#xff0c;适用的实际例子&#xff0c;以及可能遇到的常见错误及其解决方案。 第一部分&#xff1a;Vue的Watch特性…

开放式耳机漏音有多大?开放式耳机和封闭式耳机哪个音质好?

什么是开放式耳机 从名字上理解就是开放样式的耳机&#xff0c;其实也确实如此&#xff0c;开放式耳机是不需要封闭耳道来传输声音&#xff0c;主要是通过耳骨振动传递或者声波震动耳膜&#xff0c;两者声音传递的方式都不用完全封闭耳道&#xff0c;可以让耳道对外界放开&…

【软件测试】如何梳理你测试的业务

目录 前言&#xff1a; 一、为什么要梳理业务&#xff1f; 二、梳理框架 1. 测试场景 2. 业务 3. 系统 4. 数据 5. 安全 6. 性能 7. 数据分析 8. 监控报警 9. 应急预案 前言&#xff1a; 在进行软件测试之前&#xff0c;合理和清晰地梳理测试的业务是非常重要的&a…

linux运维常用命令(持续更新)

目录 一&#xff1a; 查看指定端口是否被监听 二&#xff1a;查看某个端口/服务相关进程 三&#xff1a;在B机器查看是否可以访问A机器某个端口,查看端口是否开放 四&#xff1a;查看端口占用列表 五&#xff1a;查看端口占用情况 六&#xff1a;查看哪些进程监听了2181端…

了解PHP-入门-环境搭建-集成环境安装

PHP是一种创建动态交互性站点的强有力的服务器端脚本语言&#xff0c; PHP文件通常包含 HTML标签和一些 PHP脚本代码 Hypertext Preprocessor&#xff0c;超文本预处理器。是一种免费开源服务器端脚本语言&#xff0c;默认文件扩展名是 .php &#xff0c;可以嵌入到网页代码中&…

怎么学习PHP的文件上传和图像处理技术? - 易智编译EaseEditing

学习PHP的文件上传和图像处理技术可以按照以下步骤进行&#xff1a; 掌握基础知识&#xff1a; 了解PHP的基本语法和文件操作函数。熟悉文件上传的相关概念和流程。 学习文件上传&#xff1a; 学习如何在PHP中实现文件上传功能。了解表单的 enctype 属性、文件上传限制、文件…

防爆温湿度传感器:保障工业安全环境的关键设备

在现代工业生产过程中&#xff0c;安全是一项至关重要的考虑因素。特别是在危险和爆炸性环境中&#xff0c;保障人员和设备的安全更是至关重要。为了解决这一问题&#xff0c;防爆温湿度传感器应运而生。本文将详细介绍防爆温湿度传感器的工作原理、应用范围以及其在工业安全环…

伦敦银比起期货交易有哪些优势?

伦敦银交易属于现货交易&#xff0c;因此一般不受带交易时间、地点的限制&#xff0c;交易方式灵活方便&#xff0c;随机性强&#xff0c;投资者可以在任何场所与对手进行交易。相比之下&#xff0c;白银期货必须在交易所内依照法规进行公开、集中交易&#xff0c;不能进行场外…

Huawei Auth-Http Server 1.0 passwd文件泄露漏洞

先用fofa脚本爬取所有碧海威相关资产&#xff08;fofa脚本下载地址&#xff1a;&#xff09; python3 fofa-cwillchris.py -k body"umweb/u20.png" 将上面爬取到的文件&#xff08;一般是final****.txt&#xff09;移动到脚本目录下&#xff0c;保存为1.txt ./Huaw…