#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pygame.locals import *
import pygame, os, sys
#función para cargar imagenes
def load_image(name, colorkey=False):
fullname = os.path.join(name)
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'No se puede cargar la imagen: ', fullname
raise SystemExit, message
image = image.convert()
if colorkey:
colorkey = image.get_at((0, 0))
image.set_colorkey(colorkey, RLEACCEL)
return (image)
#Creamos un "nivel"
class Nivel():
def __init__(self, Ancho, Alto):
self.bloques = []
imagen = load_image("brock.png")
filas = 3
columnas = 9
#corto la imagen de los tiles
tile_w = imagen.get_width () / columnas
tile_h = imagen.get_height () / filas
for f in xrange (filas):
for c in xrange (columnas):
rect = c * tile_w , f * tile_h , tile_w, tile_h
#y guardo los pedasos en una lista
self.bloques.append(imagen.subsurface(rect).copy ())
#genero un mapa muy simple
self.mapa = [
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[ 1, 1, 1, 1, 1]
]
#un par de variables para controlar las coliciones
espaciox = 500/len(self.mapa)
espacioy = 500/len(self.mapa[0])
self.dimenciones = (espaciox, espacioy)
def imprimir(self,superficie):
# Dibuja sobre una superficie todos los bloques del nivel.
numero_de_filas = len( self.mapa )
numero_de_columnas = len( self.mapa[0] )
espaciox = superficie.get_width()/numero_de_filas
espacioy = superficie.get_height()/numero_de_columnas
self.dimenciones = (espaciox, espacioy)
for fila in range(numero_de_filas):
for columna in range(numero_de_columnas):
pos_x = columna * espaciox
pos_y = fila * espacioy
#en caso de que sea distinto de -1
if self.mapa[fila][columna] != -1:
#imprimo la imagen indicada en el mapa
index = self.mapa[fila][columna]
bloque = self.bloques[index] #aqui la tomo
#la escalo
bloque = pygame.transform.scale(bloque,(espaciox,espacioy))
superficie.blit(bloque, (pos_x, pos_y))
def puede_pasar(self, posx, posy):
#función que resive una posición y regresa un valor boleano
columna = int( posx / self.dimenciones[0] )
fila = int( posy / self.dimenciones[1] )
try:
celda = int(self.mapa[fila][columna])
except:
# si no puede obtener la celda prohíbe pisar ahí
return False
#si la celda distinta de nuestro "valor nulo"
if celda != -1:
#es obvio que no puede pasar
return False
#si no sucede eso, en ese caso, puede pasar
return True
def distancia_al_suelo(self, pos, rango):
# función que mide la distancia al suelo en un rango
posx, posy = pos
contador = 0
while contador < rango:
contador += 1
if not(self.puede_pasar(posx, posy + contador)):
#nos regresa la distancia al suelo
return contador
#si regresa el rango, indica que no encuentra el suelo.
return rango
#creo una clase para gestionar las animaciones
#un uso alternativo, es "partir" la imagen
class AnimacionDeArchivo():
def __init__(self, columnas, filas, image):
#inicializamos las características para la animación
self.lista_frames = []
tile_w = image.get_width () / columnas
tile_h = image.get_height () / filas
for f in xrange (filas):
for c in xrange (columnas):
rect = c * tile_w , f * tile_h , tile_w, tile_h
self.lista_frames.append(image.subsurface(rect).copy ())
#variabloes que nesesito para la animación
self._frame = 0
self.inicio = pygame.time.get_ticks()
self._delay = 1000/15
self.ultima_act = 0 #ultima
def Frame_es(self, Lista_anima = [0], Reset = False, Frame_return = False):
if Reset:
self._frame = 0
if pygame.time.get_ticks() - self.ultima_act > self._delay:
self._frame += 1
if self._frame >= len(Lista_anima):
self._frame = 0
self.ultima_act = pygame.time.get_ticks()
if Frame_return:
return self.lista_frames[ Lista_anima[self._frame] ], self._frame
else:
return self.lista_frames[ Lista_anima[self._frame] ]
#primero, creamos una clase para nuestro personaje
class Personaje(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
imagen = load_image("eva.png", True)
self.animacion = AnimacionDeArchivo( 4, 4, imagen)
self.image = self.animacion.Frame_es( [1] )
self.rect = self.image.get_rect()
self.gravedad = 0.1
self.dx = 5
#algunas personas usaran dy
#yo uso fuerza salto....
self.fuerza_salto = 0
#si, es menos practico que dy...
#definimos la posición inicial
self.posx = 250
self.posy = 250
#creamos una variable para guardar el estado
self.estado = "Parado"
# y una pequeña verción del nivel
self.esenario = Nivel(500,500)
def estado_parado(self):
#lo que hace en el estado parado
#self.mover, es una función para gestionar movimiento-animación
self.mover()
key=pygame.key.get_pressed()
if key[K_UP]:
self.estado = "Salta"
self.fuerza_salto = 5 #inicializamos la fuerza del salto...
#en caso de que este en una plataforma...
distancia = self.esenario.distancia_al_suelo(self.rect.midbottom, 10)
#y la distancia que lo separa del suelo sea mayor a 10
if distancia >= 10:
#significa que esta cayendo al suelo...
self.estado = "Salta"
self.fuerza_salto = 0 #por eso ponemos la fuerza salto en 0
def estado_saltar(self):
#la serie de acciones a realizar en el estado salta
self.posy -= self.fuerza_salto # a la posición x añadimos la fuerza_salto
self.fuerza_salto -= self.gravedad # a la fuerza salto, añadimos la de la gravedad
self.mover() #llamamos a la función mover...
#deja de subir y comienza a caer...
if self.fuerza_salto < 0:
#verifico la distancia que me separa del suelo
distancia = self.esenario.distancia_al_suelo(self.rect.midbottom, 10)
if distancia <= 5:
#si es menor a cierto rango...
#cambio a el estado parado
self.estado = "Parado"
def mover(self):
#aqui definimos la función mover...
key=pygame.key.get_pressed()
if key[K_RIGHT]:
#sección de animación....
if self.estado != "Salta":
#si no esta saltando...
image = self.animacion.Frame_es( [4,4,5,5,6,6,7,7] )
#volteamos la imagen
self.image = pygame.transform.flip(image, True, False)
else:
#si salta, la imagen es...
image = self.animacion.Frame_es( [5,5], True )
self.image = pygame.transform.flip(image, True, False)
#sección de movimiento
if self.posx < 500:
self.posx += self.dx
else:
self.posx = 500
#lo mismo, pero para el otro lado...
elif key[K_LEFT]:
if self.estado != "Salta":
self.image = self.animacion.Frame_es( [4,4,5,5,6,6,7,7] )
else:
self.image = self.animacion.Frame_es( [5,5], True )
if self.posx > 0:
self.posx -= self.dx
else:
self.posx = 0
#en caso de que no se mueva en el eje x
else:
if self.estado != "Salta":
self.image = self.animacion.Frame_es( [1], Reset = True)
else:
self.image = self.animacion.Frame_es( [10,10], True )
def update(self):
#colocamos el centro de la imagen en la posición...
self.rect.center = (self.posx,self.posy)
#si el estado es tal...
#llamo a su metodo
if self.estado == "Salta":
self.estado_saltar()
if self.estado == "Parado":
self.estado_parado()
def main():
pygame.init()
pantalla = pygame.display.set_mode((500,500))
personaje = Personaje() #creo mi personaje...
sprite = pygame.sprite.RenderClear()
sprite.add(personaje)
continuar = True
nivel = Nivel(500,500) #creo mi nivel
reloj = pygame.time.Clock()
while continuar:
#relleno la pantalla
pantalla.fill((150,150,200))
for evento in pygame.event.get():
if evento.type==pygame.QUIT:
continuar=False
pygame.quit()# salir del juego
sys.exit()
sprite.draw(pantalla) # dibujo mi personaje...
nivel.imprimir(pantalla) # dibujo mi nivel...
personaje.update() # actualizo a mi personaje...
reloj.tick(60)
pygame.display.update()
main()
Nexusblake escribió:edit: una consulta, me podrias explicar la parte donde obtienes los distintos estados de la imagen? es que en mi codigo tengo definido los distintos sprites en un arreglo y los voy agregando de uno en uno segun los pixeles de la imagen, dejandome un gran trozo de codigo..
class AnimacionDeArchivo():
def __init__(self, columnas, filas, image):
#inicializamos las características para la animación
self.lista_frames = []
tile_w = image.get_width () / columnas
tile_h = image.get_height () / filas
#esto corta mi imagen como si recorriera una matriz
for f in xrange (filas):
for c in xrange (columnas):
rect = c * tile_w , f * tile_h , tile_w, tile_h
#y esta parte añade lo que "corta" a un arreglo que las contiene
self.lista_frames.append(image.subsurface(rect).copy ())
#variables que necesito para la animación
self._frame = 0
self.inicio = pygame.time.get_ticks()
self._delay = 1000/15
self.ultima_act = 0 #ultima
def Frame_es(self, Lista_anima = [0], Reset = False, Frame_return = False):
if Reset:
self._frame = 0
if pygame.time.get_ticks() - self.ultima_act > self._delay:
self._frame += 1
if self._frame >= len(Lista_anima):
self._frame = 0
self.ultima_act = pygame.time.get_ticks()
if Frame_return:
return self.lista_frames[ Lista_anima[self._frame] ], self._frame
else:
return self.lista_frames[ Lista_anima[self._frame] ]
#mi imagen:
|aaaa|
|aaaa|
|aaaa|
#mi imagen dividida en columnas y filas:
|0|1|2|
|3|4|5|
|6|7|9|
Volver a Sobre las bibliotecas multimedia
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado