Algo que reaprendo, porque cuando luego de un tiempo lo intento pasan cosas que no entiendo.
Lo quiero anotar en algún lado, al proceso correcto.
Por ejemplo, algo que se supone es sencillo.
Abro un juego, dice que tengo 2 vidas.
Esta interfase es de Virtual Nes, pero últimamente estoy usando Mesen, luego vemos ese.
Abro la ventana de busca trucos.
Pongo que sean valores hexadecimales.
Presiono Start para que aparezca la lista de valores.
Donde dice Data, escribo 2.
Presiono Search.
Me quedan las variables de valor 2:
Pierdo una vida, tengo 1.
Pongo Update.
Se muestra que algunos valores han bajado a 1. Alguno debería ser la cantidad de vidas:
Ahora quiero reducir la lista usando los botones, porque la lista no siempre es corta. Por eso dije que era un caso sencillo, la idea no es tanto hallar este cheat, sino entender cómo funciona el buscador.
Quiero que queden los valores cuyo Old sea > Now, porque antes tenía más, quiero que me diga los valores que disminuyeron.
Presiono Old > Now:
Se dieron vuelta los valores ¿es un error? El valor era 02 y aumentó a 0C, y me lo dice como si fuese el valor que disminuyó, porque los da vuelta, es un error ¿o qué estoy malinterpretando?
Pongo Undo.
No sé qué pasó, porque probé los botones, y los valores del juego parecen haber cambiado:
Pero no recuerdo haber quitado la pausa. La cuestión es que ahora el botón Old > Now me da una lista vacía, y el Now > Old me daba una lista vacía pero ahora me da esto:
¿No se supone que tenía variables de valor 2?
Voy a grabar un video así ven mejor qué hago mal, si es que hay algo.
Ahí lo tienen. ¿Por qué desaparecen TODOS los resultados sin importar que toque Old > Now o Old < Now? ¿qué hace exactamente? ¿no es para que queden los resultados que cumplen esas condiciones?
El emulador Mesen tiene una interfaz más simplona:
Pero si no pude entender el anterior que ya lo he usado, no ando con muchas ganas de intentar entender ese, además por ahora me cansé de esto.
La idea es que este Mario pueda convocar cosas como en su juego original: Maníbulas, pájaros, chispas...
Donkey Kong también otras cosas.
Otros personajes que ponga más adelante también, e incluso las cosas mismas (algunos pájaros de Mario dejan caer huevos, por ejemplo).
Algunas diferentes tipos de cosas se moverían igual, pero otras no.
El daño que hacen al colisionar con algo depende de qué cosa sea ella, y el algo. Aún no tengo seguro esto pero es básicamente poder de colisión y de defensa.
¿Cómo harían todo eso uds?
Quiero evitar líos.
Por ahora lo que se me ocurre es: - Crear una lista de Profundidades disponibles. En Flash cada cosa visible que se agrega debe tener cierta profundidad, un número, y si se pone que una tenga la misma que otra, la 1era desaparece. No sé si 1000 será muy pesado. Significaría que puede haber hasta 1000 cosas agregadas. - Crear una lista de Extras, que serían las cosas agregadas. - Cuando se agrega algo, se toma el 1er número disponible de Profundidades, y la cosa se agrega en la lista de Extras. Su nombre sería por ejemplo "Spark"+Numero (obtenido de Profundidad). Eso significa que podría haber Spark1 y Spark3, sin haber existido 2, si en medio se agregó otra cosa. Pero bueno, el número es su profundidad y para distinguir, no es un conteo de los tipos de cosas agregadas. - Cuando un extra desaparece, se agrega su número en Profundidades y su nombre se quita de Extras.
Y lo más complicado, un while que recorrería la lista de Extras llamando a sus correspondientes códigos y viendo si colisionan con otra cosa.
Para llamar a distintos códigos según qué extra sea, tendría que quitarle el número a su nombre, porque no puede existir una función Spark1Code, Spark2Code, etc, todos iguales, debe ser SparkCode, BirdCode, etc. Entonces en vez de una lista de extras podrían ser 2: - Una tiene los nombres con número para saber exacto qué cosa es, cuando se requiera moverla, etc. - La otra tiene sólo el nombre del tipo de cosa que es, así se sabe a qué código llamar.
Otra posibilidad sería que exista un objeto Pájaros, por ejemplo, donde se pongan ellos, y entonces no habría saltos en la numeración (aunque no es problema) y todos usarían el mismo código. No habría necesidad de funciones variables, pero habría muchos objetos generalmente en vano viendo si tienen algo en ellos... Creo que es mejor lo anterior.
Otra sería que en vez de una lista de Extras haya una de pájaros, etc, pero de nuevo serían muchos whiles, uno para cada lista, que generalmente estaría vacía, so...
Los códigos de las cosas agregadas, en vez de estar en la zona root pueden estar en ellos mismos, pero eso hace que se ejecuten luego de lo que esté en root, creo, así que tampoco parece buena idea.
¿Estará bien?
Ya tengo a Mario pudiendo caminar y dar latigazos, todo dependiente de la velocidad o fuerza que le ponga. Cuando tiene 1 MP convoca a una mandíbula. Me falta que se mueva. Donkey Kong camina hacia Mario golpeando su pecho a una velocidad dependiente de la que camina. No lo muestro porque me paspa grabar el video.
Código
// Las imágenes fueron tomadas con Virtualnes, zoom 2,
// copiadas desde Chrome.
// General:
fscommand("fullscreen", "true");
// Se refiere a convocados:
ListaDeExtras = [];
// Player:
attachMovie("sMarioDK", "Player", 1001);
setProperty("Player", _x, 20);
setProperty("Player", _y, 568);
// Determinan a qué función se llama:
Player.Action = "Quiet";
Player.Action2 = "Quiet";
Player.Facing = 1;
MarioDKHP = 1;
MarioDKMPMax = 1;
MarioDKMP = 1;
MarioDKMPRecovery = 0.003;
MarioDKPower = 2;
MarioDKSpeed = 0.5;
// La animación avanza cuando esto llega a 100:
MarioDKTurn = 0;
// La velocidad de la animación puede depender de la velocidad...
// de caminar, o de la fuerza, etc:
MarioDKTic = MarioDKSpeed*1.5;
// Para que al empezar a caminar o a quedarse quieto,
// el martillo quede como estaba, arriba o abajo,
// en el mismo nro de frame:
Player.EtapaDeMartillo = 1;
Player.ResetearEtapaDeMartillo = "No";
// IA:
attachMovie("sDK", "IA", 1000);
setProperty("IA", _x, 780);
setProperty("IA", _y, 568);
IA.Action2 = "Quiet";
IA.Facing = -1;
DKSpeed = 0.4;
IATurn = 0;
// Escenario:
attachMovie("sDKSuelo", "Suelo", 0);
setProperty("Suelo", _x, 0);
setProperty("Suelo", _y, 568);
// /////////////////////////////////////////////
// ////////////////// Most ///////////////////
// /////////////////////////////////////////////
function FaceRight (Character){
if(eval(Character+".Facing") == -1){
set(Character+".Facing", 1);
eval(Character)._xscale = 100;
}
}
function FaceLeft (Character){
if(eval(Character+".Facing") == 1){
set(Character+".Facing", -1);
eval(Character)._xscale = -100;
}
}
// /////////////////////////////////////////////
// ////////////////// Mario //////////////////
// /////////////////////////////////////////////
// Power up: Las criaturas que convoca se mueven mejor.
function ControlMario (){
if(Key.isDown(83)){
// Si se presiona S.
eval("SWhen"+Player.Action+Player.Action2)();
}elseif(Key.isDown(32)){
// Espacio:
eval("SpaceWhen"+Player.Action+Player.Action2)();
}elseif(Key.isDown(39)){
// Derecha:
eval("RightWhen"+Player.Action+Player.Action2)();
}elseif(Key.isDown(37)){
// Izquierda:
eval("LeftWhen"+Player.Action+Player.Action2)();
}else{
// Nada:
eval("QuietWhen"+Player.Action+Player.Action2)();
}
MarioDKTurn = MarioDKTurn + MarioDKTic;
if(MarioDKTurn >= 10){
MarioDKTurn = 0;
Player.EtapaDeMartillo++;
if(Player.EtapaDeMartillo == 7){
Player.EtapaDeMartillo = 1;
}
Player.Movie.play();
}
if(MarioDKMP < MarioDKMPMax){
MarioDKMP = MarioDKMP+MarioDKMPRecovery;
}
}
// When QuietQuiet:
function SWhenQuietQuiet (){
Whip();
}
function RightWhenQuietQuiet (){
StartToWalk();
WalkToRight();
}
function LeftWhenQuietQuiet (){
StartToWalk();
WalkToLeft();
}
// When QuietWalking:
function SWhenQuietWalking (){
Player.Action2 = "Quiet";
Whip();
}
function RightWhenQuietWalking (){
WalkToRight();
}
function LeftWhenQuietWalking (){
WalkToLeft();
}
function QuietWhenQuietWalking (){
Player.Action2 = "Quiet";
Quiet();
}
// To whens:
function Whip (){
Player.Action = "Whiping";
MarioDKTic = MarioDKPower/2;
Player.gotoAndStop(3);
if(MarioDKMP >= 1){
MarioDKMP--;
Extras++;
Name = "Extra"+Extras;
attachMovie("sDKSnapjaw", Name, Extras);
setProperty(Name, _x, Player._x+1);
setProperty(Name, _y, 568);
}
}
function StartToWalk (){
Player.Action2 = "Walking";
MarioDKTic = MarioDKSpeed*1.5;
Player.gotoAndStop(2);
}
function WalkToRight (){
Player._x = Player._x+MarioDKSpeed;
FaceRight("Player");
}
function WalkToLeft (){
Player._x = Player._x-MarioDKSpeed;
FaceLeft("Player");
}
function Quiet (){
Player.Action2 = "Quiet";
Player.gotoAndStop(1);
}
// /////////////////////////////////////////////
// ////////////////// DK IA //////////////////
// /////////////////////////////////////////////
// Power up: Puede caminar.
function DKVsMario (){
Distancia = IA._x-Player._x;
if(Distancia >0){
IA._x = IA._x-DKSpeed;
IA.Action2 = "Walking";
}elseif(Distancia <0){
IA._x = IA._x+DKSpeed;
IA.Action2 = "Walking";
}else{
IA.Action2 = "Quiet";
}
IATurn = IATurn+DKSpeed/2;
if(IATurn >= 10){
IATurn = IATurn-10;
IA.play();
}
}
El juego sería de que recibirán un ataque y deben entrenar. Irán ganando poderes y esas cosas. Se desbloquearían más personajes, etc, pero ya es otro tema.
Se me dijo que cierta persona los usó y tenía prohibido gastar más de cierta cantidad de dinero, pero me imaginaba que usarlos era más un tema de saber hacerlos que de tener dinero ¿cómo es?
Pregunto porque se le acusó con ese pretexto, o eso me dijeron, que está demostrado que gastó mucho, porque usó muchos bots, y para mí no tiene sentido porque dudo mucho que eso cueste mucho.
Si son propagandas tipo carteles sería otra cosa.
A menos que fueran bots con super IA, pero en teoría también se podría sin gastar mucho. Yo no podría con esta PC supongo, pero con una normal hoy en día ¿no? ¿es muy complicado? Seguro hay herramientas gratis que lo hacen. Se instala una IA, un programa le pide que elabore propagandas y las manda ¿no?
Tampoco tengo la habilidad como para eso, pero tampoco para manejar un avión, y no es que haya que ser un genio para eso. Los interesados podrían aprender sin mucho gasto ¿o no?
En teoría los peones tendrían que haberse movido de a 1 casillero, hasta coronar, probablemente a caballo.
Pero para que los peones no se bloqueen entre sí, algunas piezas deberían perderse, lo cual pone en duda la teoría.
Los reyes tendrían que moverse hacia las esquinas opuestas, sin enrocar, pero la posibilidad de que les hagan jaque y los obliguen a retroceder u otras cosas, hace que no pueda descartarlo.
Dije que los peones probablemente deban coronar a caballo porque esa es la pieza que más tardaría en llegar a cierto sitio.
Demasiada teoría, muy en el aire.
¿Qué opinan?
Dicen que en este juego hay más posibilidades que átomos en el universo, y yo aún no termino mi IA para Signos en línea, pero he pensado que se debe iniciar a resolver desde las situaciones más alejadas, en que sólo queda 1 casillero libre, y entonces me preguntaba qué sería lo análogo en el Ajedrez... Pero no digo las situaciones en que un jugador sólo tiene 1 opción, sino las que requieren más movimientos para ocurrir, aunque... como en este juego se puede volver a situaciones anteriores, no como en el Signos en línea, supongo que mi plan no funcionaría. Sólo puedo evaluar situaciones que sólo tienen 1 opción que termine la partida o que lleven a situaciones ya evaluadas. Si hay situaciones no resueltas que lleven a otras no resueltas, no sé. En fin, ese es el motivo, es otra cuestión que estoy pensando, pero la pregunta me pareció interesante.
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:
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; ```
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:
// 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; } ```
¡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?
Tanto borrado de variables al final es porque falta que muestre cual es el camino, tendría que comparar cada costo obtenido y quedarse con el menor ¿me conviene hacer eso al final?
El caso que estoy analizando es probablemente simplón: Pasar por los 8 tornillos (o lo que sean) tocando la menor cantidad de escaleras posible: https://www.youtube.com/watch?v=ovi2Vr1Wza0 El video ese no es mío y no se está intentando eso, es simplemente para que vean.
Pero bueno ¿estoy borrando variables inexistentes?
O sea, si el programa tuviese más posibles caminos, serían más cantidad de "CostoLetra1Letra2". Además esta L3P336Costo, que supongo es la última de largo 3, si el programa llegara a formar caminos más largos (lo configuré hasta 4 por ahora para pruebas, pero se precisan 8), sería otra. No sé por qué no se borra. Otras supongo que son fáciles de borrar.
Los dibujos empiezan teniendo 3*3 cuadraditos, siempre los números serán iguales entre sí.
Como regla he puesto que, si son X*X, se muestren (X-1)*(X-1) dibujos en la pantalla, o sea que al inicio serían 2*2.
Una muestra: Lo gris son separadores. Hay 2*2 dibujos o cuadros, de 3*3 cuadraditos cada uno. Son blancos o negros.
Hay 2^(3*3) dibujos posibles, creo, no importa si está mal el cálculo. Esa cantidad se quiere que se divida en 4, para que cada cuadro muestre la misma cantidad de dibujos.
Los dibujos se pueden representar mediante un número, especialmente uno binario. Como en Flash el negro es 000000, decido que el 0 represente negro y 1 blanco.
Quiero que se vayan mostrando dibujos en orden desde todo blanco, o sea, si los dibujos fuesen de 2*2 sería: 1er dibujo del 1er cuadro: 1111 2ndo dibujo de ese cuadro: 1110 3ero: 1101 el número va bajando, sin sobresaltos.
También quiero que inicialmente los dibujos varíen desde arriba e izquierda, por lo que, supongo, me conviene numerar a los cuadraditos así: 8 7 6 5 4 3 2 1 0 Así que el dibujo correspondiente a 111111110 sería: 0 1 1 1 1 1 1 1 1 O sea ¡al revés!
El número debe variar normal, pero debe aplicarse al revés, creo.
Creo que ya había logrado eso. Entonces quise que en vez de mostrarse todos los dibujos, se empiece por este: 1 1 0 1 1 0 0 0 0 No viene al caso por qué. La cosa es que se mostrarán menos dibujos, la cantidad a dividir en cuadros es distinta. Hay que averiguar qué cantidad es.
No tengo idea sobre celulares. Si pueden abrir archivos exe o no. swf supongo que no. O tal vez con un programa... o muy popular.
GPT:
Citar
Correcto: **un celular no puede ejecutar archivos `.exe`** de forma nativa.
### 🧾 ¿Qué es un archivo `.exe`? - Un archivo `.exe` (de *"executable"*) es un **formato de programa ejecutable exclusivo de Windows**. - Está diseñado para funcionar en **sistemas operativos Windows** (como Windows 10, 11, etc.) y **no es compatible** con sistemas como Android o iOS.
---
### 📱 ¿Por qué no se puede ejecutar un `.exe` en un celular?
#### En Android: - Android **no usa Windows** ni su arquitectura. - Los archivos `.exe` están hechos para funcionar en **procesadores x86/x64**, mientras que la mayoría de los celulares usan **procesadores ARM**. - Android usa apps en formato **.apk**, que son completamente diferentes.
#### En iOS (iPhone/iPad): - iOS es aún más restrictivo. No permite ejecutar ningún archivo que no sea una app firmada y aprobada por Apple. - Mucho menos permite ejecutar `.exe`.
---
### 🛠️ ¿Existen formas de *intentar* ejecutar `.exe` en Android?
Sí, **pero con muchas limitaciones**:
1. **Emuladores de Windows para Android**, como: - **DOSBox**: puede ejecutar programas `.exe` tipo MS-DOS (muy antiguos). - **Wine for Android**: un intento de portar Wine (de Linux) a Android para ejecutar algunos `.exe`.
❗ *Estos métodos son experimentales y generalmente no funcionan bien, especialmente con juegos o programas complejos.*
2. **Uso remoto**: - Puedes **usar una app de escritorio remoto** (como Steam Link o Microsoft Remote Desktop) para **ejecutar el `.exe` en tu PC** y **verlo/controlarlo desde tu celular**.
---
### ✅ ¿Qué puedes hacer si quieres que tu juego funcione en celulares?
Si ya haces juegos en `.exe` (probablemente con Flash, Construct, Unity u otra herramienta), puedes:
- **Exportarlo a Android/iOS**, si tu motor de desarrollo lo permite. - Por ejemplo: - Unity permite exportar a Android e iOS. - Godot también. - HTML5 (con javascript) funciona directamente en el navegador del celular.
---
### 💡 En resumen:
> **No**, un celular **no puede ejecutar archivos `.exe` directamente**, porque son programas diseñados para Windows. Si quieres que tus juegos funcionen en móviles, necesitarás exportarlos en formatos compatibles como `.apk` (Android) o usar tecnologías web como HTML5.
En la imagen pueden verse 10 textos que son valores de colores: 000000, FF0000, 00FF00, y el resto son todos 999999.
Al lado de cada valor hay una columna de cuadraditos grises.
La idea básicamente es que tengan un color y al cliquearlos su color se transfiera al valor que muestra su texto asociado.
Cada columna de esas es una película con algo como esto:
Código
onClipEvent(load){
ColorAsociado = 0;
ColorDelCentro0 = 0xCCCCCC;
ColorDelCentro1 = 0x999999;
ColorDelCentro2 = 0x666666;
ColorDelCentro3 = 0x333333;
}
en cada una los valores son distintos. ColorAsociado se refiere a qué valor cambiará. Lo demás se refiere a qué colores tendrán los centros de los cuadraditos.
Cada cuadradito tiene:
Código
onClipEvent(load){
ColorDelCentro = _parent.ColorDelCentroX;
}
donde X es 0, 1, etc, según el cuadradito que sea. Lo que hace es tomar de su película padre, el color que se le puso. Si los cuadraditos tuvieran nombre, quizá se podría haber puesto al inicio algo como: Cuadradito0.ColorDelCentro = 0xCCCCCC; Cuadradito1.ColorDelCentro = 0x999999; etc, tendría que probar.
Todos los cuadraditos tienen esto:
En frame 1: ColorDelObjetoCentro = new Color(Centro); stop ();
La parte del extremo (el borde, pero no le digo así porque tienen un borde con línea, que obvié) tiene transparencia.
El centro, llamado Centro, se extiende hasta el frame 2 y tiene:
Si el botón se deja de señalar, la película va al frame 1, donde la parte extrema del cuadradito ya no cambia de colores, queda como al inicio, un botón normal.
Dije lo que hace cuando se cliquea, pero no entiendo cómo lo hice o cómo lo hago mejor, diré más en el frame 3. Es un efecto visible de que el botón está siendo presionado, en vez de hundirse.
Lo que el botón hace cuando se suelta, lo hace luego de llegar al frame 3 porque fue ahí al cliquearse, así que lo vemos luego.
Frame 3: ColorDelExtremo = new Color(Extremo); ColorDelExtremo.setRGB(ExColorDelCentro); Con esto el color del extremo del cuadradito queda como estaba su centro. Pensé que podría ponerlo en el botón en el código de cuando se cliquea, pero algo falla, no sé.
La parte extrema del cuadradito, Extremo, ya no tiene su código de cambiar colores.
El centro tiene:
Código
onClipEvent(load){
ColorDeEsto = newColor(this);
}
onClipEvent(enterFrame){
Rojo = random(256);
Verde = random(256);
Azul = random(256);
ColorDeEsto.setRGB(Rojo*65536+Verde*256+Azul);
}
Para que cambie de colores al azar, el efecto visible en vez de hundirse, que ya comenté.
Y ahora se aplicaría lo del botón.
Código
// El centro tendrá el color asociado (de unos cuadraditos):
En cuanto a cuadraditos es lo mismo que tomar el valor que tiene su texto asociado. Es como que los colores se intercambian, el color central es ahora como indica el texto pero el texto queda como era el color central. Es como si hubiera 5 opciones: 4 en los cuadraditos y la elegida en el texto, entonces al elegir otra se pasa al texto y la que estaba elegida pasa a las elegibles.
Código
// Si se saltearon colores (es cuando se asigna el 5to...
// sin haber asignado el 4to, por ej), asignar los intermedios al azar:
Esto sería lo más importante, que el color cliqueado se transmita al valor que muestra el texto. La mención a cuadraditos es porque aparecerán en pantalla unos, que deben poder tener el color cliqueado. Con todo esto y otro código se logra.
Código
_level0.InsertarCuadros();
gotoAndStop(1);
Eso inserta dibujos con cuadraditos y el goto hace que el botón vuelva a quedar normal, mostrando en su centro qué color pondrá en el texto si se cliquea.
Todo esto es que empecé a revisarlo y no lo entendía, y algunas cosas aún no las entiendo, si se pueden hacer mejor o no. Díganme cómo hacerlo mejor o explíquenme por qué no se puede.
Sobre ponerle IA ya hice un tema, en ese sentido no pregunto en este.
Tampoco sobre el modo conque chequea si hubo victoria.
Lo que pregunto tiene que ver conque quiero agregarle cosas, por ejemplo: - Opción de que jueguen más de 2 jugadores. - Si es posible, opción de casilleros con otras formas, de modo que la cantidad de direcciones posibles sea distinta a 8. Por ahora sólo vi de 6: https://es.wikipedia.org/wiki/Teselado_hexagonal - Opción de que no se gane por hacer una línea de signos requeridos, sino por ser quien haya hecho más cuando el tablero esté lleno. - Opción de que se gane por tener la mayor cantidad de unidos, independientemente de cuan larga sea la línea. Aunque debo pensar si esto tendría gracia. - Opción de que se gane por haber formado la línea más larga posible (puede ocurrir antes de que el casillero se llene). - Opciones anti, como el antichess, o sea, que en vez de ganar por hacer una cosa u otra, eso lleve a perder. - Opción de que se gane no por hacer una línea, sino alguna figura. Por ejemplo una L. - Opción de que gane quien haga la figura más grande. - Opción de que en vez de ser signos se pongan letras y gane quien 1ero forme una palabra. - Que gane quien forme más palabras. - Las letras a poner van rotando, el jugador no elige. Por ejemplo si hay que formar "Win". - Al comienzo los jugadores se turnan en elegir una letra, luego empieza el juego poniéndolas según el orden conque las eligieron. - Lo mismo pero en cualquier orden. - Lo mismo pero puedes usar las letras de tu oponente. - Repetición de letras se permite.
Y tal vez más... Algunas cosas no son excluyentes.
Algunas cosas quizá sea mejor hacerlas en un programa aparte, pero ya que son juegos tan similares sería bueno un "todo en 1" ¿no? Además no sé cuales debería hacer aparte, tal vez el que se puede poner letras y el que es sobre formar figuras. Serían 3. ¿Ustedes harían 3 juegos o más o menos?
Teniendo en cuenta todo eso, quisiera que mi código esté mejor preparado, porque intenté hacrlo eficiente pero en eso decidí hacerlo así nomás y por ahora está así. ¿Cómo lo mejorarían?
Imagen para referencia:
Frame 1:
Código
CasillerosPorFila = 9;
JuntosRequeridos = 3;
MarcadorDeX = "Humano";
MarcadorDe0 = "IA";
Jugadores = "HumanoIA";
// Usado en el botón de quién marca con X:
function CambiarMarcadorDeX (){
if(MarcadorDeX == "Humano"){
MarcadorDeX = "IA";
}else{
MarcadorDeX = "Humano";
}
Jugadores = MarcadorDeX+MarcadorDe0;
HacerTablero();
}
// Usado en el botón de quién marca con 0:
function CambiarMarcadorDe0 (){
if(MarcadorDe0 == "IA"){
MarcadorDe0 = "Humano";
}else{
MarcadorDe0 = "IA";
}
Jugadores = MarcadorDeX+MarcadorDe0;
HacerTablero();
}
// Usado ahora y en general cuando se cambia la configuración de la partida:
ChequeoHorizontal lo que hace es fijarse si hay victoria. Si hay, hace que Win sea "Sí". Sino, llama a otros chequeos que hacen cosas parecidas. Pueden ver el código en mi otro tema reciente, pero como dije no es la cuestión aquí.
Frame 2: stop(); Nada relevante aquí, simplemente ocurre el juego, el jugador hace clic en los casilleros. Los casilleros tienen un botón con esto:
Código:
on (release) { _level0.CasilleroMarcado = _parent.CasilleroAsociado; _level0.HumanoHaMarcado(); }
Frame 3: Aquí funciona el modo IA VS IA, un objeto tiene:
Código
onClipEvent(enterFrame){
trace("SignoDeTurno: "+_level0.SignoDeTurno);
_level0.TurnoDeIA();
trace("Win: "+_level0.Win);
if(_level0.Win == "No"){
trace("SignoDeTurno: "+_level0.SignoDeTurno);
_level0.TurnoDeIA();
trace("Win: "+_level0.Win);
}
trace("Win: "+_level0.Win);
// No va un else, esto es que si la IA ganó en su 1er turno o...
// en su 2ndo, frana:
if(_level0.Win == "Sí"){
trace("Va al frame 2");
_root.gotoAndStop(2);
}
}
No me gusta mucho usar distintos frames pero parece la forma más eficiente de evitar ifs, evals, etc, no sé...