[Duda] Sobre el manejo de Sprites en Pygame (Solucionado)

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

[Duda] Sobre el manejo de Sprites en Pygame (Solucionado)

Notapor Cyberdemonk » Vie Ago 10, 2012 3:32 am

Hola a todos!

Hace poco que empeze en la programacion de juegos, al momento de ir a la practica pude ir desarrollando un simple juego tipo Breakout con Sprites, la pelota rebota bien, puedo "pintar" todos los objetos a la perfeccion, incluso poner menus.

Pero al momento de eliminar un blocke al contacto con la pelota, no sabia como hacerlo, fui leyendo articulos y probando varios codigos de los juegos que descargue en pygame.org, pero ninguno de los juegos que descargue funcionan, solo uno que justamente un usaba sprites (creeria que debe ser la vercion de python).

Probe con la funcion kill() no desaparece los sprites.

Uso Gnu/Linux en la PC que les estoy escribiendo y Windows 7 en otra PC, ambas no funciona.

Gracias de antemano.

Saludos.
Última edición por Cyberdemonk el Sab Ago 11, 2012 4:39 pm, editado 1 vez en total
Cyberdemonk
 
Mensajes: 3
Registrado: Vie Ago 10, 2012 3:22 am

Re: [Duda] Sobre el manejo de Sprites en Pygame

Notapor Barajas » Vie Ago 10, 2012 5:09 am

Hola y bienvenido...

Bueno, así como lo pones, podrían ser muchas cosas, y me parece extraño que no funcione el metodo kill()...
tal vez ver el código fuente ayudaría :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: [Duda] Sobre el manejo de Sprites en Pygame

Notapor Cyberdemonk » Sab Ago 11, 2012 2:29 am

En ves de poner el juego mismo (ademas para facilitar las cosas) directamente pongo una de mis pruebas antes de programar el Breakout, me base en el codigo siguiente:

# El juego solo hace rebotar 2 pelotas
# al momento de colicionar alguna de las 2
# "bola" se elimina.
# como veran la funcion kill() no funciona, tengo que usar
# una condicional antes del blit.

import pygame


SCREEN_ANCHO = 300
SCREEN_ALTO = 300

run = True

class bola ():
def __init__(self):
self.image = pygame.image.load("bola.png")
self.rect_pelota = self.image.get_rect()
self.rect_pelota.centerx = SCREEN_ANCHO / 2
self.rect_pelota.centery = 50
self.speed = [3 , 3]

def update(self):
if self.rect_pelota.left < 0 or self.rect_pelota.right > SCREEN_ANCHO:
self.speed[0] = -self.speed[0]
if self.rect_pelota.top < 0 or self.rect_pelota.bottom > SCREEN_ALTO:
self.speed[1] = -self.speed[1]

self.rect_pelota.move_ip((self.speed[0], self.speed[1]))

class bola2():
def __init__(self):
self.image = pygame.image.load("bola.png")
self.rect_pelota2 = self.image.get_rect()
self.rect_pelota2.centerx = 20
self.rect_pelota2.centery = 70
self.speed2 = [2 , 2]

def update(self):
if self.rect_pelota2.left < 0 or self.rect_pelota2.right > SCREEN_ANCHO:
self.speed2[0] = -self.speed2[0]
if self.rect_pelota2.top < 0 or self.rect_pelota2.bottom > SCREEN_ALTO:
self.speed2[1] = -self.speed2[1]

self.rect_pelota2.move_ip((self.speed2[0], self.speed2[1]))



def main ():
pygame.init()
pygame.display.set_caption("Prueba")
screen = pygame.display.set_mode((SCREEN_ANCHO ,SCREEN_ALTO ))

fondo = pygame.image.load("fondo.jpg")

clock = pygame.time.Clock()

pelota1 = bola()
pelota2 = bola2()


rebote = False

while run:
clock.tick(60)


pelota1.update()
pelota2.update()


if pelota1.rect_pelota.colliderect(pelota2.rect_pelota2):
pelota1.speed[1] = -pelota1.speed[1]
pelota1.speed[0] = -pelota1.speed[0]
rebotes = True

# if rebotes == True:
# pelota1.rect_pelota.kill() # no funciona

screen.blit(fondo , (0 , 0))

if rebotes != True:
screen.blit(pelota1.image , pelota1.rect_pelota)

screen.blit(pelota1.image, pelota2.rect_pelota2)

pygame.display.flip()

main()



Talves digan que podria usar el condicional antes del blit, pero...

¿Como hago cuando son varios sprites ? como los bloques del Breakout.

Podria usar 2 listas, una para los rect de los bloques y otra para los rect de los bloque que no deberian aparecer.
Usando las listas con un bucle for que "pinta" los bloque ahi se solucionaria no?
Cyberdemonk
 
Mensajes: 3
Registrado: Vie Ago 10, 2012 3:22 am

Re: [Duda] Sobre el manejo de Sprites en Pygame

Notapor Barajas » Sab Ago 11, 2012 5:08 am

Cyberdemonk escribió:¿Como hago cuando son varios sprites ? como los bloques del Breakout.

Podria usar 2 listas, una para los rect de los bloques y otra para los rect de los bloque que no deberian aparecer.
Usando las listas con un bucle for que "pinta" los bloque ahi se solucionaria no?


Chico, te estas complicando mucho la existencia :)

hay algo llamado "grupos" y hacen todo lo que quieres de forma simple http://www.losersjuegos.com.ar/traducciones/pygame/sprite/group

Mira, modificando un poco tu código, como ejemplo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#la linea anterior nos permite utilizar acentos en los comentarios...

import pygame
from pygame import *

SCREEN_ANCHO = 300
SCREEN_ALTO = 300


class bola (pygame.sprite.Sprite): # heredamos la clase sprite
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("bola.png")
#sprite tiene un atributo llamado "rect"
#ese atributo es lo que permite muchas utildades
#asi que hay que respetar su nombre
self.rect = self.image.get_rect()
self.rect.centerx = SCREEN_ANCHO / 2
self.rect.centery = 50
self.speed = [3 , 3]

def update(self):
if self.rect.left < 0 or self.rect.right > SCREEN_ANCHO:
self.speed[0] = -self.speed[0]
if self.rect.top < 0 or self.rect.bottom > SCREEN_ALTO:
self.speed[1] = -self.speed[1]

self.rect.move_ip((self.speed[0], self.speed[1]))

class bola2(pygame.sprite.Sprite): # heredamos la clase sprite
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("bola.png")
# Aquí habías colocado self.rect_pelota2, recuerda
# lo que te dije antes, no te preocupes por el nombre
# al ser objetos diferentes sus atributos les son diferentes
# ejemplo:
# tu tienes un atributo "nombre"
# yo tengo un atributo "nombre"
# pero mi nombre es diferente al tuyo :)
# a demás
# mi nombre es MIO
# tu nombre es TUYO

self.rect = self.image.get_rect()
self.rect.centerx = 20
self.rect.centery = 70
self.speed2 = [2 , 2]

def update(self):
if self.rect.left < 0 or self.rect.right > SCREEN_ANCHO:
self.speed2[0] = -self.speed2[0]
if self.rect.top < 0 or self.rect.bottom > SCREEN_ALTO:
self.speed2[1] = -self.speed2[1]

self.rect.move_ip((self.speed2[0], self.speed2[1]))



def main ():
pygame.init()
pygame.display.set_caption("Prueba")
screen = pygame.display.set_mode((SCREEN_ANCHO ,SCREEN_ALTO ))

fondo = pygame.image.load("fondo.jpg")

clock = pygame.time.Clock()

run = True

#aqui estamos bien, creamos una pelota...
pelota1 = bola()
pelota2 = bola2()

#creamos grupos de sprites
#los grupos nos permiten manejar muchos sprites
#de forma simple
grupo_pelota1 = pygame.sprite.Group(pelota1)
grupo_pelota2 = pygame.sprite.Group(pelota2)

rebotes = False

while run:
clock.tick(60)

#esto es para una salida más "limpia"
for event in pygame.event.get():
if event.type == QUIT:
run = False

pelota1.update()
pelota2.update()

#Las lineas que siguen las puedes remplazar por colisiones "entre grupos"
"""
if pelota1.rect.colliderect(pelota2.rect):
pelota1.speed[1] = -pelota1.speed[1]
pelota1.speed[0] = -pelota1.speed[0]
rebotes = True
"""
#como aquí muestro:
#no explicare como funciona exactamente esta función, te lo dejo de tarea :)
if pygame.sprite.groupcollide(grupo_pelota1, grupo_pelota2, False, True):
pelota1.speed[1] = -pelota1.speed[1]
pelota1.speed[0] = -pelota1.speed[0]

screen.blit(fondo , (0 , 0))
#screen.blit(pelota1.image, pelota2.rect_pelota2)
#esta linea de arriba es innecesaria utilizando bien a sprite...
#el método draw dibuja TODOS los sprites contenidos en el grupo
grupo_pelota1.draw(screen)
grupo_pelota2.draw(screen)
pygame.display.flip()

#como decia, una salida mas limpia...
pygame.quit()

main()


Ahora imagina un grupo de sprites llamado "bloques" y un grupo para "pelota".

Si tienes dudas, pregunta :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: [Duda] Sobre el manejo de Sprites en Pygame

Notapor Cyberdemonk » Sab Ago 11, 2012 4:38 pm

Entonces...

Con Group.add() agrego los sprites a un grupo, para despues pintar el grupo entero y con Group.remove() saco los sprites del grupo para que no aparezcan (asi controlos los sprites de la pantalla).

Ya entendi :D , seguiré leyendo la documentación de la pagina.

Solo me falta seguir probando, si tengo otra duda creare otro tema, por ahora este tema esta solucionado.

Gracias Barajas.

Saludos.
Cyberdemonk
 
Mensajes: 3
Registrado: Vie Ago 10, 2012 3:22 am

Re: [Duda] Sobre el manejo de Sprites en Pygame

Notapor hugoruscitti » Sab Ago 11, 2012 6:48 pm

Sip, recién veo la respuesta y es muy buena, justamente "grupos" es lo que te estába faltando.

Solo agregar una cosa:

Cyberdemonk escribió:... y con Group.remove() saco los sprites del grupo para que no aparezcan (asi controlos los sprites de la pantalla).


A veces es mas cómodo quitar el sprite de todos los grupos juntos. El método "kill" de los sprites hace justamente
eso, elimina el sprite de todos los grupos a los que pertenece.

Eso si, si tienes una variable que apunte al sprite no lo perderás aunque hagas "kill". "kill" solo va a eliminar al
sprite de todos los grupos a los que pertenece.

Hay un ejemplo llamado "paso_5" en esta charla en donde se muestra un juego completo que usa
grupos: http://www.losersjuegos.com.ar/referenc ... econf_2007
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron