Python:游戏:贪吃蛇(附源码)

贪吃蛇是个非常简单的游戏,适合练手。

首先分析一下这个游戏

1、蛇怎么画?

蛇是由一个个小方块组成的,那么我们可以用一个 list 记录每一个小方块的坐标,显示的时候将所有小方块画出来即可。

2、蛇怎么移动?

第一反应就是想蚯蚓蠕动一样,每一个方块向前移动一格,但这样做很麻烦,仔细想下,其实除了头尾,蛇的其他部分根本就没有动过,那就简单了,将下一格的坐标添加到 list 开头,并移除 list 的最后一个元素,就相当于蛇向前移动了一格。

3、如何判定游戏结束?

蛇移动超出了游戏区的范围或者碰到了自己就算输了,超出范围很容易判断,碰到自己也容易,只要判断下一格的坐标是否已经包含在蛇的 list 中就可以了。

理清了这些问题,我们就可以开始编码了。

先看一下我的游戏截图

本例中,回车键:开始游戏,空格键:暂停 / 继续,方向键 或 WSAD 键:控制移动方向。

每吃一个食物加10分,每增加100分速度加快一级,没有设置关卡,我玩到1100分,速度太快了,然后就 GAME OVER 了

"""贪吃蛇"""

import random
import sys
import time
import pygame
from pygame.locals import *
from collections import deque

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 480
SIZE = 20

def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText = font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))

def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption(‘贪吃蛇‘)

    light = (100, 100, 100)  # 蛇的颜色
    dark = (200, 200, 200)   # 食物颜色

    font1 = pygame.font.SysFont(‘SimHei‘, 24)  # 得分的字体
    font2 = pygame.font.Font(None, 72)  # GAME OVER 的字体
    red = (200, 30, 30)                 # GAME OVER 的字体颜色
    fwidth, fheight = font2.size(‘GAME OVER‘)
    line_width = 1                      # 网格线宽度
    black = (0, 0, 0)                   # 网格线颜色
    bgcolor = (40, 40, 60)              # 背景色

    # 方向,起始向右
    pos_x = 1
    pos_y = 0
    # 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接GAME OVER
    # b 变量就是用于防止这种情况的发生
    b = True
    # 范围
    scope_x = (0, SCREEN_WIDTH // SIZE - 1)
    scope_y = (2, SCREEN_HEIGHT // SIZE - 1)
    # 蛇
    snake = deque()
    # 食物
    food_x = 0
    food_y = 0

    # 初始化蛇
    def _init_snake():
        nonlocal snake
        snake.clear()
        snake.append((2, scope_y[0]))
        snake.append((1, scope_y[0]))
        snake.append((0, scope_y[0]))

    # 食物
    def _create_food():
        nonlocal food_x, food_y
        food_x = random.randint(scope_x[0], scope_x[1])
        food_y = random.randint(scope_y[0], scope_y[1])
        while (food_x, food_y) in snake:
            # 为了防止食物出到蛇身上
            food_x = random.randint(scope_x[0], scope_x[1])
            food_y = random.randint(scope_y[0], scope_y[1])

    _init_snake()
    _create_food()

    game_over = True
    start = False       # 是否开始,当start = True,game_over = True 时,才显示 GAME OVER
    score = 0           # 得分
    orispeed = 0.5      # 原始速度
    speed = orispeed
    last_move_time = None
    pause = False       # 暂停

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K_RETURN:
                    if game_over:
                        start = True
                        game_over = False
                        b = True
                        _init_snake()
                        _create_food()
                        pos_x = 1
                        pos_y = 0
                        # 得分
                        score = 0
                        last_move_time = time.time()
                elif event.key == K_SPACE:
                    if not game_over:
                        pause = not pause
                elif event.key in (K_w, K_UP):
                    # 这个判断是为了防止蛇向上移时按了向下键,导致直接 GAME OVER
                    if b and not pos_y:
                        pos_x = 0
                        pos_y = -1
                        b = False
                elif event.key in (K_s, K_DOWN):
                    if b and not pos_y:
                        pos_x = 0
                        pos_y = 1
                        b = False
                elif event.key in (K_a, K_LEFT):
                    if b and not pos_x:
                        pos_x = -1
                        pos_y = 0
                        b = False
                elif event.key in (K_d, K_RIGHT):
                    if b and not pos_x:
                        pos_x = 1
                        pos_y = 0
                        b = False

        # 填充背景色
        screen.fill(bgcolor)
        # 画网格线 竖线
        for x in range(SIZE, SCREEN_WIDTH, SIZE):
            pygame.draw.line(screen, black, (x, scope_y[0] * SIZE), (x, SCREEN_HEIGHT), line_width)
        # 画网格线 横线
        for y in range(scope_y[0] * SIZE, SCREEN_HEIGHT, SIZE):
            pygame.draw.line(screen, black, (0, y), (SCREEN_WIDTH, y), line_width)

        if game_over:
            if start:
                print_text(screen, font2, (SCREEN_WIDTH - fwidth)//2, (SCREEN_HEIGHT - fheight)//2, ‘GAME OVER‘, red)
        else:
            curTime = time.time()
            if curTime - last_move_time > speed:
                if not pause:
                    b = True
                    last_move_time = curTime
                    next_s = (snake[0][0] + pos_x, snake[0][1] + pos_y)
                    if next_s[0] == food_x and next_s[1] == food_y:
                        # 吃到了食物
                        _create_food()
                        snake.appendleft(next_s)
                        score += 10
                        speed = orispeed - 0.03 * (score // 100)
                    else:
                        if scope_x[0] <= next_s[0] <= scope_x[1] and scope_y[0] <= next_s[1] <= scope_y[1]                                 and next_s not in snake:
                            snake.appendleft(next_s)
                            snake.pop()
                        else:
                            game_over = True

        # 画食物
        if not game_over:
            # 避免 GAME OVER 的时候把 GAME OVER 的字给遮住了
            pygame.draw.rect(screen, light, (food_x * SIZE, food_y * SIZE, SIZE, SIZE), 0)

        # 画蛇
        for s in snake:
            pygame.draw.rect(screen, dark, (s[0] * SIZE + line_width, s[1] * SIZE + line_width,
                                            SIZE - line_width * 2, SIZE - line_width * 2), 0)

        print_text(screen, font1, 30, 7, f‘速度: {score//100}‘)
        print_text(screen, font1, 450, 7, f‘得分: {score}‘)

        pygame.display.update()

if __name__ == ‘__main__‘:
    main()

原文地址:https://www.cnblogs.com/gl1573/p/9590370.html

时间: 2024-07-30 07:34:09

Python:游戏:贪吃蛇(附源码)的相关文章

Ruby for Sketchup 贪吃蛇演示源码(naive_snake)

sketchup是非常简单易用的三维建模软件,可以利用ruby 做二次开发, api文档 http://www.rbc321.cn/api 今天在su中做了一款小游戏 贪吃蛇,说一下步骤 展示 主要思路: 我制作的的玩法是这样的 关于入口文件 # ----------------------------- # # email:[email protected] # # uri: http://www.rbc321.cn # # ------------------------------# #

python怎么连接redis(附源码)

一.源码如下: import redis # 建立连接 r = redis.Redis(host="192.168.43.110",port=6379,db=0) # 设置键值 r.set("name","belief") r.set("name_ch","信仰") # 获取值,返回的是bytes类型数据 res = r.get("name") # print(type(res)) #

一步一步搭建Svn+Apache环境(附源码包)

一步一步搭建Svn+Apache环境(附源码包) 看了很多网上的搭建方法,但是因为配置的svn和Apache的版本问题和网上写的教程的不完整等原因,阻碍了很多想要学习的朋友!!今天亲手搭建了一下Svn+Apache环境,并且详细记录了每一步搭建的细节,送给需要的朋友们! 软件版本: redhat6.4(64位) apr-1.5.1.tar.gz apr-util-1.5.3.tar.gz httpd-2.2.27.tar.gz sqlite-amalgamation-3.6.17.tar.gz

C#中国象棋+游戏大厅 服务器 + 客户端源码

来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设置 游戏互不干扰 这个象棋大厅程序完全可以当做是C#委托事件的教程,而且游戏大厅功能也很多,服务器还可设置人数和桌数,大厅客户端也实时更新相关数据. 源码下载地址:http://www.ajerp.com/bbs/forum.php?mod=viewthread&tid=29&extra=pa

控制台小游戏-贪吃蛇,c++和c#版

说是c++版,其实只是用到了c++的cout和cin而已.这是我做的第二个控制台游戏,基本上每一行代码都加上了注释. 游戏嘛,我觉得重要的是了解他的思想,所以后期学了面向对象之后这个游戏的代码我也没有重新封装. 下面请看图 代码如下:我是用dev c++写的 1 //注释. ---星辰 2 3 #include <iostream> 4 #include<Windows.h> 5 #include<ctime> 6 #include<cstdlib> 7 #

80个Python经典资料(教程+源码+工具)汇总——下载目录 ...

原文转自:http://bbs.51cto.com/thread-935214-1.html 大家好,51CTO下载中心根据资料的热度和好评度收集了80个Python资料,分享给Python开发的同学.内容包括1个Python专题.66个学习资料.7套Python源码和6个相关软件.附件较多,无法一一分享,在此大家整理一个下载目录了,可以保存以备后用,需要时可选择性下载. 附件下载地址:http://down.51cto.com/data/432858 附件内容部分预览: [专题推荐]Pytho

cocos2d-x 委托模式的巧妙运用——附源码(二)

转载请注明出处:http://blog.csdn.net/hust_superman/article/details/38292265,谢谢. 继上一篇将了委托类的具体实现后,这篇来将一下如何在游戏中使用实现的委托类.也就是如何在游戏中来调用委托类来完成一些功能.具体的应用场景和应用层会在下面介绍. 先来看一看游戏demo实现的具体图片,demo比较简单,但是资源齐全,拿到源码后可以在源码的基础上继续完善demo做出一款真正的游戏.好了,老规矩,先上图再说: 游戏中点击播放按钮后会进入游戏主界面

cocos2d-x 委托模式的巧妙运用——附源码(一)

先来说一下委托模式是什么,下面的内容摘要自维基百科: 委托模式是软件设计模式中的一项基本技巧.在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理.委托模式是一项基本技巧,许多其他的模式,如状态模式.策略模式.访问者模式本质上是在更特殊的场合采用了委托模式.委托模式使得我们可以用聚合来替代继承. 简单的Java例子 在此例中,类模拟打印机Printer拥有针式打印机RealPrinter的实例,Printer拥有的方法print()将处理转交给RealPrint

10分钟教你用python打造贪吃蛇超详细教程

10分钟教你用python打造贪吃蛇超详细教程 在家闲着没妹子约, 刚好最近又学了一下python,听说pygame挺好玩的.今天就在家研究一下, 弄了个贪吃蛇出来.希望大家喜欢. 先看程序效果: 01 整体框架 平台:pycharm 关于pygame的安装这里就不在赘述,大家自行上网找合适自己的版本的安装即可.关于pygame模块知识会穿插在下面代码中介绍,用到什么就介绍什么.这里就不统一介绍了. 整个程序由于是调用了大量的pygame里面的库函数,所以也非常简单(卧槽你这不是调包侠嘛).也就

java小游戏贪吃蛇大作战:来一起回顾童年回忆!

Java小项目之贪吃蛇 跪求关注,祝关注我的人都:身体健康,财源广进,福如东海,寿比南山,早上贵子,从不掉发! 贪吃蛇,绝对是很多朋友的童年记忆.几乎没有人会说没玩过这款小游戏,因为不管在小灵通手机,直板手机,还是半智能手机,甚至是现在的5G手机,都能看见这款游戏的身影.虽然游戏一直在进化,画面,风格,操作方式越来越精细,但是游戏本质的玩法是没变的,例如蛇不断变大,碰到墙壁会死亡等设定.这篇文章来分享java小游戏贪吃蛇:部分代码展示:这个贪吃蛇小游戏,玩法和操控,都是比较完善的,大家感兴趣的可