Pygame浅析动画精灵和碰撞检测实现方法
1、复习上节课做的一个简单的动画:
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode([640, 480])
screen.fill([255, 255, 255])
ball = pygame.image.load("beach_ball.png")
x = 0
y = 100
speed = 50
yspeed = 50
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit(0)
pygame.draw.rect(screen, [255, 255, 255], [x, y, 90, 90])
x += speed
y += yspeed
if x + 90 > 640:
speed = -speed
if x < 0:
speed = -speed
if y + 90 > 480:
yspeed = -yspeed
if y < 0:
yspeed = -yspeed
screen.blit(ball, [x, y])
pygame.display.flip()
pygame.time.delay(100)
这个程序可以在整个窗口中进行小球动画的演示
2、将之整理成用类来抽象出球及相应运动
现在我们将这里面的小球提取出来,将之包装成一个类,将小球的移动用一个函数move来表达,
那么这个小球首先会有变量image,就是从物理图片中加载入内存的变量,然后应该有一个大小size,还有一个位置point,这两个可以合并为rect(x, y, width, height),还有一个表示左右移动的速度和上下移动的速度speed[x,y]
代码如下:
import pygame
class MyBall:
def __init__(self, image_file, point, speed):
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = point
self.speed = speed
移动的逻辑是:每次移动speed的距离(speed指的是向横移动x,向纵移动y)并更新rect,若到最左边或是最右边,则speed的x方向取反,若到最上边或最下边,speed的y方向取反
代码如下:
size = width, height = 640, 480
def move(self):
self.rect = self.rect.move(self.speed)
if self.rect.left < 0 or self.rect.right > width:
self.speed[0] = -self.speed[0]
if self.rect.top < 0 or self.rect.bottom > height:
self.speed[1] = -self.speed[1]
这样,我们就完成了球的定义和移动的逻辑
下面我们再来进行小球动画跑起来:
1)恢复背景
2)移动球并更新位置
3)在新位置上画出球
4)将球打印到屏幕上
5)延时恰当的时间
代码如下:
def run(ball):
screen.fill([255, 255, 255])
ball.move()
screen.blit(ball.image, ball.rect)
pygame.display.flip()
pygame.time.delay(20)
然后我们将这个类运行起来
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
image_file = "beach_ball.png"
ball = MyBall(image_file, width/2, height/2, [2, 2])
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
run(ball)
3、利用前面抽象出来对象同时动画9个小球:
需改动的代码:
def run(balls):
screen.fill([255, 255, 255])
for ball in balls:
ball.move()
screen.blit(ball.image, ball.rect)
pygame.display.flip()
pygame.time.delay(20)
balls = []
for row in range(3):
for column in range(3):
ball = MyBall(image_file, [180*row+10, 180*column+10], [2, 2])
balls.append(ball)
4利用动画精灵类进行碰撞检测:
动画精灵的基本属性:
1)图像
2)矩形区
让球类继承于动画精灵类,就可以使用spritecollide进行碰撞检测
class MyBall(pygame.sprite.Sprite):
def __init__(self, image_file, point, speed):
pygame.sprite.Sprite.__init__(self)
def run(balls):
screen.fill([255, 255, 255])
for ball in balls:
ball.move()
screen.blit(ball.image, ball.rect)
for ball in balls:
balls.remove(ball)
if pygame.sprite.spritecollide(ball, balls, False):
ball.speed[0] = -ball.speed[0]
ball.speed[1] = -ball.speed[1]
balls.append(ball)
pygame.display.flip()
pygame.time.delay(20)
说明:由于这儿的碰撞检测是检的矩形,所以看到有些没有实际碰到也发生了检测
最后附上课堂上改进后的全部代码:
import pygame, sys
class MyBall(pygame.sprite.Sprite):
def __init__(self, point, speed):
pygame.sprite.Sprite.__init__(self) #####
self.image = pygame.image.load("beach_ball.png")
self.rect = self.image.get_rect()
self.rect.left = point[0]
self.rect.top = point[1]
self.speed = speed
def move(self):
self.rect = self.rect.move(self.speed)
if self.rect.right > width or self.rect.left < 0:
self.speed[0] = -self.speed[0]
if self.rect.bottom > height or self.rect.top < 0:
self.speed[1] = -self.speed[1]
screen.blit(self.image, self.rect) # 显示
def peng(self, balls):
balls.remove(self)
if pygame.sprite.spritecollide(self, balls, False):
self.speed[0] = -self.speed[0]
self.speed[1] = -self.speed[1]
balls.append(self)
pygame.init()
size = width,height = 640, 480
screen = pygame.display.set_mode(size)
screen.fill([255, 255, 255])
balls = []
for row in range(3):
for col in range(3):
speed = [2, 2]
point = [row * 180 + 10, col * 180 + 10]
ball = MyBall(point, speed)
balls.append(ball)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill([255, 255, 255])
for ball in balls:
ball.move()
for ball in balls:
ball.peng(balls)
pygame.display.flip()
pygame.time.delay(50)
到此这篇关于Pygame浅析动画精灵和碰撞检测实现方法的文章就介绍到这了,更多相关Pygame动画精灵和碰撞检测内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341