pygame学习笔记-打砖块游戏开发日志(三) 精灵冲突

好了,接着昨天的继续,今天我要实现的是游戏中各个元素的互动,这里用到的是pygame.sprite.collide_rect(firs_sprite,secend_sprite)这个函数,在pygame中提供很丰富的冲突检测方法。具体如下

pygame.sprite.collide_rect() 两个精灵间的矩形冲突检测

pygame.sprite.collide_rect.ratio()上一个函数的变种,可以提供一个参数(浮点数)对碰撞体积进行同比缩放

pygame.sprite.collide_circle()两个精灵之间的圆形检测(如果有radius属性,就使用radius,如果没有那么函数就会自己计算)

pygame.sprite.collide_circle.ratio()上一个函数的变种,可以提供一个参数(浮点数)对碰撞体积进行同比缩放

pygame.sprite.spritecollide() 精灵和组之间的矩形冲突,如果给函数传递True参数,那么所有的冲突精灵都会被删掉。

pygame.sprite.spritecollideany()上一个函数的变种,返回一个布尔值

pygame.sprite.groupcollide() 两个组之间的矩形冲突检测,这个函数返回一个字典,包含所有冲突精灵信息

我估计有写小伙伴和我一样,找了很久都没找到一个圆形,一个矩形的冲突检测函数。是的,他确实没有,我查了很多资料都没有找到。如果那个小伙伴知道的话还不吝赐教。  所以,在这里有两个选择。第一个,使用矩形冲突(当然,这基本上能够满足我们的需求),第二个,就是我们自己写一个冲突检测函数。通过查阅资料我知道了pygame的冲突检测是通过检查精灵的坐标集是否重叠来实现的。 所以,根据这个思路我开始写一个我想要的圆形和矩形之间的冲突检测,不过今天没有写完,这个函数我会单独写一篇博客的。今天先用pygame里带的矩形检测函数。

 

首先我们要检测的是,挡板和球之间的冲突,如果小球碰到挡板,那么小球被反弹。


def collide(first_sprite,secend_sprite):
	collide = pygame.sprite.collide_rect(first_sprite,secend_sprite)
	if collide:
		first_sprite.valy = -first_sprite.valy

然后我们要检测的是,小球和砖块之间的冲突,如果小球碰到砖块,那么删除砖块,同时让小球反弹

def update_block(first_sprite,secend_sprite):
	for sprite in secend_sprite:
		collide = pygame.sprite.collide_rect(first_sprite,sprite)
		if collide:
			secend_sprite.remove(sprite)
			first_sprite.valy = - first_sprite.valy

OK 那么这两个检测就完成了,好了,我们来看看效果。

pygame学习笔记-打砖块游戏开发日志(三) 精灵冲突_第1张图片

好了 似乎还像那么回事。

到此,我们这个打砖块的游戏主题部分算是基本都实现了。接下来我会对游戏进行完善,比如添加积分系统,或者是添加更多的关卡,也或者是使用自己写的冲突检测方法让碰撞更加的精确。

好了今天就先到这里吧,源代码如下

#!usr/bin/python
#!coding=utf-8

import pygame,sys,random,math
from pygame.sprite import Sprite,Group

class Paddle(Sprite):
	def __init__(self,screen):
		super().__init__()
		self.screen = screen
		self.image = pygame.image.load('paddle.png')
		self.rect = self.image.get_rect()
		self.rect.bottom = 490
		self.paddle_left = False
		self.paddle_right = False

	def update(self):
		if self.paddle_left and self.rect.left > 0:
			self.rect.centerx -= 8
		if self.paddle_right and self.rect.right < 600:
			self.rect.centerx += 8

	def blitme(self):
		self.screen.blit(self.image,self.rect)

class Ball(Sprite):
	def __init__(self,screen,paddle):
		super().__init__()
		self.screen = screen
		self.paddle = paddle
		self.image = pygame.image.load('ball.png')
		self.rect = self.image.get_rect()
		self.radius = self.rect.width / 2
		self.valx = 4.5
		self.valy = 2
		self.start = False


	def update(self):
		if  self.start is False:
			self.rect.bottom = self.paddle.rect.top
			self.rect.centerx = self.paddle.rect.centerx
		elif self.start is True:
			self.rect.x += self.valx
			self.rect.y += self.valy
			if self.rect.right >= 600 or self.rect.left <= 0:
				self.valx = -self.valx
			elif self.rect.top <= 0 :
				self.valy = -self.valy


	def blitme(self):
		self.screen.blit(self.image,self.rect)

class Block(Sprite):
	def __init__(self,screen):
		super().__init__()
		self.screen = screen
		self.mast_image = pygame.image.load('Block.png')
		self.rect = self.mast_image.get_rect()
		self.frame_rect = self.rect.copy()
		self.frame_rect.width = self.frame_rect.width / 4
		self.frame_rect.height = self.frame_rect.height / 2
		self.frame = 0 
		self.last_frame = 7
		self.level_01 = (1,3,3,3,1
						,4,1,5,1,4
						,4,1,0,1,4
						,4,1,5,1,4
						,1,3,3,3,1)
		self.level = self.level_01

	def update(self):
		self.frame_rect.x = self.frame % 4 * self.frame_rect.width
		self.frame_rect.y = self.frame // 4 * self.frame_rect.height
		self.image = self.mast_image.subsurface(self.frame_rect)
		self.rect = self.frame_rect
		self.rect.x = 0
		self.rect.y = 0

	def blitme(self):
		self.screen.blit(self.block_image,self.rect)

def collide(first_sprite,secend_sprite):
	collide = pygame.sprite.collide_rect(first_sprite,secend_sprite)
	if collide:
		first_sprite.valy = -first_sprite.valy
def update_block(first_sprite,secend_sprite):
	for sprite in secend_sprite:
		collide = pygame.sprite.collide_rect(first_sprite,sprite)
		if collide:
			secend_sprite.remove(sprite)
			first_sprite.valy = - first_sprite.valy

pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption('打方块')
paddle = Paddle(screen)
block = Block(screen)
blocks = Group()
ball = Ball(screen,paddle)
for pos in block.level:
	block_wall = Block(screen)
	block_wall.frame = pos
	block_wall.update()
	blocks.add(block_wall)
x = 0
y = 0 

for bx in blocks:
	bx.rect.x += (x+50)
	x += 100
	bx.rect.y += (y+30)
	if bx.rect.x >= 400:
		y += 20
		x = 0
timer = pygame.time.Clock()

while True:
	timer.tick(50)
	ticks = pygame.time.get_ticks()

	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			sys.exit()
		elif event.type == pygame.KEYDOWN:
			if event.key == pygame.K_LEFT:
				paddle.paddle_left = True
			elif event.key == pygame.K_RIGHT:
				paddle.paddle_right = True
			elif event.key == pygame.K_SPACE:
				ball.start = True

		elif event.type == pygame.KEYUP:
			if event.key == pygame.K_LEFT:
				paddle.paddle_left = False
			if event.key == pygame.K_RIGHT:
				paddle.paddle_right = False


	screen.fill((224,255,255))
	paddle.update()
	collide(ball,paddle)
	update_block(ball,blocks)
	ball.update()
	ball.blitme()
	paddle.blitme()
	blocks.draw(screen)


	pygame.display.flip()

 

你可能感兴趣的:(pygame,python)