Tilengine - The 2D retro graphics engine forum

Full Version: como crear distintos efectos
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
He estado trasteando con los ejemplos de color_cycle y column_offset.

1-sobre color_cycle es algo muy impresionante que solo modifique donde estan las olas sin tocar los demas sprites,tienes que explicarme un poco sobre las funciones que se usan y sobre todo el archivo sqx,aqui tenemos palabras clave como "first,count,dir,delay",estas palabras no se para que sirven y como se usan.

2-sobre column_offset ya me pierdo,tenemos demasiadas cosas.

Code:
num_columns = int(WIDTH / 8 + 2)
columns = (c_int * num_columns)()
foreground.set_column_offset(columns)

Que es esto.sobre todo para que sirve c_int,lo quite y no funcionaba el ejemplo,luego tenemos esto.

Code:
for n in range(num_columns):
columns[n] = int(sin(radians(x_world * 4 + n * 7)) * ((abs(sin(radians(x_world / 4)) * 12)) + 4))
foreground.set_position(x_world, 0)
background.set_position(x_world / 4, 0)
x_world += 2

Aqui ya me exploto el cerebro,podrias hacer un ejemplo mas sencillo para entender esto.Por cierto,en este ejemplo empieza con poca intensidad y va en aumento la ondulacion,hay alguna manera de que la ondulacion siempre tenga el mismo ritmo.
Buenas de nuevo,

Ciclo de color
El archivo sqx creo que no lo tengo documentado en nigún sitio... Undecided 

Un ciclo de color consiste en hacer rotar progresivamente un rango de colores de una paleta. Por cada rango definido en la secuencia:
  • first: índice del primer color (0-255)
  • count: número de colores que comprende el rango
  • dir: dirección del ciclo, ascendente o descendente
  • delay: nº de fotogramas de pausa entre cambios (cuanto más delay, más lento)
Las ejemplos no son míos, se crearon hace muchos años para windows 3.1. Un tipo los adaptó a html5 en formato json, y de ahí yo lo capturé y convertí a png + sqx con un conversor automático que me hice a medida.

Efecto en html5 online:
http://www.effectgames.com/demos/canvascycle/

Conferencia del autor original de los gráficos explicando el proceso de creación:

https://youtu.be/aMcJ1Jvtef0?t=3084

Column offset
Este efecto te permite desplazar verticalmente las columnas que forman los tiles de un mapa respecto a la posición horizontal base. Es un efecto que tenía por hardware el chip gráfico de la Mega Drive.

1. Calcular el nº de columnas visibles en pantalla, se obtiene dividiendo la resolución en píxeles de la ventana por la anchura de cada tile, más 2. WIDTH tiene el ancho de ventana, y los tiles son de 8x8:
Code:
num_columns = int(WIDTH / 8 + 2)

2. Reservar un array de tantas columnas como hemos calculado antes. Cada columna requiere un entero (int) del lenguaje C en el que está escrito Tilengine, y c_int es el tipo de dato Python equivalente al int del C:
Code:
columns = (c_int * num_columns)()

3. Activar el effecto de offset de columna pasando el array creado antes sobre la capa foreground:
Code:
foreground.set_column_offset(columns)

Para poder ver algo, tienes que escribir valores en el array columns creado anteriormente, ya que por defecto está todo a 0, que significa "no desplazar". Por ejemplo el siguiente fragmento debería generarte un efecto de rampa o pendiente suave:

Code:
for n in range(num_columns):
    columns[n] = n

Más información sobre c_int:
https://torroja.dmt.upm.es/media/files/ctypes.pdf
Gracias por la informacion. Shy

Pero me gustaria que el efecto column offser tuviera siempre la misma intensidad y no empezara con baja intensidad y luego fuera subiendo,me gustaria que fuera igual que el primer nivel de darius 2,que es un fondo de fuego con un movimiento muy parecido a este efecto. 
Buenas,

En el Darius 2 que comentas, el efecto de ondulación es horizontal, se consigue mediante efectos raster. Tienes un efecto muy parecido en los ejemplos, hay uno que se llama Wobble.c  que combina ese effecto con el de column offset. Si te fijas sólo en la parte del efecto raster, eso mismo hace Darius 2.

En cuanto a la intensidad de la ondulación. De forma genérica, la función:

sin(a) * b
  • a es la expresión que controla la fase (posición de la onda) en cada punto. En su cálculo debe intervenir la posición de la columna y un factor de tiempo o la posición inicial del escenario para que consignas el efecto de que la onda se va desplazando
  • b es la intensidad de la onda, en píxeles. Si quieres que sea constante, b debe ser un número entero en vez de una expresión compleja. Pruébalo
Gracias,voy a probar lo que me comentas. Shy
Me gustaria que me explicaras el codigo del ejemplo vertical,este ejemplo esta muy chulo pero no entiendo muy bien el codigo.

Te pongo el codigo por si no lo tienes a mano.
Code:
"""
Tilengine python example:
Use raster effects and clipping to fake progressive perspective scaling
"""

from tilengine import *
from math import tan, radians

# helper constants
WIDTH = 360
HEIGHT = 400
SKY_HEIGHT = 64
LAND_HEIGHT = HEIGHT - SKY_HEIGHT

# variables
world_y = 0


# load layer assets and basic setup
def setup_layer(layer, name):
tilemap = Tilemap.fromfile(name)
layer.setup(tilemap)
engine.set_background_color(tilemap)


# linear interpolation
def lerp(x, x0, x1, fx0, fx1):
return fx0 + (fx1 - fx0) * (x - x0) / (x1 - x0)


# raster effect function
def raster_effect(line):
if line >= SKY_HEIGHT:
line -= SKY_HEIGHT
clouds.set_position(0, world_y * 2 + row_offsets[line] - line)
terrain.set_position(0, world_y / 2 + row_offsets[line] - line)


# init
engine = Engine.create(WIDTH, HEIGHT, 3, 0, 0)
skyfog = engine.layers[0]
clouds = engine.layers[1]
terrain = engine.layers[2]

# setup layers
engine.set_load_path("../assets/zelda")
setup_layer(skyfog, "sky.tmx")
setup_layer(clouds, "clouds.tmx")
setup_layer(terrain, "zelda.tmx")
skyfog.set_blend_mode(Blend.ADD)
skyfog.set_clip(0, 0, WIDTH, SKY_HEIGHT + 63)
clouds.set_clip(0, SKY_HEIGHT, WIDTH, HEIGHT)
terrain.set_clip(0, SKY_HEIGHT, WIDTH, HEIGHT)
engine.set_background_color(Color(0, 0, 0))

# setup raster callback
engine.set_raster_callback(raster_effect)

# precalc raster effect values and store in rows list
row_offsets = [int(tan(radians(lerp(n, 0, LAND_HEIGHT, 105.0, 180.0))) * 240) for n in range(LAND_HEIGHT)]

# main loop
world_y = terrain.height - HEIGHT
window = Window.create()
while window.process():
world_y -= 1
Este efecto simula la variación de curvatura de un cilindro, usando efectos raster para variar progresivamente la posición de inicio vertical de las capas, a partir de una tabla que se ha calculado previamente. Es el mismo efecto que usaba el juego de Super Nintendo, Axelay:
https://youtu.be/V3F3l-SiN78?t=40

En contra de lo que se dice popularmente, este juego no usaba el famoso Modo 7, sino que lo hacía con efectos de raster igual que en el ejemplo que comentas. Para el cálculo de la perspectiva cilíndrica se utiliza una proyección senoidal y una interpolación lineal, son temas de matemáticas que nada tienen que ver con tilengine.