接着昨天的程序继续写下去,昨天我们已经绘制了好了挡板并且实现了挡板对键盘的响应使之能够根据按键进行移动。今天我们开始绘制砖块。那么大概的思路是将所有砖块定义为精灵,然后全部添加进一个精灵组里面。这样方便后面去做砖块和球的冲突判断。
这里我使用了surface.subsurface(rect)这个方法,给砖块进行贴图。我们先绘制一个砖块,来看看代码功能是否正常。其实代码非常简单。
class Block(Sprite):
def __init__(self,screen):
super().__init__()
self.screen = screen
self.image = pygame.image.load('Block.png')
self.rect = self.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.rect = self.frame_rect
self.frame = 0
self.last_frame = 7
def update(self):
self.block_image = self.image.subsurface(self.frame_rect)
def blitme(self):
self.screen.blit(self.block_image,self.rect)
好了让我们来看看效果怎么样?
那么接下来要做的就是将砖块放入精灵组中,并且将砖块排列好。
这里我用的是数组对砖块进行排列。
其实这里我用的还是一种比较原始的方法,这个在后面有很大的优化空间。首先我来定义一个数组,这个数组用来规划砖块的摆放。其中的数字代表当前砖块的帧,也就是说数字里的数字规定砖块类型。
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)
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
好了,我们来看看效果。
看来效果还可以。 接下来我们就该把球画上去了。
球的代码也很简单,我们来定义一个Ball的类,并且创建实例。确保球能够以一定的速度运行。同时在触碰到屏幕边缘时反弹。
class Ball(Sprite):
def __init__(self,screen):
super().__init__()
self.screen = screen
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
def update(self):
self.rect.x += self.valx
self.rect.y += self.valy
if self.rect.right >= 600 or self.rect.left <= 0:
self.valx = -self.valx
if self.rect.top <= 0 :
self.valy = -self.valy
print(self.valx,self.rect.right,self.rect.left)
def blitme(self):
self.screen.blit(self.image,self.rect)
效果如下:
OK 现在,这个游戏里所有的元素都已经添加完毕了,但是现在,小球、挡板、砖块之间,并不能产生任何的互动,这是因为他们目前还都是独立的精灵,明天我会利用精灵冲突,实现元素之间的互动,从而使这个游戏更趋于完整。
完整代码如下:
#!usr/bin/python
#!coding=utf-8
import pygame,sys,random
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):
super().__init__()
self.screen = screen
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
def update(self):
self.rect.x += self.valx
self.rect.y += self.valy
if self.rect.right >= 600 or self.rect.left <= 0:
self.valx = -self.valx
if self.rect.top <= 0 :
self.valy = -self.valy
print(self.valx,self.rect.right,self.rect.left)
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)
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption('打方块')
paddle = Paddle(screen)
block = Block(screen)
blocks = Group()
ball = Ball(screen)
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
if event.key == pygame.K_RIGHT:
paddle.paddle_right = 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()
ball.update()
ball.blitme()
paddle.blitme()
blocks.draw(screen)
pygame.display.flip()