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

Python 如何在碰撞后实施超时/冷却,python,python-3.x,pygame,Python,Python 3.x,Pygame,我一直在做一个pygame游戏,两名玩家试图将球击入网内。我在我的游戏中有一个增强功能,但是,我想要一些增强垫,当它们被收集时,我会得到+3的增强。在我下面的代码中,有一个巨大的黄色代码,当有人悬停在上面时,他们会得到提升,但他们可以永远停留在上面,并得到很多提升。我想知道一种方法,即一旦收集到增压垫,它会在3秒钟内变为非活动状态,并变为灰色。有什么办法吗 import pygame from pygame.math import Vector2 import time, datetime im

我一直在做一个
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
从pygame.math导入向量2
导入时间,日期时间
导入系统
pygame.font.init()
pygame.init()
宽度=1150
高度=800
screen=pygame.display.set_模式((宽度、高度))
clock=pygame.time.clock()
REDCAR_ORIGINAL=pygame.Surface((50,30),pygame.SRCALPHA)
pygame.draw.polygon(
红车原版,(255,0,0),[(0,30),(50,20),(50,10),(0,0)])
红色角度=180
redcar=pygame.transform.rotate(redcar\u原始,redangle)
红色角度=180
booster=pygame.Surface((50150),pygame.SRCALPHA)
增压器填充((255,255,0))
booster1=booster.get_rect(左上方=(0340))
boostermask=pygame.mask.from_曲面(booster)
redspeed=5
dx=0
dy=0
x=800
y=500
redscore=0
位置红色=矢量2(x,y)
vel_red=矢量2(-redspeed,0)
redrect=redcar.get_rect(中心=pos_red)
红色角度=180
redcar=pygame.transform.rotate(redcar\u原始,redangle)
位置蓝色=矢量2(275300)
#面具。
mask_red=pygame.mask.from_surface(redcar)
def redboosts():
全球水平红
全局计时器
全局dt
如果计时器>0:
红色水平刻度至长度(10)
定时器-=dt
def减速():
红色水平刻度至长度(5)
计时器=3
dt=1
运行=真
运行时:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
运行=错误
elif event.type==pygame.KEYDOWN:
如果event.key==pygame.K\r:
#将汽车复位到起动位置。
红色角度=180
redcar=pygame.transform.rotate(redcar\u原始,redangle)
位置红色=矢量2(800500)
vel_red=矢量2(-redspeed,0)
redrect=redcar.get_rect(中心=pos_red)
mask_red=pygame.mask.from_surface(redcar)
#elif event.key==pygame.K_:
#蓝色水平。缩放至长度(2)
elif event.type==pygame.KEYUP:
如果event.key==pygame.K_UP:
红色水平刻度至长度(5)
elif event.key==pygame.K_向下:
红色水平刻度至长度(5)
打印(计时器)
keys=pygame.key.get_pressed()
如果键[pygame.K_左]:
红色角度+=5
红色水平。旋转ip(-5)
redcar=pygame.transform.rotate(redcar\u原始,redangle)
redrect=redcar.get_rect(center=redrect.center)
#旋转后我们需要一个新的面具。
mask_red=pygame.mask.from_surface(redcar)
elif keys[pygame.K_RIGHT]:
红色角度-=5
红色水平。旋转ip(5)
redcar=pygame.transform.rotate(redcar\u原始,redangle)
redrect=redcar.get_rect(center=redrect.center)
mask_red=pygame.mask.from_surface(redcar)
如果键[pygame.K_UP]:
红宝石
如果键[pygame.K_DOWN]:
红色水平刻度至长度(2)
如果键[pygame.K_s]:
蓝色水平。缩放至长度(2)
如果y 450:
y=440
如果x>480:
x=470
如果redrect.top<0且vel_red.y<0:
redrect.top=0
位置红色=矢量2(红色直线中心)
elif redrect.bottom>screen.get_height()和vel_red.y>0:
redrect.bottom=screen.get_height()
位置红色=矢量2(红色直线中心)
如果redrect.left<0且vel_red.x<0:
redrect.left=0
位置红色=矢量2(红色直线中心)
elif redrect.right>screen.get_width()和vel_red.x>0:
redrect.right=screen.get_width()
位置红色=矢量2(红色直线中心)
位置红色+=水平红色
redrect.center=pos_red
偏移量=booster1[0]-redrect[0],booster1[1]-redrect[1]
collectboost=mask_red.重叠(boostermask,偏移)

如果计时器不错,那么让我们使用一些面向对象编程来整理代码。这意味着对数据结构和行为进行分组,并利用多态性。既然我们使用pygame,就让我们使用它的类,但是现在让我们忽略增强功能

我添加了一些注释进行解释

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()
导入pygame
从pygame.math导入向量2
导入时间,日期时间
导入系统
导入pygame.freetype
pygame.font.init()
pygame.init()
宽度=1150
高度=800
screen=pygame.display.set_模式((宽度、高度))
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(无,34)
#所有与汽车有关的东西都归这一类
类车(pygame.sprite.sprite):
定义初始化(自):
super()。\uuuu init\uuuuu()
自身速度=3
#因为我们想在按下按钮后重置汽车,
#让我们有一个重置函数,这样就不会有重复的代码
self.reset()
def重置(自):
#如果增压>0,我们可以开得更快
self.boost=0
自转角=180
self.vel=矢量2(-self.speed,0)
自我更新_图像((800500))
def更新_图像(自身,中心):
#由于我们经常更新图像、矩形和遮罩,
#让我们在函数中也这样做
self.image=pygame.transform.rotate(原始的、self.angle的红车)
self.rect=self.image.get_rect(中心=中心)
self.mask=pygame.mask.from_surface(self.image)
def更新(se)