Cherils; 20151119

Aunque probablemente no toque hoy nada (bueno, nunca digas nunca), voy a apuntar unas cosas que se me están ocurriendo para ROM3.

En principio hemos hablado de que, para cambiar un poco, ROM3 contendrá un único nivel un poco más largo que emplee scripting para puzzles sencillos, rollo castillo de Ninjajar (bueno, dentro de las limitaciones del mscnes, aunque no descarto petarlo todo bien para llevarlo al mismo nivel que el msc3 de MK2). El ahorro en pantallas, enemigos y decoraciones del nivel extra dará para esto y más.

El tema estará inspirado en la cueva que introdujimos en el Perils de Megadrive. Podemos llenarlo de enemigos para que el rollo resonador y matar siga activo, aunque pondremos bastantes menos. Además, metermos un boss al final que no se accesible hasta que encontremos ciertos objetos y resolvamos un puzzle muy tonto. La resolución de otros puzzles será necesaria para conseguir los otros objetos.

El tema es que hay una compuerta sellada que nos impide el acceso a la recámara del bicho maligno mayor. Para abrir la compuerta sellada hay que completar un puzzle de ruedas dentadas (o cogs, en inglés) a lo TR1 colocando tres ruedas dentadas en el sitio correcto (tengo que pensar cómo dar pistas para sugerir la colocación correcta) – hay que explicar también que si se activa el mecanismo con las ruedas en orden incorrecto la cueva se viene abajo y será GAME OVER.

Una vez colocadas las ruedas, hay que activar dos interruptores, pisándolos. Obviamente, sólo podemos activar uno con nuestro cuerpo, así que habrá que conseguir un peso que dejar en el otro botón.

En principio no quiero introducir un inventario, con lo que sólo podríamos llevar un objeto cada vez, como en Goddess. Lo que haré, para que no sea un puto tedio, es intentar que el mapa de rutas de vuelta al hub principal que sean relativamente sencillas, rollo caer por un pozo inutilizable en el viaje “de ida” y artefactos similares.

Luego tenemos el tema del boss. Para no joder la marrana con la limitación de sprites, el boss debería medir a lo sumo 6 sprites de ancho, o sea, 48 pixels. Eso es ya enorme y me deja sin sprites seguro, así que tendré que buscar un tamaño menor dependiendo del número de patrones que me queden libres. De entrada Josito ha pintado todos los enemigos y las plataformas. Podría pasar de plataformas y ganar así más patrones, aunque no demasiados, la verdad. Haré también las modificaciones necesarias al motor para poder generar por HW las versiones espejadas de los metasprites en vez de hacerlo directamente en los patrones. Ya veré de cuánto espacio dispongo para esto.

El boss tendrá un patrón de movimiento prefijado en la pantalla y disparará proyectiles (¡cuidado con esto y con el límite de sprites, de nuevo!). Cheril tendrá que trepar por algunas plataformas, situarse arriba, y saltar un cierto número (¿8, 10?) de veces sobre su cabeza. Nada del otro mundo, pero efectivo.

Creo que un monstruo de 32 x 32 pixels es lo suficientemente grande en un juego de estas características donde todos los demás sprites son relativamente pequeños.

~~

TODO para ROM2, que no se me olvide:

Cambiar la detección de las cintas transportadoras de un punto a dos, porque ahora lo que ocurre es que la cinta te desliza hasta el punto en el que no es detectada, pero en este punto aún estamos sobre ella (con un pie). La colisión vertical se hace sobre dos puntos, +4 pixels y +11 pixels del origen horizontal, que corresponden vagamente con los dos pies, pero la detección de cinta transportadora se hace únicamente sobre el punto +7 pixels del origen. Con cambiar a que se detecte en los mismos puntos que la colisión lo tengo arreglado.

~~

Necesitaría para ROM3:

  • Introducir los suelos resbalosos: detección de (un nuevo) atributo de “suelo resbaloso” en el tile que pisamos y cambiar de forma dinámica AX y RX.
  • Introducir una forma de presentar textos en pantalla. Debido a las restrucciones sobre la actualización de los nametables, tendré que mostrar la caja de texto linea a linea usando el array de updates que cada VBLANK se copian al nametable. Cuando haya que redibujar la pantalla, me temo que habrá que hacer un reenter completo (fade out, ppu_off, redibujado, ppu_on_all, fade in). También habrá que apagar los sprites antes de empezar.  Esto me limitará un poco pero no es ningún drama.
  • Desactivar ventiladores. Desactivar cintas transportadoras. (para ganar espacio).
  • ¿Dejo sierras? No sé si pegan – a lo mejor cambiando el sprite por otra cosa.
  • ¿Dejo fantys? Sí, aquí creo que sí que pegan.

~~

Creo que me voy a quitar de encima el detallito del impacto con las prisioneras en D’Veel’Ng y a arreglar el tema de la detección de cintas transportadoras en ROM2 antes de hacer nada más complejo. Es un ratow. Pero después de desayunar.

~

D’Veel’Ng: al final lo que he hecho ha sido mucho más chulo: nuevos cells para la prisionera acusando el impacto. Ahora sí que está esto maqueao – maqueao.

Perils, ROM2: modificada la detección de las cintas transportadoras. Arreglado el problema.

Next: probablemente, pezones. Hay que darle un poco de vidilla al Goddess, que se me anquilosa.

~

¡Pezones on! La verdad es que era un patrón de movimiento la mar de sencillo. Como tengo patrones de sprites libres aún, he creado un sprite con forma de tile superior de agua para taparlo bien. Apenas se ve unos instantes, pero es suficiente para que yo me coscase de que el recorte era cuadrado y no con formita de ola.

Ahora mismo funcionan así:

  • En el colocador, definimos la posición desde donde saltan (dentro de agua, se entiende).
  • Con la “velocidad” del colocador, definimos la frecuencia con la que salen. Ahora mismo esta frecuencia es PEZON_WAIT + v*8, y PEZON_WAIT vale 50 (1 segundo) en mi configuración actual. Esto significa que la espera mínima será de 1 segundo entre que entra en el agua y vuelve a saltar. Para lograr 2 segundos habrá que usar v = 6 (6*8 = 48 ~ 50, más o menos) y así.
  • Internamente reaprovecho en_mx y en_my, que no los uso, para almacenar el maximo que hay que esperar y la cuenta de dicha espera.
  • En en_alive guardo el estado: 0 esperando, 1 saltando.
  • En el estado esperando, se decrementa en_mx. Cuando llega a 0, se posicion al pezón usando la coordenada de subpixel enf_y, se inicializa su velocidad actual enf_vy al valor PEZON_THRUST, y se pasa al estado saltando.
  • En el estado saltando, se modifica en cada frame enf_vy con el valor de PEZON_G (la gravedad), y se suma enf_vy a enf_y para moverlo. Luego se convierte de subpixel a pixel en en_y, y se compara con la posición inicial en en_y1. Si es mayor o igual, se borra el sprite, se reinicia el contador, y se pasa al estado esperando.

Piece of cake. Que sí.

Y ahora ¿qué? ¿chac chac?

~

Cuchillas que hace Chac Chac

A ver, voy a hacer un poco de brainstorming que esto me ayuda a pensar y a resolver mierda. Veamos…

Las cuchillas que hacen chac chac van colocadas en pasillos y puede haber como máximo tres, porque las voy a colocar en el colocador de enemigos. Vamos, que serán como enemigos. Luego las pintaré como tiles porque esto me conviene más, como se verá más abajo. Ocupan tres tiles de alto (48 pixels) y se colocan en el tile que ocuparía su tile superior. El mapa ya va preparado dejando espacios de tres tiles de alto para colocarlas.

Necesitaré seis tiles en el tileset para representarlas. A ver cómo lo represento aquí:

0   1   2   3   4   5
vv  ··  XX  ^^  vv  XX
··  ^^  vv  XX  ^^  XX

Los tiles 2 a 5 tendrán comportamiento 1 para que maten al jugador si toca la cuchilla.

Tendremos seis estados en los que se pintarán esto:

0   1   2   3   4   5
··  vv  XX  XX  XX  vv
··  ··  vv  XX  vv  ··
··  ··  ··  vv  ··  ··
··  ··  ··  ^^  ··  ··
··  ··  ^^  XX  ^^  ··
··  ^^  XX  XX  XX  ^^

Estado 0: Espera ahí sin pintar nada un número de cuadros definido haciendo alguna cuenta con la velocidad que pongamos en el colocador, al igual que la espera de los peces. A esta espera le llamamos “IDLE_1”.

Estado 1: La cuchilla “avisa” que va a salir. Aún no mata. Muestra los dientecicos y espera un número fijo (configurable) de frames, tiempo que llamaremos “IDLE_2” (por ejemplo, 50 frames – 1 segundo)

Estado 2: Aquí ya mata. Este estado dura “IDLE_3” frames, configurables (corto, 8 frames o así).

Estado 3: También mata. La chuchilla ha hecho chac. Este estado dura “IDLE_4” frames, configurables (por ejemplo, 150 frames, 3 segundos).

Estado 4: Igual que el 2.

Estado 5: Igual que el 1.

Las actualizaciones se hacen usando la función draw_map_tile para que se actualicen los comportamientos en el buffer de forma automática y te maten y dejen de matar acorde a ello.

Voy a hacer la infraestructura necesaria (pintar los tiles, modificar la importación…) y luego veo de implementarlo todo.

~~

Puah, en realidad con el planteamiento de más arriba era cosa fácil y ha salido a la primera 🙂 Ya hay pezones y chac chacs, ahora tengo que ver qué mas cosas meter. Pero antes voy a hacer un repaso y voy a ir a lo importante: tengo que programar toda la interacción con los objetos y tal, que dije que lo iba a hacer como hotspots. Luego haré una lista de lo necesario y lo resolveré en un santiamén.

Me encantan las mañanas productivas ¡y sin emplear apenas tiempo!

~~~~

Hotspots con la lógica del juego.

Tengo muy decidido que los objetos (piedra, papel y tijeras, además de la llave) van a ser hotspots, o sea, se pintarán como sprites. Ahora mismo los tengo en el tileset. Los voy a mover al spriteset. Tengo OAM libre de sobra para mostrar el objeto que llevamos en el marcador usando un sprite. Lo colocaré en las entradas 24-27, tras los que ocupan los sprites. Los colores del spriteset son un poco raros pero algún apaño podré hacer.

Con un sencillo custom puedo controlar qué objeto llevo e intercambiar el que llevo por el que hay en el hotspot cuando lo toque. Esto es sencillo porque el objeto que hay en el hotspot lo tengo copiado en RAM.

Voy a marcarme este primer hito: coger objeto, mostrarlo en el marcador, intercambiar por otro si ya tienes uno, etc.

~

Hecho. Ya se puede coger el objeto que hay en un hotspot, intercambiándose por lo que llevemos “casilla vacía” incluída. Ahora tengo que automatizar el “utilizar” un objeto. Se me ocurre que puedo hacerlo con hotspots también.

Si defino un offset HS_USE_OFFS, podemos hacer que si se pulsa “B” sobre un hotspot (invisible) de tipo T y el objeto que llevamos en el inventario (pinv) es T – HS_USE_OFFS, se sume 1 a la variable p_objs. Así puedo ir controlando cosas sin scripting. Con esto puedo implementar los templos sin ningún trabajo. Además, tengo que meter la animación de “usar objeto”. A ver, se me ocurre esto:

  • Player pulsa FIRE sobre un hotspot en el rango de los “receptores”.
  • Si pinv != T – HS_USE_OFFS, se saca el “NO!” como en el Perils (tengo que añadirlo al spriteset).
  • Si pinv == T – HS_USE_OFFS, se suma a p_objs, se activa la animación, se desactiva el hotspot.
  • Mientras esté la animación, el jugador no se mueve (hacer esto en player_move).

Esto suena bien 🙂 Vamos al líow. A ver si me da tiempo.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s