利用pgzero做一个接球的小游戏

说明

pgzero为python的一个用于游戏制作的库,它基于pygame模块

可用如下命令去安装

pip install pygame
pip install pgzero

接下来我们就开始写代码了

制作

参数

新建一个define.py的文件,定义一系列常量

#窗口标题
WINDOW_TITLE = "Don't Drop It"
#窗口(宽,高)
WINDOW_SIZE = (800,600)
#背景颜色
WINDOW_BACKGROUNT_COLOR = 'white'

图形

我们新建一个名为actors.py的文件

并导入模块

import pgzrun
import pygame.rect
import define
import random

小球类

建立一个填充颜色的圆形图形的类(小球)

class Ball:
    def __init__(self):
        #球的初始位置
        self.init_pos = (define.WINDOW_SIZE[0]//2,define.WINDOW_SIZE[1]//2)
        #球的位置
        self.x,self.y = self.init_pos
        #球的半径
        self.r = 20
        #球的颜色
        self.color = 'blue'
        #球的速度
        self.speed_x = random.sample([4,-4,-4],1)[0]
        self.speed_y = 4

    #绘制
    def show(self,surface):
        surface.draw.filled_circle((self.x,self.y),self.r,self.color)

    #动画
    def action(self):
        #移动
        self.y = self.y + self.speed_y
        self.x = self.x+self.speed_x
        #当球触碰边界
        if self.y >= define.WINDOW_SIZE[1]-self.r or self.y <= self.r:
            self.speed_y = -self.speed_y
        if self.x >= define.WINDOW_SIZE[0]-self.r or self.x<=self.r:
            self.speed_x = -self.speed_x

    #碰撞改变方向
    def changeDirect(self):
        lst_x = [1,-1,-self.speed_x,self.speed_x,5,-5,-self.speed_x,self.speed_x,5,-5]
        ra_num = random.randint(0,len(lst_x)-1)
        self.speed_x = lst_x[ra_num]

        lst_y = [-3,-4,-5,-3,-4]
        ra_num = random.randint(0, len(lst_y) - 1)
        self.speed_y = lst_y[ra_num]

木板类

玩家控制的木板的类

class Bar:
    def __init__(self):
        #宽度和高度
        self.width = define.WINDOW_SIZE[0]/6
        self.height = define.WINDOW_SIZE[1]/30
        #初始位置
        self.init_pos =  (define.WINDOW_SIZE[0]//2,define.WINDOW_SIZE[1]*0.7)
        self.x = self.init_pos[0]
        #颜色
        self.color = 'red'


    #绘制
    def show(self,surface):
        if self.x >= define.WINDOW_SIZE[0]-self.width:
            self.x = define.WINDOW_SIZE[0]-self.width
        if self.x<=0:
            self.x = 0
        box = pygame.rect.Rect((self.x,self.init_pos[1]),(self.width,self.height))
        surface.draw.filled_rect(box,self.color)

主程序

游戏所用的图形已经定义了,接下来该利用这些图形进行一系列的交互了

首先导入模块

import pgzrun
import pygame,sys
import define
import actors
from tkinter import messagebox

将我们能定义的图形对象实例化

#创建游戏对象
ball = actors.Ball()
bar = actors.Bar()

设置窗口大小

TITLE = define.WINDOW_TITLE
WIDTH, HEIGHT = define.WINDOW_SIZE

碰撞检测,此处我们自己来完成碰撞检测

#碰撞检测
def actorsAcol():
    if ball.y == bar.init_pos[1] and bar.x <= ball.x and ball.x<=bar.x+bar.width:
        ball.changeDirect()

判断游戏结束

#判断游戏结束
def judgeGameOver():
    if ball.y+ball.r*2 >= define.WINDOW_SIZE[1]:
        pygame.quit()
        messagebox.showinfo('GameOver','GameOver')
        sys.exit()

下面的函数为pgzrun预留出的接口的,我们只需写函数的具体实现即可,无需手动调用

绘制图形

#pgzurn绘制函数,无需手动调用,只需定义即可(名称必须为draw)
def draw():
    screen.fill(define.WINDOW_BACKGROUNT_COLOR)
    ball.show(screen)
    bar.show(screen)

刷新帧

#pgzurn刷新函数
def update():
    ball.action()
    actorsAcol()
    judgeGameOver()

获取鼠标位置传给 bar对象

#pgzurn获取鼠标位置
def on_mouse_move(pos):
    bar.x = pos[0]-bar.width//2

程序入口

pgzrun.go()

注意:pgzrun.go()不能与if __name__ == '__main__':同时使用,否则会创建窗口失败,至于原因我也不知道为什么,可能跟这个模块的实现方式有关

运行

  • 主窗口

  • 游戏结束

扩展

这个游戏还可以添加障碍物类和分数结算功能,其实现原理与碰撞检测跟Bar类相似,这里不过多叙述了

开源

传送门:Github

最后修改:2022 年 05 月 12 日
如果觉得我的文章对你有用,请随意赞赏