精华内容
下载资源
问答
  • Python制作贪吃蛇游戏,致敬童年

    千次阅读 2019-04-06 01:05:10
    Python制作贪吃蛇游戏,致敬童年 小时候,我们沉迷于一款经久不衰的游戏------贪吃蛇。不管是在游戏机上玩,还是老版手机上玩,都使得我们的童年很有趣,很快乐。和小伙伴们一起比赛,看谁玩的分数最高,谁就牛逼...

    用Python制作贪吃蛇游戏,致敬童年

    小时候,我们沉迷于一款经久不衰的游戏------贪吃蛇。不管是在游戏机上玩,还是老版手机上玩,都使得我们的童年很有趣,很快乐。和小伙伴们一起比赛,看谁玩的分数最高,谁就牛逼,就被称为“大哥”。今天就咱们就用 python 来实现简易版的贪吃蛇游戏。
    在这里插入图片描述

    1.游戏简介

    用户通过操控贪吃蛇,使用上下左右键使蛇去吃到尽可能多特定点的食物。其中,在游戏期间,蛇不能碰到墙壁,也不能咬到自身。

    本教程借助 pygame实现游戏界面,安装:

    pip install pygame
    

    贪吃蛇的身体是由list构成的,list中每一个元组代表贪吃蛇在棋盘上的坐标,在游戏中移动这些图案,就制作出一条圆滚滚的贪吃蛇来。

    2.游戏步骤

    导包
    # 设置棋盘的长宽
    BOARDWIDTH = 48
    BOARDHEIGHT = 28
    class Food(object):    # 食物
    class Snack(object):    # 贪吃蛇
    def init_board(screen):   # 初始界面
    def game_over(snack):    # 游戏失败
    def print_text        # 打印字符
    def press(keys, snack):     # 按键
    def game_init():      # 游戏初始化
    def game(screen):       # 开始游戏
    def main()      # 主程序
    

    3.游戏实现

    (1)导包

    import pygame
    import time
    import numpy as np
    # 此模块包含游戏所需的常量
    from pygame.locals import *
    

    (2)设置棋盘的长宽和初始分数
    其中设置棋盘的长为48,宽为28;

    BOARDWIDTH = 48
    BOARDHEIGHT = 28
    # 分数
    score = 0
    

    (3)设置食物

    class Food(object):
        def __init__(self):
            self.item = (4, 5)
    
        # 画出食物
        def _draw(self, screen, i, j):
            color = 255, 0, 255
            radius = 10
            width = 10
            # i:1---34   j:1---25
            position = 10 + 20 * i, 10 + 20 * j
            # 画出半径为 10 的粉色实心圆
            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])
    
    

    (4)设置贪吃蛇
    设置贪吃蛇时需要借助pygame.draw.circle,这个函数的主要参数有screen:就是你要在其中画出贪吃蛇的游戏界面,color:图案的颜色(RGB), position:图案在屏幕上的位置, radius:⚪的半径,width:内部填色的大小,如果为零,图案就是空心圆;如果与半径大小相同,图案就是实心圆。

    class Snack(object):
        def __init__(self):
            # self.item = [(3, 25), (2, 25), (1, 25), (1,24), (1,23),
            # (1,22), (1,21), (1,20), (1,19), (1,18), (1,17), (1,16)]
            # x 水平方向 y 竖直方向
            # 初始方向竖直向上
            self.item = [(3, 25), (2, 25), (1, 25), (1, 24), ]
            self.x = 0
            self.y = -1
    
        def move(self, enlarge):
            # 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 (food_x == snack_x) and (food_y == snack_y):
                score += 100
                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):
            # 画出贪吃蛇
            # 蛇头为半径为 15 的红色实心圆
            radius = 15
            width = 15
            # i:1---34   j:1---25
            color = 255, 0, 0
            # position 为图形的坐标
            position = 10 + 20 * self.item[0][0], 10 + 20 * self.item[0][1]
            pygame.draw.circle(screen, color, position, radius, width)
            # 蛇身为半径为 10 的黄色实心圆
            radius = 10
            width = 10
            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)
    
    

    (5)设置初始界面
    用board_width、board_height分别为游戏界面的宽度和高度,根据计算得出边框占据的位置,然后打印出正方形来。pygame.draw.rect和pygame.draw.circle用法类似,区别就是rect四个参数分别为screen:屏幕,color:颜色,pos:横坐标 x,纵坐标 y,矩形的长,矩形的宽。

    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 26*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)
    
    

    (6)定义游戏失败
    如何定义游戏失败呢 ,就需要蛇是否触碰到边界,或者咬到自身呢,利用python内置数据结构set:set这种数据结构中不能有重复元素。如果将list变成set之后,长度变短了,就说明list中有重复元素,即贪吃蛇咬到自己了。

    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 == 0 or broad_x == BOARDWIDTH - 1:
            flag = 1
        if broad_y == 0 or broad_y == BOARDHEIGHT - 1:
            flag = 1
    
        if flag:
            return True
        else:
            return False
    
    

    (7)打印字符

    def print_text(screen, font, x, y, text, color=(255, 0, 0)):
        # 在屏幕上打印字符
        imgText = font.render(text, True, color)
        screen.blit(imgText, (x, y))
    

    (8)设置按键

    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, -1)
        # 下移
        elif keys[K_s] or keys[K_DOWN]:
            snack.toward(0, 1)
        # 左移
        elif keys[K_a] or keys[K_LEFT]:
            snack.toward(-1, 0)
        # 右移
        elif keys[K_d] or keys[K_RIGHT]:
            snack.toward(1, 0)
        # 重置游戏
        elif keys[K_r]:
            score = 0
            main()
        # 退出游戏
        elif keys[K_ESCAPE]:
            exit()
    

    (9)游戏初始化

    def game_init():
        # pygame 初始化
        pygame.init()
        # 设置游戏界面大小
        screen = pygame.display.set_mode((BOARDWIDTH * 20, BOARDHEIGHT * 20))
        # 设置游戏标题
        pygame.display.set_caption('贪吃蛇游戏')
        # sound = pygame.mixer.Sound(AUDIONAME)
        # channel = pygame.mixer.find_channel(True)
        # channel.play(sound)
        return screen
    

    (10)开始游戏
    ①pygame.event.get从队列中获取事件,也就是说必须先获取事件,才能得到用户的键盘输入和其他操作,
    ②screen.fill用于填充屏幕;
    ③pygame.key.get_pressed用于获取用户的键盘输入;
    ④pygame.display.update用来刷新到之前的图案;
    ⑤time.sleep用于控制刷新的频率。

    def game(screen):
        snack = Snack()
        food = Food()
        # 设置中文字体和大小
        font = pygame.font.SysFont('SimHei', 20)
        is_fail = 0
        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    exit()
            # 填充屏幕
            screen.fill((0, 0, 100))
            init_board(screen=screen)
            # 获得用户按键命令
            keys = pygame.key.get_pressed()
            press(keys, snack)
            # 游戏失败打印提示
            if is_fail:
                font2 = pygame.font.Font(None, 40)
                print_text(screen, font, 0, 0, text)
                print_text(screen, font2, 400, 200, "GAME OVER")
            # 游戏主进程
            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.1)
    

    (11)主程序

    def main():
        screen = game_init()
        game(screen)
    
    
    if __name__ == '__main__':
        main()
    
    展开全文
  • 近几年来 Python 语言得到了快速发展,而 Pygame 作为 Python 开发应用和游戏必备的库更是展现了 Python 的优越性。今天我们就将借助 Pygame 实现贪吃蛇游戏...

    近几年来 Python 语言得到了快速发展,而 Pygame 作为 Python 开发应用和游戏必备的库更是展现了 Python 的优越性。今天我们就将借助 Pygame 实现贪吃蛇游戏。

    Pygame 模块是跨平台 Python 模块,专为电子游戏设计,包含图像、声音。建立在 SDL 基础上,允许实时电子游戏研发而无需被低级语言 (如机器语言和汇编语言) 束缚。

    最终游戏效果如下可见:

     

    1

    实验前的准备

    本次课程主要利用 Pygame 模块来进行开发,首先我们需要打开 Xfce 终端,并使用 pip 命令来安装 Pygame

    $ sudo pip3 install pygame
    

    2

    主要思路

    我们的贪吃蛇游戏将主要包括三个核心模块,分别是游戏开始模块、游戏运行模块、游戏结束模块。这三个模块是这样配合工作的:先是显示游戏开始模块,然后一个循环一直在游戏运行模块和显示游戏结束模块之间运行。 

    游戏主要思路:

    1. 绘制一个 640*480 的窗口

    2. 定义小方格的大小(必须要能被 640 和 480 整除)

    3. 绘制游戏开始的画面,等待按键事件输入

    4. 程序主循环里面包含两个模块,一个是游戏运行模块,另一个是显示游戏结束画面的模块

    5. 游戏运行模块:

    • 随机初始化设置一个点作为贪吃蛇的起点

    • 以这个点为起点,建立一个长度为 3 格的贪吃蛇(列表)

    • 初始化一个运动的方向

    • 随机一个苹果的位置

    • 在游戏循环里处理事件

    • 根据按键改变蛇的运动方向

    • 检查游戏是否结束(撞到边界或者撞到自己)

    • 检查贪吃蛇是否吃到苹果

    • 绘制背景,方格,贪吃蛇,苹果,分数等游戏的元素

  • 显示游戏结束画面的模块

    • 绘制 Game Over

    • 等待用户按键重新开始游戏

    3

    游戏搭建

    我们把蛇身看成是一个个小方格组成的,用常量 CELLSIZE 表示方格的大小,我们把游戏屏幕也看成是由同样的小方格组成的,我们可以通过方格来与屏幕具体像素联系起来,简化编程,所以有了 CELLWIDTH 和 CELLHEIGHT 两个变量。

    在 main () 方法中,我们初始化 pygame,并进行一些基本设置,然后显示游戏开始画面,之后进入游戏主循环。

    核心框架:

    # -*- coding: UTF-8 -*-
    # snake.py
    
    import random, sys, time, pygame
    from pygame.locals import *
    
    # 屏幕刷新率(在这里相当于贪吃蛇的速度)
    FPS = 5
    # 屏幕宽度
    WINDOWWIDTH = 640
    # 屏幕高度
    WINDOWHEIGHT = 480
    # 小方格的大小
    CELLSIZE = 20
    
    # 断言,屏幕的宽和高必须能被方块大小整除
    assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size."
    assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size."
    
    # 横向和纵向的方格数
    CELLWIDTH = int(WINDOWWIDTH / CELLSIZE)
    CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE)
    
    # 定义常用颜色
    WHITE = (255, 255, 255)
    BLACK = ( 0, 0, 0)
    RED = (255, 0, 0)
    GREEN = ( 0, 255, 0)
    DARKGREEN = ( 0, 155, 0)
    DARKGRAY = ( 40, 40, 40)
    BGCOLOR = BLACK
    
    # 定义贪吃蛇的动作
    UP = 'up'
    DOWN = 'down'
    LEFT = 'left'
    RIGHT = 'right'
    
    # 贪吃蛇的头(后面会经常用到)
    HEAD = 0
    
    def main():
    
        # 定义全局变量
        global FPSCLOCK, DISPLAYSURF, BASICFONT
    
        # 初始化pygame
        pygame.init()
        # 获得pygame时钟
        FPSCLOCK = pygame.time.Clock()
        # 设置屏幕宽高
        DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
        # 设置基本字体
        BASICFONT = pygame.font.Font('resources/ARBERKLEY.ttf', 18)
        # 设置窗口的标题
        pygame.display.set_caption('Snake')
    
        # 显示游戏开始画面
        showStartScreen()
    
        while True:
    
            # 这里一直循环于游戏运行时和显示游戏结束画面之间,运行游戏里有一个循环,显示游戏结束画面也有一个循环,两个循环都有相应的return,这样就可以达到切换这两个模块的效果
    
            # 运行游戏
            runGame()
    
            # 显示游戏结束画面
            showGameOverScreen()
    
    # 绘制所有的方格
    def drawGrid():
        for x in range(0, WINDOWWIDTH, CELLSIZE):
            # 绘制垂直线
            pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, WINDOWHEIGHT))
        for y in range(0, WINDOWHEIGHT, CELLSIZE):
            # 绘制水平线
            pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (WINDOWWIDTH, y))
    
    # 随机生成一个苹果的坐标位置
    def getRandomLocation():
        return {'x': random.randint(0, CELLWIDTH - 1), 'y': random.randint(0, CELLHEIGHT - 1)}
    
    # 根据coord绘制苹果
    def drawApple(coord):
        x = coord['x'] * CELLSIZE
        y = coord['y'] * CELLSIZE
        appleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
        pygame.draw.rect(DISPLAYSURF, RED, appleRect)
    
    # 根据wormCoords列表绘制贪吃蛇
    def drawWorm(wormCoords):
        for coord in wormCoords:
            x = coord['x'] * CELLSIZE
            y = coord['y'] * CELLSIZE
            wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
            pygame.draw.rect(DISPLAYSURF, DARKGREEN, wormSegmentRect)
            wormInnerSegmentRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
            pygame.draw.rect(DISPLAYSURF, GREEN, wormInnerSegmentRect)
    
    # 显示分数
    def drawScore(score):
        scoreSurf = BASICFONT.render('Score: %s' % (score), True, WHITE)
        scoreRect = scoreSurf.get_rect()
        scoreRect.topleft = (WINDOWWIDTH - 120, 10)
        DISPLAYSURF.blit(scoreSurf, scoreRect)
    
    # 退出游戏
    def terminate():
        pygame.quit()
        sys.exit()
    
    # 提示按键消息
    def drawPressKeyMsg():
        pressKeySurf = BASICFONT.render('Press a key to play.', True, DARKGRAY)
        pressKeyRect = pressKeySurf.get_rect()
        pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30)
        DISPLAYSURF.blit(pressKeySurf, pressKeyRect)
    
    # 检测按键事件
    def checkForKeyPress():
        if len(pygame.event.get(QUIT)) > 0:
            terminate()
    
        keyUpEvents = pygame.event.get(KEYUP)
        if len(keyUpEvents) == 0:
            return None
        if keyUpEvents[0].key == K_ESCAPE:
            terminate()
        return keyUpEvents[0].key
    
    # 显示游戏开始画面
    def showStartScreen():
        pass
    
    # 游戏运行时
    def runGame():
        pass
    
    # 显示游戏结束画面
    def showGameOverScreen():
        pass
    
    if __name__ == '__main__':
        main()

    开始模块:

    游戏开始画面主要显示游戏名称和提示按键信息,同时调用检测按键事件以确定是否有按键事件产生,若有,则退出开始画面,进入游戏运行画面,或是直接退出游戏。showStartScreen () 的具体实现如下:

    # 显示游戏开始画面
    def showStartScreen():
    
        DISPLAYSURF.fill(BGCOLOR)
        titleFont = pygame.font.Font('resources/ARBERKLEY.ttf', 100)
        titleSurf = titleFont.render('Snake!', True, GREEN)
        titleRect = titleSurf.get_rect()
        titleRect.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
        DISPLAYSURF.blit(titleSurf, titleRect)
    
        drawPressKeyMsg()
    
        pygame.display.update()
    
        while True:
            if checkForKeyPress():
                pygame.event.get()
                return

    运行模块:

    为了防止蛇身一出来就离墙太近,导致游戏失败,所以我们的蛇身会离墙有一段距离。产生的随机数范围为(5,CELLWIDTH-6)。我们用字典这种数据结构将坐标存放起来,用列表把这些字典元素包容在一起。具体实现如下:

    # 游戏运行画面
    def runGame():
        # 随机初始化设置一个点作为贪吃蛇的起点
        startx = random.randint(5, CELLWIDTH - 6)
        starty = random.randint(5, CELLHEIGHT - 6)
    
        # 以这个点为起点,建立一个长度为3格的贪吃蛇(列表)
        wormCoords = [{'x': startx, 'y': starty},
                      {'x': startx - 1, 'y': starty},
                      {'x': startx - 2, 'y': starty}]
    
        direction = RIGHT # 初始化一个运动的方向
    
        # 随机一个苹果的位置
        apple = getRandomLocation()
    
        # 游戏主循环
        while True:
            # 事件处理
            for event in pygame.event.get():
                # 退出事件
                if event.type == QUIT:
                    terminate()
                # 按键事件
                elif event.type == KEYDOWN:
                    #如果按下的是左键或a键,且当前的方向不是向右,就改变方向,以此类推
                    if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
                        direction = LEFT
                    elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
                        direction = RIGHT
                    elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
                        direction = UP
                    elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
                        direction = DOWN
                    elif event.key == K_ESCAPE:
                        terminate()
    
            # 检查贪吃蛇是否撞到撞到边界,即检查蛇头的坐标
            if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == CELLWIDTH or wormCoords[HEAD]['y'] == -1 or wormCoords[HEAD]['y'] == CELLHEIGHT:
                # game over
                return
    
            # 检查贪吃蛇是否撞到自己,即检查蛇头的坐标是否等于蛇身的坐标
            for wormBody in wormCoords[1:]:
                if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
                    # game over
                    return
    
            # 检查贪吃蛇是否吃到苹果,若没吃到,则删除尾端,蛇身前进一格
            if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
                # 不移除蛇的最后一个尾巴格
                # 重新随机生成一个苹果
                apple = getRandomLocation()
            else:
                # 移除蛇的最后一个尾巴格
                del wormCoords[-1]
    
            # 根据方向,添加一个新的蛇头,以这种方式来移动贪吃蛇
            if direction == UP:
                newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1}
            elif direction == DOWN:
                newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1}
            elif direction == LEFT:
                newHead = {'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']}
            elif direction == RIGHT:
                newHead = {'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']}
    
            # 插入新的蛇头在数组的最前面
            wormCoords.insert(0, newHead)
    
            # 绘制背景
            DISPLAYSURF.fill(BGCOLOR)
    
            # 绘制所有的方格
            drawGrid()
    
            # 绘制贪吃蛇
            drawWorm(wormCoords)
    
            # 绘制苹果
            drawApple(apple)
    
            # 绘制分数(分数为贪吃蛇列表当前的长度-3)
            drawScore(len(wormCoords) - 3)
    
            # 更新屏幕
            pygame.display.update()
    
            # 设置帧率
            FPSCLOCK.tick(FPS)

    结束模块:

    游戏结束画面与游戏开始画面类似,showGameOverScreen () 的具体实现如下:

    # 显示游戏结束画面
    def showGameOverScreen():
        gameOverFont = pygame.font.Font('resources/ARBERKLEY.ttf', 50)
        gameSurf = gameOverFont.render('Game', True, WHITE)
        overSurf = gameOverFont.render('Over', True, WHITE)
        gameRect = gameSurf.get_rect()
        overRect = overSurf.get_rect()
        gameRect.midtop = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2-gameRect.height-10)
        overRect.midtop = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
    
        DISPLAYSURF.blit(gameSurf, gameRect)
        DISPLAYSURF.blit(overSurf, overRect)
        drawPressKeyMsg()
        pygame.display.update()
        pygame.time.wait(500)
        checkForKeyPress()
    
        while True:
            if checkForKeyPress():
                pygame.event.get()
                return

    完整代码:

    https://www.shiyanlou.com/courses/940

    实验楼推出「楼 + Python 实战・第 20 期」,实验楼 CTO 指导,通过 40 个编程实验 + 46 个挑战作业 + 186 个教学视频 + 2 次直播,带你 11 周系统掌握 Python 三大领域,成为有真正工作能力的工程师!

    无论你是计算机专业还是非计算机专业,都可以报名,前提只有一样:对 Python 学习感兴趣,并能坚持每周付出 12 小时的时间学习。

    课程评价:52 人,死磕 Python 84 天后,结果感受是这样的  /  往期学员评价

    报名方式:请点击文末阅读原文直接报名,或添加助教小姐姐微信(sylmm003)进行咨询 / 报名。

    福利:现在报名还可领取 100 元优惠券一张~

    ???????????? 点击阅读原文,获取 11 周通关 Python 秘籍~

    展开全文
  • python代码实现贪吃蛇游戏 2. pygame库的安装 1. pygame库的简介 很多人学习python,不知道从何学起。 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。 很多已经做案例的人,却不知道...

    文章目录

     

    1. pygame库的简介

    很多人学习python,不知道从何学起。
    很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
    很多已经做案例的人,却不知道如何去学习更加高深的知识。
    那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤
    QQ群:623406465

    PyPoice是SDL多媒体库的Python包装模块。它包含Python函数和类,这些类和类允许使用SDL对CDROM、音频和视频输出、键盘、鼠标和操纵杆输入进行支持。
    Pygame是一个利用SDL库的写就的游戏库, 是一组用来开发游戏软件的 Python 程序模块。SDL,全名Simple DirectMedia Layer,SDL是用C写的,不过它也可以使用C++进行开发,当然还有很多其它的语言,Pygame就是Python中使用它的一个库。pygame允许你在 Python 程序中创建功能丰富的游戏和多媒体程序,是一个高可移植性的模块可以支持多个操作系统,用它来开发小游戏非常适合。

    2. pygame库的安装

    命令行pip安装,换国内源

    pip install pygame -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
    

    3. python代码实现贪吃蛇小游戏

    利用python的pygame第三方库和面向对象编程的方法,实现简单的贪吃蛇小游戏,还可用pyinstaller打包成exe,方便自己想玩的时候直接点开或者分享给别人。

    # -*- coding: UTF-8 -*-
    """
    @File    :practice_03.py
    @Author  :叶庭云
    @Date    :2020/10/2 21:41
    @CSDN    :https://blog.csdn.net/fyfugoyfa
    """
    import pygame
    import sys
    import random
    from pygame.locals import *
    
    
    class Snake(object):
    
        # 制作背景和蛇、果实的的颜色, 0-255,  0,0,0,是代表黑色,  255,255,255代表白色
        def __init__(self):
            self.black = pygame.Color(0, 0, 0)
            self.red = pygame.Color(255, 0, 0)
            self.white = pygame.Color(255, 255, 255)
    
        # 游戏结束
        def gameover(self):
            pygame.quit()
            sys.exit()
        # 初始化
        def initialize(self):
            pygame.init()
            # 定义蛇运动的速度
            clock = pygame.time.Clock()
            # 定义一个游戏界面
            playSurface = pygame.display.set_mode((800, 600))
            # 设置界面名字
            pygame.display.set_caption('python贪吃蛇小游戏')
            # 初始化变量
            snakePosition = [80, 80]  # 贪吃蛇起始位置,前面的参数数水平方向的距离,后面的参数是垂直方向的距离
            # 贪吃蛇的长度,设定为方块的三百,每个方块的长度为25
            snakebody = [[80, 80], [60, 80], [40, 80]]
            targetPosition = [200, 400]  # 方块的初始位置
            targetflag = 1       # 定义一个标记,目的用来判断果实是否被吃掉
            direction = 'right'  # 初始化运动方向
            changeDirection = direction  # 改变方向变量
            self.main(snakebody, targetPosition, targetflag, direction, changeDirection, snakePosition, playSurface, clock)
    
        # 主函数
        def main(self, snakebody, targetPosition, targetflag, direction, changeDirection, snakePosition, playSurface, clock):
            while True:
                # 用循环来获得pygame中的所有事件
                for event in pygame.event.get():
                    if event.type == QUIT:
                        pygame.quit()
                        sys.exit()
                    # 创建一个键盘的事件
                    elif event.type == KEYDOWN:
                        # 判断键盘的方向
                        if event.key == K_RIGHT:
                            changeDirection = 'right'
                            print('向右')
                        if event.key == K_LEFT:
                            changeDirection = 'left'
                            print("向左")
                        if event.key == K_DOWN:
                            print('向下')
                            changeDirection = 'down'
                        if event.key == K_UP:
                            print('向上')
                            changeDirection = 'up'
                        # 判断是否按下了esc键
                        if event.key == K_ESCAPE:
                            pygame.event.post(pygame.event.Event(QUIT))
    
                # 判断蛇的方向
                if changeDirection == 'left' and not direction == 'right':
                    direction = changeDirection
                if changeDirection == 'right' and not direction == 'left':
                    direction = changeDirection
                if changeDirection == 'down' and not direction == 'up':
                    direction = changeDirection
                if changeDirection == 'up' and not direction == 'down':
                    direction = changeDirection
                # 根据方向移动蛇头位置
                if direction == 'right':
                    snakePosition[0] += 20
                if direction == 'left':
                    snakePosition[0] -= 20
                if direction == 'up':
                    snakePosition[1] -= 20
                if direction == 'down':
                    snakePosition[1] += 20
    
                # 增加蛇的长度
                # 判断蛇是否吃掉了果实
                snakebody.insert(0, list(snakePosition))
                if snakePosition[0] == targetPosition[0] and snakePosition[1] == targetPosition[1]:
                    targetflag = 0
                else:
                    snakebody.pop()
                # 随机再生成一个新的方块
                if targetflag == 0:
                    x = random.randrange(1, 40)  # 水平方向
                    y = random.randrange(1, 30)  # 垂直方向
                    targetPosition = [int(x * 20), int(y * 20)]
                    targetflag = 1
                # 绘制显示图
                playSurface.fill(self.black)  # 背景
                for position in snakebody:
                    pygame.draw.rect(playSurface, self.white, Rect(position[0], position[1], 20, 20))  # 蛇的身体
                    pygame.draw.rect(playSurface, self.red, Rect(targetPosition[0], targetPosition[1], 20, 20))  # 果实
                # 游戏结束
                pygame.display.flip()
                if snakePosition[0] > 900 or snakePosition[0] < 0:
                    snake.gameover()
                elif snakePosition[1] > 800 or snakePosition[1] < 0:
                    snake.gameover()
                for i in snakebody[1:]:
                    if snakePosition[0] == i[0] and snakePosition[1] == i[1]:
                        snake.gameover()
    
                # 控制游戏速度,值越大速度越快
                clock.tick(5)
    
    
    snake = Snake()
    snake.initialize()
    

    运行效果如下:

    4. pyinstaller打包成exe

    PyInstaller是一个跨平台的Python应用打包工具,支持Windows/Linux/MacOS三大主流平台,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,从而允许最终用户在无需安装 Python 的情况下执行应用程序。

    pyinstaller安装

    pip install pyinstaller -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
    
    •  

    pyinstaller打包python程序
    PyInstaller 最简单使用只需要指定作为程序入口的脚本文件。PyInstaller 执行打包程序后会在当前目录下创建下列文件和目录:main.spec 文件,其前缀和脚本名相同,指定了打包时所需的各种参数;build 子目录,其中存放打包过程中生成的临时文件。warnxxxx.txt文件记录了生成过程中的警告/错误信息。如果 PyInstaller 运行有问题,需要检查warnxxxx.txt文件来获取错误的详细内容。xref-xxxx.html文件输出PyInstaller 分析脚本得到的模块依赖关系图。dist子目录,存放生成的最终文件。如果使用单文件模式将只有单个执行文件;如果使用目录模式的话,会有一个和脚本同名的子目录,其内才是真正的可执行文件以及附属文件。

    命令行输入以下代码:

    pyinstaller -F -i 图标文件路径 .py文件路径
    
    •  

    -F | --onefile:生成单一的可执行文件
    -i | --icon:为执行文件指定图标

    找到dist文件夹里的带图标的exe程序,双击运行,正常运行进入游戏可以玩说明打包程序成功。

    展开全文
  • python贪吃蛇游戏

    2020-06-05 23:49:58
    贪吃蛇的身体是由list构成,list中的每一个元组代表着贪吃蛇在棋盘上的坐标位置,我们只需在这些位置上画上图案就能制作出一条贪吃蛇来,让贪吃蛇动起来就要用一个move函数来实现。 贪吃蛇是怎么移动的呢? 如果...

     


    1.游戏规则:

    开局游戏随机生成一个食物和贪吃蛇,每吃到一个食物,贪吃蛇的长度加一;如果贪吃蛇蛇头撞到墙壁或者自己的身子,游戏结束。

     

    2.运行环境及需求分析:

     

    运行环境:Windows系统

     

    需求分析:

    贪吃蛇的身体是由list构成,list中的每一个元组代表着贪吃蛇在棋盘上的坐标位置,我们只需在这些位置上画上图案就能制作出一条贪吃蛇来,让贪吃蛇动起来就要用一个move函数来实现。

    贪吃蛇是怎么移动的呢?

    如果贪吃蛇没吃到食物,那么就删除list中最后一个坐标,再在蛇头部分插入新的坐标位置;如何确定新的位置坐标呢?我们就要确定贪吃蛇的移动方向(x,y),然后在移动方向上增加坐标位置,就实现了贪吃蛇的前进了。如果贪吃蛇吃到了食物,蛇尾的坐标位置不用删除。最重要的是,贪吃蛇不能向当前方向的反方向移动,它的条件是当前方向和移动方向的乘积不能为负值。

    如何确定贪吃蛇获取食物?

    需要能控制贪吃蛇上下移动获取食物;食物随机产生且不能与贪吃蛇的蛇身坐标重合,当贪吃蛇的蛇头的坐标和食物的坐标重合的话,表明贪吃蛇已吃到食物,蛇的长度增加一;如果随机产生的食物的坐标和贪吃蛇的位置重合,就继续随机产生事物的坐标,直至确保食物的坐标与蛇位置坐标不重合为止。

    如何判断游戏是否结束?

    如果贪吃蛇的蛇头坐标与墙壁边框坐标重合,游戏结束;如果贪吃蛇的各个部分有重合,换句话说,蛇头坐标与蛇身每个位置坐标有重合的话,游戏结束。

     

    3.代码实现

    import pygame
    import time
    import numpy as np
    # 此模块包含游戏所需的常量
    from pygame.locals import *
    
    # 设置棋盘的长宽
    BOARDWIDTH = 48
    BOARDHEIGHT = 28
    # 分数
    score = 0
    
    # 食物
    class Food(object):
        def __init__(self):
            self.item = (4, 5)
        # 画出食物
        def _draw(self, screen, i, j):
            color = 255, 0, 255
            radius = 10
            width = 10
            # i:1---34   j:1---25
            position = 10 + 20 * i, 10 + 20 * j
            # 画出半径为 10 的粉色实心圆
            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 = [(3, 25), (2, 25), (1, 25), (1,24), (1,23),
            # (1,22), (1,21), (1,20), (1,19), (1,18), (1,17), (1,16)]
            # x 水平方向 y 竖直方向
            # 初始方向竖直向上
            self.item = [(3, 25), (2, 25), (1, 25), (1, 24), ]
            self.x = 0
            self.y = -1
        def move(self, enlarge):
            # 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 (food_x == snack_x) and (food_y == snack_y):
                score += 10
                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):
            # 画出贪吃蛇
            # 蛇头为半径为 15 的红色实心圆
            radius = 15
            width = 15
            # i:1---34   j:1---25
            color = 255, 0, 0
            # position 为图形的坐标
            position = 10 + 20 * self.item[0][0], 10 + 20 * self.item[0][1]
            pygame.draw.circle(screen, color, position, radius, width)
            # 蛇身为半径为 10 的黄色实心圆
            radius = 10
            width = 10
            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 26*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 == 0 or broad_x == BOARDWIDTH - 1:
            flag = 1
        if broad_y == 0 or broad_y == BOARDHEIGHT - 1:
            flag = 1
        if flag:
            return True
        else:
            return False
    # 打印字符
    def print_text(screen, font, x, y, text, color=(255, 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, -1)
        # 下移
        elif keys[K_s] or keys[K_DOWN]:
            snack.toward(0, 1)
        # 左移
        elif keys[K_a] or keys[K_LEFT]:
            snack.toward(-1, 0)
        # 右移
        elif keys[K_d] or keys[K_RIGHT]:
            snack.toward(1, 0)
        # 重置游戏
        elif keys[K_r]:
            score = 0
            main()
        # 退出游戏
        elif keys[K_ESCAPE]:
            exit()
    # 游戏初始化
    def game_init():
        # pygame 初始化
        pygame.init()
        # 设置游戏界面大小
        screen = pygame.display.set_mode((BOARDWIDTH * 20, BOARDHEIGHT * 20))
        # 设置游戏标题
        pygame.display.set_caption('贪吃蛇游戏')
        # sound = pygame.mixer.Sound(AUDIONAME)
        # channel = pygame.mixer.find_channel(True)
        # channel.play(sound)
        return screen
    # 开始游戏
    def game(screen):
        snack = Snack()
        food = Food()
        # 设置中文字体和大小
        font = pygame.font.SysFont('SimHei', 20)
        is_fail = 0
        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    exit()
            # 填充屏幕
            screen.fill((0, 0, 100))
            init_board(screen=screen)
            # 获得用户按键命令
            keys = pygame.key.get_pressed()
            press(keys, snack)
            # 游戏失败打印提示
            if is_fail:
                font2 = pygame.font.Font(None, 40)
                print_text(screen, font, 0, 0, text)
                print_text(screen, font2, 400, 200, "GAME OVER")
            # 游戏主进程
            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.1)
    # 主程序
    def main():
        screen = game_init()
        game(screen)
    if __name__ == '__main__':
        main()
    运行界面
    运行界面

     

    展开全文
  • 初次学习pygame模块,自己在网上找的学习视频,了解pygame做游戏的一些基础,设计了一个比较简单的贪吃蛇游戏。 文末有完整代码,安装完所需的库就可以运行了,大家可以尝试运行。
  • 使用python简单的制作贪吃蛇游戏

    千次阅读 2020-05-27 15:02:56
    前言 本文的文字及图片来源于网络,仅供学习、...回味童年经典,今天我们来一同学习贪吃蛇游戏制作。 开发工具 python版本:3.6.8 编辑器:pycharm 相关模块 import copy import random import pygame 模块安装 pip
  • python贪吃蛇游戏制作思路详解

    千次阅读 2020-03-03 00:14:58
    让人不得不感叹啊,以前那种玩贪吃蛇,俄罗斯方块,是男人就下一百层这些游戏都能玩好久都不腻的时光一去不复返了。 今天呢,就编写了一个独家的贪吃蛇游戏和大家一起分享曾经的快乐~ 来,咱们先上图为敬,给大家...
  • 游戏界面贪吃蛇游戏是一代人的梦,本期文章我们简单制作一个贪吃蛇游戏import cv2import numpy as npfrom random import randintfrom random import choice代码截图首先导入我们需要的第三方库,然后定义一个...
  • 制作一个Python贪吃蛇游戏 玩家需要吃到绿色的食物,吃到之后右上角会显示当前分数。 撞墙或者往反方向运动,则显示游戏结束,此时可以重来或直接退出游戏Python 代码 __author__ = 'Scar' from tkinter ...
  • Python游戏贪吃蛇

    2021-01-20 03:49:11
    pygame是python的一个制作2D游戏的模块,如果对制作游戏没有兴趣,我不建议深入学习这个模块 。 我说一下这个游戏最核心的代码是如何实现的,贪吃蛇最重要的就是让这条蛇一直沿着你规定的方向走下去,然后吃掉一个...
  • 贪吃蛇是个非常简单的游戏,适合练手。先来看一下我的游戏截图: 玩法介绍: 回车键:开始游戏 空格键:暂停 / 继续 ↑↓←→方向键 或 WSAD 键:控制移动方向。 食物分红、绿、蓝三种,分别对应 10 分、20 ...
  • 前言 本文的文字及图片来源于网络,仅供学习、交流使用,不...回味童年经典,今天我们来一同学习贪吃蛇游戏制作。 开发工具 python版本:3.6.8 编辑器:pycharm 相关模块 import copy import random import py
  • 本文给大家分享的是一个使用cocos2d-python游戏引擎库制作出来的贪吃蛇大作战的游戏代码,基于Python 2.7 和 cocos2d 库,有需要的小伙伴可以参考下
  • python游戏开发:手把手教你制作贪吃蛇工具准备效果展示项目分析逻辑代码处理完整代码 工具准备 开发环境:win10,python3.7 开发工具:pycharm 所需工具库:pygame,sys,random 效果展示 项目分析 1.创建两个类...

空空如也

空空如也

1 2 3 4
收藏数 76
精华内容 30
关键字:

python制作贪吃蛇游戏

python 订阅