第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)

我们已经学会了Pygame 的事件、Pygame 图片的转换以及移动、基本的图形绘制、透明度调整这些内容。但距离我们真正的实现一个小游戏还差一个重要的环节,那就是碰撞检测,在讲碰撞检测之前,我们需要补充一个新的知识点,叫做动画精灵。

动画精灵是指在游戏开发中,那些被赋予灵魂的事物,像前面例子中的小猪。

在真正的游戏开发中,远远不止只有一个精灵,数量随时都会发生变化,比如说:敌人不断地出现以及被消灭,它们的移动轨迹也并不都是一样的,既然移动轨迹不同,就一定会发生碰撞,这就说明我们的精灵还要支持碰撞检测,碰撞检测是游戏开发中一个重要的环节。

在此之前,我们一直使用面向过程的思维方式在写代码,先载入一张图片,构造一条小猪,然后对各种事件进行按顺序的处理,让小猪可以依照我们的想法去移动、去撞墙,我们的代码也越来越完善了。但是,这种思维方式有一定的局限性,比方说,你的精灵多起来了,你的小猪一多,那你就需要花很多时间去考量大量重复的代码应该如何去部署才能使得你的代码更优美,语句之间不会产生冲突,然后你就焦头乱额了。

所以现在我们来学习面向对象的游戏开发思维是怎样的。

从今天开始,这几节课,我来带大家完成一个小游戏来学习新的知识,同时,体验一个游戏开发的过程,这个小游戏的名字叫做 Play TheBall。

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)    至此,游戏结束!

以下是游戏素材:

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)
第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)
接下来我们先完成基础的操作,就是生成五个球,然后进行随机移动

from pygame.locals import *
from random import *
import pygame
import sys

class Ball(pygame.sprite.Sprite) :  #继承动画精灵基类
    def __init__ (self,imgae,position,speed,bg_size) :
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(imgae).convert_alpha()   
        self.rect = self.image.get_rect()   #获得球的尺寸
        self.rect.left , self.rect.top = position   #将出现的位置赋给球
        self.speed = speed  #设置速度
        self.width , self.height = bg_size[0] , bg_size[1]  #获得活动边界,就是背景的边界

    def move(self):
        self.rect = self.rect.move(self.speed)  #根据自身的速度进行移动

def main() :
    pygame.init()

    bg_image = r"D:\Code\Python\Pygame\pygame6:动画精灵\background.png"
    ball_image = r"D:\Code\Python\Pygame\pygame6:动画精灵\gray_ball.png" 
    
    running = True  #为了以后而已有多种方法退出程序
    
    bg_size = width , height = 1024 , 681       #背景大小
    screen = pygame.display.set_mode(bg_size) # 设置背景大小
    background = pygame.image.load(bg_image).convert_alpha()       #画背景

    balls = []

    for i in range (5) :    #生成5个球
        position = randint (0,width-100) ,  randint(0,height-100)   #要减去100是因为球图片尺寸的大小为100,随机生成位置
        speed  = [ randint (-10,10) , randint(-10,10) ]
        ball  = Ball(ball_image,position,speed,bg_size)  #生成球的对象
        balls.append(ball)  #将所有的球对象添加到类表中,方便管理
        
    clock = pygame.time.Clock()    #生成刷新帧率控制器

    while running :
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()

        screen.blit(background, (0, 0)) #将背景画到screen上

        for each in balls:  #每个球进行移动并重新绘制
            each.move()
            screen.blit(each.image, each.rect)

        pygame.display.flip()
        clock.tick(30)

if __name__ == "__main__":
    main()

第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)
这时圆球已经会到处游走,但是跑着跑着跑出背景区域,因为没有给他设置边界

from pygame.locals import *
from random import *
import pygame
import sys

class Ball(pygame.sprite.Sprite) :  #继承动画精灵基类
    def __init__ (self,imgae,position,speed,bg_size) :
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(imgae).convert_alpha()   
        self.rect = self.image.get_rect()   #获得球的尺寸
        self.rect.left , self.rect.top = position   #将出现的位置赋给球
        self.speed = speed  #设置速度
        self.width , self.height = bg_size[0] , bg_size[1]  #获得活动边界,就是背景的边界

    def move(self):
        self.rect = self.rect.move(self.speed)  #根据自身的速度进行移动

        if self.rect.right < 0:    #图片的右边已经超出边界的左边,即整个球已经出界
            self.rect.left = self.width    #让他从右边界回来
        if self.rect.bottom < 0:    #图片的底已经超出边界的上面
            self.rect.top = self.height   #让他从底部回来
        if self.rect.left > self.width:   #图片的左边已经超出边界的右边
            self.rect.right = 0     #让他从左边回来
        if self.rect.top > self.height:  #如果图片的顶部已经超出边界的底部
            self.rect.bottom = 0    #让他从顶部回来

def main() :
    pygame.init()

    bg_image = r"D:\Code\Python\Pygame\pygame6:动画精灵\background.png"
    ball_image = r"D:\Code\Python\Pygame\pygame6:动画精灵\gray_ball.png" 
    
    running = True  #为了以后而已有多种方法退出程序
    
    bg_size = width , height = 1024 , 681       #背景大小
    screen = pygame.display.set_mode(bg_size) # 设置背景大小
    background = pygame.image.load(bg_image).convert_alpha()       #画背景

    balls = []

    for i in range (5) :    #生成5个球
        position = randint (0,width-100) ,  randint(0,height-100)   #要减去100是因为球图片尺寸的大小为100,随机生成位置
        speed  = [ randint (-10,10) , randint(-10,10) ]
        ball  = Ball(ball_image,position,speed,bg_size)  #生成球的对象
        balls.append(ball)  #将所有的球对象添加到类表中,方便管理
        
    clock = pygame.time.Clock()    #生成刷新帧率控制器

    while running :
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()

        screen.blit(background, (0, 0)) #将背景画到screen上

        for each in balls:  #每个球进行移动并重新绘制
            each.move()
            screen.blit(each.image, each.rect)

        pygame.display.flip()
        clock.tick(30)

if __name__ == "__main__":
    main()

这个时候加了约束框之后,就不会再发生一去不回来的效果,而是会从另一边穿出
第085讲: Pygame:动画精灵 | 学习记录(小甲鱼零基础入门学习Python)