From 9d57ae40095b2928672b2f4b23a87b8d5927753e Mon Sep 17 00:00:00 2001 From: flavio Date: Wed, 07 Dec 2011 23:10:50 +0000 Subject: CucaraSims Base --- (limited to 'Bicho.py') diff --git a/Bicho.py b/Bicho.py new file mode 100644 index 0000000..ffd7f08 --- /dev/null +++ b/Bicho.py @@ -0,0 +1,359 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Bicho.py por: +# Flavio Danesse +# CeibalJAM! - Uruguay + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import pygame, gc, random +from pygame.locals import * + +gc.enable() + +from math import sin, cos, radians +import Globals as VG + +INDICE_ROTACION = 25 + +class Bicho(pygame.sprite.Sprite): + def __init__(self, juego_main): + pygame.sprite.Sprite.__init__(self) + self.juego= juego_main + self.alimento_en_escenario= self.juego.alimento + self.agua_en_escenario= self.juego.agua + + self.velocidad = 8 + + self.anios = 0 + self.dias = 0 + self.horas = 0 + + self.hambre = 0 + self.sed = 0 + + self.sonido_bicho = self.juego.sonido_bicho + self.area_visible = self.juego.area_visible + + random.seed() + self.tipo = random.choice(self.juego.imagenes_bicho) + self.imagen_original = self.get_imagen_original() + if self.juego.imagenes_bicho.index(self.tipo) == 2 or self.juego.imagenes_bicho.index(self.tipo) == 3: + self.sexo = "F" + else: + self.sexo = "M" + + self.image = self.imagen_original.copy() + self.rect = self.image.get_rect() + + acciones = ["camina", "gira", "quieto"] + self.accion = random.choice(acciones) + + self.sent = 0 + self.angulo = 0 + + self.contador = 0 + + self.escalas_mudas = VG.ESCALASMUDAS + self.dias_mudas = VG.DIASMUDAS + self.control_mudas = self.dias_mudas[0] + + self.x, self.y = (0,0) + self.dx = 0 + self.dy = 0 + self.posicionar_al_azar() + + self.dias_repro = VG.DIASREPRO + self.control_repro = self.dias_repro[0] + + # Tamaños + def get_imagen_original(self): + return pygame.transform.scale(self.tipo, (60,50)) + + def set_muda(self, escala=(63,50)): + # cuando crece, muda el exoesqueleto + self.imagen_original = pygame.transform.scale(self.tipo, escala) + self.image = pygame.transform.rotate(self.imagen_original, -self.angulo) + x,y = self.rect.x, self.rect.y + self.rect = self.image.get_rect() + self.rect.x, self.rect.y = x, y + self.juego.event_muda(posicion=(self.rect.x, self.rect.y), tamanio=escala) + + def posicionar_al_azar(self): + # elige una posicion inicial al azar para el bicho + lista_de_rectangulos = [] + for bicho in self.juego.Bichos.sprites(): + # los rectangulos de los otros bichos + rectangulo = (bicho.rect.x, bicho.rect.y, bicho.rect.w, bicho.rect.h) + lista_de_rectangulos.append(rectangulo) + + random.seed() + x = random.randrange(self.area_visible[0]+10, self.area_visible[0]+self.area_visible[2]-10, 1) + y = random.randrange(self.area_visible[1]+10, self.area_visible[1]+self.area_visible[3]-10, 1) + self.x, self.y = (x,y) + self.dx = 0 + self.dy = 0 + self.actualizar_posicion() + + while self.rect.collidelist(lista_de_rectangulos) != -1: + x = random.randrange(self.area_visible[0]+10, self.area_visible[0]+self.area_visible[2]-10, 1) + y = random.randrange(self.area_visible[1]+10, self.area_visible[1]+self.area_visible[3]-10, 1) + self.x, self.y = (x,y) + self.dx = 0 + self.dy = 0 + self.actualizar_posicion() + + def play_sonido_bicho(self): + self.sonido_bicho.play() + + def set_tiempo_de_vida(self): + self.horas += 1 + if self.horas == 24: + self.dias += 1 + self.horas = 0 + + if self.dias == 365: + self.anios += 1 + self.dias = 0 + + def update(self): + # Actualiza el sprite + # determinar condiciones de vida + if self.hambre <= VG.LIMITEHAMBRE or self.sed <= VG.LIMITESED or self.dias >= VG.LIMITEVIDA: + comportamiento = "muere" + else: + comportamiento = "vive" + + # Si está viva + if comportamiento == "vive": + # Mudas de exoesqueleto + if self.dias == self.control_mudas and self.horas == 0: + + indice = self.dias_mudas.index(self.dias) + self.set_muda(escala=self.escalas_mudas[indice]) + self.velocidad += int(self.velocidad/3) + + if indice+1 < len(self.dias_mudas): + self.control_mudas = self.dias_mudas[indice+1] + else: + self.control_mudas = self.dias_mudas[0] + + # Reproducción + if self.dias == self.control_repro and self.horas == 0 and self.sexo == "F": + indice = self.dias_repro.index(self.dias) + + if indice+1 < len(self.dias_repro): + self.control_repro = self.dias_repro[indice+1] + else: + self.control_repro = self.dias_repro[0] + + if self.juego.machos: + self.juego.event_reproduccion(posicion=(self.rect.centerx, self.rect.centery)) + + comportamiento = "normal" + + elif comportamiento == "muere": + # se muere + self.juego.event_morir(posicion=(self.rect.centerx, self.rect.centery), dias=self.dias) + self.kill() + return + + if not self.agua_en_escenario.sprites() or self.sed >= 100: + # Si no hay alimento en el escenario o el bicho no tiene sed + comportamiento = "normal" + elif self.agua_en_escenario.sprites() and self.sed < 100: + # si hay alimento y tiene hambre + comportamiento = "buscar agua" + + if comportamiento == "normal": + if not self.alimento_en_escenario.sprites() or self.hambre >= 100: + # Si no hay alimento en el escenario o el bicho no tiene hambre + comportamiento = "normal" + elif self.alimento_en_escenario.sprites() and self.hambre < 100: + # si hay alimento y tiene hambre + comportamiento = "buscar comida" + + self.comportamiento(comportamiento) + + def comportamiento(self, comportamiento): + # decide el tipo de comportamiento según necesidades + if comportamiento == "normal": + if self.contador == 30: + # cada 30 pasadas, cambia acción + acciones = ["camina", "gira", "quieto"] + random.seed() + self.accion = random.choice(acciones) + self.contador = 0 + self.contador += 1 + self.decide() + elif comportamiento == "buscar comida": + self.alimentarse() + elif comportamiento == "buscar agua": + self.beber() + else: + print "comportamiento sin tratar: ", comportamiento + + def beber(self): + # Busca el alimento, cuando lo encuentra se alimenta + agua = self.agua_en_escenario.sprites()[0] + + if self.rect.colliderect(agua.rect): + # si ya llegamos al agua no nos movemos + self.accion = "quieto" + + if self.contador >= 30: + # cada treinta pasadas bebe + self.sed += VG.RINDEAGUA + agua.cantidad -= VG.CONSUMOAGUA + self.contador = 0 + if self.sed >= 100: self.sed = 150 + if agua.cantidad <= 0: + agua.kill() + self.agua_en_escenario.empty() + self.contador += 1 + return + + else: + # Si no hemos llegado al agua + posicion_agua = agua.rect.center + + # calcular la distancia al alimento + distancia_x = posicion_agua[0] - self.rect.x + distancia_y = posicion_agua[1] - self.rect.y + + self.dx, self.dy = self.get_vector(self.angulo) + + # calcular distancia si me muevo en el sentido actual + futura_posicion_x = self.rect.x + self.dx + futura_posicion_y = self.rect.y + self.dy + + # Verificar si al moverme me acerco o me alejo del alimento + if ((futura_posicion_x - self.rect.x) <= distancia_x and (futura_posicion_y - self.rect.y) <= distancia_y): + # Si me acerco, camino + self.accion = "camina" + self.decide() + else: + # si no me acerco, giro + self.accion = "gira" + self.decide() + + def alimentarse(self): + # Busca el alimento, cuando lo encuentra se alimenta + alimento = self.alimento_en_escenario.sprites()[0] + + if self.rect.colliderect(alimento.rect): + # si ya llegamos al alimento no nos movemos + self.accion = "quieto" + + if self.contador >= 30: + # cada treinta pasadas come + self.hambre += VG.RINDEALIMENTO + alimento.cantidad -= VG.CONSUMOALIMENTO + self.contador = 0 + if self.hambre >= 100: self.hambre = 150 + if alimento.cantidad <= 0: + # el que come de último limpia :P + alimento.kill() + self.alimento_en_escenario.empty() + self.contador += 1 + return + + else: + # Si no hemos llegado al alimento + posicion_alimento = alimento.rect.center + + # calcular la distancia al alimento + distancia_x = posicion_alimento[0] - self.rect.x + distancia_y = posicion_alimento[1] - self.rect.y + + self.dx, self.dy = self.get_vector(self.angulo) + + # calcular distancia si me muevo en el sentido actual + futura_posicion_x = self.rect.x + self.dx + futura_posicion_y = self.rect.y + self.dy + + # Verificar si al moverme me acerco o me alejo del alimento + if ((futura_posicion_x - self.rect.x) <= distancia_x and (futura_posicion_y - self.rect.y) <= distancia_y): + # Si me acerco, camino + self.accion = "camina" + self.decide() + else: + # si no me acerco, giro + self.accion = "gira" + self.decide() + + def decide(self): + # gira, camina o se queda quieto + if self.accion == "gira": + self.gira() + self.accion = "camina" + + if self.accion == "camina": + self.dx, self.dy = self.get_vector(self.angulo) + self.actualizar_posicion() + + if self.accion == "quieto": + pass + + def gira(self, sent=0): + # la cuca gira + random.seed() + if sent == 0: self.sent = random.randrange(1, 3, 1) + + if self.sent == 1: + # hacia la izquierda + self.angulo -= int(0.7 * INDICE_ROTACION) + elif self.sent == 2: + # hacia la derecha + self.angulo += int(0.7 * INDICE_ROTACION) + + self.image = pygame.transform.rotate(self.imagen_original, -self.angulo) + + def actualizar_posicion(self): + # La cuca se mueve + x = self.x + self.dx + y = self.y + self.dy + posicion = (x,y) + if self.area_visible.collidepoint(posicion): + # Si no me salgo del area permitida + if not self.verificar_colision_en_grupo(posicion): + # Si no caminaré sobre otra cucaracha + self.x += self.dx + self.y += self.dy + self.rect.centerx = int(self.x) + self.rect.centery = int(self.y) + else: + self.gira(sent=self.sent) + self.accion = "quieto" + else: + self.gira(sent=self.sent) + + def verificar_colision_en_grupo(self, posicion): + # evita que caminen unas sobre otras + grupo = self.groups() + for group in grupo: + for cuca in group.sprites(): + if cuca != self: + if cuca.rect.collidepoint(posicion): + return True + return False + + def get_vector(self, angulo): + # Recibe un ángulo que da orientación. Devuelve el incremento de puntos x,y + x = int(cos(radians(angulo)) * self.velocidad) + y = int(sin(radians(angulo)) * self.velocidad) + return x,y + -- cgit v0.9.1