gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 02:16:21 25 4
gpt4 key购买 nike

我一直在制作一个 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类,但让我们暂时忽略提升内容。

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

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()

每个 Booster 都有 3 秒的超时时间,并且会提升 1 秒。

我们利用 OrderedUpdates以正确的顺序绘制我们的 Sprite ,和spritecollidecollide_mask用于碰撞检测。

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

enter image description here

关于python - 如何在碰撞后实现超时/冷却,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52553011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com