如何在碰撞后实现超时/冷却

2024-02-20

我一直在做一个pygame两名玩家尝试将球击入网中的游戏。我的游戏中有一个增强功能,但是,我想要一些增强垫,当它们被收集时,我会获得 +3 增强。在我下面的代码中,有一个巨大的黄色物体,当有人将鼠标悬停在它上面时,他们会得到提升,但他们可以永远停留在上面并获得很多提升。我想要一种方法,让增强垫在被收集后变得不活动 3 秒,并变成灰色。有什么办法吗?

import pygame
from pygame.math import Vector2
import time, datetime
import sys

pygame.font.init()
pygame.init()

WIDTH = 1150
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(
    REDCAR_ORIGINAL, (255, 0, 0), [(0, 30), (50, 20), (50, 10), (0, 0)])
redangle = 180
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redangle = 180
booster = pygame.Surface((50, 150), pygame.SRCALPHA)
booster.fill((255, 255, 0))
booster1 = booster.get_rect(topleft=(0, 340))
boostermask = pygame.mask.from_surface(booster)

redspeed = 5

dx = 0
dy = 0
x = 800
y = 500
redscore = 0

pos_red = Vector2(x,y)
vel_red = Vector2(-redspeed,0)
redrect = redcar.get_rect(center=pos_red)
redangle = 180
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
pos_blue = Vector2(275,300)

# Masks.
mask_red = pygame.mask.from_surface(redcar)

def redboosts():
    global vel_red
    global timer
    global dt
    if timer > 0:
        vel_red.scale_to_length(10)
        timer -= dt

def slowdown():
    vel_red.scale_to_length(5)

timer = 3
dt = 1

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
          if event.key == pygame.K_r:
              # Reset the car to the start position.
              redangle = 180
              redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
              pos_red = Vector2(800, 500)
              vel_red = Vector2(-redspeed, 0)
              redrect = redcar.get_rect(center=pos_red)
              mask_red = pygame.mask.from_surface(redcar)
          #elif event.key == pygame.K_s:
          #    vel_blue.scale_to_length(2)
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                vel_red.scale_to_length(5)
            elif event.key == pygame.K_DOWN:
              vel_red.scale_to_length(5)

    print(timer)

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
              redangle += 5
              vel_red.rotate_ip(-5)
              redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
              redrect = redcar.get_rect(center=redrect.center)
              # We need a new mask after the rotation.
              mask_red = pygame.mask.from_surface(redcar)
    elif keys[pygame.K_RIGHT]:
              redangle -= 5
              vel_red.rotate_ip(5)
              redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
              redrect = redcar.get_rect(center=redrect.center)
              mask_red = pygame.mask.from_surface(redcar)

    if keys[pygame.K_UP]:
              redboosts()
    if keys[pygame.K_DOWN]:
              vel_red.scale_to_length(2)
    if keys[pygame.K_s]:
              vel_blue.scale_to_length(2)

    if y <0:
        y = 10
    if y > 450:
        y = 440
    if x > 480:
        x = 470

    if redrect.top < 0 and vel_red.y < 0:
        redrect.top = 0
        pos_red = Vector2(redrect.center)
    elif redrect.bottom > screen.get_height() and vel_red.y > 0:
        redrect.bottom = screen.get_height()
        pos_red = Vector2(redrect.center)
    if redrect.left < 0 and vel_red.x < 0:
        redrect.left = 0
        pos_red = Vector2(redrect.center)
    elif redrect.right > screen.get_width() and vel_red.x > 0:
        redrect.right = screen.get_width()
        pos_red = Vector2(redrect.center)

    pos_red += vel_red
    redrect.center = pos_red

    offset = booster1[0] - redrect[0], booster1[1] - redrect[1]
    collectboost = mask_red.overlap(boostermask, offset)

    if timer <= 0:
        timer = 0
        vel_red.scale_to_length(5)
        slowdown()

    if collectboost:
        timer += 3
    screen.fill((50,200,50))
    screen.blit(redcar, redrect)
    screen.blit(booster, booster1)

    pygame.display.flip()
    dt = clock.tick(120)/1000
pygame.quit()

还不错,但是让我们使用一些面向对象的编程来稍微整理一下代码。这意味着对数据结构和行为进行分组并利用多态性。既然我们使用 pygame,那么我们就使用它的Sprite https://www.pygame.org/docs/ref/sprite.html类,但现在让我们忽略增强的东西。

我添加了一些评论以进行解释。

import pygame
from pygame.math import Vector2
import time, datetime
import sys

pygame.font.init()
pygame.init()

WIDTH = 1150
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(REDCAR_ORIGINAL, (255, 0, 0), [(0, 30), (50, 20), (50, 10), (0, 0)])

# Everything car related goes into this class
class Car(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.speed = 5
        # since we want to reset the car on a press of a button, 
        # let's have a reset function so we don't have duplicate code
        self.reset()

    def reset(self):
        self.angle = 180
        self.vel = Vector2(-self.speed, 0)
        self.update_image((800, 500))

    def update_image(self, center):
        # since we update the image, rect and mask a lot, 
        # let's do this in a function, also
        self.image = pygame.transform.rotate(REDCAR_ORIGINAL, self.angle)
        self.rect = self.image.get_rect(center=center)
        self.mask = pygame.mask.from_surface(self.image)

    def update(self):
        # basic input handling
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
              self.angle += 5
              self.vel.rotate_ip(-5)
        elif keys[pygame.K_RIGHT]:
              self.angle -= 5
              self.vel.rotate_ip(5)

        self.update_image(self.rect.center)

        # ensure the car does not go out of screen
        self.rect.move_ip(self.vel)
        self.rect.clamp_ip(pygame.display.get_surface().get_rect())

red_car = Car()
all_sprites = pygame.sprite.Group(red_car)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
          if event.key == pygame.K_r:
              red_car.reset()

    # clean little main loop, yeah
    all_sprites.update()

    screen.fill((50,200,50))

    all_sprites.draw(screen)

    pygame.display.flip()
    dt = clock.tick(120)/1000

pygame.quit()

现在这可行了,让我们Boost班级。由于我们使用类,因此很容易添加多个类。每个人都有自己的状态;我们使用简单的减法来实现超时:

import pygame
from pygame.math import Vector2
import time, datetime
import sys
import pygame.freetype

pygame.font.init()
pygame.init()

WIDTH = 1150
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(REDCAR_ORIGINAL, (255, 0, 0), [(0, 30), (50, 20), (50, 10), (0, 0)])

FONT = pygame.freetype.SysFont(None, 34)

# Everything car related goes into this class
class Car(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.speed = 3
        # since we want to reset the car on a press of a button, 
        # let's have a reset function so we don't have duplicate code
        self.reset()

    def reset(self):
        # if boost is > 0, we can drive faster
        self.boost = 0
        self.angle = 180
        self.vel = Vector2(-self.speed, 0)
        self.update_image((800, 500))

    def update_image(self, center):
        # since we update the image, rect and mask a lot, 
        # let's do this in a function, also
        self.image = pygame.transform.rotate(REDCAR_ORIGINAL, self.angle)
        self.rect = self.image.get_rect(center=center)
        self.mask = pygame.mask.from_surface(self.image)

    def update(self, dt):

        if self.boost > 0:
            self.boost -= dt
        if self.boost < 0:
            self.boost = 0

        # basic input handling
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
              self.angle += 5
              self.vel.rotate_ip(-5)
        elif keys[pygame.K_RIGHT]:
              self.angle -= 5
              self.vel.rotate_ip(5)

        self.update_image(self.rect.center)

        # double the speed if we have boost
        self.rect.move_ip(self.vel * (2 if self.boost else 1))

        # ensure the car does not go out of screen
        self.rect.clamp_ip(pygame.display.get_surface().get_rect())

class Booster(pygame.sprite.Sprite):
    def __init__(self, rect, cars):
        super().__init__()
        rect = pygame.rect.Rect(rect)
        # a simple timeout. We do nothing if timeout > 0
        self.timeout = 0
        self.image = pygame.Surface(rect.size, pygame.SRCALPHA)
        self.image.fill(pygame.color.Color('yellow'))
        self.rect = rect
        self.mask = pygame.mask.from_surface(self.image)
        self.cars = cars

    def update(self, dt):
        disabled = self.timeout > 0

        if disabled:
            self.timeout -= dt
            self.image.fill(pygame.color.Color('grey'))
            FONT.render_to(self.image, (10, 10), str((self.timeout // 1000) + 1), pygame.color.Color('white'))

        if self.timeout < 0:
            self.timeout = 0

        if disabled and self.timeout == 0:
            # let's reactive
            self.image.fill(pygame.color.Color('yellow'))
        if not disabled:
            for car in pygame.sprite.spritecollide(self, self.cars, False, pygame.sprite.collide_mask):
                # let's boost the car
                car.boost += 1000
                # let's deactivate
                self.timeout = 3000
                break

red_car = Car()
cars = pygame.sprite.Group(red_car)
all_sprites = pygame.sprite.OrderedUpdates()

# see how easy it is now to create multiple Booster
for r in [(0, 340, 50, 150), (200, 200, 150, 50), (600, 600, 100, 100)]:
    all_sprites.add(Booster(r, cars))

all_sprites.add(red_car)

dt = 0
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
          if event.key == pygame.K_r:
              red_car.reset()

    # clean little main loop, yeah
    all_sprites.update(dt)

    screen.fill((50,200,50))

    all_sprites.draw(screen)

    pygame.display.flip()
    dt = clock.tick(120)

pygame.quit()

每个助推器有 3 秒的超时时间,并且会助推 1 秒。

我们利用OrderedUpdates https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.OrderedUpdates以正确的顺序绘制我们的精灵,并且spritecollide https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.spritecollide and collide_mask https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.collide_mask用于碰撞检测。

这是我们正在运行的小游戏的糟糕 gif:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在碰撞后实现超时/冷却 的相关文章

  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • 以矢量化方式在另一个 DataFrame 中查找包含值子集的行

    如何匹配此 DataFrame 中的值source car id lat lon 0 100 10 0 15 0 1 100 12 0 10 0 2 100 09 0 08 0 3 110 23 0 12 0 4 110 18 0 32 0
  • 组和平均 NumPy 矩阵

    假设我有一个任意的 numpy 矩阵 如下所示 arr 6 0 12 0 1 0 7 0 9 0 1 0 8 0 7 0 1 0 4 0 3 0 2 0 6 0 1 0 2 0 2 0 5 0 2 0 9 0 4 0 3 0 2 0 1 0
  • 无法使用 BeautifulSoup 和 Requests 抓取下拉菜单

    我想抓取百年灵网站上的产品页面以获取各种信息 示例页面 https www breitling com gb en watches navitimer b01 chronograph 46 AB0127211C1A1 https www b
  • 使用 pandas 将字符串对象转换为 int/float

    import pandas as pd path1 home supertramp Desktop 100 life 180 data csv mydf pd read csv path1 numcigar Never 0 1 5 Ciga
  • numpy:大量线段/点的快速规则间隔平均值

    我沿着一维线有许多 约 100 万个 不规则间隔的点 P 这些标记线段 这样 如果点是 0 x a x b x c x d 则线段从 0 gt x a x a gt x b x b gt x c x c gt x d 等 我还有每个段的 y
  • scikit-learn 和tensorflow 有什么区别?可以一起使用它们吗?

    对于这个问题我无法得到满意的答案 据我了解 TensorFlow是一个数值计算库 经常用于深度学习应用 而Scikit learn是一个通用机器学习框架 但它们之间的确切区别是什么 TensorFlow 的目的和功能是什么 我可以一起使用它
  • reStructuredText:README.rst 未在 PyPI 上解析

    我有一个托管在 Github 和 PyPI 上的 Python 项目 在 Github 上 https github com sloria TextBlob blob master README rst https github com s
  • 在 iPython/pandas 中绘制多条线会生成多个图

    我试图了解 matplotlib 的状态机模型 但在尝试在单个图上绘制多条线时遇到错误 据我了解 以下代码应该生成包含两行的单个图 import pandas as pd import pandas io data as web aapl
  • 如何使用 Celery 多工作人员启用自动缩放?

    命令celery worker A proj autoscale 10 1 loglevel info启动具有自动缩放功能的工作人员 当创建多个工人时 me mypc projects x celery multi start mywork
  • Pandas:将 pytz.FixedOffset 应用于系列

    我有一个带有timestamp列看起来像这样 0 2020 01 26 05 00 00 08 00 1 2020 01 26 06 00 00 08 00 Name timestamp dtype datetime64 ns pytz F
  • 如何使用 django-pyodbc (ubuntu 16.04) 配置数据库设置 Django-MSSQL?

    我是 Django 新手 目前正在尝试使用另一个数据库来保存我的模型 即MS SQL 我的数据库部署在docker容器中 903876e64b67 microsoft mssql server linux bin sh c opt mssq
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 删除 HoloViews 中的 Bokeh 徽标

    是否可以从 HoloViews 生成的图中删除 Bokeh 徽标 没有什么反对的 只是在某些报告中显示它可能没有意义 我知道在 Bokeh 中我可以简单地执行以下操作 p bkp figure p toolbar logo None UPD
  • 在 matplotlib 中绘制多边形的并集[重复]

    这个问题在这里已经有答案了 我正在尝试绘制几个多边形的并集matplotlib 具有一定的 alpha 水平 我当前的代码在交叉点处颜色较深 有没有办法让交叉路口与其他地方的颜色相同 import matplotlib pyplot as
  • 沿轴 0 重复 scipy csr 稀疏矩阵

    我想重复 scipy csr 稀疏矩阵的行 但是当我尝试调用 numpy 的重复方法时 它只是将稀疏矩阵视为对象 并且只会将其作为 ndarray 中的对象重复 我浏览了文档 但找不到任何实用程序来重复 scipy csr 稀疏矩阵的行 我
  • Streamlabs API 405 响应代码

    我正在尝试使用Streamlabs API https dev streamlabs com Streamlabs API 使用 Oauth2 来创建应用程序 因此 首先我将使用我的应用程序的用户发送到一个授权链接 其中包含我的应用程序的客
  • 如何从 nltk 下载器中删除数据/模型?

    我在 python3 NLTK 中安装了一些 NLTK 包 通过nltk download 尝试过它们 但不需要它们 现在想删除它们 我怎样才能删除例如包large grammars来自我的 NLTK 安装 我不想删除完整的 NLTK 安装
  • 在父类中访问子类变量

    我有一个父类和一个继承的子类 我想知道如何访问我的父类中的子类变量 我尝试了这个但失败了 class Parent object def init self print x class Child Parent x 1 x Child Er
  • 使用 SERVER_NAME 时出现 Flask 404

    在我的 Flask 配置中 我将 SERVER NAME 设置为 app example com 之类的域 我这样做是因为我需要使用url for with external网址 如果未设置 SERVER NAME Flask 会认为服务器

随机推荐

  • 如何在 TypeScript 中删除数组项?

    我有一个在 TypeScript 中创建的数组 它有一个用作键的属性 如果我有该密钥 我如何从中删除项目 与 JavaScript 中的方式相同 delete myArray key 请注意 这将元素设置为undefined 更好地使用Ar
  • 如何正确使用drawMyLocation

    我试图用 android 中的默认蓝点向用户显示当前位置 在我的地图页面中 我还有一个显示不同兴趣点的布局 我无法弄清楚要为某些变量添加什么 并且想知道是否有人可以帮助我 这就是我到目前为止用来显示我的位置的方法 Location loca
  • 从完成处理程序返回值 - Swift

    我在实用程序类中使用 loadImage 方法 并且在通过闭包返回图像时遇到一些问题 基本上因为我的代码可能返回图像或错误 所以在调用方法时将其分配给图像属性将不起作用 我在类的方法声明中使用的方法是否错误 或者我应该以不同的方式调用该方法
  • 我的 ffmpeg 输出总是在最后添加额外的 30 秒静音

    这是我用来将 1 个音频和 1 个图像合并为 1 个视频的代码 参数 由于某种原因 无论来源如何 它都会在输出视频的末尾添加 30 秒的静音 我在 Win10 x64 上运行它 安装了最新的 ffmpeg 我检查了代码 但无法确定它在哪里造
  • 自动在句点和逗号后添加空格,同时避免数字

    这是当前的正则表达式 当人们写下以下内容时 我用它来清理句子 你好 我是安德烈斯 对吗 它将自动转换为 你好 我是安德烈斯 对吧 当字符串中有数字时就会出现问题 例子 我有 40 381 32 美元 将转换为 我有 40 381 32 美元
  • 无法找到资源

    我不确切知道这是否是一个错误 但我一直收到运行时 IOException 错误 指出无法找到资源 我正在画布背景中的应用程序 c WPF 中加载一些图像 具体取决于数据库状态 问题是 我无法加载最后一个 按字母顺序排序 文件 例如 我的文件
  • iOS - 缩放和裁剪 CMSampleBufferRef/CVImageBufferRef

    我正在使用 AVFoundation 并从中获取示例缓冲区AVCaptureVideoDataOutput 我可以使用以下方法将其直接写入 videoWriter void writeBufferFrame CMSampleBufferRe
  • Java:获取打印机状态(缺纸/缺纸)

    我是这样打印的 FileWriter imp new FileWriter COM2 while linea br readLine null imp write linea imp write 0x0A 现在我使用端口 COM2 我有一台
  • Unidata 数据库导出 - 如何使用 TO DELIM 添加标题

    在 Unidata 中 将查询转储到分隔文件时 例如 列出 MYFILE 1000 ATB1 ATB2 ATB3 至 DELIM tmp extract txt 是否有任何 UDT OPTIONS 控制是否写入标题行 当前唯一的解决方法涉及
  • 从子线程停止主线程

    我正在编写一个python程序 在主函数中我正在启动一个连续运行的线程 启动线程后 主函数进入 while 循环 连续获取用户输入 如果子线程中出现异常 我也想结束主函数 最好的方法是什么 提前致谢 让线程 控制 其父级并不是一个好的做法
  • 排除日期晚于今天的项目

    我有一个关于 XSLT 的问题 在一个网站上 我有一个简单的日历 显示未来将要发生的事件 但当一个事件完成后 它应该从我的列表中删除 我所说的 完成 是指活动的日期已经过了今天 每个事件都附有日期 看下面的代码
  • 故意依赖 Linq Side Effects 是不好的做法吗?

    像这样的编程模式经常出现 int staleCount 0 fileUpdatesGridView DataSource MultiMerger TargetIds Select id gt FileDatabaseMerger merge
  • 使用 listpreference 并获取密钥有效,但没有“确定”按钮

    我在我的 android 应用程序中使用 listpreference 并获取我的键值 一切都很好并且工作正常 现在你们已经帮助了我 但是 当我的 listpreference 菜单弹出时 它们只包含一个取消按钮 假设用户正在红色 蓝色和绿
  • 在文本文件中附加新行的最佳变体是什么?

    我使用此代码将新行附加到文件末尾 let text New line to string let mut option OpenOptions new option read true option write true option cr
  • JTable 单元格中有两行或多行?

    如何将两行或多行放入一个 JTable 单元格中 我尝试在行尾添加 n 但它不起作用 尝试这样的 HTML lineOne br lineTwo
  • 关于 OpenGL 不变限定符的困惑

    我在翻阅橙皮书 第 3 版 时 在第 9 章中发现了一段关于不变限定符的段落 它说 The 不变的限定符指示编译器并链接到忽略与输出计算不直接相关的表达式和函数 这段话出现在两个类似的代码片段之后 uniform mat4 MVPmatri
  • 如何每 x 秒调用一个函数并更新状态(React)

    我在这方面遇到了很多麻烦 我尝试了各种方法 我想在单击开始按钮后每秒调用一个函数 然后在单击停止按钮后暂停它 我不断出现我无法解释的奇怪行为 我怎样才能在没有课程的情况下做出反应 我有 triid 的东西 const simulation
  • 是否可以使用 System.IO.Packaging.Package 压缩文件夹并稍后向其中添加文件/文件夹?

    我想知道我们是否可以使用 net 类 ZipPackage http msdn microsoft com en us library system io packaging zippackage aspx将文件夹压缩到file zip文件
  • QTableView - 限制所选项目的数量?

    问题就在标题里 没有函数 QTableView set Max Number SelectedItems int 当所选项目的数量为 2 时 我想禁用项目选择 Thanks 您可以通过以下方式禁用选择 connect ui gt table
  • 如何在碰撞后实现超时/冷却

    我一直在做一个pygame两名玩家尝试将球击入网中的游戏 我的游戏中有一个增强功能 但是 我想要一些增强垫 当它们被收集时 我会获得 3 增强 在我下面的代码中 有一个巨大的黄色物体 当有人将鼠标悬停在它上面时 他们会得到提升 但他们可以永