精华内容
下载资源
问答
  • python小游戏实例之二(2019-09-19) python小游戏实例之二(2019-09-19)
  • python游戏编程之旅】第五篇---嗷大喵爱吃鱼小游戏开发实例-附件资源
  • python小游戏开发——简单弹球游戏

    万次阅读 多人点赞 2019-04-25 11:09:28
    本案例采用 python 实现了一个简单的弹球游戏。该游戏在一个单独的图形窗口中运行。游戏初始化后,在游戏窗口点击鼠标左键开始游戏。玩家通过控制键盘的左、右方向键来控制弹板的移动,弹球和弹板撞击一次,得一分,...

    一家懂得用细节留住客户的3年潮牌老店我必须支持!➕🛰:luyao1931

    在这里插入图片描述

    案例介绍

    本案例采用 python 实现了一个简单的弹球游戏。该游戏在一个单独的图形窗口中运行。游戏初始化后,在游戏窗口点击鼠标左键开始游戏。玩家通过控制键盘的左、右方向键来控制弹板的移动,弹球和弹板撞击一次,得一分,当弹球触底时,本局游戏结束。玩家一共有四条生命,即可以玩四次游戏,当生命大于等于“ 0 ”时,可以继续游戏,当生命小于“ 0 ”时,游戏结束。

    学习目标

    本案例主要是对 python 和 GUI 编程(本案例为库 tkinter )的基础知识的运用,包括 python 的语法、类、函数、条件判断、引入模块、类的继承等基础知识和 tkinter 的创建图形界面、canvas 组件的创建及其属性、方法、事件等的操作的基础知识。通过本案例的学习,将强化对这些知识的理解和运用,为进一步学习打下良好的基础。

    需要的引入的模块

    本案例以 python3.5.3 版本为基础,需要引入模块 tkinter, 该模块是 Python 的标准 Tk GUI 工具包的接口,是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。

    案例结构和主要算法

    该案例为一个游戏,其运行的主要逻辑为:
    设置游戏:绘制窗口、弹板、初始弹球,设置生命提示文本、得分提示文本、游戏提示文本,将鼠标左键单击事件与开始游戏函数绑定在一起。
    单击鼠标左键开始游戏后,解除鼠标左键单击事件绑定、重设得分、删除游戏提示文本。
    进入游戏循环。判断弹球是否触底?
    弹球触底:弹球速度设为“ 0 ”,生命值减 1,再判断生命值是否小于“ 0 ”。如果小于“ 0 ”,游戏结束,否则重新开始执行第 1 项。
    弹球未触底:首先绘制弹球,然后再重新执行第 3 项。
    弹球偏移量确定的算法为:
    预设弹球速度为 10,预设弹球运动方向为 direction =[1,-1](向右向上运动)。
    当弹球碰到画布上顶边、左边、右边和碰到弹板时,方向取反。
    取横坐标 x = direction[0]、纵坐标 y = direction[1],将方向与速度相乘,得到弹球的偏移量(x,y)。
    判定弹球与弹板相撞的算法为:
    取得弹球和弹板的坐标。
    当弹球的横坐标在弹板之间,且弹球的右下角的纵坐标在弹板的左上角与右下角的纵坐标之间时,判定为弹球与弹板相撞。
    该案例包含的功能模块
    该案例只有一个程序文件:pinball_game.py,其包含的功能模块为:

    类 GameObject 定义了游戏的对象的一些通用方法,各方法如下:
    delete( ) 函数:该函数功能为删除指定对象。
    get_coords( ) 函数:该函数功能为获得指定对象的坐标。
    move( ) 函数:该函数功能为对指定对象进行移动。
    类 Racket(GameObject) 继承类 GameObject,定义了游戏中弹板的一些参数和方法,具体内容如下:
    init( ) 函数:该函数功能为定义变量和调用父类的实例的init方法。
    draw( ) 函数:该函数功能为定义了如何绘制弹板。
    类 Ball(GameObject) 继承类 GameObject,定义了游戏中弹球的一些参数和方法,具体内容如下:
    init( ) 函数:该函数功能为定义变量和调用父类的实例的init方法。
    draw( ) 函数:该函数功能为定义了如何绘制弹球。
    类 Game(tk.Frame) 继承类 tk.Frame, 定义了游戏中的变量和游戏的完整流程,具体内容如下:
    init( ) 函数:该函数定义了游戏参数的初始值,包括生命、得分、画布大小、画布的创建和放置、初始化弹板位置并绘制,设置游戏,并将键盘焦点转移到画布组件上,同时将键盘左、右键按键事件与弹板左、右移动函数绑定在一起。
    setup_game( ) 函数:该函数功能为加载或设置游戏,设置内容依次为
    重设弹球;
    设置生命提示文本;
    设置得分提示文本;
    设置游戏提示文本;
    将鼠标左键单击事件与开始游戏函数绑定在一起。
    reset_ball( ) 函数:该函数功能为重设弹球,将弹球设置在弹板中间位置的上方。
    update_lives_text( ) 函数:该函数功能为设置或更新生命提示文本。
    update_scores_text( ) 函数:该函数功能为设置或更新得分提示文本。
    start_game( ) 函数:该函数功能为定义了开始游戏后的程序运行流程或逻辑,依次为解除绑定、重设得分、删除提示文本、开始游戏循环。
    reset_score( ) 函数:该函数功能为重置得分为“ 0 ”。
    game_loop( ) 函数:该函数功能为定义了游戏循环的内容。如果弹球触底,就将弹球的速度变为“ 0 ”,生命减 1,否则绘制弹球,再次进行游戏循环。如果生命小于 0,游戏结束,否则调整得分,重新设置游戏,再开始一局。
    hit_racket( ) 函数:该函数功能为定义了弹球与弹板的碰撞条件,每碰撞一次就更新一次得分。

    # -*- coding: utf-8 -*-
    
    import tkinter as tk
    
    # 游戏对象的一些通用方法
    class GameObject(object):
        def __init__(self, canvas, item):
            self.canvas = canvas
            self.item = item
    
        # 删除对象
        def delete(self):
            self.canvas.delete(self.item)
    
        # 得到对象的坐标
        def get_coords(self):
            return self.canvas.coords(self.item)
    
        # 对象移动
        def move(self, x, y):
            self.canvas.move(self.item, x, y)
    
    class Racket(GameObject):
        def __init__(self, canvas, x, y):
            item = canvas.create_rectangle(x, y, x + 90, y + 10, fill='green')
            super().__init__(canvas, item)
    
        # 绘制弹板
        def draw(self, offset):
            pos = self.get_coords()
            width = self.canvas.winfo_width()
            # 当弹板在画布内时,按给定偏移量移动
            if pos[0] + offset >= 0 and pos[2] + offset <= width:
                super().move(offset, 0)
    
    class Ball(GameObject):
        def __init__(self, canvas, x, y):
            self.direction = [1, -1]
            self.speed = 10
            item = canvas.create_oval(x, y, x + 20, y + 20, fill='blue')
            super().__init__(canvas, item)
    
        # 绘制弹球
        def draw(self):
            pos = self.get_coords()
            self.canvas_width = self.canvas.winfo_width()
            # 方向判断
            if pos[1] <= 0:
                self.direction[1] *= -1
            if game.hit_racket():
                self.direction[1] *= -1
            if pos[0] <= 0 or pos[2] >= self.canvas_width:
                self.direction[0] *= -1
            # 偏移量
            x = self.direction[0] * self.speed
            y = self.direction[1] * self.speed
            self.move(x, y)
    
    # 游戏类,定义了游戏的完整流程
    class Game(tk.Frame):
        def __init__(self, master):
            #调用父类 ( tk.Frame ) 并返回该类实例的__init__方法。
            super().__init__(master)
    
            self.lives = 3
            self.scores = 0
            self.width = 800
            self.height = 600
    
            # 设置画板并放置
            self.canvas = tk.Canvas(self, bg='#f8c26c', width=self.width, height=self.height)
            self.canvas.pack()
            self.pack()
    
            self.ball = None
            self.lives_text = None
            self.scores_text = None
    
            # 初始化弹板
            self.racket = Racket(self.canvas, self.width/2-45, 480)
    
            self.setup_game()
            # 将键盘焦点转移到画布组件上
            self.canvas.focus_set()
    
            # 将键盘左右键与弹板左右移动绑定在一起
            self.canvas.bind('<KeyPress-Left>', lambda turn_left: self.racket.draw(-20))
            self.canvas.bind('<KeyPress-Right>', lambda turn_right: self.racket.draw(20))
    
        # 加载游戏,或预置游戏
        def setup_game(self):
            # 将球设置在弹板中间位置的上方
            self.reset_ball()
            # 预置生命、得分和游戏提示的文本
            self.update_lives_text()
            self.update_scores_text()
            self.text = self.canvas.create_text(400, 200, text='单击鼠标左键开始游戏', font=('Helvetica', 36))
            # 将鼠标左键单击与开始游戏绑定在一起
            self.canvas.bind('<Button-1>', lambda start_game: self.start_game())
    
        # 在游戏预置时添加弹球,弹球在弹板中间位置的上方
        def reset_ball(self):
            if self.ball != None:
                self.ball.delete()
            racket_pos = self.racket.get_coords()
            x = (racket_pos[0] + racket_pos[2]) * 0.5-10
            self.ball = Ball(self.canvas, x, 350)
    
        # 更新生命的数字
        def update_lives_text(self):
            text = '生命: %s' % self.lives
            if self.lives_text is None:
                self.lives_text = self.canvas.create_text(60, 30, text=text, font=('Helvetica', 16), fill='green')
            else:
                self.canvas.itemconfig(self.lives_text, text=text)
    
        # 更新得分的数字
        def update_scores_text(self):
            text = '得分: %s' % self.scores
            if self.scores_text is None:
                self.scores_text = self.canvas.create_text(60, 60, text=text, font=('Helvetica', 16), fill='green')
            else:
                self.scores = self.scores + 1
                text = '得分: %s' % self.scores
                self.canvas.itemconfig(self.scores_text, text=text)
    
        # 开始游戏
        def start_game(self):
            # 依次解除绑定、重设得分、删除提示文本、开始游戏循环
            self.canvas.unbind('<Button-1>')
            self.reset_score()
            self.canvas.delete(self.text)
            self.game_loop()
    
        # 重置得分的数字为“ 0 ”
        def reset_score(self):
            self.scores = 0
            text = '得分: %s' % self.scores
            self.canvas.itemconfig(self.scores_text, text=text)
    
        # 游戏循环
        def game_loop(self):
            # 如果弹球超过底部,则将弹球的速度变为 0,lives 减 1,否则绘制弹球,再次进行游戏循环
            if self.ball.get_coords()[3] >= self.height:
                self.ball.speed = 0
                self.lives -= 1
                # 如果 lives 小于 0,游戏结束,否则调整 scores,重新预置游戏
                if self.lives < 0:
                    self.canvas.create_text(400, 200, text='游戏结束', font=('Helvetica', 36), fill='red')
                else:
                    self.scores = self.scores - 1
                    self.after(1000, self.setup_game)
            else:
                self.ball.draw()
                self.after(50, self.game_loop)
    
        # 弹球与弹板的碰撞条件,当碰撞一次就更新一次得分
        def hit_racket(self):
            ball_pos = self.ball.get_coords()
            racket_pos = self.racket.get_coords()
            if ball_pos[2] >= racket_pos[0] and ball_pos[0] <= racket_pos[2]:
                if ball_pos[3] >= racket_pos[1] and ball_pos[3] <= racket_pos[3]:
                    self.update_scores_text()
                    return True
            return False
    
    if __name__ == '__main__':
        root = tk.Tk()
        root.title('弹球游戏')
        # 设定窗口大小不可改变
        root.resizable(0, 0)
        # 设定窗口总是显示在最前面
        root.wm_attributes("-topmost", 1)
        game = Game(root)
        game.mainloop()
    
    

    感谢阅读,记得上面扫码关注哦,给生活填趣!

    展开全文
  • 【Python】 Python小游戏-贪吃蛇大冒险

    万次阅读 多人点赞 2021-04-17 17:26:59
    一、前言 距上次更新博客,又过去很长时间了,感觉再不更新一下,自己写博客的习惯...二、贪吃蛇大冒险小游戏 一、游戏简介 1.1游戏操作及游戏规则 (1)游戏开始后,通过键盘上下左右键控制贪吃蛇移动寻找食物; (2

    一、前言

    距上次更新博客,又过去很长时间了,感觉再不更新一下,自己写博客的习惯就要废了,哈哈。从去年九月份开学之后,疫情学期期末考试开学考、实验室项目软著申请和新项目设计、课程集训等事情较多,没有很多时间;然后这个学期我到大三下学期,实验室工作交接完就准备考研,之后也没有很多时间来写博客,所以赶紧来更新一下,和大家分享一些知识和心得,希望喜欢的小伙伴可以点赞、收藏和关注,哈哈。

    二、贪吃蛇大冒险小游戏

    一、游戏简介

    1.1游戏操作及游戏规则
    (1)游戏开始后,通过键盘上下左右键控制贪吃蛇移动寻找食物;
    (2)贪吃蛇每吃一个食物,身长会增加一个单位;
    (3)在正常模式中,贪吃蛇如果碰到墙面或咬到自身,则游戏失败;
    (4)在可穿墙模式中,贪吃蛇可以穿过墙面,但咬到自身后,游戏失败。

    二、游戏总体设计

    2.1 游戏总体设计框架图
    在这里插入图片描述

    三、编译语言以及用到的库文件描述

    3.1 Python语言
    Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),Python语言具有非常简洁且清晰的语法特点,随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。目前,基于Python语言的相关技术正在飞速发展,用户数量急剧增大,相关的资源越来越多。
    3.2 pygame库
    Pygame是跨平台Pyth,Pygame 作者是 Pete Shinners, 协议为 GNU Lesser General Public License。Pygame包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚。基于这样一个设想,所有需要的游戏功能和理念(主要是图像方面)都完全简化为游戏逻辑本身,所有的资源结构都可以由高级语言提供,如Python。
    3.3 random库
    Random是产生随机数的库,即随机数发生器,random产生的是伪随机数或者说是用一种复杂的方法计算得到的序列值,因此每次运算时需要一个不同的种子值。种子值不同,得到的序列值也不同。
    3.4 time库
    time库是Python中处理时间的标准库,用于计算机时间的表达,提供获取系统时间并格式化输出功能,提供系统级精确计时功能,也可用于程序性能分析。
    3.5 sys库
    sys.exit([ arg ])用于程序的退出,sys.exit(n) 退出程序,正常退出时exit(0)。这是通过引发SystemExit 异常来实现的,因此遵循finally语句的子句所指定的清理操作try ,并且可以拦截外层的退出尝试。可选参数arg可以是一个整数,给出退出状态(默认为零)或其他类型的对象。如果它是整数,则零被认为是“成功终止”,并且任何非零值等视为“异常终止”。

    四、游戏设计与实现

    4.1游戏整体设计

    • 1.定义贪吃蛇对象,包括蛇头和蛇身两个部分,蛇头单独设置,蛇身使用列表来存储;
      2.定义食物对象,包括食物对象的初始化、随机颜色和随机位置的设置;
      3.定义初始化界面,在该界面中设置文本为“正常模式”、“可穿墙模式”和“退出”的三个按钮供玩家选择;
      4.定义正常模式,包括游戏窗口显示、主循环和判断贪吃蛇死亡的设置;
      5.定义可穿墙模式,包括游戏窗口显示、主循环和判断贪吃蛇死亡的设置;
      6.定义游戏结束窗口,包括窗口显示和最后得分显示的设置。

    4.2主要函数解析

    • 4.2.1 new_food()函数
      食物对象初始化函数,传入形参为贪吃蛇蛇头坐标。当贪吃蛇吃掉食物后,通过该函数生成新的食物。通过传入形参判断新生成的食物坐标是否与蛇头坐标相同,若相同则重新生成新的坐标。
    • 4.2.2 start_game()函数
      正常模式的主循环函数,通过该函数进行正常模式下贪吃蛇和食物的初始化、玩家控制贪吃蛇运动、蛇头和蛇身的判断更新和得分统计实现。
    • 4.2.3 die_snake()函数
      正常模式下贪吃蛇死亡判断函数,传入形参为贪吃蛇蛇头和蛇身坐标数据。在该函数中设置布尔型变量die_flag,若死亡设置为Ture并返回,没有死亡为False。通过遍历蛇身存储列表,判断蛇身坐标是否与蛇头坐标相同,若相同则判定贪吃蛇咬到自身,死亡。同时,判断贪吃蛇是否撞墙,及判断蛇头的x和y坐标是否窗体的宽高,若超过则死亡。
    • 4.2.4 start_kgame()函数
      可穿墙模式的主循环函数,通过该函数进行可穿墙模式下贪吃蛇和食物的初始化、玩家控制贪吃蛇运动、蛇头和蛇身的判断更新和得分统计实现。
    • 4.2.5 through_snake()函数
      可穿墙模式下贪吃蛇死亡判断函数,传入形参为贪吃蛇蛇头和蛇身坐标数据。在该函数中设置布尔型变量die_flag,若死亡设置为Ture并返回,没有死亡为False。通过遍历蛇身存储列表,判断蛇身坐标是否与蛇头坐标相同,若相同则判定贪吃蛇咬到自身,死亡。
    • 4.2.6 show_end()函数
      游戏结束时,结束界面设置函数。在该函数中进行结束界面窗体的初始化,在窗体中显示玩家的最终得分,并在改函数中调用pygame库quit方法,使该库停止工作。
    • 4.2.7 into_game()函数
      游戏初始界面实现函数,在该函数中进行游戏初始界面窗体的初始化。在该界面窗体中设置文本为“正常模式”、“可穿墙模式”和“退出”的三个点击按钮,通过设置循环,调用button函数(详细见6.2.8)监听玩家的点击。
    • 4.2.8 button()函数
      游戏初始界面按钮监听函数,在该函数中实现对玩家鼠标点击事件和键盘输入事件的监听。并根据玩家选择,运行按钮对应的触发函数。即点击“正常模式”按钮,运行正常模式的主循环函数,以此类推。

    五、运行模块代码结构

    在运行模块,进行pygame库的初始化、设置游戏背景音乐、显示窗口各个参数的设置以及游戏初始界面的显示设置,具体结果代码如下图:
    在这里插入图片描述在这里插入图片描述
    六、游戏运行测试(截图)

    1. 游戏初始选择界面
      在这里插入图片描述

    2. 正常模式运行界面
      在这里插入图片描述

    3. 可穿墙模式运行界面在这里插入图片描述

    4. 游戏结束界面
      在这里插入图片描述
      七、游戏完整代码

    import sys
    import time
    import pygame
    from random import *
    # Position类,通过其构造函数,设置x和y
    class Position(object):
        def __init__(self, x, y):
            self.x = x
            self.y = y
    # 生成随机的食物
    def new_food(head):
        while True:
            new_food = Position(randint(0, 48) * 20, randint(0, 29) * 20)
            # 判断新生成的事物是否和贪吃蛇蛇头重合,重合则不创键
            if new_food.x != head.x and new_food.y != head.y:
                break
            else:
                continue
        return new_food
    # 绘制,在窗体中绘制贪吃蛇、食物
    # color:颜色,position: 坐标
    def rect(color, position):
        pygame.draw.circle(window, color, (position.x, position.y), 10)
    # 初始界面和游戏中点差退出游戏时
    def exit_end():
        pygame.quit()
        quit()
    # 游戏结束时,显示得分的窗体的设置
    def show_end():
        # 设计窗口
        # 定义窗口大小
        small_window = pygame.display.set_mode((960, 600))
        init_background = pygame.image.load("image/init_bgimg.jpg")
        small_window.blit(init_background, (0, 0))
        # 定义标题
        pygame.display.set_caption("贪吃蛇大冒险")
        # 定义背景图片
        font = pygame.font.SysFont("simHei", 40)
        fontsurf = font.render('游戏结束! 你的得分为: %s' % score, False, black)
        small_window.blit(fontsurf, (250, 200))
        pygame.display.update()
        time.sleep(2)
        pygame.quit()
        sys.exit()
    # 正常模式死亡设置
    # head: 蛇头, snake_body:蛇身
    def die_snake(head, snake_body):
        # 定义标志物,默认为false,true时判定贪吃蛇碰到自己,死亡
        die_flag = False
        # 遍历存放贪吃蛇位姿的列表,从第1个开始,(第0个位蛇头)
        for body in snake_body[1:]:
            # 如果蛇头的xy和蛇身xy相等,则判定相撞,设置flag为ture
            if head.x == body.x and head.y == body.y:
                die_flag = True
        # 若蛇头的xy在显示窗体外,或flag为true,则显示结束界面,并退出游戏
        if head.x < 0 or head.x > 960 or head.y < 0 or head.y > 600 or die_flag:
            pygame.mixer.music.stop()
            show_end()
    # 正常模式主体设置
    def start_game():
        # 定义存分数的全局变量
        global score
        global color
        color = (randint(10, 255), randint(10, 255), randint(10, 255))
        # 定义存放玩家键盘输入运动方向的变量,初始为向右
        run_direction = "right"
        # 定义贪吃蛇运动方向的变量,初始为玩家键入方向
        run = run_direction
        # 实例化蛇头、蛇身、食物对象
        head = Position(160, 160)
        # 初始化蛇身长度为3个单位
        snake_body = [Position(head.x, head.y + 20), Position(head.x, head.y + 40), Position(head.x, head.y + 60)]
        # 初始化食物位置
        food = Position(300, 300)
        # 死循环
        while True:
            window.blit(background, (0,0))
            # 监听玩家键盘输入的运动方向值,并根据输入转为up、down、right或left,方便程序中调用
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    show_end()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        run_direction = "up"
                    elif event.key == pygame.K_RIGHT:
                        run_direction = "right"
                    elif event.key == pygame.K_LEFT:
                        run_direction = "left"
                    elif event.key == pygame.K_DOWN:
                        run_direction = "down"
            # 食物
            rect(color, food)
            # 蛇头
            rect(black, head)
            # 蛇身
            for pos in snake_body:
                rect(white, pos)
            # 判断贪吃蛇原运动方向与玩家键盘输入的运动方向是否违反正常运动情况
            if run == "up" and not run_direction == "down":
                run = run_direction
            elif run == "down" and not run_direction == "up":
                run = run_direction
            elif run == "left" and not run_direction == "right":
                run = run_direction
            elif run == "right" and not run_direction == "left":
                run = run_direction
            # 插入蛇头位置到蛇身列表中
            snake_body.insert(0, Position(head.x, head.y))
            # 根据玩家键入方向进行蛇头xy的更新
            if run == "up":
                head.y -= 20
            elif run == "down":
                head.y += 20
            elif run == "left":
                head.x -= 20
            elif run == "right":
                head.x += 20
            # 判断是否死亡
            die_snake(head, snake_body)
            # 判断蛇头和食物坐标,若相等,则加分,并生成新的食物
            if head.x == food.x and head.y == food.y:
                score += 1
                food = new_food(head)
                color = (randint(10, 255), randint(10, 255), randint(10, 255))
            else:
                snake_body.pop()
            font = pygame.font.SysFont("simHei", 25)
            mode_title = font.render('正常模式', False, grey)
            socre_title = font.render('得分: %s' % score, False, grey)
            window.blit(mode_title, (50, 30))
            window.blit(socre_title, (50, 65))
            # 绘制更新
            pygame.display.update()
            # 通过帧率设置贪吃蛇速度
            clock.tick(8)
    # 可穿墙模式死亡设置
    # head:蛇头,snake_body:蛇身
    def through_snake(head, snake_body):
        # 定义标志位
        die_flag = False
        # 遍历,蛇头碰到蛇身时,flag为true退出游戏
        for body in snake_body[1:]:
            if head.x == body.x and head.y == body.y:
                die_flag = True
        if die_flag:
            pygame.mixer.music.stop()
            show_end()
        else:  # 当蛇头的xy出窗体时
            # 四种穿墙情况,分别设置
            if head.x < 0:
                head.x = 960
            if head.x > 960:
                head.x = 0
            if head.y < 0:
                head.y = 600
            if head.y > 600:
                head.y = 0
    # 穿墙模式主体设置
    def start_kgame():
        global score
        global color
        color = (randint(10, 255), randint(10, 255), randint(10, 255))
        # 定义蛇初始方向
        run_direction = "up"
        run = run_direction
        # 实例化蛇头、蛇身、食物对象
        head = Position(160, 160)
        # 三格
        snake_body = [Position(head.x, head.y + 20), Position(head.x, head.y + 40), Position(head.x, head.y + 60)]
        # 初始化事物位置
        food = Position(300, 300)
        # 死循环,监听键盘键值
        while True:
            window.blit(background, (0, 0))
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    show_end()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        run_direction = "up"
                    elif event.key == pygame.K_RIGHT:
                        run_direction = "right"
                    elif event.key == pygame.K_LEFT:
                        run_direction = "left"
                    elif event.key == pygame.K_DOWN:
                        run_direction = "down"
            # 食物
            rect(color, food)
            # 蛇头
            rect(black, head)
            # 蛇身
            for pos in snake_body:
                rect(white, pos)
            # 判断贪吃蛇原运动方向与玩家键盘输入的运动方向是否违反正常运动情况
            if run == "up" and not run_direction == "down":  # 若运动方向为向上,玩家输入运动方向向下,则违背贪吃蛇正常运动情况
                run = run_direction
            elif run == "down" and not run_direction == "up":
                run = run_direction
            elif run == "left" and not run_direction == "right":
                run = run_direction
            elif run == "right" and not run_direction == "left":
                run = run_direction
            # 插入蛇头位置到蛇身列表中
            snake_body.insert(0, Position(head.x, head.y))
            # 根据玩家键入方向进行蛇头xy的更新
            if run == "up":
                head.y -= 20
            elif run == "down":
                head.y += 20
            elif run == "left":
                head.x -= 20
            elif run == "right":
                head.x += 20
            # 穿墙实现
            through_snake(head, snake_body)
            # 判断是否加分和随机生成新的食物
            if head.x == food.x and head.y == food.y:
                score += 1
                food = new_food(head)
                color = (randint(10, 255), randint(10, 255), randint(10, 255))
            else:
                snake_body.pop()
            font = pygame.font.SysFont("simHei", 25)
            mode_title = font.render('穿墙模式', False, grey)
            socre_title = font.render('得分: %s' % score, False, grey)
            window.blit(mode_title, (50, 30))
            window.blit(socre_title, (50, 65))
            # 绘制更新
            pygame.display.update()
            # 通过帧率设置贪吃蛇速度
            clock.tick(8)
    # 监听函数,监听键盘输入
    # msg: 按钮信息,x: 按钮的x轴,y: 按钮的y轴,w: 按钮的宽,h: 按钮的高,ic: 按钮初始颜色,ac: 按钮按下颜色,action: 按钮按下的动作
    def button(msg, x, y, w, h, ic, ac, action=None):
        # 获取鼠标位置
        mouse = pygame.mouse.get_pos()
        # 获取键盘输入
        click = pygame.mouse.get_pressed()
        if x + w > mouse[0] > x and y + h > mouse[1] > y:
            pygame.draw.rect(window, ac, (x, y, w, h))
            if click[0] == 1 and action != None:
                action()
        else:
            pygame.draw.rect(window, ic, (x, y, w, h))
        # 设置按钮中的文字样式和居中对齐
        font = pygame.font.SysFont('simHei', 20)
        smallfont = font.render(msg, True, white)
        smallrect = smallfont.get_rect()
        smallrect.center = ((x + (w / 2)), (y + (h / 2)))
        window.blit(smallfont, smallrect)
    # 游戏初始界面,选择模式
    def into_game():
        into = True
        while into:
            window.blit(init_background, (0, 0))
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    exit_end()
            # 设置字体
            font = pygame.font.SysFont("simHei", 50)
            # 初始界面显示文字
            fontsurf = font.render('欢迎来到贪吃蛇大冒险!', True, black)  # 文字
            fontrect = fontsurf.get_rect()
            fontrect.center = ((width / 2), 200)
            window.blit(fontsurf, fontrect)
            button("正常模式", 370, 370, 200, 40, blue, brightred, start_game)
            button("可穿墙模式", 370, 420, 200, 40, violte, brightred, start_kgame)
            button("退出", 370, 470, 200, 40, red,brightred, exit_end)
            pygame.display.update()
            clock.tick(15)
    

    三、总结

    这是一个简单的Python小游戏,具体代码已贴在博客上。然后相关的技术文档、背景音乐、字体、代码等我也压缩上传到了csdn下载区中。
    https://download.csdn.net/download/weixin_45087775/16809231?spm=1001.2014.3001.5503

    展开全文
  • 实例python 用 tkinter 开发简单扫雷小游戏.pdf
  • 实例python 用 tkinter 开发简单扫雷小游戏

    千次阅读 热门讨论 2021-05-30 17:36:46
    Python tkinter 开发扫雷小游戏 支持标记、展开,适合新手小白练习。 对象、函数、递归

    1. 扫雷游戏

    效果

    在这里插入图片描述

    2. 代码

    # 导入所需库
    from tkinter import *
    import random
    
    class main:
        # 定义一个类,继承 tkinter 的 Button
        # 用来保存按钮的状态和在网格布局中的位置
        class minebtn(Button):
            def __init__(self,master,xy,**kw):
                Button.__init__(self,master,**kw)
                self.xy = xy
                self._state = 0
                # 状态
                # 0: 未点开
                # 1: 已点开
                # 2: 标记
                # 3: 问号
                
        def __init__(self):
            # 定义规格及雷数
            self.width = 9
            self.height = 9
            self.minenum = 10
            # Windows 7 默认的三种规格和雷数
            # 9*9,10
            # 16*16,40
            # 16*32,99
            
            self.rest = self.minenum    # 剩余未标记的雷
    		
    		# 雷数的颜色
            self.colorlist = ['green',	# 绿色
                              'DodgerBlue',	# 浅蓝色
                              'DarkOrange1',# 橙色
                              'blue',	# 蓝色
                              'red',	# 红色
                              'Chocolate4',	# 棕色
                              'grey',	# 灰色
                              'black']	# 黑色
            
            self.setgui()
    
        def setgui(self):
    
            # GUI界面
    
            self.root = Tk()
            self.root.title('扫雷')
    
            self.restlabel = Label(self.root,text=f'剩余:{self.minenum}')
            self.restlabel.grid(row=0,column=0,columnspan=3)
    
            self.mineplace = random.sample(range(self.width*self.height),self.minenum)  # 随机抽取雷
            self.mineplace = [(x%self.width,x//self.height) for x in self.mineplace]    # 将雷的序号转变为坐标
    
            self.mines = {}
    
            for y in range(self.height):
                for x in range(self.width):
                    self.mines[(x,y)] = self.minebtn(self.root,xy=(x,y),font=('黑体',8,'bold'),width=2,bd=1,relief='ridge')
                    self.mines[(x,y)].bind('<ButtonRelease-1>',lambda event:self._open(event.widget))   # 左键单击点开
                    self.mines[(x,y)].bind('<ButtonRelease-3>',lambda event:self.make(event.widget))    # 右键单击事件
                    self.mines[(x,y)].grid(row=y+1,column=x,sticky='nswe')
    
            self.root.mainloop()
    
        # 点开
        def _open(self,widget):
            xy = widget.xy
            x = xy[0]
            y = xy[1]   # 获取当前按钮的坐标
    
            # 如果是雷则显示全部雷的位置
            if widget.xy in self.mineplace:
                self.showmine()
                return
    
            # 如果已经点开了就什么也不做
            if widget._state == 1:
                return
            
            widget.configure(relief='flat',bg='white')  # 更改当前按钮的样式
            
            widget._state = 1   # 按钮状态设为点开
    
            # 获取周围八个雷的坐标
            near = [(x-1,y-1),
                    (x,y-1),
                    (x+1,y-1),
                    (x-1,y),
                    (x+1,y),
                    (x-1,y+1),
                    (x,y+1),
                    (x+1,y+1)]
            
            _sum = 0
            around = []
            
            for o, p in near:
                # 排除掉在雷区之外的雷
                if 0 <= o <= self.width - 1 and 0 <= p <= self.height - 1:
                    around.append((o,p))
    
                    # 计算周围的雷数
                    if self.mines[(o,p)].xy in self.mineplace:
                        _sum += 1
    
            #如果周围没有雷则打开周围未标记的雷,直到有雷为止
            if _sum == 0:
                widget['text'] = ''
    
                for i, j in around:                
                    if self.mines[(i,j)]._state == 0:
                        self._open(self.mines[(i,j)])
            else:
                widget['text'] = _sum   # 显示雷数
    
                # 对应数字设置对应颜色
                widget['fg'] = self.colorlist[_sum-1]
    
        # 右键单击设置标记/问号
        def make(self,widget):
            string = {0:'',2:'♀',3:'?'}
            
            if widget._state == 0:
                widget._state = 2
                widget['text'] = string[2]
                self.rest -= 1
                self.restlabel['text'] = f'剩余:{self.rest}'
                
            elif widget._state == 2:
                widget._state = 3
                widget['text'] = string[3]
                self.rest += 1
                self.restlabel['text'] = f'剩余:{self.rest}'
                
            elif widget._state == 3:
                widget._state = 0
                widget['text'] = string[0]
    
        # 如果踩到雷,显示所有的雷
        def showmine(self):
            for i, j in self.mineplace:
                self.mines[(i,j)].configure(text='ி',fg='red')
                    
    main()
    
    

    源码下载:
    python 扫雷游戏源码

    原创不易,如果你觉得这篇文章很赞的话,

    点赞收藏再走吧!


    yeanky

    2021/05/30
    展开全文
  • Python游戏开发,pygame模块,Python实现推箱子小游戏

    多人点赞 热门讨论 2021-07-27 14:01:02
    Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 Python实恐龙跳一跳小游戏Python实现塔防小游戏 Python实现接水果和金币小游戏 ...

    往期回顾

    Python实现“小兔子和Bun”游戏

    Python实现八音符小游戏

    Python实现拼图小游戏

    Python实现滑雪小游戏

    Python实现经典90坦克大战

    Python实现FlappyBird的小游戏

    Python实恐龙跳一跳小游戏现

    Python实现塔防小游戏

    Python实现接水果和金币小游戏

    Python实现简易版飞机大战小游戏

    Python实现俄罗斯方块小游戏

    前言:

    周二给大家用python写了个推箱子小游戏,在这里分享给大家,让我们愉快地开始吧~

    效果

    image.png

    开发工具

    Python版本: 3.6.4

    相关模块:

    pygame模块;

    以及一些Python自带的模块。

    环境搭建

    安装Python并添加到环境变量,pip安装需要的相关模块即可。

    原理简介

    游戏简介(来源:百度百科):

    经典的推箱子是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。

    控制方式:

    ↑↓←→键控制人物行动,r键重新开始本关。

    逐步实现:

    Step1:定义游戏精灵类

    由于游戏涉及到碰撞检测,所以我们先来定义一些游戏精灵类,包括推箱子的人、箱子、墙和目标位置指示标记。

    首先我们来定义一下推箱子的人这个精灵类:

    图片

    他需要拥有可以移动的能力,这里设置了一个模拟移动的选项,是为了通过模拟移动判断他是否可以向上/下/左/右移动。

    因为地图上的其他东西性质类似,所以我们把它们定义成同一个精灵类(T_T其实性质都类似,但是感觉还是有必要区分一下人和物的):

    图片

    其中箱子需要拥有可以移动的能力,其他则不能移动。模拟移动选项的功能与之前类似。

    Step2:定义游戏地图类

    这里我们定义一个游戏地图类,目的是用该类来创建任意的游戏地图。因此,该类应当可以增加并保存游戏元素(人、墙、箱子等),并在屏幕上把地图画出来。同时也应当自带一个方法来判断此地图上的箱子是否都已经送到了指定位置(这样子方便切换关卡):

    图片

    Step3:定义游戏界面类

    游戏界面类负责解析levels文件夹下的游戏各关卡的地图文件,并利用游戏地图类创建并显示游戏地图:

    图片

    同时因为游戏地图面积>游戏窗口界面, 所以该类需要增加根据人物位置滚动游戏地图的功能:

    图片

    Step4:定义某关的游戏主循环

    主循环主要负责实例化游戏界面类,并根据按键检测的结果对游戏界面类进行一些操作:

    图片

    其中人物移动的逻辑为:

    人移动的目标位置为空白格,则人移动;若撞到箱子,箱子可以和人方向一样移动一格,则人和箱子均移动;其他情况人和箱子均无法移动。

    Step5:定义游戏开始、切换和结束界面

    做的比较简陋,直接给源码吧。

    开始界面:

    图片

    切换界面:

    图片

    结束界面:

    图片

    Step6:实现游戏主函数

    把所有界面串起来就好啦:

    图片

    文章到这里就结束了,感谢你的观看,Python24个小游戏系列,下篇文章分享外星人入侵小游戏

    为了感谢读者们,我想把我最近收藏的一些编程干货分享给大家,回馈每一个读者,希望能帮到你们。

    干货主要有:

    ① 2000多本Python电子书(主流和经典的书籍应该都有了)

    ② Python标准库资料(最全中文版)

    ③ 项目源码(四五十个有趣且经典的练手项目及源码)

    ④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

    ⑤ Python学习路线图(告别不入流的学习)

    ⑥ 两天的Python爬虫训练营直播权限

    All done~点赞支持下~详见个人简介或者私信获取完整源代码。。

    展开全文
  • Python实现经典吃豆豆小游戏 Python实现“小兔子和Bun”游戏 Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 Python实恐龙跳一跳小游戏...
  • 一、序列应用――猜单词游戏1. 游戏介绍猜单词游戏就是计?a机随机产生一个单词,打乱字母顺序,供玩家去猜测。此游戏采用控制字符界面,2. 程序设计思路游戏中,可使用序列中的元组存储所有待猜测的单词。因为猜单词...
  • Python游戏开发入门 Python游戏开发入门:pygame最小开发框架-1 Python游戏开发入门:pygame屏幕绘制机制-2 Python游戏开发入门:pygame事件处理机制-3 Python游戏开发入门:pygame色彩与绘图机制-4 代码如下...
  • 10分钟学会用python游戏实例教程

    万次阅读 多人点赞 2019-04-15 08:46:23
    本人电脑是windows 10、python3.6,pygame下载地址: https://pypi.python.org/pypi/Pygame/1.9.3 请自行下载对应python版本的 pygame 运行以下命令 创建Pygame窗口及响应用户输入 新建一个文件夹alien_...
  • 本文实例讲述了python实现的简单RPG游戏流程。分享给大家供大家参考。具体如下:#RPGrpg = Truewhp = 100mahp = 100hhp = 100MHP = 10def dgrnd () :wa = raw_input ("What does Warrior do?")ma = raw_input ("What...
  • Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 前言: 本期我们将仿制一个Chrome浏览器里隐藏多年的彩蛋小游戏,即"恐龙跳一跳"(当然...
  • 本期我们将制作一个类似八音符的小游戏。 让我们愉快地开始吧~~~ 开发工具** **Python版本:**3.6.4 相关模块: cocos2d模块; pyaudio模块; 以及一些Python自带的模块。 环境搭建 安装Python并添加到环境变量,...
  • python入门教程:实现打砖块小游戏代码实例

    万次阅读 多人点赞 2020-02-28 21:59:47
    这篇文章主要介绍了Python打砖块小游戏,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 这次用Python实现的是一个接球打砖块的小游戏,...
  • 通过python可以开发网页、开发游戏、编写爬虫采集数据、进行数据挖掘和... 本文将结合一个简单的案例对python环境下的scrapy爬虫框架进行介绍,希望可以让初学者能够快速的找到当爬虫的感觉。 步骤1:安装 scrapy...
  • python小游戏

    2020-06-24 16:26:25
    摘要 Python 是一种跨平台的、开源的、免费的、解释型的高级编程语言。它具有丰富的、强大的库,能够把其他语言制作的各种模块很轻松地联结在一起,所以Python 常被称为“胶水”语言...本文通过对2048小游戏的设计与分
  • 本书共17章,内容包括Python环境搭建、数字类型与字符串、流程控制、列表与元组、集合和字典、函数、面向对象程序设计、模块开发、文件操作、错误和异常、正则表达式、图形用户界面、进程和线程、...
  • 今天呢,给大家展示一下Python有趣的小地方,展示给大家看看,我做的小游戏,是否有大家小时候的回忆呢。下面就废话不多说了,给大家展示一遍!感兴趣的小伙伴不懂也没事,可以下载一个PyCharm,跟着我的图片代码...
  • 这个Python项目是一个小游戏,名叫《外星人入侵》,就是移动飞船并射击来击杀外星人的游戏。项目依赖的基础的库是pygame,这是一个可以很方便的用于开发游戏的库,提供很多游戏界面,游戏元素显示的函数,...
  • 本章将通过一个太空射击游戏实例来介绍python中pygame的基本使用方法,包括创建游戏体,键盘、鼠标操作,基本的物理碰撞、UI显示和逻辑处理等。 5.1浅谈游戏开发 游戏开发是一个复杂的过程,一款游戏的背后,有数人...
  • 今天跟大家分享一下Python实例80问,伙伴们如果有需要的话,下拉文末获取网盘链接哦。1.Python Hello World 实例2.Python 数字求和3.Python 平方根4.Python 二次方程5.Python 计算三角形的面积6.Python 计算圆的...
  • 基于微信程序平台开发的的拍卖系统,项目主要分为圈子和拍卖两大部分业务,通过圈子进行信息交互和动态的管理提升用户粘性,结合企业和大V合作进行专项拍卖和宣传。系统包含了程序、API、运营中心三个子系统组成...
  • 然后就莫名其妙的看了一位B站大佬的视频,主要是做的一个2048游戏Python程序。 (看完之后,觉得人和人的差距怎么那么大!!!) 1、效果展示如下: 2、源代码如下: #coding=utf-8 ''' Author :SongBaoBao ...
  • Python 这个名字的灵感来自于英国喜剧团体 Monty Python,它的开发团队有一个重要的基础目标,就是使语言使用起来很有趣。Python 易于设置,并且是用相对直接的风格来编写,对错误会提供即时反馈,对初学者而言是个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,577
精华内容 5,830
关键字:

python小游戏开发实例

python 订阅