elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  El martillo no se queda donde lo dejé.
0 Usuarios y 2 Visitantes están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: El martillo no se queda donde lo dejé.  (Leído 244 veces)
Tachikomaia


Desconectado Desconectado

Mensajes: 1.518


Hackentifiko!


Ver Perfil
El martillo no se queda donde lo dejé.
« en: 31 Marzo 2025, 20:54 pm »

Tengo 2 animaciones de Mario martillando.

En una está quieto, en la otra caminando.

Ambas tienen 6 frames.

En los 1eros 3 el martillo está arriba, en las demás abajo.

Cuando el personaje pase de quieto a caminando, o viceversa, debo cambiar la animación y quiero que el martillo quede como estaba, o sea, si estaba en el 2ndo frame en que está arriba, la otra animación debe empezar ahí.

Para eso puse una variable EtapaDeMartillo, que marca a qué frame debe irse.

Cada animación, en el frame 1, establece que es 1, y en los demás le suma 1.

Cuando debe ocurrir el cambio de animación, uso esto:
Código
  1. Player.SaveDeEtapaDeMartillo = Player.EtapaDeMartillo;
  2. Player.gotoAndStop(3);
  3. Player.Movie.gotoAndStop(Player.SaveDeEtapaDeMartillo);
  4. Player.EtapaDeMartillo = Player.SaveDeEtapaDeMartillo;
  5.  
Donde dice 3, en el otro caso es 2. No hay problema con eso. Lo demás son intentos de hacer que funcione pero no hay caso. No entiendo bien qué pasa, tengo estos prints:
f1, 1
f2, 2
f3, 3
f4, 4
quiet
f1, 4
f4, 2
walking
f1, 2
f2, 2
significa que, durante 4 frames estuvo bien, en el frame 1 la variable es 1, en el 2 es 2, etc, hasta 4, se estaba ejecutando la animación de que estaba quieto. En el 4to es cuando baja el martillo. Ahí empecé a caminar. Se activa el frame 1 de la otra animación, aunque ese frame no se muestre, aparentemente es inevitable, cuando carga la película se activa eso. Eso hace que EtapaDeMartillo sea 1, pero va al frame 4 donde debe ser 4, se le suma 1 ahí y queda 2, pero debe ser 4. Luego cuando dejo de caminar el martillo aparece encima, supongo que porque está en el frame 2.

Con SaveDeEtapaDeMartillo intenté que luego de que se cargue la película y se modifique EtapaDeMartillo, esta variable lo vuelva a su valor original, pero no funciona, como expliqué, es como si 1ero se ejecutara este código y luego el que está en la película.

Puedo poner un if en el 1er frame de las animaciones, que no resetee EtapaDeMartillo si acaba de ocurrir un cambio, pero parece una forma muy tosca de hacerlo ¿qué alternativas son mejores?

Citar
Tienes un problema clásico de _sincronización_ entre el código y la línea de tiempo en Flash/ActionScript. Básicamente, cuando haces `gotoAndStop()`, inmediatamente se ejecutan las acciones del primer frame del `MovieClip` al que estás yendo, **antes** de que tu siguiente línea de código se ejecute. Por eso tu variable `EtapaDeMartillo` se sobrescribe con `1` antes de que tengas oportunidad de restaurarla.

### ✅ Diagnóstico
Tu flujo actual es este:

1. Guardas `EtapaDeMartillo` en `SaveDeEtapaDeMartillo`.
2. Haces `gotoAndStop()` para cambiar de animación (`2` o `3`).
3. Al entrar al nuevo `MovieClip`, se ejecuta el **Frame 1**, que **resetea** `EtapaDeMartillo` a `1`.
4. Luego intentas restaurar `EtapaDeMartillo`, pero ya es tarde: el `MovieClip` ya avanzó y está desfasado.

---

## 🛠️ Soluciones posibles

### ✅ Solución 1: Usar una bandera para evitar el reset

Es la que tú mencionas, y aunque suene "tosca", **es una de las soluciones más robustas y utilizadas** en este tipo de casos. Aquí te la detallo bien organizada:

```actionscript
// Antes de cambiar de animación
Player.SkipResetEtapa = true;
Player.SaveDeEtapaDeMartillo = Player.EtapaDeMartillo;
Player.gotoAndStop(3); // o 2
Player.Movie.gotoAndStop(Player.SaveDeEtapaDeMartillo);
Player.EtapaDeMartillo = Player.SaveDeEtapaDeMartillo;
```

Y en el **frame 1** de cada animación:

```actionscript
if (!Player.SkipResetEtapa) {
    Player.EtapaDeMartillo = 1;
} else {
    Player.SkipResetEtapa = false;
}
```

Esto evita que el frame 1 sobrescriba `EtapaDeMartillo` si acabás de hacer un cambio controlado.

> 💡 *Este patrón se llama "flag de inicialización" y es muy común para evitar que el código embebido en los frames interfiera con lógica externa.*

---

### ✅ Solución 2: Mover la lógica de `EtapaDeMartillo` fuera de los frames

En lugar de que cada frame modifique `EtapaDeMartillo` desde la línea de tiempo, mueve la lógica a un solo lugar central en tu código. Esto te da **control total** y evita que los `gotoAndStop()` ejecuten código no deseado.

**Ventajas:**
- Código más limpio y mantenible.
- Sin efectos colaterales de `gotoAndStop`.

**Desventajas:**
- Necesitas refactorizar un poco tu animación para que no dependa de código en los frames.

---

### ✅ Solución 3: Usar `onEnterFrame` para aplicar el cambio luego del `gotoAndStop`

Otra técnica es **dejar que el frame se cargue** y luego, en el siguiente frame (es decir, en el siguiente `onEnterFrame`), restaurar la variable:

```actionscript
Player.SaveDeEtapaDeMartillo = Player.EtapaDeMartillo;
Player.gotoAndStop(3);
Player.RestaurarEtapa = true;

// Luego, en el onEnterFrame del jugador
if (Player.RestaurarEtapa) {
    Player.Movie.gotoAndStop(Player.SaveDeEtapaDeMartillo);
    Player.EtapaDeMartillo = Player.SaveDeEtapaDeMartillo;
    Player.RestaurarEtapa = false;
}
```

Esto asegura que el código del `MovieClip` se ejecute primero, y tú corrijas después.

---

## ✅ Recomendación final

La solución **más simple y efectiva** en tu caso es la **bandera en el frame 1**. Es clara, fácil de mantener, y resuelve el problema sin grandes refactorizaciones.

```actionscript
// En el frame 1
if (!Player.SkipResetEtapa) {
    Player.EtapaDeMartillo = 1;
} else {
    Player.SkipResetEtapa = false;
}
```

Y en tu código principal:

```actionscript
Player.SkipResetEtapa = true;
Player.SaveDeEtapaDeMartillo = Player.EtapaDeMartillo;
Player.gotoAndStop(3); // o 2
Player.Movie.gotoAndStop(Player.SaveDeEtapaDeMartillo);
Player.EtapaDeMartillo = Player.SaveDeEtapaDeMartillo;
```

¡Con esto deberías tener el martillo siempre en sincronía! 🛠️🍄

¿Querés que lo adaptemos a un ejemplo visual o interactivo en HTML?

Explícame la solución 2: Mover la lógica de EtapaDeMartillo fuera de los frames.

Citar
¡Claro! Vamos a desglosar bien la **Solución 2: mover la lógica de `EtapaDeMartillo` fuera de los frames**, para que entiendas **qué significa, cómo se hace, y por qué es útil**.

---

## 🧠 ¿Qué significa mover la lógica fuera de los frames?

En Flash/ActionScript, es común poner código dentro de los **frames de la línea de tiempo** de un `MovieClip`. Esto puede funcionar, pero también puede causar problemas de control, como el que estás teniendo.

**Mover la lógica fuera de los frames** quiere decir:

> En vez de que los propios frames del `MovieClip` modifiquen la variable `EtapaDeMartillo`, lo haces tú **desde el código externo**, es decir, desde donde estás controlando al personaje (`Player`), centralizando el control.

---

## 🧱 ¿Cómo es tu estructura actual?

Actualmente, en el `MovieClip` de la animación (por ejemplo, `Player.Movie`), en cada frame tenés algo como:

```actionscript
// En el frame 1
Player.EtapaDeMartillo = 1;

// En el frame 2
Player.EtapaDeMartillo += 1;

// En el frame 3
Player.EtapaDeMartillo += 1;

// ...
```

Esto significa que **el MovieClip decide** qué valor tiene `EtapaDeMartillo` en cada momento, según el frame.

---

## 🔄 ¿Cómo lo cambiamos?

Vamos a quitar esa lógica de los frames del `MovieClip`, y pasarla a un código central. Por ejemplo, en un `onEnterFrame` principal, o en el controlador del jugador.

### 1. Limpia los frames del MovieClip

Quita cualquier código que modifique directamente `EtapaDeMartillo` desde los frames del `MovieClip`.

```actionscript
// Frame 1, 2, 3, 4, etc.
(Eliminar el código que modifica Player.EtapaDeMartillo)
```

---

### 2. Controlás tú el avance de la animación y la etapa del martillo

En tu controlador de juego, pon algo como esto:

```actionscript
// Este código iría en onEnterFrame o en un bucle de juego
if (Player.estado == "quieto") {
    Player.gotoAndStop(2);
} else if (Player.estado == "caminando") {
    Player.gotoAndStop(3);
}

// Lógica del martillo
Player.EtapaDeMartillo += 1;
if (Player.EtapaDeMartillo > 6) {
    Player.EtapaDeMartillo = 1;
}

// Mostrar el frame correcto en la animación del martillo
Player.Movie.gotoAndStop(Player.EtapaDeMartillo);
```

---

## 🎯 ¿Qué ganás con esto?

- 🔄 **Sincronización perfecta**: sos vos quien decide **cuándo y cómo avanza el martillo**, no la animación.
- 💥 **Evita conflictos**: ya no hay riesgo de que un `gotoAndStop()` dispare código oculto en los frames y arruine tu sincronización.
- 🧼 **Código más limpio y predecible**: todo está en un solo lugar.

---

## 📌 Consideraciones

- Asegurate de que `EtapaDeMartillo` se actualice **una vez por frame**, y que `gotoAndStop()` apunte al frame correcto.
- Si querés que el martillo esté arriba por 3 frames y abajo por 3, simplemente ajustá tu lógica según el número del frame.

---

## 💡 Ejemplo completo simplificado

```actionscript
// En onEnterFrame
Player.EtapaDeMartillo += 1;
if (Player.EtapaDeMartillo > 6) {
    Player.EtapaDeMartillo = 1;
}

// Cambiar animación según estado
if (Player.estado == "quieto") {
    Player.gotoAndStop(2);
} else if (Player.estado == "caminando") {
    Player.gotoAndStop(3);
}

// Mostrar el frame correspondiente de la animación
Player.Movie.gotoAndStop(Player.EtapaDeMartillo);
```

---

¿Querés que te ayude a adaptar esto a tu código actual paso a paso?

Intentaré eso.


En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
porque no queda la imagen donde yo quiero [resuelto]
Desarrollo Web
adamsst 3 2,531 Último mensaje 18 Julio 2013, 20:12 pm
por T0p1t0
Y donde queda la herramienta EvilFoca de Chema Alonso?
Hacking Wireless
AlbertoPerez 1 5,320 Último mensaje 17 Septiembre 2015, 23:15 pm
por Sh4k4
Esta herramienta ayuda a abrir el IHS de un procesador con un martillo
Noticias
wolfbcn 0 1,247 Último mensaje 13 Febrero 2017, 02:19 am
por wolfbcn
Donde se queda?
Dudas Generales
Robocop8 9 4,748 Último mensaje 21 Julio 2017, 11:30 am
por Orubatosu
¿Queda algún sitio donde subir un swf que los navegadores ejecuten?
Dudas Generales
Tachikomaia 2 4,272 Último mensaje 26 Marzo 2024, 22:48 pm
por EdePC
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines