qin_yin 发表于 2021-1-6 19:23:04

pygame碰撞检测

import pygame
import sys
import random


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

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


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

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

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

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

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

# 子弹列表
bullet_list = []
# 敌机列表
enemy_aircraft_list = []

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

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

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

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

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

move_times = 0
times = 0
run = True
while True:
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
            sys.exit()

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

      if event.type == pygame.MOUSEBUTTONDOWN:
            if our_aircraft_rect.left < event.pos < \
                  our_aircraft_rect.right and our_aircraft_rect.top < event.pos < our_aircraft_rect.bottom:
                click_event = True

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

      if event.type == pygame.MOUSEMOTION and click_event:
            if click_event:
                our_aircraft_rect = our_aircraft_rect.move(event.rel, event.rel)

    if not run:
      print(1)
      continue

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

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

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

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

    if times == 5:
      x = our_aircraft_rect.right - (our_aircraft_rect.w / 2) - 3#(oid_bullet_rect.w / 2 )
      y = our_aircraft_rect.top
      # 生成子弹
      new_bullet = oid_bullet_rect.move(x, y)
      bullet_list.append(new_bullet)
      # 每循环100次生成一个敌机
      while move_times == 100:
            new_aircraft_position = random.choice(), -100
            overlap = False
            for each in enemy_aircraft_list:
                if each.left < new_aircraft_position < each.right:
                  overlap = True
                  break
            else:
                  # 生成敌机
                new_enemy_aircraft = oid_enemy_aircraft_rect.move(new_aircraft_position)
                enemy_aircraft_list.append(new_enemy_aircraft)
                move_times = 0
                break
      times = 0

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

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

    # 移动子弹
    for each in range(len(bullet_list)):
      new_bullet = bullet_list.move(0, -10)
      bullet_list = new_bullet
      screen.blit(bullet, new_bullet)
      if new_bullet.top < 0:
            del_bullets.append(new_bullet)
    times += 1

    # 删除超出窗口范围的子弹对象
    for i in del_bullets:
      bullet_list.remove(i)
    # 移动敌方飞机
    for each in range(len(enemy_aircraft_list)):
      new_enemy_aircraft = enemy_aircraft_list.move(0, 1)
      enemy_aircraft_list = new_enemy_aircraft
      # 碰撞检测
      x_distance = (our_aircraft_rect.w / 2) + (new_enemy_aircraft.w / 2)
      y_distance = (our_aircraft_rect.h / 2) + (new_enemy_aircraft.w / 2)
      x1 = new_enemy_aircraft.x + (new_enemy_aircraft.w / 2)
      y1 = new_enemy_aircraft.y + (new_enemy_aircraft.h / 2)
      x2 = our_aircraft_rect.x + (our_aircraft_rect.w / 2)
      y2 = our_aircraft_rect.y + (our_aircraft_rect.h / 2)
      if abs(x1 - x2) <= x_distance and abs(y1 - y2) <= y_distance:
            print('撞死了')


      screen.blit(enemy_aircraft, new_enemy_aircraft)
    move_times += 1
    screen.blit(our_aircraft, our_aircraft_rect)
    fcolck.tick(50)
    # 更新窗口
    pygame.display.update()

由于以上是用两个矩形的中心点来判段是否发现碰撞,但是这样的检测还不够精准,比如以下图中的情况也会被判定撞死了

zzxzrm 发表于 2021-1-8 18:02:20

这样写法的碰撞检测会检测飞机图片在透明部分和敌机的透明部分是否相撞,建议你使用对象把敌机和我方飞机的透明部分的collide_mask定义出来再用pygame.sprite.spritecollide进行检测{:10_256:}
页: [1]
查看完整版本: pygame碰撞检测