20232424 陈鹏宇 2023-2024-2 《Python程序设计》实验四报告

20232424陈鹏宇 2024-05-29 23:53:19

20232424 陈鹏宇 2023-2024-2 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2324
姓名: 陈鹏宇
学号: 20232424
实验教师:王志强
实验日期:2024年5月15日
必修/选修: 公选课

1.实验内容

设计两个个简单小游戏:
a).炫彩小球
b).勇闯地下一百层

2. 实验过程及结果

  • 设计思路概述:不满足于控制台文字的交互,想自己动手设计出可进行简单键鼠交互的游戏

一、炫彩小球
1.设计步骤:
a).导入库:

  • pgzrun: 这是 Pygame Zero 的一个模块,用于快速创建简单的游戏。
  • random: 用于生成随机数。
import pgzrun  # 导入游戏库
import random  # 导入随机库

b).设置窗口大小:

  • WIDTH 和 HEIGHT 定义了窗口的宽度和高度。
WIDTH = 800   # 设置窗口的宽度
HEIGHT = 600  # 设置窗口的高度

c).初始化小球列表:

  • balls = [] 创建了一个空列表,用于存储所有小球的信息。
balls = []  # 存储所有小球的信息,初始为空列表

d).绘制函数draw():

  • 每帧调用该函数来绘制游戏画面。
  • screen.fill('white') 用白色填充屏幕,创建白色背景。
  • 使用 for 循环遍历 balls 列表中的每个小球,并使用 screen.draw.filled_circle() 绘制它们。
  • 每个小球由一组信息表示:位置 (ball[0], ball[1])、半径 ball[4] 和颜色 (ball[5], ball[6], ball[7])。
  • 在绘制每个小球时,还绘制了多层颜色的环绕,使得小球看起来是渐变的。
def draw():   # 绘制模块,每帧重复执行
    screen.fill('white')  # 白色背景
    for ball in balls:  # 绘制所有的圆
        screen.draw.filled_circle((ball[0], ball[1]), ball[4], (ball[5], ball[6], ball[7]))
        for x in range(1, ball[4], 3): # 用同心圆填充
            screen.draw.filled_circle((ball[0], ball[1]), ball[4]-x, (random.randint(
                ball[5], 255), random.randint(ball[6], 255), random.randint(ball[7], 255)))

e).更新函数 update():

  • 每帧调用该函数来更新游戏状态。
  • 使用 for 循环遍历 balls 列表中的每个小球。
  • 更新小球的位置 (ball[0], ball[1]),根据其速度 (ball[2], ball[3]) 和边界情况。
  • 当小球碰到屏幕边界时,其速度会反向,使得小球在屏幕内弹来弹去。
def update():  # 更新模块,每帧重复操作
    for ball in balls:
        ball[0] = ball[0] + ball[2]   # 利用x方向速度更新x坐标
        ball[1] = ball[1] + ball[3]   # 利用y方向速度更新y坐标
        if ball[0] > WIDTH-ball[4] or ball[0] < ball[4]:  # 当小球碰到左右边界时,x方向速度反转
            ball[2] = -ball[2]
        if ball[1] > HEIGHT-ball[4] or ball[1] < ball[4]:  # 当小球碰到上下边界时,y方向速度反转
            ball[3] = -ball[3]

f).鼠标移动事件处理函数 on_mouse_move():

  • 当鼠标移动时,会触发该事件处理函数。
  • 如果鼠标左键被按下 (mouse.LEFT in buttons),则会在鼠标位置创建一个新的小球。
  • 小球的初始位置为鼠标位置 (pos[0], pos[1]),速度初始化为 (1,5)间随机数,半径范围在 5 到 50 之间,颜色为随机生成的 (colorR, colorG, colorB)。
def on_mouse_move(pos, rel, buttons): # 当鼠标移动时
    if mouse.LEFT in buttons:         # 当鼠标左键按下时
        x = pos[0]   # 鼠标的x坐标,设为小球的x坐标
        y = pos[1]   # 鼠标的y坐标,设为小球的y坐标
        speed_x = random.randint(1, 5)  # 小球x方向的速度
        speed_y = random.randint(1, 5)  # 小球y方向的速度
        r = random.randint(5, 50)      # 小球的半径
        colorR = random.randint(10, 255)  # 小球的三个颜色分量
        colorG = random.randint(10, 255)
        colorB = random.randint(10, 255)
        # 存储小球所有信息的列表
        ball = [x, y, speed_x, speed_y, r, colorR, colorG, colorB]
        balls.append(ball)  # 把第i号小球的信息添加到balls中

g).开始游戏 pgzrun.go():

  • 启动游戏循环,开始执行游戏逻辑。
pgzrun.go()   # 开始执行游戏

2.代码运行结果:

3.一点修改:
将小球速度改为0,半径改为固定值10,则该程序可变为画笔工具(炫)

4.源代码:
a).小球:

import pgzrun  # 导入游戏库
import random  # 导入随机库
WIDTH = 800   # 设置窗口的宽度
HEIGHT = 600  # 设置窗口的高度
balls = []  # 存储所有小球的信息,初始为空列表

def draw():   # 绘制模块,每帧重复执行
    screen.fill('white')  # 白色背景
    for ball in balls:  # 绘制所有的圆
        screen.draw.filled_circle((ball[0], ball[1]), ball[4], (ball[5], ball[6], ball[7]))
        for x in range(1, ball[4], 3): # 用同心圆填充
            screen.draw.filled_circle((ball[0], ball[1]), ball[4]-x, (random.randint(
                ball[5], 255), random.randint(ball[6], 255), random.randint(ball[7], 255)))

def update():  # 更新模块,每帧重复操作
    for ball in balls:
        ball[0] = ball[0] + ball[2]   # 利用x方向速度更新x坐标
        ball[1] = ball[1] + ball[3]   # 利用y方向速度更新y坐标
        if ball[0] > WIDTH-ball[4] or ball[0] < ball[4]:  # 当小球碰到左右边界时,x方向速度反转
            ball[2] = -ball[2]
        if ball[1] > HEIGHT-ball[4] or ball[1] < ball[4]:  # 当小球碰到上下边界时,y方向速度反转
            ball[3] = -ball[3]

def on_mouse_move(pos, rel, buttons): # 当鼠标移动时
    if mouse.LEFT in buttons:         # 当鼠标左键按下时
        x = pos[0]   # 鼠标的x坐标,设为小球的x坐标
        y = pos[1]   # 鼠标的y坐标,设为小球的y坐标
        speed_x = random.randint(1, 5)  # 小球x方向的速度
        speed_y = random.randint(1, 5)  # 小球y方向的速度
        r = random.randint(5, 50)      # 小球的半径
        colorR = random.randint(10, 255)  # 小球的三个颜色分量
        colorG = random.randint(10, 255)
        colorB = random.randint(10, 255)
        # 存储小球所有信息的列表
        ball = [x, y, speed_x, speed_y, r, colorR, colorG, colorB]
        balls.append(ball)  # 把第i号小球的信息添加到balls中

pgzrun.go()   # 开始执行游戏

b).画笔:

import pgzrun # 导入游戏库
import random # 导入随机库
WIDTH = 800 # 设置窗口的宽度
HEIGHT = 600 # 设置窗口的高度

balls = [] # 存储所有小球的信息,初始为空列表

def draw(): # 绘制模块,每帧重复执行
    screen.fill('white') # 白色背景
    for ball in balls: # 绘制所有的圆
        screen.draw.filled_circle((ball[0], ball[1]), ball[4], (ball[5], ball[6],
                                  ball[7]))
        for x in range(1,ball[4],3):
            screen.draw.filled_circle((ball[0],ball[1]),ball[4]-x,(random.randint(ball[5],255),random.randint(ball[6],255),random.randint(ball[7],255)))

def update(): # 更新模块,每帧重复操作
    for ball in balls:
        ball[0] = ball[0] + ball[2] # 利用x方向速度更新x坐标
        ball[1] = ball[1] + ball[3] # 利用y方向速度更新y坐标
        # 当小球碰到左右边界时,x方向速度反向
        if ball[0] > WIDTH-ball[4] or ball[0] < ball[4]:
            ball[2] = -ball[2]
        # 当小球碰到上下边界时,y方向速度反向
        if ball[1] > HEIGHT-ball[4] or ball[1] < ball[4]:
            ball[3] = -ball[3]

def on_mouse_move(pos, rel, buttons): # 当鼠标移动时
    if mouse.LEFT in buttons:         # 当按下鼠标左键时
        x = pos[0] # 鼠标的x坐标,设为小球的x坐标
        y = pos[1] # 鼠标的y坐标,设为小球的y坐标
        speed_x = 0 # 小球x方向的速度
        speed_y = 0 # 小球y方向的速度
        r = 10     # 小球的半径
        colorR = random.randint(10, 255) # 小球的3个颜色分量
        colorG = random.randint(10, 255)
        colorB = random.randint(10, 255)
        # 存储小球所有信息的列表
        ball = [x, y, speed_x, speed_y, r, colorR, colorG, colorB]
        balls.append(ball) # 把该小球的信息添加到balls中

pgzrun.go() # 开始执行游戏

二、勇闯地下一百层
1.设计步骤:
a).导入库:

  • pgzrun: 这是 Pygame Zero 的一个模块,用于快速创建简单的游戏。
  • random: 用于生成随机数。
import pgzrun  # 导入游戏库
import random  # 导入随机库

b).常量:

  • WIDTH 和 HEIGHT:这些常量定义了游戏窗口的尺寸。
  • playerSpeed 和 brickSpeed:这些常量设置了玩家和砖块的速度。
  • isLoose:这个布尔变量跟踪游戏是否失败。
  • score:这个变量记录玩家的分数。
WIDTH = 600    # 设置窗口的宽度
HEIGHT = 800   # 设置窗口的高度
playerSpeed = 5  # 玩家水平移动速度
brickSpeed = 2   # 砖块自动上移速度
isLoose = False  # 游戏是否失败
score = 0     # 游戏得分

c).初始化游戏元素:

  • alien:这是玩家的角色,初始化为一个 Actor 对象,其图像为 'alien'。
  • bricks:这个列表包含多个 Actor 对象,表示游戏中的砖块。
alien = Actor('alien')  # 导入玩家图片
alien.x = WIDTH/2      # 设置玩家的x坐标
alien.y = HEIGHT/5     # 设置玩家的y坐标
lastAlienY = alien.y  # 记录角色上一帧的y坐标
bricks = []  # 存储所有砖块的列表,开始为空
for i in range(5):
    brick = Actor('brick')  # 导入砖块图片
    brick.pos = 100*(i+1), 150*(i+1)    # 设置砖块的(x,y)坐标
    bricks.append(brick)  # 把当前砖块加入列表中

d).绘制函数draw():

  • 这个函数负责在屏幕上呈现游戏元素。
  • 它清空屏幕、绘制玩家、绘制砖块,并显示分数。
  • 如果游戏失败(isLoose 为 True),它会显示一条消息。
def draw():    # 绘制模块,每帧重复执行
    screen.clear()  # 清空游戏画面
    alien.draw()  # 绘制玩家
    for brick in bricks:  # 绘制列表中每个砖块
        brick.draw()  # 绘制砖块
    screen.draw.text("你已坚持了 "+str(score)+"层!", (400, 20), fontsize=25,
                     fontname='s', color='white')
    if isLoose:  # 如果游戏失败,输出相关信息
        screen.draw.text("游戏失败!", (80, HEIGHT/2-100),
                         fontsize=100, fontname='s', color='red')

e).更新函数 update():

  • 这个函数在每一帧更新时被调用,负责更新游戏状态。
  • 它检查玩家是否站在砖块上,并在是的情况下允许水平移动。
  • 如果玩家不在任何砖块上,它使玩家下落。
  • 它还更新砖块的位置,使它们向上移动。
  • 如果玩家成功着陆在一个新的砖块上,则增加玩家的分数。
def update():  # 更新模块,每帧重复操作
    global isLoose, playerSpeed, brickSpeed, score, lastAlienY

    isPlayerOnGround = False  # 开始假设角色没有站在砖块上
    for brick in bricks: # 对列表中所有砖块遍历
        # 玩家正好站在砖块上面,在方块左右之间,可以左右移动
        if abs(alien.bottom-brick.top) < 5  \
            and brick.left - alien.left < alien.width*2/3 \
            and alien.right - brick.right < alien.width*2/3:
            alien.image = 'alien' # 设为在砖块上站立的图片
            isPlayerOnGround = True  # 玩家在一块砖上
            alien.bottom = brick.top  # 玩家跟着砖块一直向上移动
            if lastAlienY < alien.y:
                score += 1  # 之前还不在砖上,表示现在刚开始落到砖上,分数+1

            if keyboard.left:  # 如果按下键盘左键
                alien.x = alien.x - playerSpeed  # 玩家左移
            if keyboard.right:  # 如果按下键盘右键
                alien.x = alien.x + playerSpeed  # 玩家右移

    lastAlienY = alien.y  # 对所有砖块遍历后,更新lastAlienY的值

    if not isPlayerOnGround:
        alien.image = 'alien_falling'  # 设为在空中的玩家图片
        alien.y += 5  # 玩家不在任何一块砖上,就下落

    for brick in bricks: # 所有砖块缓慢上移
        brick.y -= brickSpeed

    if bricks[0].top < 10: # 最上面的一个砖块达到画面顶部时
        del bricks[0]  # 删除最上面的砖块
        brick = Actor('brick') # 新增一个砖块
        brick.x = random.randint(100, 500) # 水平位置随机
        brick.y = HEIGHT # 从最下部出现
        bricks.append(brick) # 将新砖块添加到列表中

    if alien.top < 0 or alien.bottom > HEIGHT:  # 角色超出上下范围,游戏失败
        playerSpeed = 0  # 玩家水平移动速度设为0
        brickSpeed = 0   # 砖块自动上移速度设为0
        isLoose = True   # 游戏失败

f).开始游戏 pgzrun.go():

  • 启动游戏循环,开始执行游戏逻辑。
pgzrun.go()   # 开始执行游戏

2.代码运行结果:

3.源代码:

import pgzrun  # 导入游戏库
import random  # 导入随机库

WIDTH = 600    # 设置窗口的宽度
HEIGHT = 800   # 设置窗口的高度
playerSpeed = 5  # 玩家水平移动速度
brickSpeed = 2   # 砖块自动上移速度
isLoose = False  # 游戏是否失败
score = 0     # 游戏得分

alien = Actor('alien')  # 导入玩家图片
alien.x = WIDTH/2      # 设置玩家的x坐标
alien.y = HEIGHT/5     # 设置玩家的y坐标
lastAlienY = alien.y  # 记录角色上一帧的y坐标

bricks = []  # 存储所有砖块的列表,开始为空
for i in range(5):
    brick = Actor('brick')  # 导入砖块图片
    brick.pos = 100*(i+1), 150*(i+1)    # 设置砖块的(x,y)坐标
    bricks.append(brick)  # 把当前砖块加入列表中

def draw():    # 绘制模块,每帧重复执行
    screen.clear()  # 清空游戏画面
    alien.draw()  # 绘制玩家
    for brick in bricks:  # 绘制列表中每个砖块
        brick.draw()  # 绘制砖块
    screen.draw.text("你已坚持了 "+str(score)+"层!", (400, 20), fontsize=25,
                     fontname='s', color='white')
    if isLoose:  # 如果游戏失败,输出相关信息
        screen.draw.text("游戏失败!", (80, HEIGHT/2-100),
                         fontsize=100, fontname='s', color='red')
def update():  # 更新模块,每帧重复操作
    global isLoose, playerSpeed, brickSpeed, score, lastAlienY

    isPlayerOnGround = False  # 开始假设角色没有站在砖块上
    for brick in bricks: # 对列表中所有砖块遍历
        # 玩家正好站在砖块上面,在方块左右之间,可以左右移动
        if abs(alien.bottom-brick.top) < 5  \
            and brick.left - alien.left < alien.width*2/3 \
            and alien.right - brick.right < alien.width*2/3:
            alien.image = 'alien' # 设为在砖块上站立的图片
            isPlayerOnGround = True  # 玩家在一块砖上
            alien.bottom = brick.top  # 玩家跟着砖块一直向上移动
            if lastAlienY < alien.y:
                score += 1  # 之前还不在砖上,表示现在刚开始落到砖上,分数+1

            if keyboard.left:  # 如果按下键盘左键
                alien.x = alien.x - playerSpeed  # 玩家左移
            if keyboard.right:  # 如果按下键盘右键
                alien.x = alien.x + playerSpeed  # 玩家右移

    lastAlienY = alien.y  # 对所有砖块遍历后,更新lastAlienY的值

    if not isPlayerOnGround:
        alien.image = 'alien_falling'  # 设为在空中的玩家图片
        alien.y += 5  # 玩家不在任何一块砖上,就下落

    for brick in bricks: # 所有砖块缓慢上移
        brick.y -= brickSpeed

    if bricks[0].top < 10: # 最上面的一个砖块达到画面顶部时
        del bricks[0]  # 删除最上面的砖块
        brick = Actor('brick') # 新增一个砖块
        brick.x = random.randint(100, 500) # 水平位置随机
        brick.y = HEIGHT # 从最下部出现
        bricks.append(brick) # 将新砖块添加到列表中

    if alien.top < 0 or alien.bottom > HEIGHT:  # 角色超出上下范围,游戏失败
        playerSpeed = 0  # 玩家水平移动速度设为0
        brickSpeed = 0   # 砖块自动上移速度设为0
        isLoose = True   # 游戏失败

pgzrun.go()  # 开始执行游戏

3. 实验过程中遇到的问题和解决过程

  • 问题1:不知道编写小游戏还需要引用pygame与pyzero库,不知道怎么添加软件包
  • 问题1解决方案:到CSDN查阅相关文章,为项目添加上软件包
  • 问题2:在写小球程序时经常出现程序中小球扎堆不随机的情况
  • 问题2解决方案:将小球的x,y方向速度都设为随机数,增加程序趣味性
  • 问题3:在编写勇闯地下程序时,砖块的生成和移动逻辑有误,导致砖块出现在屏幕外或者移动异常,影响游戏的正常进行
  • 问题3解决方案:使用AI工具辅助修改
  • 问题4:想为游戏角色增加跳跃功能,以获得更好的游戏体验,但修改代码过程中错漏百出
  • 问题4解决方案:由于时间和水平有限暂未解决
  • 问题5:想将3款游戏运用菜单式管理,但是bug频出
  • 问题5解决方案:由于时间和水平有限暂未解决

其他(感悟、思考等)

首先,Python的强大和灵活性让我印象深刻。在学习的过程中,我逐渐了解到Python的简洁明了和易于上手的特点,其语法清晰,代码易于阅读和维护,这使得我在编写程序时能够更加高效和准确。其次,Python的学习过程也让我认识到了编程思维的重要性。编程不仅仅是一种技能,更是一种解决问题的思维方式。通过Python的学习,我学会了如何将问题分解成更小的部分,并使用逻辑和算法来解决它们。这种思维方式不仅对我的学习有帮助,也对我的日常生活产生了积极的影响。最后,王老师的课堂活泼有趣,不同于平日的其他科目的课堂。课上王老师深入浅出的讲解带我领略到了python真正的魅力,如自己编写计算器程序、使用socket与舍友通过程序进行对话等,不同于高中时期简单的输入输出语句那样机械,此外,英语打卡也让人印象深刻,甚至在英语听写课堂中救我一命(doge)。总之,人生苦短,我用Python!

...全文
368 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
源码链接: https://pan.quark.cn/s/a4b39357ea24 微信小程序是由腾讯公司设计的一种轻量级应用开发平台,主要面向移动设备,旨在为用户带来无需下载安装即可直接使用的应用服务体验。在微信小程序的开发实践中,"模仿美团菜单 swiper分类菜单"是一项常见的技术应用,其目的是达成与美团外卖应用相似的交互模式,使用户能够轻松地浏览和挑选各种商品或服务。 在微信小程序的技术体系中,`swiper`组件属于轮播图功能模块,通常用于呈现多张图片或卡片式的切换界面,能够达成动态滑动展示不同分类菜单的功能。在模拟美团菜单的应用情境下,`swiper`组件一般与`swiper-item`组件协同工作,每一个`swiper-item`对应一个分类,用户可通过左右滑动来切换不同的分类菜单。 为了达成这样的功能,首先需要在微信小程序的`json`配置文档中引入`swiper`组件,并在`wxml`结构文档中构建相应的布局代码,将每个分类以`swiper-item`的形式进行组织。同时,需要在`wxss`样式文档中定义恰当的样式,保证分类菜单的视觉呈现符合设计规范。 接下来,我们将在`js`逻辑文档中处理`swiper`的切换逻辑,通过监听`bindchange`事件来识别当前选中的分类,并根据这一信息动态获取对应的子菜单信息。为了达成类似美团的层级菜单功能,可能还需要借助`picker`或`navigator`组件来展示二级分类或商品详情。 在开发阶段,需要关注以下关键点: 1. 数据绑定:保证数据与界面之间的双向链接准确无误,以便在选择分类时即时更新显示内容。 2. 动态加载:针对大量数据,可能需要采取异步加载机制,防止一次性加载过多内容引发性能瓶颈...
代码下载地址: https://pan.quark.cn/s/72bd50ecb2fb 《微信飞机大战素材详解》 微信飞机大战作为一款广受欢迎的休闲游戏,凭借其便捷的操作方式和紧张刺激的游戏过程,赢得了众多用户的青睐。本文将系统性地剖析这款游戏的关键素材,旨在帮助开发者全面掌握游戏的设计理念与实现方法。 我们聚焦于游戏的核心构成——"AirplaneResource"。此名称一般指向游戏资源库,其中收纳了游戏中所有的视觉素材、音频资料以及动画元素。在微信飞机大战的语境下,这些资源构成了游戏画面呈现、音效播放和动态效果的基础。 1. **图像素材**:游戏中的飞机造型、敌方单位、弹药以及爆炸效果等视觉元素,均以图像素材的形式进行展示。图像素材通常涵盖PNG或JPG格式的静态图片,也包括GIF或APNG格式的动态图片。开发者需要细致地设计并优化这些图像,确保在各种设备上都能实现流畅的渲染,同时维持视觉表现力。 2. **声音素材**:游戏的背景音乐、射击音效、爆炸声等音频片段,对于构建游戏氛围具有决定性作用。这些音频文件可能以MP3、WAV或OGG格式进行存储,开发者需要权衡音频的压缩程度与音质,以确保在不牺牲游戏体验的前提下,有效控制文件体积。 3. **动画序列**:飞机的飞行轨迹、攻击动作、爆炸过程等动态表现,通常借助序列帧动画技术实现。这些序列帧图片组合而成的动画,通过编程控制播放速率和顺序,为游戏增添生动的动态效果。 4. **物理接触判定**:游戏中飞机与弹药之间的接触判定,是通过算法完成的。开发者可能会采用基础的矩形接触判定或更精密的像素级接触判定,以保证游戏的公平性和挑战性。 5. **游戏规则**:微信飞机大战的得分机制、生命值系统、敌机生成逻辑等...

110

社区成员

发帖
与我相关
我的任务
社区描述
人生苦短,我用Python!
python3.11 高校
社区管理员
  • blackwall0321
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧