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


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Simulación de empuje.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Simulación de empuje.  (Leído 1,236 veces)
Tachikomaia


Conectado Conectado

Mensajes: 1.507


Hackentifiko!


Ver Perfil
Simulación de empuje.
« en: 1 Diciembre 2024, 10:29 am »

En el siguiente video hay 2 pruebas.

En la 1era, cuando el personaje camina tiene 2 estados, y en uno es más ancho que en el otro, estira los pies hacia adelante. Eso hace que el barril sea empujado muchas veces en un mismo contacto, lo cual le da demasiada velocidad, está mal. El error ocurre porque en este caso el contacto se produjo cuando el personaje era menos ancho, luego se ensancha y entonces el programa sigue detectando que está tocando el barril, hasta que por fin se aleja suficiente.

En la 2nda prueba, el personaje no cambia al caminar, siempre tiene el mismo ancho, el movimiento del barril está bien, pero el personaje debería cambiar al caminar.

https://youtu.be/eWPQZnodI1U

¿Cómo logro que quede bien?

Puedo poner un ancho único. Que, sin importar el ancho del personaje, el contacto se produzca siempre a la misma distancia. Pero no me gusta eso.

Puedo poner que al ocurrir el hecho una variable cambie durante un tiempo, en el cual el barril no podrá ser empujado de nuevo. Tampoco me parece buena idea.

Busco una solución digamos lógica o realista. Si alguien va caminando, cuando adelanta la pierna tiene más ancho, entonces empuja algo que está más lejos. Si justo lo empuja cuando tiene las 2 piernas juntas, es como si lo empujara varias veces, pero ¿con menos fuerza? No sé, e intentando encontrar fallas cambié varias cosas así que algunas puede que hayan quedado mal.

El código en resumen es:
1- Cuando el personaje camina, se calcula su distancia con respecto al barril:
DistanciaPlayerBarril = ValorAbsoluto(PlayerX-BarrilX);
Las coordenadas que se consideran son los centros de los objetos, o sea, distancia entre el centro del personaje y el centro del barril.

2- Se calcula esto:
MinDistanciaSinChoque = PlayerAncho/2+14+0.2;
O sea, el ancho del personaje/2 + el ancho del barril/2 (da 14) y 0.2 que es lo que el personaje se moverá.
Es la mínima distancia a la que están sin chocar. Como el personaje se moverá 0.2, se agrega eso.

3- Se compara la distancia con eso, para detectar si el personaje tocará el barril o no:
if (DistanciaPlayerBarril<MinDistanciaSinChoque) {

4- Supongamos que habrá contacto, ya que es lo relevante aquí. En tal caso tengo esto:
// Determinar movimientos:
// MinDistanciaSinChoque -> mov 0.2, empuje 0.
// 0 -> mov 0, empuje 0.2.
MovimientoDelPers = DistanciaPlayerBarril*0.2/MinDistanciaSinChoque;
...la idea es que normalmente el personaje se mueva 0.2, pero si va a tocar el barril se mueva menos, y lo que reste se aplique a la velocidad del barril, en el siguiente paso del programa.
Entre más cerca estén, menos se moverá el personaje.

5- Aquí puse que el barril aumente siempre la misma velocidad independientemente de cuánto sea MovimientoDelPers, porque eso me daba problemas. Deberá mejorarse:
BarrilSpeed = BarrilSpeed+0.3;
...antes creo que tenía esto:
BarrilSpeed = BarrilSpeed+0.2-MovimientoDelPers;
Como el barril se detiene si su velocidad es muy poca, eso me daba problemas, creo que era así.

Creo que eso es todo. Luego se reduce la velocidad del barril debido a rozamiento, pero eso creo que ya está bien, ya pregunté aquí.


En Mario Bros, cuando Mario toca un caparazón de tortuga o similar, ésta adquiere más velocidad que la que él puede tener y además no tiene rozamiento, por eso en ese juego no ocurren estos problemas xP


En línea

Tachikomaia


Conectado Conectado

Mensajes: 1.507


Hackentifiko!


Ver Perfil
Re: Simulación de empuje.
« Respuesta #1 en: 4 Diciembre 2024, 09:26 am »

Logré algo que me parece aceptable a pesar de todo.

Básicamente puse que al momento de empujar se considere el ancho máximo del personaje.

Y tenía un error en que el ancho del barril es 24, o sea que el número en el cálculo era 12, no 14. Cuando tenía los números 14 y 12 en el cálculo y sustituí uno porque se considere el ancho variable del personaje, sustituí el incorrecto. Igual no sé si era el problema.

https://youtu.be/QltICF6s-Gw

Lo que sucede al final es que el personaje empezó a caminar cuando un barril lo estaba tocando, eso es otro tema.

Código
  1. // Indica si el juego continúa o no:
  2. Game = "Ok";
  3. // Por motivos que no recuerdo, las imágenes se ponen...
  4. // en un objeto I.
  5. // Agregar personaje:
  6. I.attachMovie("sMedaMan", "Player", 1);
  7. // X es porque la posición real del personaje no admite...
  8. // tantos valores, los simplifica, se pierde parte;
  9. // de este modo no:
  10. I.Player.X = 0;
  11. I.Player._X = I.Player.X;
  12. I.Player._Y = 584;
  13. I.Player.Action = "Quiet";
  14. LV = 1;
  15. Recorrido = 0;
  16. BarrilesToAdd = 0;
  17. // Aunque hay 0 barriles se pone 10 porque también es...
  18. // el valor que determina qué tan adelante se ponen,
  19. // y el valor 1 es del personaje,
  20. // entonces realmente los barriles es esto-10:
  21. Barriles = 10;
  22. // La mínima distancia a la que Medaman y un barril se tocan...
  23. // depende de qué dibujo tenga Medaman, ya que al caminar,
  24. // uno es más ancho. Pero para simplificar,
  25. // se considerará el más ancho: 32. El ancho del barril es 24.
  26. // Además se agrega 0.2 porque es lo que Medaman...
  27. // se podría mover, y 0.05 para evitar fallas por...
  28. // inexactitudes al operar decimales.
  29. MinDistanciaSinChoque = 16+12+0.25;
  30. // /////////////////////////////////////////////
  31. // /////////////////  MedaMan  /////////////////
  32. // /////////////////////////////////////////////
  33. function AumentarRecorrido () {
  34. Recorrido++;
  35. if (Recorrido == 50) {
  36. Recorrido = 0;
  37. LV++;
  38. }
  39. }
  40. function Walk () {
  41. I.Player.Action = "Walking";
  42. I.Player.gotoAndStop(2);
  43. // Ver si empuja algún barril:
  44. I.Player.Empujar = "No";
  45. // Se comienza desde 10 por lo ya explicado
  46. // (tal vez convenga chequear desde el último):
  47. BarrilesChequeados = 10;
  48. trace("Checking empuje");
  49. do {
  50. BarrilesChequeados++;
  51. BarrilaChequear = "I.Barril"+BarrilesChequeados;
  52. BarrilX = eval("I.Barril"+BarrilesChequeados+".X");
  53. // Si el barril existe:
  54. if (BarrilX != undefined) {
  55. DistanciaPlayerBarril = Math.abs(I.Player.X-BarrilX);
  56. if (DistanciaPlayerBarril < MinDistanciaSinChoque) {
  57. trace ("Empuja");
  58. I.Player.Empujar = "Sí";
  59. break;
  60. }
  61. }
  62. } while (BarrilesChequeados<Barriles);
  63. if (I.Player.Empujar == "No") {
  64. // El personaje avanza lo normal:
  65. I.Player.X = I.Player.X+0.2;
  66. AumentarRecorrido();
  67. } else {
  68. // Avanza menos:
  69. I.Player.X = I.Player.X+0.1;
  70. // Ojo que fue hecho para que avance 0.2, puede que lo empuje desde muy lejos.
  71. // Recorrido debe aumentar acorde a eso, arreglarlo:
  72. AumentarRecorrido();
  73. // Empuja un barril:
  74. // Esto sólo aumenta la velocidad, ojo que si no se mueve puede que quede tocando al personaje:
  75. BarrilSpeed = BarrilaChequear+".Speed";
  76. set (BarrilSpeed, 0.15);
  77. }
  78. I.Player._X = I.Player.X;
  79. }
  80. function Quiet () {
  81. I.Player.Action = "Quiet";
  82. I.Player.gotoAndStop(1);
  83. }
  84. // Whens:
  85. function RightWhenQuiet () {
  86. // Ver si toca algún barril:
  87. BarrilesChequeados = 10;
  88. do {
  89. BarrilesChequeados++;
  90. if (I.Player.hitTest(eval("I.Barril"+BarrilesChequeados)) == true) {
  91. trace("Apareció en barril");
  92. // Game over:
  93. Game = "Over";
  94. I.Player.gotoAndStop(2);
  95. break;
  96. }
  97. } while (BarrilesChequeados<Barriles);
  98. if (Game == "Ok") {
  99. Walk();
  100. } else {
  101. // Esto probablemente esté bien antes del break:
  102. gotoAndStop (3);
  103. }
  104. }
  105. function RightWhenWalking () {
  106. // AumentarRecorrido();
  107. Walk();
  108. }
  109. function QuietWhenWalking () {
  110. Quiet();
  111. }
  112. // QuietWhenQuiet nada hace.
  113. function ControlPlayer () {
  114. if (Key.isDown(39)) {
  115. // Si se presiona derecha:
  116. eval("RightWhen"+I.Player.Action)();
  117. } else {
  118. // Si nada se presiona:
  119. eval("QuietWhen"+I.Player.Action)();
  120. }
  121. }
  122. // /////////////////////////////////////////////
  123. // ////////////////  Barriles  /////////////////
  124. // /////////////////////////////////////////////
  125. function AddBarriles () {
  126. BarrilesToAdd = BarrilesToAdd+random(LV)/1000;
  127. while (BarrilesToAdd>=1) {
  128. BarrilesToAdd--;
  129. Barriles++;
  130. // Probablemente innecesario, y causante de bugs si no se parchea:
  131. if (Barriles>1010) {
  132. Barriles = 11;
  133. }
  134. BarrilAgreado = "Barril"+Barriles;
  135. I.attachMovie("sBarril", BarrilAgreado, Barriles);
  136. BarrilAgreado = "I."+BarrilAgreado;
  137. set(BarrilAgreado+".X", 0);
  138. setProperty (BarrilAgreado, _x, 0);
  139. setProperty (BarrilAgreado, _y, 584);
  140. set (BarrilAgreado+".Speed", random(LV)/10);
  141. set (BarrilAgreado+".Spin", 0.1+random(LV)/10);
  142. }
  143. }
  144. function MoveBarriles () {
  145. Moved = 10;
  146. // trace("Checking golpe");
  147. do {
  148. Moved++;
  149. BarrilaMover = "I.Barril"+Moved;
  150. BarrilSpeed = BarrilaMover+".Speed";
  151. EvaluedBarrilSpeed = eval(BarrilSpeed);
  152. // Aplicar rozamiento:
  153. if (EvaluedBarrilSpeed > 0) {
  154. EvaluedBarrilSpeed = EvaluedBarrilSpeed/1.0025;
  155. // Si la velocidad queda muy baja:
  156. if (EvaluedBarrilSpeed < 0.05) {
  157. // Frena completamente:
  158. EvaluedBarrilSpeed = 0;
  159. }
  160. set (BarrilSpeed, EvaluedBarrilSpeed);
  161. }
  162. BarrilX = eval(BarrilaMover+".X")+EvaluedBarrilSpeed;
  163. // Si ya no está en la pantalla:
  164. if (BarrilX>850) {
  165. // Quitarlo:
  166. removeMovieClip (BarrilaMover);
  167. } else {
  168. // Actualizar posición y girar su parte:
  169. set(BarrilaMover+".X", BarrilX);
  170. setProperty (BarrilaMover, _x, BarrilX);
  171. ParteaRotar = BarrilaMover+".Part";
  172. setProperty (ParteaRotar, _rotation, getProperty(ParteaRotar, _rotation)+EvaluedBarrilSpeed*2);
  173. // Si tocan al personaje y él se está moviendo:
  174. if (I.Player.hitTest(eval(BarrilaMover)) == true && I.Player.Action == "Walking") {
  175. trace("Golpeado");
  176. // Game over:
  177. gotoAndStop (3);
  178. break;
  179. } else {
  180. // Ver si tocó al barril anterior, que está delante:
  181. BarrilAnterior = "I.Barril"+(Moved-1);
  182. if (eval(BarrilaMover).hitTest(eval(BarrilAnterior)) == true) {
  183. // Pasarle la velocidad:
  184. set (BarrilAnterior+".Speed", eval(BarrilAnterior+".Speed")+EvaluedBarrilSpeed);
  185. // Quedar sin velocidad:
  186. set (BarrilSpeed, 0);
  187. }
  188. }
  189. }
  190. } while (Moved<Barriles);
  191. }


« Última modificación: 4 Diciembre 2024, 09:31 am por Tachikomaia » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Simulacion Banco
Programación C/C++
Gerik 2 11,194 Último mensaje 4 Octubre 2010, 06:44 am
por leogtz
Simulación con Pspice
Electrónica
Constantinoplero 8 7,494 Último mensaje 11 Marzo 2013, 14:58 pm
por Constantinoplero
simulacion de planta
Java
HunterLuis 1 1,676 Último mensaje 17 Marzo 2015, 18:19 pm
por Usuario Invitado
¿Es la realidad una simulación? « 1 2 »
Foro Libre
Eleкtro 12 5,964 Último mensaje 2 Julio 2018, 02:26 am
por okik
Simulacion de Comunicacion. « 1 2 »
Programación C/C++
AlbertoBSD 14 4,165 Último mensaje 18 Noviembre 2018, 02:03 am
por AlbertoBSD
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines