在游戏开发中,碰撞检测是一种用于确定游戏中物体是否相互接触或碰撞的技术。这些物体可以是游戏中的角色、道具、障碍物、子弹等。碰撞检测的主要目的是检测游戏中的物体之间是否发生碰撞,以便触发适当的游戏逻辑、处理碰撞效果或改变物体的状态。
1. 碰撞处理
游戏中每个对象都会存在 bbox 对象,我们通过判断不同物体之间的 bounding box 是否相交来确定两个对象是否发生碰撞,然后进行相应的处。游戏中有如下 4 种情况进行碰撞判断,处理:
- 英雄飞机子弹 <—> 敌机序列,英雄子弹和敌机消失
- 英雄飞机子弹 <—> 敌机子弹,英雄飞机子弹和敌机子弹消失
- 英雄飞机 <—> 敌机序列,敌机消失
- 英雄飞机 <—> 敌机子弹,敌机子弹消失
class MainScene: # 碰撞检测 def detect_conlision(self): # 敌机和英雄子弹 for bullet in self.hero.bullets.bullet_list: if not bullet.visible: continue for enemy in self.enemy.enemies: if not enemy.visible or not bullet.visible: continue if pygame.Rect.colliderect(bullet.bbox, enemy.bbox): bullet.set_unused() enemy.set_unused() # 敌机和英雄飞机 for enemy in self.enemy.enemies: if not enemy.visible: continue if pygame.Rect.colliderect(self.hero.bbox, enemy.bbox): enemy.set_unused() # 敌机子弹和英雄飞机 for enemy in self.enemy.enemies: if not enemy.bullet.visible: continue if pygame.Rect.colliderect(self.hero.bbox, enemy.bullet.bbox): enemy.bullet.set_unused() # 敌机子弹和英雄子弹 for enemy in self.enemy.enemies: if not enemy.bullet.visible: continue for bullet in self.hero.bullets.bullet_list: if not bullet.visible: continue if pygame.Rect.colliderect(bullet.bbox, enemy.bullet.bbox): enemy.bullet.set_unused() bullet.set_unused()
2. 战斗数据
首先,我们在 MainScene 类的 init 函数中增加几个变量用于统计战斗数据:
class MainScene(object): # 初始化主场景 def __init__(self): # 统计战斗数据 self.defeat_count = 0 # 击败敌机数 self.damage_count = 0 # 被击中次数 self.impact_count = 0 # 被撞击次数
并在碰撞处理函数中,统计相关数据。然后,在 MainScene 类中新增 draw_battle_data 函数用于在窗口中绘制战斗数据:
class MainScene(object): def draw_battle_data(self): # 使用 SimHei 字体,并设置 16 号大小 font = pygame.font.Font('source/fonts/SimHei.ttf', 16) text = f"击毁数:{self.defeat_count} 被击中:{self.damage_count} 被撞击:{self.impact_count}" # 文字内容、抗锯齿、颜色 text = font.render(text, True, (255, 255, 255)) # 绘制文本内容 self.scene.blit(text, (150, 20))
最后,在 MainScene 类中的 draw_elements 函数中调用 draw_battle_data 函数即可。
注意:在绘制时,默认中文乱码,我们在这里加载了 SimHei 支持中文的字体。