Generar múltiples instancias del mismo objeto simultáneamente en Python
Soy un programador principiante que está comenzando con Python y estoy comenzando creando un juego en pygame. Básicamente, el juego genera círculos en posiciones aleatorias y, cuando se hace clic, te otorga puntos.
Recientemente me encontré con un obstáculo cuando quiero generar varias instancias del mismo objeto (en este caso, círculos) al mismo tiempo. He probado cosas como sleep()
y algún otro código relacionado con contadores, pero siempre da como resultado que el siguiente círculo generado anule el anterior (es decir, el programa genera el círculo 1, pero cuando entra el círculo 2, el círculo 1 desaparece).
¿Alguien sabe una solución para esto? ¡Realmente agradecería su ayuda!
import pygame
import random
import time
pygame.init()
window = pygame.display.set_mode((800,600))
class circle():
def __init__(self, color, x, y, radius, width,):
self.color = color
self.x = x
self.y = y
self.radius = radius
self.width = width
def draw(self, win, outline=None):
pygame.draw.circle(win, self.color, (self.x, self.y, self.radius, self.width), 0)
run=True
while run:
window.fill((0, 0, 0))
pygame.draw.circle(window, (255, 255, 255), (random.randint(0, 800),random.randint(0, 600)), 20, 20)
time.sleep(1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False
pygame.quit()
quit()
No funciona de esa manera. time.sleep
, pygame.time.wait()
o pygame.time.delay
no es la forma correcta de controlar el tiempo y el juego dentro de un bucle de aplicación. El juego no responde mientras esperas. El bucle de la aplicación se ejecuta continuamente. Tienes que medir el tiempo en el bucle y generar los objetos según el tiempo transcurrido.
pygame.Surface.fill
borra toda la pantalla. Agregue los objetos recién creados a una lista. Vuelva a dibujar todos los objetos y la escena completa en cada cuadro.
Ver también Hora, evento del temporizador y reloj
Tienes 2 opciones. Úselo pygame.time.get_ticks()
para medir el tiempo. Defina un intervalo de tiempo después del cual debería aparecer un nuevo objeto. Cree un objeto cuando se alcance el momento y calcule el momento para el siguiente objeto:
object_list = []
time_interval = 500 # 500 milliseconds == 0.1 seconds
next_object_time = 0
while run:
# [...]
current_time = pygame.time.get_ticks()
if current_time > next_object_time:
next_object_time += time_interval
object_list.append(Object())
Ejemplo mínimo:
repl.it/@Rabbid76/PyGame-TimerSpawnObjects
import pygame, random
pygame.init()
window = pygame.display.set_mode((300, 300))
class Object:
def __init__(self):
self.radius = 50
self.x = random.randrange(self.radius, window.get_width()-self.radius)
self.y = random.randrange(self.radius, window.get_height()-self.radius)
self.color = pygame.Color(0)
self.color.hsla = (random.randrange(0, 360), 100, 50, 100)
object_list = []
time_interval = 200 # 200 milliseconds == 0.2 seconds
next_object_time = 0
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
current_time = pygame.time.get_ticks()
if current_time > next_object_time:
next_object_time += time_interval
object_list.append(Object())
window.fill(0)
for object in object_list[:]:
pygame.draw.circle(window, object.color, (object.x, object.y), round(object.radius))
object.radius -= 0.2
if object.radius < 1:
object_list.remove(object)
pygame.display.flip()
pygame.quit()
exit()
La otra opción es utilizar el pygame.event
módulo. Úselo pygame.time.set_timer()
para crear repetidamente un USEREVENT
en la cola de eventos. El tiempo debe fijarse en milisegundos. p.ej:
object_list = []
time_interval = 500 # 500 milliseconds == 0.1 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
Tenga en cuenta que en pygame se pueden definir eventos de clientes. Cada evento necesita una identificación única. Los identificadores de los eventos de usuario deben estar entre pygame.USEREVENT
(24) y pygame.NUMEVENTS
(32). En este caso pygame.USEREVENT+1
es la identificación del evento para el evento del temporizador.
Reciba el evento en el bucle de eventos:
while run:
for event in pygame.event.get():
if event.type == timer_event:
object_list.append(Object())
El evento del temporizador se puede detener pasando 0 al argumento de tiempopygame.time.set_timer
de .
Ejemplo mínimo:
repl.it/@Rabbid76/PyGame-TimerEventSpawn
import pygame, random
pygame.init()
window = pygame.display.set_mode((300, 300))
class Object:
def __init__(self):
self.radius = 50
self.x = random.randrange(self.radius, window.get_width()-self.radius)
self.y = random.randrange(self.radius, window.get_height()-self.radius)
self.color = pygame.Color(0)
self.color.hsla = (random.randrange(0, 360), 100, 50, 100)
object_list = []
time_interval = 200 # 200 milliseconds == 0.2 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == timer_event:
object_list.append(Object())
window.fill(0)
for object in object_list[:]:
pygame.draw.circle(window, object.color, (object.x, object.y), round(object.radius))
object.radius -= 0.2
if object.radius < 1:
object_list.remove(object)
pygame.display.flip()
pygame.quit()
exit()