[sbfury] 4 new revisions pushed by hugoruscitti on 2010-06-20 01:52 GMT

2 views
Skip to first unread message

codesite...@google.com

unread,
Jun 19, 2010, 9:53:51 PM6/19/10
to losersjue...@googlegroups.com
4 new revisions:

Revision: ce5ab9454e
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 15:54:40 2010
Log: creando sistema de sonidos.
http://code.google.com/p/sbfury/source/detail?r=ce5ab9454e

Revision: be1867dc2b
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 15:58:19 2010
Log: documentando el nuevo modulo de sonidos.
http://code.google.com/p/sbfury/source/detail?r=be1867dc2b

Revision: 39b8e5b51f
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 16:30:00 2010
Log: documentando el personaje shaolin y un poco como es la
implementacion ...
http://code.google.com/p/sbfury/source/detail?r=39b8e5b51f

Revision: 9cd86895ed
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 18:49:49 2010
Log: creando estados para los personajes e implementando un sistema de AI
s...
http://code.google.com/p/sbfury/source/detail?r=9cd86895ed

==============================================================================
Revision: ce5ab9454e
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 15:54:40 2010
Log: creando sistema de sonidos.
http://code.google.com/p/sbfury/source/detail?r=ce5ab9454e

Added:
/data/sounds/punch1.ogg
/data/sounds/punch1.wav
/sbfury/sound.py
Modified:
/sbfury/collision.py
/sbfury/common.py
/sbfury/config.py

=======================================
--- /dev/null
+++ /data/sounds/punch1.ogg Sat Jun 19 15:54:40 2010
Binary file, no diff available.
=======================================
--- /dev/null
+++ /data/sounds/punch1.wav Sat Jun 19 15:54:40 2010
Binary file, no diff available.
=======================================
--- /dev/null
+++ /sbfury/sound.py Sat Jun 19 15:54:40 2010
@@ -0,0 +1,17 @@
+# -*- encoding: utf-8 -*-
+# Shaolin's Blind Fury
+#
+# Copyright 2008 - Hugo Ruscitti
+# License: GPLv3 (see http://www.gnu.org/licenses/gpl.html)
+
+import config
+import common
+
+class Sound:
+
+ def __init__(self):
+ self.sounds = {}
+ self.sounds['punch1'] = common.load_sound("sounds/punch1.wav")
+
+ def play(self, code):
+ self.sounds[code].play()
=======================================
--- /sbfury/collision.py Wed Jun 9 22:58:56 2010
+++ /sbfury/collision.py Sat Jun 19 15:54:40 2010
@@ -24,6 +24,7 @@
super(HitEffect, self).__init__(must_be_updated=True)
self.image = self.animation.image
self.position = x, y
+ common.sound.play('punch1')

def update(self, dt):
"""Update animation state. Returns True if animation are done."""
=======================================
--- /sbfury/common.py Sat May 29 21:13:43 2010
+++ /sbfury/common.py Sat Jun 19 15:54:40 2010
@@ -11,6 +11,8 @@
import cocos
from cocos.director import director
from cocos.scenes import *
+from sound import Sound
+


def load_image(filename):
@@ -27,6 +29,12 @@
return pyglet.image.load(path).get_texture(rectangle=True)


+def load_sound(filename):
+ "Carga un sonido desde el directorio data"
+ dirname = os.path.abspath(os.path.dirname(__file__))
+ path = os.path.join(dirname, '..', 'data', filename)
+ return pyglet.media.load(path, streaming=False)
+
def load_animation(filename):
"""Creates a animation from file

@@ -65,3 +73,7 @@
def in_range(value, min, max):
"""Evaluate if value are in (min, max)"""
return min < value < max
+
+
+
+sound = Sound()
=======================================
--- /sbfury/config.py Sun Jun 13 11:30:30 2010
+++ /sbfury/config.py Sat Jun 19 15:54:40 2010
@@ -8,7 +8,7 @@
# Use `False` for fast blits
DEBUG_GL = False

-DEBUG = False
+DEBUG = True


NEW_PYGLET_LOOP = True
@@ -21,3 +21,4 @@
SHAOLIN_INITIAL_JUMP_SPEED = 12
SHOW_COLLISION_BOXES = False
SHOW_CONTROL_POINTS = False
+SOUNDS_ENABLED = True

==============================================================================
Revision: be1867dc2b
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 15:58:19 2010
Log: documentando el nuevo modulo de sonidos.
http://code.google.com/p/sbfury/source/detail?r=be1867dc2b

Added:
/doc/source/sonidos.rst
Modified:
/doc/source/index.rst

=======================================
--- /dev/null
+++ /doc/source/sonidos.rst Sat Jun 19 15:58:19 2010
@@ -0,0 +1,13 @@
+Sonidos
+=======
+
+El sistema de sonidos es muy sencillo, está representado
+por un objeto llamado ``Sound`` y se instancia dentro
+del script ``common``.
+
+Por lo tanto cuando quiera repoducir un sonido se tiene
+que llamar a este objeto de la siguiente manera:
+
+.. code-block:: python
+
+ common.sound.play('punch1')
=======================================
--- /doc/source/index.rst Sun Jun 6 19:36:23 2010
+++ /doc/source/index.rst Sat Jun 19 15:58:19 2010
@@ -16,6 +16,7 @@
colisiones
stage
shaolin
+ sonidos


Indices and tables

==============================================================================
Revision: 39b8e5b51f
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 16:30:00 2010
Log: documentando el personaje shaolin y un poco como es la implementacion
de estados.
http://code.google.com/p/sbfury/source/detail?r=39b8e5b51f

Modified:
/doc/source/shaolin.rst

=======================================
--- /doc/source/shaolin.rst Sun Jun 6 19:36:23 2010
+++ /doc/source/shaolin.rst Sat Jun 19 16:30:00 2010
@@ -1,4 +1,85 @@
Shaolin, el protagonista
========================

-
+Inicio
+------
+
+El personaje del videojuego se encuentra implementado en la
+clase ``Shaolin`` dentro del directorio ``shaolin``.
+
+El objeto que instancia al shaolin es la escena ``game`` dentro
+de la función ``_create_player_and_stage``.
+
+Estas son las lineas mas significativas:
+
+.. code-block:: python
+
+ shaolin_sprite = shaolin.shaolin.Shaolin()
+ control_layer = control.Control(shaolin_sprite)
+
+
+Control del personaje
+---------------------
+
+En el código anterior puedes ver que el objeto que se vincula
+al shaolin es ``Control``, esto es así porque en realidad
+quien determina los cambios de estado del shaolin es el propio
+usuario.
+
+El objeto control consulta el estado del teclado todo el tiempo
+y cuando detecta un evento llama el método ``on_control_press`` del
+shaolin.
+
+
+Shaolin, una maquina de estados
+-------------------------------
+
+El personaje del juego tiene que realizar muchas acciones: caminar,
+correr, golpear, saltar... etc.
+
+Para representar este comportamiento se ha optado por implementar
+el patrón estratégia (el mismo que se utiliza para administrar escenas).
+
+La idea es así, el personaje tiene un atributo que indica en qué
+estado se encuentra. Inicialmente está en estado ``Stand``:
+
+ class Shaolin(Sprite):
+
+ def __init__(self):
+ ...
+ self.set_state(states.Stand(self))
+
+entonces, a partir de ese momento lo que hace el personaje
+depende de lo que le han asignado como estado.
+
+Si el jugador pulsa una tecla, el objeto Shaolin recibe
+la tecla pulsada y la envía directamente a su instancia
+de objeto ``state`` para que la procese.
+
+Entonces, por ejemplo, el estado ``Stand`` puede interpretar
+una tecla como ``left`` para cambiar a otro estado, y así
+lograr que el personaje camine cuando se pulsa una tecla.
+
+Este es un código boceto de la clase ``Stand``:
+
+.. code-block:: python
+
+ class Stand(state):
+
+ def __init__(self, shaolin):
+ self.shaolin = shaolin
+ self.shaolin.set_animation('stand')
+
+ def on_control_press(self, map):
+ if map.motion:
+ new_state = Walk(self.shaolin, map)
+ self.shaolin.set_state(new_state)
+
+ def update(self, dt):
+ # lo que tenga que hacer cuando esta parado.
+ self.shaolin.update_animation(dt)
+
+
+Es decir, los nuevos estados se pueden crear indicando el
+objeto que manejan (en este caso shaolin) y luego llamando
+al método ``set_state``.

==============================================================================
Revision: 9cd86895ed
Author: Hugo Ruscitti <hugoru...@gmail.com>
Date: Sat Jun 19 18:49:49 2010
Log: creando estados para los personajes e implementando un sistema de AI
simple, usando una lista circular de estados.
http://code.google.com/p/sbfury/source/detail?r=9cd86895ed

Added:
/doc/source/enemies.rst
Modified:
/doc/source/index.rst
/sbfury/enemies/__init__.py
/sbfury/enemies/fat.py
/sbfury/enemies/hannia.py
/sbfury/enemies/state.py

=======================================
--- /dev/null
+++ /doc/source/enemies.rst Sat Jun 19 18:49:49 2010
@@ -0,0 +1,51 @@
+Enemies
+=======
+
+Los enemigos del juego son bastante similares al protagonista, tienen
+estados, también varias animaciones e interactúan con el sistema
+de colisiones.
+
+Todos los enemigos están dentro del módulo ``enemies`` y hereda del
+objeto ``Enemy``.
+
+
+Inteligencia artíficial con una rueda de estados
+------------------------------------------------
+
+Para que los enemigos se muevan por el escenario y puedan
+simular un comportamiento hostíl contra nuestro protagista se
+ha optado por un enfoque simple:
+
+ - cada enemigo tiene una lista de posibles estados.
+ - el comportamiento del personaje es cumplir cada uno de esos estados
en orden.
+ - la cadena de estados se utiliza como una rueda, vuelve a comenzar
cuando termina.
+
+De esta forma, si quieremos un personaje que pelee mal, tendríamos que
+armarle una cadena de estados acorde::
+
+ comportamiento = [WalkToPlayer(), Wait(), WalkRandom(), Wait(),
Punch()]
+
+(lo anterior es un ejemplo conceptual solamente).
+
+
+Un ejemplo
+----------
+
+Todos los enemigos que se generan tienen que tener esta lista circular
+de estados para ejecutar. Esto se suele hacer en el mismo constructor
+del personaje:
+
+.. code-block:: python
+
+ class SampleEnemy(enemy):
+
+ def __init__(self):
+ [...]
+ self.set_ai_states([state.Wait(self, 1),
state.WalkRandom(self, 1)])
+ self.go_to_next_ai_state()
+
+
+Luego, cada estado de la cadena tiene que hacer su tarea en un tiempo
+determinado por el ultimo argumento, y cuando termina tiene que llamar
+internamente a ``go_to_next_ai_state`` para seguir con el siguiente
+estado.
=======================================
--- /doc/source/index.rst Sat Jun 19 15:58:19 2010
+++ /doc/source/index.rst Sat Jun 19 18:49:49 2010
@@ -17,6 +17,7 @@
stage
shaolin
sonidos
+ enemies


Indices and tables
=======================================
--- /sbfury/enemies/__init__.py Sat May 29 21:13:43 2010
+++ /sbfury/enemies/__init__.py Sat Jun 19 18:49:49 2010
@@ -6,5 +6,30 @@
super(Enemy, self).__init__(must_be_updated=must_be_updated)
self.flip = True

+ def set_ai_states(self, ai_states):
+ "Define la rueda de estados que tiene que seguir el personaje (AI
simple)."
+ self.ai_states = ai_states
+ self.i = 0
+
+ def reset_ai_state(self):
+ "Reinicia la rueda de estados, generalmente porque lo han
golpeado."
+ self.i = 0
+
+ def _get_next_ai_state(self):
+ "Retorna el siguiente estado de la rueda de AI."
+ if self.i >= len(self.ai_states):
+ self.i = 0
+
+ next_state = self.ai_states[self.i]
+ self.i += 1
+
+ return next_state
+
+ def go_to_next_ai_state(self):
+ "Hace que el personaje siga las ordenes de la rueda de AI"
+ next_state = self._get_next_ai_state()
+ next_state.start()
+ self.set_state(next_state)
+
import fat
import hannia
=======================================
--- /sbfury/enemies/fat.py Sat May 29 21:13:43 2010
+++ /sbfury/enemies/fat.py Sat Jun 19 18:49:49 2010
@@ -24,7 +24,8 @@
super(Fat, self).__init__(must_be_updated=True)
self.position = x, y
self._load_animations()
- self.set_state(state.Stand(self))
+ self.set_ai_states([state.Wait(self, 4), state.Wait(self, 4)])
+ self.go_to_next_ai_state()
self.shadow = shadow.Shadow()
self.move(0, 0)

=======================================
--- /sbfury/enemies/hannia.py Sat May 29 21:13:43 2010
+++ /sbfury/enemies/hannia.py Sat Jun 19 18:49:49 2010
@@ -24,7 +24,8 @@
super(Hannia, self).__init__(must_be_updated=True)
self.position = x, y
self._load_animations()
- self.set_state(state.Walk(self))
+ self.set_ai_states([state.Wait(self, 1), state.WalkRandom(self,
1)])
+ self.go_to_next_ai_state()
self.shadow = shadow.Shadow()
self.move(0, 0)

=======================================
--- /sbfury/enemies/state.py Sat May 29 21:13:43 2010
+++ /sbfury/enemies/state.py Sat Jun 19 18:49:49 2010
@@ -5,6 +5,8 @@
# License: GPLv3 (see http://www.gnu.org/licenses/gpl.html)

from sprite import State
+import random
+


class Stand(State):
@@ -30,17 +32,47 @@
return True


-class Walk(Stand):
-
- def __init__(self, target):
+class Wait(Stand):
+
+ def __init__(self, target, seconds):
+ State.__init__(self, target)
+ self.seconds_to_wait = seconds
+
+ def start(self):
+ self.target.set_animation('stand')
+ self.dt = 0
+ print self.target, "Esperando:", self.seconds_to_wait, "segundos"
+
+ def update(self, dt):
+ self.dt += dt
+ self.target.update_animation(dt)
+
+ if self.dt > self.seconds_to_wait:
+ self.target.go_to_next_ai_state()
+
+class WalkRandom(Stand):
+
+ def __init__(self, target, seconds):
Stand.__init__(self, target)
- target.set_animation('walk')
+ self.seconds = seconds
+
+ def start(self):
+ self.dt = 0
+ self.target.set_animation('walk')
+ self.dx = random.choice([-0.25, 0.1, 0.25])
+ self.dy = random.choice([-0.25, 0.1, 0.25])

def update(self, dt):
+ self.target.move(self.dx * dt, self.dy * dt)
+ self.dt += dt
self.target.update_animation(dt)

+ if self.dt > self.seconds:
+ self.target.go_to_next_ai_state()
+

class HitStand(State):
+ "Recibe un golpe simple."

def __init__(self, target, collision_force):
State.__init__(self, target)
@@ -52,10 +84,13 @@

def update(self, dt):
if self.target.update_animation(dt):
- self.target.set_state(Stand(self.target))
+ "Si termina de sufrir el golpe reinicia la rueda de estados
AI."
+ self.target.reset_ai_state()
+ self.target.go_to_next_ai_state()


class HardHit(State):
+ "Cuando lo golpean fuerte."

def __init__(self, target):
State.__init__(self, target)
@@ -91,6 +126,7 @@
self.target.set_frame(3)

class Ground(State):
+ "Cuando el personaje permanece en el suelo"

def __init__(self, target):
State.__init__(self, target)
@@ -106,6 +142,7 @@


class GroundToStand(State):
+ "Representa al enemigo cuando se levanta del suelo."

def __init__(self, target):
State.__init__(self, target)
@@ -113,4 +150,6 @@

def update(self, dt):
if self.target.update_animation(dt):
- self.target.set_state(Stand(self.target))
+ "Si termina de sufrir el golpe reinicia la rueda de estados
AI."
+ self.target.reset_ai_state()
+ self.target.go_to_next_ai_state()
Reply all
Reply to author
Forward
0 new messages