pygame检测精灵与精灵的碰撞_Pygame(三)--走出黑暗的洞穴(2)

bc37ec54e5fdc70a5b66af08b7ea1033.png

在上一期,阿呆提及了柏拉图,收藏数激增...嗯...

75e8d76bf3817d86408a5d71f7c48676.png

本期阿呆请来了本华叔~

aedb71ab846b59c710790ab96810810a.png

本华叔说:“音乐凭借自身的特性成了一种合适的素材,能够把人心的活动,亦即意欲的活动---其本质永远就在于满足和不满足,虽然这里面有着无数的级别-连带其至为微妙、细腻的差别和变化,忠实地塑造和重现出来。”

今天,阿呆就带领大家开启音乐之旅~

这是材料,各位看官请收好~

链接:https://pan.baidu.com/s/1lJch03Ma32S5oRUiuDXr-A 提取码:4qrb

Part 1 锦上添花

上一期的最后,我们留了一个小问题:如何避免小鸟的重叠?

1. 碰撞检测

Pygame 中已经内置了碰撞检测来而检查每一个其他动画精灵的位置和大小,防止出现重叠的现象。动画精灵模块的spritecollide()函数用来检测某个精灵是否与制定组的其他精灵发生碰撞,这个函数的形式如下:

spritecollide(被检测的精灵(sprite),指定组(group),是否重叠(False))

另外,与上一期中建立的小鸟列表不同,我们将会使用 Pygame 的组类。组和碰撞检测密切相关。它不仅可以检测不同组的碰撞,还能检测组内部的碰撞。

最后,我们需要把小鸟的动画部分放在一个函数中,在Python中创建或定义函数要使def关键字,随后就可以用函数名来使用或调用这个函数。我们的函数命名为 animate()。在这个函数中,我们把同一组精灵的碰撞检测分为四步:

1.1 先移动所有小鸟

1.2 从这个组中删除这只小鸟

1.3 检查这个小鸟与组中其他小鸟的碰撞

1.4 把小鸟添加到原来的组中

按照以上的文字说明,代码如下:

def animate(group):
    screen.fill(THECOLORS['white'])
    for ball in group:
        ball.move()
    for ball in group:
        group.remove(ball)
        if pygame.sprite.spritecollide(ball, group, False):
            ball.speed[0] = -ball.speed[0]
            ball.speed[1] = -ball.speed[1]    
        group.add(ball)
        ball.move()
        screen.blit(ball.image, ball.rect)
    pygame.display.flip()
    pygame.time.delay(20) 

运行代码,就会发现两只小鸟相遇后,转眼间又相忘于江湖啦~

b76bc1d3f097ecb6c36505b41a723d2d.png

2. 控制帧速率

为了让我们的程序更准确完美,我们采用pygame.time.Clock()来代替time.delay()。用大白话说,我们在程序中加入一个定时器,设定每次循环所需的时间,这样我们就不用在每个循环中都增加一个时间延迟啦~

不过,这个循环时间该怎么设定呢?我们采用帧速率(fps)这个参数,也就是循环在每秒运行的次数。而每个循环所用的时间就由1000ms/帧速率算得。如果循环时间超过了设定的范围,程序就会报错。大多数现代计算机都完全可以按20~30fps 的速率运行Pygame 程序。我们这里使用30fps,即在主循环中加入:

 clock.tick(30)

好了,来看看我们的完整代码吧,有点儿长,大家要多练习呀~

#引入
import pygame
import random 
from pygame.color import THECOLORS

#定义小鸟类
class AngryBirdClass(pygame.sprite.Sprite):
    def __init__(self, image_file, location,speed):
        pygame.sprite.Sprite.__init__(self) 
        self.image = pygame.image.load(image_file)
        self.rect = self.image.get_rect()
        self.rect.left,self.rect.top = location
        self.speed = speed
    #动画函数   
    def move(self):
        self.rect = self.rect.move(self.speed)
        if self.rect.left < 0 or self.rect.right > width:
            self.speed[0] = -self.speed[0]
        if self.rect.top < 0 or self.rect.bottom > height:
            self.speed[1] = -self.speed[1]
def animate(group):
    screen.fill(THECOLORS['white'])
    #先移动所有小鸟
    for bird in group:
        bird.move()
    #将小鸟从组中删除
    for bird in group:
        group.remove(bird)
        #检查碰撞
        if pygame.sprite.spritecollide(bird, group, False):
            bird.speed[0] = -bird.speed[0]
            bird.speed[1] = -bird.speed[1]
        #将小鸟添加回原组   
        group.add(bird)
        bird.move()
        screen.blit(bird.image, bird.rect)
    pygame.display.flip() 
#设置窗口大小、颜色、载入图片   
size = width,height = 800,600
screen = pygame.display.set_mode(size)
screen.fill(THECOLORS['white'])
img_file1 = 'redBird.png'
img_file2 = 'blueBird.png'
#创建Clock的实例
clock = pygame.time.Clock()
#创建小组
group = pygame.sprite.Group()
for row in range(0,1):
    for column in range(0,2):
        location = [column*180+10,row*180+10]
        speed = [random.choice([-3,3]),random.choice([-5,5])]
        bird = AngryBirdClass(img_file1,location,speed)
        group.add(bird)
        
for row in range(0,2):
    for column in range(0,1):
        location = [column*180+100,row*180+100]
        speed = [random.choice([-5,5]),random.choice([-3,3])]
        bird = AngryBirdClass(img_file2,location,speed)
        group.add(bird)
#主循环
mRunning = True
while mRunning:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            mRunning = False
            #检查帧速率
            frame_rate = clock.get_fps()
            print ('frame rate =',frame_rate )
    animate(group)
    #控制帧速率
    clock.tick(30)
pygame.quit()

Part2 Let's play band

沉浸在编程世界的阿呆似乎忘记了自己是一名心理系的学生~为了说明我木有不务正业,现在开始强行找补~

f3ed08d14b9829258d69b19cd18c7d26.png

其实啊,游戏里包含着许多心理学的概念呢~例如:游戏里有不同的难度等级、可以将经验迁移到新情境中,更重要的是,它能随时反馈结果,让我们产生参与感和沉浸感。咱们接下来就会跟计算机第一次亲密接触啦~

2.1 鼠标事件

在Pygame中,我们希望能按下鼠标就做某件事情,我们可以利用 MOUSEBUTTONDOWN 事件得到鼠标按钮何时按下,现在,我们就用它来播放一首优美的歌曲。还记得怎么导入音乐吗?我们首先用load()函数载入音乐,接着设置音量及播放,代码如下:

mp3FileName = 'CanonInD.mp3'
pygame.mixer.music.load(mp3FileName)
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play()

在导入我们所需要的音乐、背景&按钮图片后,在主循环中,我们加入以下代码,按下鼠标后,音乐就会播放啦~

if event.type == pygame.MOUSEBUTTONDOWN:
    unpause = not unpause

运行代码,我们会发现,当我们的鼠标点击

aaa79f14ffb0693a68cdc985dad18bf0.png
音乐播放

当我们点击

228bd0885d66996171fbd9c03d862450.png
音乐暂停

效果如下:

548ef2bd58e90c603de47c511e9ebf1a.png

9fd3811afc850c781907c259604ba5b0.png

完整代码:

#引入
import pygame
#初始化
pygame.init()
#设定窗口大小、标题、背景图片
size = width,height = 400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Canon')
pngFileName_3 = 'bgWhale.png'
backGround = pygame.image.load(pngFileName_3)
screen.blit(backGround,[0,0])
#载入Canon音乐
mp3FileName = 'CanonInD.mp3'
pygame.mixer.music.load(mp3FileName)
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play()
#给unpause赋予播放状态
unpause = False
#载入图片
pngFileName_1 = 'unpause.png'
pngFileName_2 = 'pause.png'
imgRect_1 = pygame.image.load(pngFileName_1)
imgRect_2 = pygame.image.load(pngFileName_2)
#设定按钮的位置
unpause_rect = imgRect_1.get_rect()
unpause_rect.left,unpause_rect.top = (0),(height - unpause_rect.height)
#创建Clock的实例
clock = pygame.time.Clock()
#主循环
mRunning = True
while mRunning:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            mRunning = False
        #鼠标按下事件
        if event.type == pygame.MOUSEBUTTONDOWN:
            unpause = not unpause
        #播放
        if unpause:
            screen.blit(imgRect_1,unpause_rect)
            pygame.mixer.music.unpause()
        #暂停
        else:
            screen.blit(imgRect_2 ,unpause_rect)
            pygame.mixer.music.pause()
        #帧速率
        clock.tick(30)
        pygame.display.flip()
pygame.quit()

【小练习】

我们学会了用鼠标与计算机交互,如果想使用键盘来操作,该怎么办呢?其实很简单,在Pygame中,键盘事件是 KEYDOWN。至于键盘上的每个键,都以K_开头,比如字母a,用K_a表示,向上箭头用K_UP表示。我们想用空格键来控制音乐的开关,就用K_SPACE。在主循环中,我们将鼠标的命令行替换为如下代码:

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                unpause = not unpause

大家自己动手试试吧~

2.2 键盘事件

刚才我们在键盘上小试牛刀,为了不让大家有审美疲劳,用盲僧来镇楼!

ba52fbf0fc33eb1acb469a6584ef1fc5.png

阿呆碎碎念:补充一个插入文本的小知识

在载入图片后,可加上以下代码,其中第一行的字体大家可以在C盘>Windows>Fonts文件夹里自行选择哦~

font = pygame.font.Font('C:WindowsFontscambriab.ttf',14)
text = font.render(u'Force is meaningless without skills!',True,[255,255,255],1)
text_rect = text.get_rect()
text_rect.center = (200,270)

现在我们让盲僧动起来吧~我们预先设定盲僧有三种状态:正面、向左转、向右转。在程序的开头,我们为这三种状态的图片创建了一个列表,然后将图片按特定的顺序放入列表:

mangseng_images = ['HeroMangSeng_Down.png','HeroMangSeng_Right.png','HeroMangSeng_Left.png']

首先,我们创建一个盲僧的类,定义他的初始状态、位置、角度等信息。其中,他的初始位置我们用他的中心位置来定义:

        self.rect.center = [300,300]

接着,我们用一个类来改变盲僧的状态,它会在角度的值改变时载入正确的图片,并设置好盲僧运动的速度。速度由水平和竖直两个方向构成。我们只改变左右方向的速度,即x方向。同时,盲僧的状态不能超过+-1,即向左转&向右转,按照这个思路,代码如下:

    def turn(self, direction):
        self.angle = self.angle + direction
        if self.angle > 1: 
            self.angle = 1       
        if self.angle < -1: 
            self.angle = 1
        center = self.rect.center
        self.image = pygame.image.load(mangseng_images[self.angle])
        self.rect = self.image.get_rect()
        self.rect.center = center
        speed = [self.angle,0]
        return speed

盲僧位移后,还要限制他不要移动到窗口外:

    def move(self, speed):
        self.rect.centerx = self.rect.centerx + speed[0]
        if self.rect.centerx < 50: 
            self.rect.centerx = self.rect.centerx - speed[0]
        if self.rect.centerx > 550: 
            self.rect.centerx = self.rect.centerx - speed[0]

随后,重绘屏幕、设置窗口大小。在主循环中,我们加入按键事件,用左箭头让盲僧向左转并加入向左转的图片,用右箭头让盲僧向右转同时载入向右转的图片,空格键退出游戏:

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                speed = mangseng.turn(-1)
            elif event.key == pygame.K_RIGHT:
                speed = mangseng.turn(1)
            elif event.key == pygame.K_SPACE:
                running = False;

执行程序后,我们可以看到如下效果:

af4bdc5cbc84da8ef273f4dc1072a25a.png
开始时,盲僧正面图

fe955ec043e2c4e4ac9bdb184e45d685.png
按住键盘上左箭头,盲僧向左

c256f15fbcedb147bd1e5750572221a1.png
按住键盘右箭头,盲僧向右

完整代码如下:

#引入
import pygame
from pygame.color import THECOLORS
#载入三种状态的图片
mangseng_images = ['HeroMangSeng_Down.png','HeroMangSeng_Right.png','HeroMangSeng_Left.png']
#定义盲僧类
class MangSengClass(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self) 
        self.image = pygame.image.load('HeroMangSeng_Down.png')
        self.rect = self.image.get_rect()
        #以盲僧的中心来定义他的位置
        self.rect.center = [300,300]
        self.angle = 0
    #改变盲僧的方向    
    def turn(self, direction):
        self.angle = self.angle + direction
        #限制盲僧的状态
        if self.angle > 1: 
            self.angle = 1       
        if self.angle < -1: 
            self.angle = 1
        center = self.rect.center
        self.image = pygame.image.load(mangseng_images[self.angle])
        self.rect = self.image.get_rect()
        self.rect.center = center
        #设定水平方向的速度
        speed = [self.angle,0]
        return speed
    #动画函数,限定盲僧在窗口内运动
    def move(self, speed):
        self.rect.centerx = self.rect.centerx + speed[0]
        if self.rect.centerx < 50: 
            self.rect.centerx = 50
        if self.rect.centerx > 550: 
            self.rect.centerx = 550
#重绘屏幕
def animate():
    screen.fill(THECOLORS['white'])
    screen.blit(mangseng.image, mangseng.rect)
    pygame.display.flip()
#设置窗口大小、游戏名称、颜色、速度范围   
pygame.init()
size = width,height = 600,600
screen = pygame.display.set_mode(size)
pygame.display.set_caption('盲僧')
#创建Clock的实例
clock = pygame.time.Clock()
mangseng = MangSengClass()
speed = [0,6]
#主循环
running = True
while running:
    #控制帧速率
    clock.tick(30)
    #键盘事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
             running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                speed = mangseng.turn(-1)
            elif event.key == pygame.K_RIGHT:
                speed = mangseng.turn(1)
            elif event.key == pygame.K_SPACE:
                running = False;
    mangseng.move(speed)
    animate()
pygame.quit()

【小练习】

怎样在这个程序中加入背景音乐呢?只需要在设定好窗口大小的命令行中插入以下代码就可以啦~

musicFileName = 'bg_music.ogg
pygame.mixer.music.load(musicFileName)
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play()

今天就到这里啦,下期阿呆会和大家一起完成一个完整的小游戏哦,不见不散~

Believer (Kaskade Remix) - Imagine Dragons/Kaskade - 单曲 - 网易云音乐​music.163.com
817dcd9d1af503e23b440b6316737468.png

a0de22a3283b038bbe6902bc5533d8c6.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值