Estoy tratando de implementar una variable que tome los valores discretos 1, 0, -1, 0 en ese orden, cambiando a un nuevo valor en cada step. Es decir, para los primeros steps de juego la variable valdría lo siguiente:

Step   Variable
1        1
2        0
3        -1
4        0
5        1
6        0
7        -1
8        0
9        1
10        0
etcétera

Mi pregunta es cuál será la forma más eficiente de hacer esto, dado que en el peor de los casos habrá 154 instancias ejecutando el código para darle el valor a la variable. Pensé en 3 formas (tomando como v la variable y n una variable auxiliar que parte en 0 y se incrementa en 1 en cada step):

1. Una función definida como:

v=-n+1    para n=0,1,2
v=0           para n=3

Además el código tendrá que hacer n=0 cuando n>3

2. usando trigonometría:

v=cos(n*pi()/2)
para n=0,1,2,3,4,etc.

Esta forma tiene la ventaja de que no requiere resetear a cero la variable n

3. Definiendo una función para cada valor de n (se parece a la solución Nº1 pero no requiere descomponer la función en 2 partes):

f[0]=1;
f[1]=0;
f[2]=-1;
f[3]=0;
v=f[n];
para n=0,1,2,3

Esta forma también requiere hacer n=0 cuando n>3

Voy a ser más concreto. Todo esto es para poder desplazar un sprite horizontalmente 1 pixel para dar la impresión de que está vibrando. Mi idea es que en el evento draw el código tome la forma:

draw_sprite_ext(sprite_index,-1,x+v,y,image_xscale,image_yscale,image_angle,image_blend,image_alpha);

Pensé en hacer que el sprite (que es de 32x32) tenga 4 subimágenes en vez de una, con cada subimagen desplazada 1 pixel horizontalmente respecto a la anterior de acuerdo a la secuencia que indiqué y así me evito todo el problema del cálculo de v en el evento step. Pero como voy a tener 4 objetos que tienen que hacer esto, cada uno con su sprite, paso de tener 4 imágenes de 32x32 a 16 imágenes de 32x32. Tal vez esta forma no sea tan descabellada considerando los tamaños de los sprites.

¿Qué será más eficiente de hacer para lograr lo que quiero?   :-\


Yo usaría algo así:

CREATE
[gml]
incremento = 1
variable = 1
[/gml]

[DRAW] o [STEP], después de haber desplazado el objeto o el sprite
[gml]
if (variable >= 1) or (variable <= -1)
     incremento *= -1
variable += incremento
[/gml]

Personalmente no creo que tengas que preocuparte por la eficiencia en este caso. El método de 4 subimágenes para simular el temblor se me hace bastante viable ya que 4 sprites animados de 32X32 es algo ligero pensando en el equipo promedio. Dudo que este método consuma muchos recursos. Quizás yo evitaría usar las funciones trigonométricas, ya que de cuando en cuando me topo hilos en la GMC mencionando que son lentas o más demandantes que la mayoría de las funciones de GML, pero la verdad es que no he hecho pruebas para comprobar si realmente afectan el rendimiento de un juego.

De ahí en fuera, creo que cualquier método de los que has planteados serviría.

Gracias por la respuesta. Parece que el método que propones es el más eficiente; se podría comprimir aún más como:

if variable!=0
     incremento *= -1
variable += incremento


Ahora, la página de textura es una sola y me caben con holgura los 16 sprites de 32x32 en ella (para el caso de que todo lo haga con varias subimágenes en vez de usar código en step). Respecto a las funciones trigonométricas, tenía entendido que son rápidas y por eso no las descarté desde el principio (https://www.yoyogames.com/tech_blog/75). Sin embargo, parece que me voy a decantar por el método de las subimágenes.