目标:实现子弹击中飞机的碰撞检查
子弹是个矩形,飞机也是矩形,只要简单是使用pygame.Rect.colliderect()这个函数就能判断是否碰撞了。
- pygame.Rect.colliderect() — 检测两个 Rect 对象是否重叠,碰了返回 True,否则返回 False
假设子弹的位置 bullet_rect ,飞机的位置 plane_rect
if pygame.Rect.colliderect(bullet.rect, plane_rect):
也可以用
bullet_rect.colliderect(plane_rect)
效果是一样的。
子弹或者飞机逃逸屏幕判断,也是同样的道理,屏幕也是一个Rect,用碰撞检查下,如果没碰撞了,就是逃逸了,很简单吧。
# 用一条语句实现了跑出屏幕的检查,我真是佩服我自己
if not self.rect.colliderect(self.main_scent.get_rect()):
print(self.rect)
看电影去了,演示代码待续。
bullet.py里,加入超出屏幕的检查,超过就自动退出所有 sprite.Grout()
import pygame
import math
import random
class Bullet(pygame.sprite.Sprite):
def __init__(self,scene):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('images/bullet0.png')
self.rect = self.image.get_rect()
self.x_speed = 0.00
self.y_speed = 2.00
self.angle = 0
self.main_scent = scene
#会自动调用
def update(self):
self.rect.x += self.x_speed
self.rect.y += self.y_speed
# 可以用传递 scene来计算屏幕大小,演示用就简单些吧。
# if (self.rect.x < 0 or self.rect.y < 0 or
# self.rect.x >480 or self.rect.y > 860):
# 用一条语句实现了跑出屏幕的检查,我真是佩服我自己
if not self.rect.colliderect(self.main_scent.get_rect()):
print('the bullet is out of screen')
#超过屏幕自动删除
self.kill()
#为了和飞机的位置配合,需要设置初始位置
def set_pos(self,x, y):
self.rect.x = x
self.rect.y = y
# 为了跟踪弹用的
def get_pos(self):
return (self.rect.x,self.rect.y)
def set_speed(self,speed, angle = 0):
self.angle = math.pi * angle/180
self.x_speed = speed * math.cos(self.angle)
self.y_speed = speed * math.sin(self.angle)
main.py里加入两种碰撞检查语句。
import pygame
from sys import exit
from bullet import *
#定义屏幕类
class MainScene(object):
#初始化
def __init__(self):
pygame.init()
self.size = (480,860)
self.scene = pygame.display.set_mode(self.size)
pygame.display.set_caption("自学飞机大战--V0.98")
self.image = pygame.image.load('./images/bg.png')
self.quit_image = pygame.image.load('./images/quit.png')
self.restart_image = pygame.image.load('./images/restart.png')
self.quit_rect = self.quit_image.get_rect()
self.restart_rect = self.restart_image.get_rect()
bullet = Bullet(self.scene)
bullet.set_speed(3,45)
self.bullet_sprite = pygame.sprite.Group()
self.bullet_sprite.add(bullet)
#绘制各个元素
def drawElements(self):
self.scene.blit(self.image,(0,0))
self.restart_rect.left, self.restart_rect.top = 150,150
self.scene.blit(self.restart_image,self.restart_rect)
self.quit_rect.left, self.quit_rect.top = 150, 300
self.scene.blit(self.quit_image,self.quit_rect)
def collideEvent(self):
for bullet in self.bullet_sprite:
#用rect的函数来检查
if bullet.rect.colliderect(self.quit_rect):
print('collide quit image')
# 用pygame的函数来检查,两种方法都可以。
if pygame.Rect.colliderect(bullet.rect, self.restart_rect):
print('collide restart image')
#处理键盘和鼠标相应
def handleEvent(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
# 获得鼠标点击三个按钮的点击情况(1,0,0)
# 如果第一个参数为1,表示左键被按下
# 如果第二个参数为1,表示滚轮被按下
# 如果第三个参数为1,表示右键被按下
buttons = pygame.mouse.get_pressed()
# 我们只处理左键被按下的情况
if buttons[0]:
# 注释的代码为跟踪弹的实现方式
# 获得拖动鼠标的拖动位置
pos_mouse = pygame.mouse.get_pos()
# print (self.quit_rect,pos_mouse)
if self.quit_rect.collidepoint(pos_mouse):
print('quit')
if self.restart_rect.collidepoint(pos_mouse):
print('restart')
# if (self.quit_rect.left < pos_mouse[0] < self.quit_rect.right
# and self.quit_rect.top < pos_mouse[1] < self.quit_rect.bottom):
# print ("quit")
#运行主程序
def runScene(self):
while True:
self.drawElements()
self.handleEvent()
self.collideEvent()
self.bullet_sprite.draw(self.scene)
self.bullet_sprite.update()
pygame.display.update()
# pygame.time.delay(100)
if __name__ == '__main__':
mainScene = MainScene()
mainScene.runScene()
还有其他的碰撞检查方式,可以自行阅读官方文档