pygame游戏_Pygame游戏——Pong游戏(三)

fb3e90810ff8f4feedd7603183477be4.png
笑脸与挡板的碰撞检测

这里我们需要检查笑脸的底部中心刚好碰到挡板的左边一角和右边一角的临界状态,除此之外我们还要确定笑脸的y坐标也要在垂直的范围之内。

竖直方向

1d06cc689792dd1694de9ea39deaa9b5.png

我们假设一个临界状态——笑脸底部和挡板顶部刚好接触:

pic_y + pic.get_height() = paddle_y

即笑脸距离屏幕顶部的距离加上笑脸的高度正好等于挡板距离屏幕顶部的距离。

还有一个临界状态——笑脸继续向下运动,笑脸的底部正好和挡板的底部重合接触:

pic_y + pic.get_height() = paddle_y + paddle_height

即笑脸距离屏幕顶部的距离加上笑脸的高度正好等于挡板距离屏幕顶部的距离加上挡板自身的高度。所以,我们可以控制笑脸在竖直方向的位置变化:

if pic_y + pic.get_height() >= paddle_y and pic_y + pic.get_height() <= 
       paddle_y + paddle_height:

如果没有第二个条件的限制,笑脸将会到达屏幕的底端,接着会继续反弹上来,但是我们不想这样,这样触碰到挡板是无效的,不能计算用户的得分。

还有一点就是,我们还要保证笑脸的竖直方向的速度是大于0的,即笑脸是朝下运动的。这样可以避免我们漏掉一个球之后,再次反弹时触碰到挡板。

speedy > 0

所以竖直方向的条件判断:

if pic_y + pic.get_height() >= paddle_y and pic_y + pic.get_height() <= 
       paddle_y + paddle_height and speedy > 0:

注意:斜杠字符“”运行我们将太长的代码折返到下一行。

水平方向——挡板左边

3ac3007d268b6f719416fdf9a18273b4.png

假设一个临界状态——笑脸的底部中心刚好在挡板的左上一角:

pic_x + pic.get_width()/2 = paddle_x

即笑脸距离屏幕左边的距离加上自身宽度的一半正好等于挡板距离屏幕左边的距离。

当笑脸往左或往右,这个临界状态都会被打破。

当笑脸往左的时候,pic_x在变小:

pic_x + pic.get_width()/2 < paddle_x

这样笑脸就不会碰到挡板了。

当笑脸往右的时候,pic_x在变大:

pic_x + pic.get_width()/2 > paddle_x

这样还是可以保证笑脸和挡板发生碰撞。

所以水平方向——左边的判断条件:

if pic_x + pic.get_width()/2 >= paddle_x:

6ceab4ced29843b036ecc0fd54f4202c.png

假设一个临界状态——笑脸底部中心刚好处在挡板右上角:

pic_x  + pic.get_width()/2 = paddle_x + paddle_width

即笑脸距离屏幕左边的距离加上自身宽度的一半正好等于挡板距离屏幕左边的距离加上挡板的宽度。

当笑脸往左或往右,这个临界状态同样都会被打破。

当笑脸往左的时候,pic_x在变小:

pic_x  + pic.get_width()/2 < paddle_x + paddle_width

这样笑脸还是可以触碰到挡板的。

当笑脸往右的时候,pic_x在变大:

pic_x  + pic.get_width()/2 > paddle_x + paddle_width

这样的话笑脸就离开了挡板,不会发生碰撞。

所以水平方向——右边的判断条件:

if pic_x  + pic.get_width()/2 <= paddle_x + paddle_width

综合挡板左右两边的临界判断,最终水平方向的条件判断为:

if pic_x + pic.get_width()/2 >= paddle_x and pic_x + pic.get_width()/2
           <= paddle_x + paddle_width:

所以,挡板和笑脸的碰撞判断完整代码:

import pygame # 导入模块
from pygame.locals import *

pygame.init()  # 初始化模块
screen = pygame.display.set_mode((800,600))  # 创建一个Surface对象窗口
pygame.display.set_caption("Pong游戏")  # 设置标题
keep_going = True  # 循环标志
BLACK = (0,0,0)
clock = pygame.time.Clock()

# 挡板
WHITE = (255,255,255)
paddle_width = 200 # 挡板宽度
paddle_height = 25 # 挡板高度
paddle_x = 300    # 挡板left属性
paddle_y = 550    # 挡板top属性

# 笑脸图片
pic = pygame.image.load("Smile.bmp").convert_alpha()
colorkey = pic.get_at((0,0))
pic.set_colorkey(colorkey)

# 速度和位置
speedx = 5
speedy = 5
pic_x = 0
pic_y = 0


while keep_going:
    for event in pygame.event.get():
        if event.type == QUIT:
            keep_going = False

    pic_x += speedx
    pic_y += speedy

    # 墙壁碰撞检测
    if pic_x <= 0 or pic_x + pic.get_width() >= 800:
        speedx = - speedx

    if pic_y <= 0 or pic_y + pic.get_height() >= 600:
        speedy = -speedy

    screen.fill(BLACK) # 填充背景

    # 绘制挡板
    paddle_x = pygame.mouse.get_pos()[0]
    paddle_x -= paddle_width/2
    pygame.draw.rect(screen,WHITE,(paddle_x,paddle_y,paddle_width,paddle_height))

    # 绘制笑脸图片
    screen.blit(pic,(pic_x,pic_y))

    # 笑脸和挡板碰撞检测
    if pic_y + pic.get_height() >= paddle_y and pic_y + pic.get_height() <= 
       paddle_y + paddle_height and speedy > 0:
        if pic_x + pic.get_width()/2 >= paddle_x and pic_x + pic.get_width()/2
           <= paddle_x + paddle_width:
            speedy = -speedy

    pygame.display.flip()
    clock.tick(60) # 设置帧速率

pygame.quit()                

597bb9b740c1e2feae19a1883167bfb4.gif

自己可以动手尝试下,后面我们将加入游戏计分机制。

谢谢大家的关注与支持,有不足的地方欢迎指正和交流!

更多内容可以关注微信公众号【陪孩子一起学编程】

http://weixin.qq.com/r/hymfhyjEF3VorWzk93yV (二维码自动识别)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值