Se puso de pie y se alejó, dejando a sus espaldas el árbol con la flor en el suelo. Quería que ese mismo lugar que consideraba que fue el inicio de todo, fuera también el final. No sabía por qué, sólo le gustaba hacer cosas simbólicas.
El día anterior le había dicho lo que sentía. La noche pasada y toda la mañana estuvo pensando en ella: en cómo había tomado coraje para llamarla aquel 28 de enero, en lo que hablaron, del zoológico, de los animales, del calor, la pileta, de cómo ella tenía ganas de volver a ver la peli de nemo; las llamadas que se sucedieron a partir de ese día, aprovechando que llegaba temprano a la facultad para marcar el teléfono y hablar, saber cómo estaba, compartir anécdotas; la vez que llegó tarde al parcial; cuando le comentó que creyó que le había ido mal; cuando le contó que le fue bien; cuando pensaban en el día en que ella fuera a una de sus clases; el momento en que le dijo que no iba a poder, la organización que hicieron para verse igual; el reencuentro, la caminata que tuvieron, las cosas que se contaron, la eterna sonrisa en la cara de ella; el momento en que se despidieron, la charla a la noche, la proposición de una salida al aire libre.
Nunca supo si de verdad ella se sentía como él creía, pero sí estuvo contento todo ese tiempo, “quizás sea ella”, se decía, y lo pensaba de verdad. Pero tuvo miedo, no quería hacer algo que la alejara el resto del año. Quería estar con ella.
La salida que llegó, los mensajes que fueron y vinieron hasta encontrarse, la caminata hasta el lugar; ella que sabía mucho, él que no; ella que hacía bromas, él que trataba pero no tenía inspiración; el momento que quizás hubiese merecido ese beso que tanto se preguntó si debió dar y que no hizo por temor, por inexperiencia, por tantas cosas; el almuerzo compartido, el show de la creación, la búsqueda de más animales; la despedida amistosa; el silencio que guardaron desde ese día hasta el inicio de clases.
El primer día que se sintió bien al estar sólo con ella; la primera semana, la segunda, la tercera; la curiosidad que la alejó; él que quería una relación, que le preguntó por las suyas; la semana que siguió, la semana que ella lo ignoró, la semana que él sufrió, que lamentó haber sido curioso; las semanas que tardó en recuperar su confianza; ella que ya no parecía interesada, que hablaba con otra gente; que ya no era sólo él como al principio.
Su cumpleaños; él que quería salir con ella, ella que no podía; tampoco lo lamentaba, que “no era bueno sentir culpa” decía; el juego que él le presentó, el que empezaron a jugar cada tanto; un par de salidas, un almuerzo, una tarde; el invierno, el silencio que guardaron.
El regreso de clases, el intento de acercamiento, el dejarse llevar por las emociones; el aburrimiento de las materias, la aparente indiferencia de ella hacia él, su cumpleaños acercándose, el regalo sentimental que él quería hacerle, por el que trabajó tanto; la semana en que todo parecía salir bien, el cumpleaños de ella, el mal inicio que tuvo, la tardanza en recibir el regalo, el tiempo que tardó en abrirlo, el gracias, y todo que seguía como siempre.
El detalle de una salida que se confundió con una cita, ella que no quería esa relación, él que aún tenía esperanza; la semana que lo puso mal; la flor que compró para disculparse con sinceridad; la respuesta de ella cuando se la dio, su frenético rechazo; la tarde de él de meditación en el parque, la necesidad de decir lo que sentía, la preparación que hizo, la flor que llevaba aún; el día en que lo dijo; el día que retornó al parque, la caminata que tomó mientras recordaba todo, los recuerdos y sentimientos que más atesoraba y que guardó en la flor; la necesidad de aceptar que había terminado; el futuro para el que se preparaba, que ya no dependería de él, en el que no estarían juntos, en el que ella sería con otra persona lo que él quizo para los dos.
Todo lo que aceptó cuando dejó la flor en el árbol y se alejó del parque caminando a su casa...
Saturday, October 22, 2011
Monday, February 14, 2011
Dungeon Crawler III
Después de experimentar con el dibujo de las barras y la info del personaje, me puse a hacer una visión extendida del nivel -estilo mapa- que no se si estará en la versión final (aunque está bueno poder ver cómo quedaron la mayoría de los chunks unidos). Ah, también hice magia y ahora hay hasta 16x16 chunks, dando un nivel de 80x80 bloques máximo.
Lo divertido del domingo y hoy a la mañana fue armar la generación de niveles. Primero se definían al azar las dimensiones del nivel. Como recordarán, cada chunk tenía 8 bits, NSEO ABCD, habiendo un 1 en N/S/E/O si existía una salida en esa dirección. La idea, entonces, era generar primero por X y luego por Y. Si no era el primer chunk en X, entonces asignaba su bit de salida Oeste al mismo que tenía el de salida Este de su vecino (X-1). Si no era el primer chunk en Y, hacía lo mismo con el de arriba. Si era el último en X, chequeaba que su salida Este fuera igual a la Oeste del primero en X, idem Y.
Pseudocódigo para los que lo pueden entender (nota: los tabs son nuestros amigos)
for (y = 0; y <= chunkSizeY; y++) {
for (x = 0; x <= chunkSizeX; x++) {
chunk[y][x] = random(); //Genera byte al azar
if (x > 0) chunk[y][x][5] = chunk[y][x - 1][4]
if (y > 0) chunk[y][x][7] = chunk[y - 1][x][6]
if (x == chunkSizeX - 1) chunk[y][x][4] = chunk[y][0][5]
if (y == chunkSizeY - 1) chunk[y][x][6] = chunk[0][x][7]
//Extras
}
}
Luego de los chequeos de salidas de arriba, hay que evitar que existan islas -pedazos de nivel inconectables-. La idea que se me ocurrió fue forzar a que haya una salida en 1 que no sea obligatoria, o sea, si por ejemplo estamos con x = 1, y = 0, la salida Oeste sería obligatoriamente la misma que la del Este del vecino, entonces por más que esté en 1 no cuenta y habría que ver las otras tres que son 'libres', digamos.
En el caso en que todas las salidas sean obligatorias, fuerzo a que exista una salida al norte, cosa de que no me quede ese chunk separado del resto. Generado el nivel, busco una posición al azar para el pj y otra para la salida.
¿Ventajas de no tener islas? Todo el nivel es explorable, no me tengo que preocupar porque no se pueda llegar a la salida, o encontrar un item o bicho, o algo. Bajar la escalera (ese es el dibujo) indica que hay que regenerar el nivel, las posiciones, los items, bichos, etc.
Lo siguiente sería agregar los mobs. En principio tengo pensado momias y murciélagos, después veré qué cosas se pueden dibujar con 8x8 pixels. Cada bicho definiría su poder de daño según su raza y la profundidad del dungeon, al igual que su HP. Estoy pensando en que aparecerían cuando el pj va caminando por ahí, al igual que con los items. Y además creo que estaría bueno dejar que se muevan en tiempo real -o sea, no un turno yo, un turno ellos- cosa de hacerlo más emocionante.
Bajar el hp de un bicho a cero quizás lo haría droppear algún item y daría una cierta experiencia que depende de la raza del bicho y la profundidad del dungeon.
En fin, tengo muchas cosas para pensar sobre cómo continuar y hacerlo divertido y justo en su dificultad. Creo que ya está al 50%, dado que así es un juego de exploración -aunque no el más entretenido quizás-.
Se aceptan ideas sobre mobs, items, skills, etc!!
a las
11:55:00 PM
Saturday, February 12, 2011
Dungeon Crawler II
Hace bastante que no comento los avances en el juego y ahora tengo algo de tiempo (un recreo bah :P)
Bueno, en principio empecé el martes a la tarde cuando tuve el programador en mis manos -bwahahaha-, lo segui el jueves con más tiempo y recién un poco. Las cosas que se pueden hacer por ahora es observar el nivel moviéndose con las flechas. El mundo es de hasta 75x75 (por tener 15x15 de los registros que comentaba antes, a los cuales voy a llamar Chunk porque me recuerdan a lo que hace Minecraft)
Un Chunk, entonces, es un byte codificado como "NSEO ABCD", habiendo un bit en N/S/E/O si hay una salida en esa dirección y siendo ABCD la forma que tiene el conjunto de bloques. Hay 16 combinaciones de ABCD, pero sólo ocho de ellas dan forma a conjuntos distintos -no, no me iba a poner a pensar dieciseis diferentes-.
El truco está en que cuando AB != CD, se generan dos conjuntos de 5x5 bloques que luego mediante un AND lógico arman las diferentes combinaciones. Si AB == CD, entonces se genera un único conjunto según el valor de AB.
Finalmente, si por ejemplo no hay salida al "norte", eso se traduce en un bloque de 5x5 vacío con la parte superior bloqueada que tendrá efecto en el conjunto final mediante un OR. Todo esto muy teóricamente, en realidad no necesita tooodos los 5x5 bloques para sacar los datos que usa.
Lo interesante vino cuando tuve que juntar dos o tres chunks para armar el byte que dice dónde hay bloques en las posiciones {(x + i, y), i <- [0 .. 8)} del mundo. Luego de eso tuve problemas con el redireccionamiento indirecto del PIC porque creía que andaba de otra forma :P
Bueno, en principio empecé el martes a la tarde cuando tuve el programador en mis manos -bwahahaha-, lo segui el jueves con más tiempo y recién un poco. Las cosas que se pueden hacer por ahora es observar el nivel moviéndose con las flechas. El mundo es de hasta 75x75 (por tener 15x15 de los registros que comentaba antes, a los cuales voy a llamar Chunk porque me recuerdan a lo que hace Minecraft)
Un Chunk, entonces, es un byte codificado como "NSEO ABCD", habiendo un bit en N/S/E/O si hay una salida en esa dirección y siendo ABCD la forma que tiene el conjunto de bloques. Hay 16 combinaciones de ABCD, pero sólo ocho de ellas dan forma a conjuntos distintos -no, no me iba a poner a pensar dieciseis diferentes-.
El truco está en que cuando AB != CD, se generan dos conjuntos de 5x5 bloques que luego mediante un AND lógico arman las diferentes combinaciones. Si AB == CD, entonces se genera un único conjunto según el valor de AB.
Finalmente, si por ejemplo no hay salida al "norte", eso se traduce en un bloque de 5x5 vacío con la parte superior bloqueada que tendrá efecto en el conjunto final mediante un OR. Todo esto muy teóricamente, en realidad no necesita tooodos los 5x5 bloques para sacar los datos que usa.
Lo interesante vino cuando tuve que juntar dos o tres chunks para armar el byte que dice dónde hay bloques en las posiciones {(x + i, y), i <- [0 .. 8)} del mundo. Luego de eso tuve problemas con el redireccionamiento indirecto del PIC porque creía que andaba de otra forma :P
Como resultado final, tengo un nivel de tamaño variable, de 1 hasta 15 chunks encolumnados por otros 1 a 15 chunks en fila, dándome los 15x15 chunks, o 75x75 bloques. Además, el mundo es circular y no tiene fin, ya que irse por el este termina llevando al oeste.
Pero basta por un rato de charla técnica y veamos un video:
El video creo que muestra un par de bugs (a ver si los encuentran!) que venían del mal uso del redireccionamiento indirecto. Estuve un rato en la mañana tratando de arreglarlo y es genial cuando sabés que algo está andando 'raro', entendés por qué salen los errores y tenés una sospecha de cuál es el problema, todo para que una búsqueda en google te dé la razón :)
Lo que hice hace un rato es agregar los datos del personaje. A modo de prueba le puse 17/50 de MP (magic points), 40/50 de HP y lvl 39. Dibujar las barras de HP y MP fue un desafío que creo haber solucionado de manera inteligente.
Por ejemplo, para el HP tengo dos barras, cada barra ocupando dos posiciones, digamosle, en el lcd, con cada subbarra teniendo ocho pixels de alto. La idea entonces fue usar el recurso mágico de la búsqueda binaria. Con cuatro subbarras (una potencia de dos), con ocho pixels cada una (otra potencia de dos), tenía entonces 32 pixels para ver de dibujar. La idea consiste en tomar la mitad del máximo de HP (25), ver si es mayor o menor que el actual (40), y a partir de ahí decidir si había que pintar más o menos de 16 pixels, para luego repetir el proceso.
En este caso, sería así:
MHP: 50
HP: 40
pixels = 0
MHP / 2 = 25
40 >= 25
pixels = 16
(MHP / 2) + MHP / 4 = 25 + 12 = 37
40 >= 37
pixels = 16 + 8 = 24
(MHP / 2) + MHP / 4 + MHP / 8 = 25 + 12 + 6 = 43
40 <>pixels = 16 + 8 = 24
(MHP / 2) + MHP / 4 + MHP / 16 = 25 + 12 + 3 = 40
40 >= 40
pixels = 16 + 8 + 2 = 26
Con 26 pixels para dibujar, sabía que tenía las primeras tres subbarras completamente llenas y la 4ta con 26 - 24 = 2 pixels
Lo mismo pasa con la de MP. El problema está en la barra de experiencia (XP), que no usa un byte sino dos (para poder tener 31256/65536 xp en vez de los limitados 78/255). La idea en el fondo sería la misma, aunque un poco más complicada porque tendría que manejar dos registros, pero creo que mañana estaría andando.
Y para terminar, dejo video de cómo quedó todo eso:
a las
12:47:00 AM
Subscribe to:
Posts (Atom)