python使用PyGame实现打砖块游戏

 更新时间:2023年12月22日 08:55:02   作者:微小冷  
打砖块也是一个非常经典的小游戏,玩法大致如下,用一个小车接一个小球,然后反射小球,使之打在砖块上,当小球碰到砖块之后,则砖块被消掉,逻辑十分清晰,本文将给大家介绍了python使用PyGame实现打砖块游戏,文中有详细的代码示例供大家参考,需要的朋友可以参考下

效果

在设计游戏之前,先设置一些常量,供后续选用。

import pygame
import random

WIDTH, HEIGHT = 640, 400 # 游戏窗口尺寸

SIZE = 20   # 砖块尺寸

# 颜色定义
C_PADDLE = (120, 120, 120)
C_BRICK = (0, 128, 55)
C_BALL = (233,233,233)
BLACK = (25, 25, 25)
RED = (255, 0, 0)

砖块实现

可玩性比较高的打砖块游戏,其砖块有着不同的属性,有一些砖块打不掉,有些在打碎之后会掉落一些东西,接住之后可以发生裂变反应。考虑到作为一个初学者小游戏,我们先让所有砖块有着相同的特质,但为了日后的扩展,所以用类来实现砖块。

作为一个砖块来说,只有三个属性,坐标( x , y ) (x,y)(x,y)以及边长size,又因为砖块不会动,所以这些参数仅作为传入的参数,而无需调用。而砖块唯一的行为,就是与小球发生碰撞,所以需要有一个判定方法。最终,砖块类实现如下

class Brick:
    def __init__(self, col, row, dy=50, size=SIZE, color=C_BRICK):
        x = col*size
        y = row*size + dy
        self.color = color
        self.rect = pygame.Rect(x, y, size, size)

    def hitRect(self, rect):
        return self.rect.colliderect(rect)

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, self.rect)

在实际应用中,显然不可能只有一个砖块,所以在Brick中设置一个静态方法,用以生成随机的砖块,其生成逻辑是,随机生成一个数,如果这个数大于0.3,那么就在当前位置生成一个砖块,否则跳过。

@staticmethod
def randBricks(dense=0.3, size=SIZE, xEdge=WIDTH):
    bricks = []
    for row in range(5):
        col = 0
        while (col+1)* size < xEdge:
            bricks.append(Brick(col, row))
            col += 1 if random.random()>dense else 2
    return bricks

小车

和砖块相比,小车只多了一个左右移动的功能,即点击左箭头,相左移动,点击右箭头,向右移动。而且其移动的范围不能超出x轴的边界,其小车类实现如下。

class Car:
    def __init__(self, width, height=10, speed = 10, color=C_PADDLE,
                 xEdge=WIDTH, yEdge=HEIGHT):
        self.width, self.height = width, height
        self.xEdge = xEdge
        self.color = color
        self.x = (xEdge - width) // 2
        self.y = yEdge - 30
        self.vx = speed     # 只有x方向的速度

    def move(self, keys):
        if keys[pygame.K_LEFT] and self.x > 0:
            self.x -= self.vx
        if keys[pygame.K_RIGHT] and self.x < self.xEdge - self.width:
            self.x += self.vx

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))

小球

相比于不动的砖块,只需要左右移动的小车,小球的行为会稍微复杂一点,不仅需要考虑和墙壁以及小车的碰撞,也要考虑和砖块的碰撞。在这个过程中,需要进行诸多边界的判断,所以除了小球的半径和位置之外,设置L,R,U,D四个函数,用于计算其左右上下的边界位置。小球类实现如下。

class Ball:
    # xEdge, yEdge分别是水平核垂直方向的边缘
    def __init__(self, radius, speed=5,
                 xEdge=WIDTH, yEdge=HEIGHT, color=C_BALL):
        self.r = radius
        self.xEdge, self.yEdge = xEdge, yEdge
        self.color = color
        self.x = random.randint(radius, xEdge - radius)
        self.y = random.randint(yEdge//3, yEdge // 2)
        self.vx = self.vy = speed

    L = lambda self : self.x - self.r
    R = lambda self : self.x + self.r
    U = lambda self : self.y + self.r
    D = lambda self : self.y - self.r
    xy = lambda self : (self.x, self.y)

    def move(self):
        self.x += self.vx
        self.y += self.vy

    def rect(self):
        d = self.r * 2
        return pygame.Rect(self.L(), self.D(), d, d)

    # 撞击边缘
    def hitEdge(self):
        if self.L() < 0 or self.R() > self.xEdge:
            self.vx *= -1
        if self.U() < 0:
            self.vy *= -1
        elif self.U() > self.yEdge:
            return True
        return False

    # 撞击car
    def hitCar(self, car):
        if self.y + self.r >= car.y and car.x <= self.x <= car.x + car.width:
            self.vy *= -1

    def hitBricks(self, bricks):
        for brick in bricks[:]:
            if brick.hitRect(self.rect()):
                self.vy *= -1
                bricks.remove(brick)
                return 1
        return 0

    def draw(self, screen):
        pygame.draw.circle(screen, self.color, (self.x, self.y), self.r)

其中,hitBricks的返回值为1时,表示击中了砖块,否则表示未击中。

初始化和主循环

在具体写主循环之前,先设置一个GameOver的显示函数,这个函数的出镜率很高,在之前的实战中也用到过。

def drawGamerOver(screen, font, width=WIDTH, height=HEIGHT):
    w, h = font.size('GAME OVER')
    msg = font.render('GAME OVER', True, RED)
    screen.blit(msg, ((width - w) // 2, (height - h) // 2 - 40))

    w, h = font.size('点击任意位置,再来一局')
    msg = font.render('点击任意位置,再来一局', True, RED)
    screen.blit(msg, ((width - w) // 2, (height - h) // 2 + 40))

然后是初始化,主要包括小球、小车、砖块的初始化,以及PyGame的初始化。

def init():
    ball = Ball(10)
    car = Car(100)
    bricks = Brick.randBricks()
    return ball, car, bricks

# 初始化 Pygame
pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
font = pygame.font.Font(r"SimHei.ttf", 30)
pygame.display.set_caption("打砖块")


# 初始化弹球、板、砖块的位置
ball, car, bricks = init()
score, running, gameOver = 0, True, False

其running用于调控主循环,gameOver则表示当前游戏失败,若失败,则跳入游戏失败的窗口。最后,主循环如下

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False
            break
        if gameOver:
            ball, car, bricks = init()
            gameOver, score = False, 0

    if not running:
        break

    if not gameOver:
        keys = pygame.key.get_pressed()
        car.move(keys)      # 移动小车
        ball.move()         # 移动弹球
        ball.hitCar(car)
        if ball.hitEdge():
            bricks = Brick.randBricks()  # 重新初始化游戏
            gameOver = True  # 游戏结束

        score += ball.hitBricks(bricks)

    # 清空窗口
    window.fill(BLACK)

    if not gameOver:
        car.draw(window)
        ball.draw(window)
        for brick in bricks:
            brick.draw(window)
        # 显示分数
        score_text = font.render(f"Score: {score}", True, C_BRICK)
        window.blit(score_text, (20, 20))
    else:
        drawGamerOver(window, font)

    pygame.display.flip()   # 更新屏幕显示
    pygame.time.delay(30)   # 控制帧率

以上就是python使用PyGame实现打砖块游戏的详细内容,更多关于python PyGame打砖块游戏的资料请关注脚本之家其它相关文章!

相关文章

  • Python 修改CSV文件实例详解

    Python 修改CSV文件实例详解

    这篇文章主要为大家介绍了Python 修改CSV文件实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 利用Python和C语言分别实现哈夫曼编码

    利用Python和C语言分别实现哈夫曼编码

    这篇文章主要为大家详细介绍了如何利用Python和C语言分别实现哈夫曼编码,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-07-07
  • opencv python 图像去噪的实现方法

    opencv python 图像去噪的实现方法

    这篇文章主要介绍了opencv python 图像去噪的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • Python数据处理Pandas库的使用详解

    Python数据处理Pandas库的使用详解

    这篇文章主要为大家详细介绍了pandas库的使用方法,包括数据导入与导出、数据查看和筛选、数据处理和分组操作等,感兴趣的小伙伴可以了解一下
    2023-07-07
  • python数字图像处理之图像的批量处理

    python数字图像处理之图像的批量处理

    这篇文章主要为大家介绍了python数字图像处理之图像的批量处理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 把项目从Python2.x移植到Python3.x的经验总结

    把项目从Python2.x移植到Python3.x的经验总结

    这篇文章主要介绍了把项目从Python2.x移植到Python3.x的经验总结,包括作者所使用的Jinja2框架中一些需要注意的地方,需要的朋友可以参考下
    2015-04-04
  • Python机器学习NLP自然语言处理基本操作精确分词

    Python机器学习NLP自然语言处理基本操作精确分词

    本文是Python机器学习NLP自然语言处理系列文章,带大家开启一段学习自然语言处理 (NLP) 的旅程. 本文主要学习NLP自然语言处理基本操作之如何精确分词
    2021-09-09
  • GPU排队脚本实现空闲触发python脚本实现示例

    GPU排队脚本实现空闲触发python脚本实现示例

    有的服务器是多用户使用,GPU的资源常常被占据着,很可能在夜间GPU空闲了,但来不及运行自己的脚本。如果没有和别人共享服务器的话,自己的多个程序想排队使用GPU,也可以用这个脚本
    2021-11-11
  • Python干货实战之逆向登录世界上最大的游戏平台Stream

    Python干货实战之逆向登录世界上最大的游戏平台Stream

    有些网页中的数据进行了算法加密 这些算法代码是JavaScript 加密的地方就是在js文件里,我们需要破解这些算法加密 就需要了解这加密的过程 获取加密过程中的代码 然后进行后续的反反爬虫操作
    2021-10-10
  • Python实现数据集划分(训练集和测试集)

    Python实现数据集划分(训练集和测试集)

    这篇文章主要为大家详细介绍了Python是如何实现数据集划分的,分为训练集和测试集,文中的实现方法讲解详细,感兴趣的小伙伴可以了解一下
    2023-05-05

最新评论