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

本期阿呆请来了本华叔~

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

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

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

链接: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) 

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

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 = locationself.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

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

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

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

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

音乐播放

当我们点击

音乐暂停

效果如下:

完整代码:

#引入
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 键盘事件

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

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

在载入图片后,可加上以下代码,其中第一行的字体大家可以在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 + directionif self.angle > 1: self.angle = 1       if self.angle < -1: self.angle = 1center = self.rect.centerself.image = pygame.image.load(mangseng_images[self.angle])self.rect = self.image.get_rect()self.rect.center = centerspeed = [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;

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

开始时,盲僧正面图
按住键盘上左箭头,盲僧向左
按住键盘右箭头,盲僧向右

完整代码如下:

#引入
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 = 1center = self.rect.centerself.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 = 50if 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 = Falseif 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

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

  1. pygame精灵组有哪些方法_pygame 的精灵使用

    pygame 的精灵使用 pygame.sprite.Sprite 是 pygame 中用来实现精灵的一个类,在使用时并不需要对它实例化,只需要继承它,然后按需写出自己的类,因此非常简单.使用. 1. ...

  2. pygame飞机大战用精灵组(sprite)的层(layer)编写(十三)BOSS想看烟火了

    还是有点郁闷,写了那么久,居然没有一个点赞的. 就当写日记了. 接上篇-- BOSS很纳闷,说好的,要看到打中的效果,可为什么子弹消失了,英雄却没反应. 好好的打英雄的游戏,变成了英雄吃子弹的游戏了. ...

  3. Python pygame,精灵和精灵组

    plane_sprites.py(模块,定义派生精灵子类,继承pygame.sprite.Sprite): import pygame# 自定义的派生精灵子类,继承pygame.sprite.Spri ...

  4. python精灵和精灵组_Pygame精灵和精灵组

    Pygame精灵和精灵组 Pygame 提供了两个类 pygame.sprite.Sprite -- 存储 图像数据 image 和 位置 rect 的 对象 pygame.sprite.Group ...

  5. pygame中的监听事件以及精灵和精灵组

    pygame监听事件以及精灵和精灵组 文章目录 pygame监听事件以及精灵和精灵组 1.游戏循环中监听事件 1.事件(event) 2.监听 3.代码实现 二.理解精灵和精灵组 1.精灵 2.精灵组 ...

  6. 用pygame实现网上游戏‘球球情侣‘(检测矩形和某颜色碰撞的例子)

    网上有个'球球情侣'游戏,游戏中有两个不同颜色的球,玩者首先用鼠标画曲线画出球移动的路径,分别右击两个球,使两球沿曲线移动,如果两球碰到一起,进入下一关.编写很多关是游戏公司的事,我们只编写最简单的一 ...

  7. 精灵与精灵组的常用属性

    精灵常用的属性 pygame.sprite.Sprite.update - 控制精灵行为的方法 pygame.sprite.Sprite.add - 将精灵添加到组 pygame.sprite.Spr ...

  8. Python 理解 精灵 和 精灵组

    1.1 精灵 和 精灵组 在刚刚完成的案例中,图像加载.位置编号.绘制图像 都需要程序员编写代码分别处理. 为了简化开发步骤: pygame 提供两个类. pygame.sprite.Sprite - ...

  9. Python精灵和精灵组

    plane_sprites.py import pygame# 如果一个类的父类不是object # 在重写初始化方法时,一定要先super()一下父类的__init__方法 # 保证父类中实现的__ ...

  10. Python_精灵和精灵组

    1. 基本概念 接下来介绍两个pygame中提供的高级类, 精灵和精灵组. 在介绍这两个类之前, 先来共同回顾一下到目前为止掌握的游戏开发套路. 在游戏初始化,需要加载一下游戏中所有的图像, 然后呢, ...

最新文章

  1. 【BZOJ】1013 [JSOI2008]球形空间产生器sphere
  2. python导入包相当于什么_Python 引入包的两种方式区别
  3. IC/FPGA笔试/面试题分析(十)CMOS门电路
  4. adc0808温度换算公式_温湿度传感器的三种模拟量换算关系
  5. Spring EL运算符实例
  6. PHP的Smarty较为完整的笔记
  7. 西门子smartclient怎么用_西门子官方应用Sm@rtClient Lite APP
  8. 你的目的是什么是谁指使你_电视剧《谁说我结不了婚》第25-27集剧情:魏书帮程璐搞定投资人...
  9. Eclipse远程调试Java代码的三种方法
  10. MATLAB程序详细解析,遗传算法——matlab代码解析
  11. 《Elasticsearch 源码解析与优化实战》样章-第 6 章 数据模型
  12. sklearn gridsearchcv_Sklearn与Tensorflow的完美结合
  13. 解决sendmail服务启动慢的方法
  14. 利用veiw建立Centos5.5 双机智能DNS手册
  15. 2012.4.17内存相关
  16. linux锐捷校园网认证失败,Ubuntu中校园网锐捷认证用mentohust解决版本过低问题
  17. RS锁存器,D锁存器、D触发器简介
  18. e语言截图软件怎么保存在c盘,电脑截图文件保存在哪_电脑截图保存在哪里
  19. 《SICP》习题第1章
  20. 征途完美单机版_征途世界单机版

热门文章

  1. 域名解析与邮件服务器收发问题
  2. 13. Magento 后台top栏开发(二)
  3. css中的clip:rect() 只能在绝对定位的元素上使用
  4. [2019杭电多校第五场][hdu6628]permutation 1
  5. .net core 介绍好文章
  6. 线程的四种实现方式,一些方法及线程的同步
  7. C#控件之TreeView
  8. spring教程(一):简单实现(转)
  9. 第一篇:webservice初探
  10. 学习JavaScript闭包