dispara cuadrado: mi primer pygame

Encuentra personas para llevar adelante tu proyecto, muestra el progreso de esos proyectos y participa en competencias grupales.

Moderador: Dokan

dispara cuadrado: mi primer pygame

Notapor estudiante » Dom Ene 31, 2010 4:53 pm

Hola:
Primero, felicitarlos por la página. Muy buena

Me presento: Mi nombre es Hugo (tambien), pero pueden llamarme "Estudiante". No soy programador, soy ingeniero mecánico.

Les presento el juego que he hecho.
-¿Está bien la velocidad (los FPS)?. En mi Pentium IV en promedio tengo 44 FPS.

- ¿Se entiende el código?

- ¿Alguna sugerencia de cómo mejorarlo, hacerlo menos soso? Por favor, no me digan que lo borre todo :(

Les indico como se juega, mueven el cuadrito rojo ("TheCannon") con flecha izquierda o derecha. Disparan la bala ("thebullet") con barra esapaciadora. Tienen que darle al otro cuadrito amarillo que es "target".


Código: Seleccionar todo
#! /usr/bin/env python

# A simple actor1 game.

import pygame
import random



class World(pygame.sprite.Sprite):
   def __init__(self,w_screen=500,h_screen=600):
      
      pygame.font.init()
      
      self.fuente = pygame.font.Font(None, 30)
      
      self.rect=pygame.rect.Rect(0,0,w_screen,h_screen)
      

      self.screen = pygame.display.set_mode((w_screen, h_screen))
      self.clock = pygame.time.Clock()

      self.score = 0

      self.thecannon = Cannon((w_screen/2, h_screen*3/5, 10, 10),(0, 0), self.screen)
      
      
      self.obstL = Obstacle((0, 0, 10, h_screen),(0, 0), self.screen)
      self.obstR = Obstacle((w_screen-11, 0, 10, h_screen),(0, 0), self.screen)
      self.obstU = Obstacle((0, 0, w_screen, 10 ),(0, 0), self.screen)
      self.obstD = Obstacle((0, h_screen*3/5+20 , w_screen, 10),(0, 0), self.screen)
      randposx = random.randint(20, w_screen-20)
      randposy = random.randint(20, h_screen/2)
      self.target = Miactor((randposx, randposy, 25, 25), (0, 0), self.screen)
      self.obst1 = Obstacle((w_screen/3, randposy+30, 200, 20),(0, 0), self.screen)
      
      self.running = True
      
      self.targets = pygame.sprite.Group()
      self.sprites = pygame.sprite.Group()

      self.sprites_obstacles = pygame.sprite.Group()
      
      self.sprites_obstacles.add(self.target, self.obst1, self.obstL, self.obstR,self.obstU,self.obstD)
      
      
      self.permit_space = True
   
   def on_event(self):
      evento=pygame.event.get()
      
      keylist=pygame.key.get_pressed()
      
      if keylist[pygame.K_ESCAPE]:
         self.running = False
      elif keylist[pygame.K_RIGHT]:
         self.thecannon.dvx=5
      elif keylist[pygame.K_LEFT]:
         self.thecannon.dvx=-5   
      elif keylist[pygame.K_a]:
         evento_keyspace=pygame.event.wait()
         print "hola"
         print self.thecannon.cannonmouth.x
         self.thecannon.cannonmouth.x=self.thecannon.x            
         print self.thecannon.cannonmouth.x
      elif  keylist[pygame.K_SPACE]:
         if self.permit_space:
            evento_keyspace=pygame.event.wait()
            self.thebullet=Miactor((self.thecannon.rect.right, self.thecannon.rect.top-5,5,5)\
            , (2,-2), self.screen)
            self.sprites.add(self.thebullet)
            self.permit_space = False
         else :
            pass
   
   def on_running(self):
      while self.running:
   
         self.thecannon.update()
         self.sprites_obstacles.update()
         self.on_event()
         #print len(self.sprites)
         if len(self.sprites) == 0:
            pass
         else:
            self.sprites_obstacles.update()
            self.sprites.update()
            self.on_collision()
            
         
         self.clock.tick(100)
         puntos_image = self.fuente.render('FPS '+str(self.clock.get_fps()), 1, (255,255,255))
         
         
         
         self.screen.blit(puntos_image, (self.screen.get_width()*3/5, self.screen.get_height()*4/5))
         pygame.display.update()
         self.screen.fill((0,0,0))
   
   def on_collision(self):
         
      sprite_collided=pygame.sprite.spritecollideany(self.thebullet, self.sprites_obstacles)
      
      
      
      if sprite_collided:
         
         actorposx, actorposy = self.thebullet.rect.center
         actorposx_next =actorposx+self.thebullet.vx
         actorposy_next= actorposy+self.thebullet.vy
         
         if sprite_collided==self.target:
            print "punto!"
            self.running=False
         elif sprite_collided.rect.collidepoint(actorposx_next, actorposy):
            self.thebullet.vx= -self.thebullet.vx
         elif sprite_collided.rect.collidepoint(actorposx,actorposy_next):
            self.thebullet.vy=-self.thebullet.vy
            
      else:
         pass
         
         

class Miactor(pygame.sprite.Sprite):

   def __init__(self, (x, y, w, h), (vx, vy), surface):
      pygame.sprite.Sprite.__init__(self)
      self.image=surface
      self.rect = surface.get_rect()
      self.x = x
      self.y = y
      self.w = w
      self.h = h
      self.vx = vx
      self.vy = vy
      self.dvx = 0
      self.dvy = 0
      self.color = 255, 255, 0
      #self.vmax=(5,3)
      
   def draw(self):
      """Draw the actor"""
      mydib=pygame.draw.rect(self.image, self.color, ( self.x, self.y, self.w, self.h ))
      self.rect=mydib
   
   def move(self):
      """ Move the actor """
      
      self.x += self.vx +self.dvx
      self.dvx  = 0
      self.y += self.vy + self.dvy
      self.dvy = 0
   
   def update(self):
      self.move()
      self.draw()
      

class Cannon(Miactor):
   def __init__(self, (x, y, w, h), (vx, vy), surface):
      Miactor.__init__(self, (x, y, w, h), (vx, vy), surface)
      self.color = 255, 0, 0
      self.vmax=(10,3)
      self.rect = pygame.Rect(x,y,w,h)
      self.cannonmouth=Miactor((x+w,y-h/2,w/2,h/2 ),(0, 0), surface)

   def move(self):
      """ Move the actor """
      self.cannonmouth.x=self.x+self.w
      self.x += self.vx+self.dvx
      
      self.dvx=0
      self.y += self.vy+self.dvy
      self.dvy=0
      
   
   def update(self):
      self.draw()
      self.move()
      
      
      self.cannonmouth.update()
class Obstacle(Miactor):
   def __init__(self, (x, y, w, h), (vx, vy), surface):
      Miactor.__init__(self, (x, y, w, h), (vx, vy), surface)
      self.color = 0, 0, 255
      self.vmax=(0,0)
      self.rect = pygame.Rect(x,y,w,h)
      


""" The GAME """

el_mundo=World()
el_mundo.on_running()
   
estudiante
 
Mensajes: 13
Registrado: Dom Ene 31, 2010 4:24 pm
Ubicación: Perú

Notapor Juanxo » Dom Ene 31, 2010 8:13 pm

Buenas estudiante:

Le estoy echando un ojo al juego, y creo que hay un pequeño problema.

Si me salgo por los límites de la pantalla y disparo, no se ve la bala(logico), pero el problema es que ya no puedo volver a disparar, ya que self.permit_space pasa a ser false.

Yo te recomendaría limitar el movimiento del player, evitando que pueda salir por los limites de la pantalla

Ya te diré más cosas cuando lo mire más a fondo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor hugoruscitti » Dom Ene 31, 2010 11:40 pm

Buenisimo, yo creo que está muy bien, y adems es divertido...

En mi equipo marca mas cuados por segundo, pero igualmente
está bien, en pygame se utiliza "clock.tick" como lo estás
haciendo tu:

Imagen

Con respecto a mejoras, yo agregaría un manejador de eventos
para que se pueda cerrar el programa cuando se pulsa el
botón de cerrar ventana. Pero es un detalle menor, solamente
habría que que colocar lo siguiente en el método "on_event"
de la clase "World":

Código: Seleccionar todo
   def on_event(self):
      evento=pygame.event.get()

      for x in evento:
          if x.type == pygame.QUIT:
              self.running = False
      ....


ah, otra cosa que podría resultar interesante es colocar
audio, por ejemplo mediante tonos aleatorios cuando el
cuadrado toca alguna pared. He visto esto en algunos
juegos y le añade mucha diversión.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor endaramiz » Mié Feb 03, 2010 12:38 pm

Me he mirado el código por encima y tiene buena pinta. Lo único que me ha llamado un poco la atención han sido los "else: pass". No me acuerdo mucho de python, pero acabo de leer que el pass no hace nada. Por lo tanto, se puede eliminar el "else" ya que, aunque haya un "if", no obliga a poner "elif" o "else".

Me gusta. A partir de aquí podrías seguir jugando con el código y hacer, por ejemplo, que una bala rebote un número limitado de veces y que luego puedas disparar otra...

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona


Volver a Propuestas de desarrollo y concursos

¿Quién está conectado?

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