鱼C论坛

 找回密码
 立即注册
查看: 1301|回复: 1

pygame碰撞检测

[复制链接]
发表于 2021-1-6 19:23:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import pygame
  2. import sys
  3. import random


  4. size = width, height = 800, 600
  5. screen = pygame.display.set_mode(size)

  6. # 加载图片背景
  7. game_background = pygame.image.load(r'D:\python库\我的项目\打飞机小游戏\image\bg.png')
  8. # 绘制 surface(背景图片) 对象
  9. screen.blit(game_background, (0, 0))


  10. # 加载敌方飞机
  11. enemy_aircraft = pygame.image.load(r'D:\python库\我的项目\打飞机小游戏\image\敌机小正常效果.png')
  12. oid_enemy_aircraft_rect = enemy_aircraft.get_rect()

  13. # 加载子弹
  14. bullet = pygame.image.load(r'D:\python库\我的项目\打飞机小游戏\image\子弹1.png')

  15. # 加载我方飞机素材
  16. our_aircraft = pygame.image.load(r'D:\python库\我的项目\打飞机小游戏\image\玩家对象.png')

  17. # 获得我方飞机的矩形范围
  18. our_aircraft_rect = our_aircraft.get_rect()

  19. # 初始化我方飞机位置
  20. our_aircraft_rect = our_aircraft_rect.move(400, 400)

  21. # 子弹列表
  22. bullet_list = []
  23. # 敌机列表
  24. enemy_aircraft_list = []

  25. # 子弹位置
  26. oid_bullet_rect = bullet.get_rect()

  27. # 绘制 surface(我方飞机) 对象
  28. screen.blit(our_aircraft, our_aircraft_rect)

  29. # 画面刷新
  30. pygame.display.flip()

  31. # 用判断发生点击事件是否点击到我方飞机
  32. click_event = False

  33. # 帧速度
  34. fcolck = pygame.time.Clock()

  35. move_times = 0
  36. times = 0
  37. run = True
  38. while True:
  39.     for event in pygame.event.get():
  40.         if event.type == pygame.QUIT:
  41.             sys.exit()

  42.         if event.type == pygame.KEYDOWN:
  43.             run = not run
  44.             print(1)

  45.         if event.type == pygame.MOUSEBUTTONDOWN:
  46.             if our_aircraft_rect.left < event.pos[0] < \
  47.                     our_aircraft_rect.right and our_aircraft_rect.top < event.pos[1] < our_aircraft_rect.bottom:
  48.                 click_event = True

  49.         if event.type == pygame.MOUSEBUTTONUP:
  50.             click_event = False

  51.         if event.type == pygame.MOUSEMOTION and click_event:
  52.             if click_event:
  53.                 our_aircraft_rect = our_aircraft_rect.move(event.rel[0], event.rel[1])

  54.     if not run:
  55.         print(1)
  56.         continue

  57.     if our_aircraft_rect.top < 0:
  58.         our_aircraft_rect.top = 0

  59.     elif our_aircraft_rect.bottom > height:
  60.         our_aircraft_rect.bottom = height

  61.     if our_aircraft_rect.left < 0:
  62.         our_aircraft_rect.left = 0

  63.     elif our_aircraft_rect.right > width:
  64.         our_aircraft_rect.right = width

  65.     if times == 5:
  66.         x = our_aircraft_rect.right - (our_aircraft_rect.w / 2) - 3#(oid_bullet_rect.w / 2 )
  67.         y = our_aircraft_rect.top
  68.         # 生成子弹
  69.         new_bullet = oid_bullet_rect.move(x, y)
  70.         bullet_list.append(new_bullet)
  71.         # 每循环100次生成一个敌机
  72.         while move_times == 100:
  73.             new_aircraft_position = random.choice([x for x in range(width-51)]), -100
  74.             overlap = False
  75.             for each in enemy_aircraft_list:
  76.                 if each.left < new_aircraft_position[0] < each.right:
  77.                     overlap = True
  78.                     break
  79.             else:
  80.                   # 生成敌机
  81.                 new_enemy_aircraft = oid_enemy_aircraft_rect.move(new_aircraft_position)
  82.                 enemy_aircraft_list.append(new_enemy_aircraft)
  83.                 move_times = 0
  84.                 break
  85.         times = 0

  86.     # 重绘背景
  87.     screen.blit(game_background, (0, 0))

  88.     # 删除子弹对象列表
  89.     del_bullets = []

  90.     # 移动子弹
  91.     for each in range(len(bullet_list)):
  92.         new_bullet = bullet_list[each].move(0, -10)
  93.         bullet_list[each] = new_bullet
  94.         screen.blit(bullet, new_bullet)
  95.         if new_bullet.top < 0:
  96.             del_bullets.append(new_bullet)
  97.     times += 1

  98.     # 删除超出窗口范围的子弹对象
  99.     for i in del_bullets:
  100.         bullet_list.remove(i)
  101.     # 移动敌方飞机
  102.     for each in range(len(enemy_aircraft_list)):
  103.         new_enemy_aircraft = enemy_aircraft_list[each].move(0, 1)
  104.         enemy_aircraft_list[each] = new_enemy_aircraft
  105.         # 碰撞检测
  106.         x_distance = (our_aircraft_rect.w / 2) + (new_enemy_aircraft.w / 2)
  107.         y_distance = (our_aircraft_rect.h / 2) + (new_enemy_aircraft.w / 2)
  108.         x1 = new_enemy_aircraft.x + (new_enemy_aircraft.w / 2)
  109.         y1 = new_enemy_aircraft.y + (new_enemy_aircraft.h / 2)
  110.         x2 = our_aircraft_rect.x + (our_aircraft_rect.w / 2)
  111.         y2 = our_aircraft_rect.y + (our_aircraft_rect.h / 2)
  112.         if abs(x1 - x2) <= x_distance and abs(y1 - y2) <= y_distance:
  113.             print('撞死了')


  114.         screen.blit(enemy_aircraft, new_enemy_aircraft)
  115.     move_times += 1
  116.     screen.blit(our_aircraft, our_aircraft_rect)
  117.     fcolck.tick(50)
  118.     # 更新窗口
  119.     pygame.display.update()
复制代码

由于以上是用两个矩形的中心点来判段是否发现碰撞,但是这样的检测还不够精准,比如以下图中的情况也会被判定撞死了
捕22获.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-1-8 18:02:20 | 显示全部楼层
这样写法的碰撞检测会检测飞机图片在透明部分和敌机的透明部分是否相撞,建议你使用对象把敌机和我方飞机的透明部分的collide_mask定义出来再用pygame.sprite.spritecollide进行检测
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-13 13:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表