{"id":1175,"date":"2025-11-30T08:00:00","date_gmt":"2025-11-30T07:00:00","guid":{"rendered":"https:\/\/jorgeturiel.es\/?p=1175"},"modified":"2025-11-13T13:44:57","modified_gmt":"2025-11-13T12:44:57","slug":"ghosts-n-goblins-y-cge-parte-5","status":"publish","type":"post","link":"https:\/\/jorgeturiel.es\/?p=1175","title":{"rendered":"Ghosts \u2018n Goblins y CGE. Parte 5"},"content":{"rendered":"\n<p>En esta entrada veremos como ejecutar una animaci\u00f3n una sola vez, configurando su funcionamiento por c\u00f3digo, y cuando esta animaci\u00f3n termine, ejecutar otra animaci\u00f3n en bucle.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\"><a><\/a> Preparando la animaci\u00f3n<\/h2>\n\n\n\n<p>Cuando Arthur dispara su lanza este realiza una animaci\u00f3n y luego el arma es disparada. Para conseguir este \u201cefecto\u201d crearemos una animaci\u00f3n y al terminar esta se lanzar\u00e1 el arma. <\/p>\n\n\n\n<p>Abre la hoja de sprites de Arthur, que creamos en los cap\u00edtulos anteriores.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"482\" height=\"307\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-5.png\" alt=\"\" class=\"wp-image-1176\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-5.png 482w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-5-300x191.png 300w\" sizes=\"auto, (max-width: 482px) 100vw, 482px\" \/><figcaption class=\"wp-element-caption\">Seleccionar hoja de sprites de Arthur<\/figcaption><\/figure>\n<\/div>\n\n\n<p>En la primera animaci\u00f3n, <em>NewAnimation<\/em>, ten\u00edamos todos los sprites. Selecci\u00f3nala, y luego selecciona las im\u00e1genes de Arthur lanzado el arma, pulsa el bot\u00f3n derecho del rat\u00f3n, y en el men\u00fa emergente selecciona <em>Create new animation from selection<\/em>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"546\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-6-1024x546.png\" alt=\"\" class=\"wp-image-1178\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-6-1024x546.png 1024w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-6-300x160.png 300w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-6-768x409.png 768w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-6.png 1073w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Seleccionar elementos para animaci\u00f3n<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Nombra la nueva animaci\u00f3n con <em>Shot<\/em><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"943\" height=\"530\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-7.png\" alt=\"\" class=\"wp-image-1179\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-7.png 943w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-7-300x169.png 300w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-7-768x432.png 768w\" sizes=\"auto, (max-width: 943px) 100vw, 943px\" \/><figcaption class=\"wp-element-caption\">Renombrar animaci\u00f3n<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"> Programando la animaci\u00f3n<\/h2>\n\n\n\n<p>Para gestionar la animaciones debes a\u00f1adir dos unidades nuevas a la cl\u00e1usula uses. Esta son: <em>CastleSceneCore<\/em> y <em>X3DNodes.<\/em><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"658\" height=\"137\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-8.png\" alt=\"\" class=\"wp-image-1181\" style=\"width:735px;height:auto\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-8.png 658w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-8-300x62.png 300w\" sizes=\"auto, (max-width: 658px) 100vw, 658px\" \/><figcaption class=\"wp-element-caption\">A\u00f1adir<em> CastleSceneCore y X3DNodes.<\/em><\/figcaption><\/figure>\n<\/div>\n\n\n<p>Crea una variable, en la secci\u00f3n <em>private<\/em> de la clase <em>TmainView<\/em>, llamada <em>PlayerAnimationToLoop<\/em>, la ser\u00e1 de tipo <em>String, <\/em>y la usaremos para guardar el nombre la animaci\u00f3n actual de Athur. Y que le servir\u00e1 para luego recuperarla.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"648\" height=\"195\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-9.png\" alt=\"\" class=\"wp-image-1183\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-9.png 648w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-9-300x90.png 300w\" sizes=\"auto, (max-width: 648px) 100vw, 648px\" \/><figcaption class=\"wp-element-caption\">Declaraci\u00f3n de PlayerAnimationToLoop<\/figcaption><\/figure>\n<\/div>\n\n\n<p>A\u00f1ade un procedimiento a la secci\u00f3n <em>Private<\/em> que se llama PlayAnimationOnceAndLoop.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"701\" height=\"392\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-10.png\" alt=\"\" class=\"wp-image-1184\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-10.png 701w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-10-300x168.png 300w\" sizes=\"auto, (max-width: 701px) 100vw, 701px\" \/><figcaption class=\"wp-element-caption\">Declaraci\u00f3n PlayAnimationOnceAndLoop<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Este procedimiento tendr\u00e1 los siguiente par\u00e1metros:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Scene. Indica la escena a la que pertenece la animaci\u00f3n<\/li>\n\n\n\n<li>AnimationNameToPlayOnce, indica la animaci\u00f3n que se ejecutar\u00e1 una vez<\/li>\n\n\n\n<li>AnimationNameToLoop, indica la animaci\u00f3n que se ejecutar\u00e1 una vez termine la animaci\u00f3n anterior.<\/li>\n<\/ul>\n\n\n\n<p>El c\u00f3digo de este procedimiento es como sigue:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \">procedure TViewMain.PlayAnimationOnceAndLoop(Scene: TCastleScene;\n  const AnimationNameToPlayOnce, AnimationNameToLoop: string);\nvar\n  Parameters: TPlayAnimationParameters;\nbegin\n  Parameters := TPlayAnimationParameters.Create;\n  try\n    Parameters.Loop := False;\n    Parameters.Name := AnimationNameToPlayOnce;\n    Parameters.Forward := True;\n    Parameters.StopNotification :=\n    {$IFDEF FPC}\n       @OnAnimationStop;\n      {$ELSE]}\n      OnAnimationStop;\n    {$ENDIF}\n    PlayerAnimationToLoop := AnimationNameToLoop;\n    Scene.PlayAnimation(Parameters);\n  finally\n    FreeAndNil(Parameters);\n  end;\n\nend; <\/pre><\/div>\n\n\n\n<p>Lo primero es crear un objeto de tipo <em>TPlayAnimationParameters<\/em> el cual nos sirve para configurar como funcionar\u00e1 la animaci\u00f3n. A su propiedad <em>Loop<\/em> le asignamos el valor <em>False<\/em> de esta manera la animaci\u00f3n solo se ejecutar\u00e1 una vez. Le asignamos el nombre que hemos recibido por par\u00e1metros en su propiedad <em>Name.<\/em> En el evento <em>StopNotification<\/em> le asignamos un procedimiento llamado <em>OnAnimationStop<\/em>. Guardamos el nombre de la animaci\u00f3n pasada por par\u00e1metro en la variable.<\/p>\n\n\n\n<p><em>PlayerAnimationToLoop. <\/em>Y por \u00faltimo, a la escena pasada por par\u00e1metros le indicamos que ejecute una animaci\u00f3n, seg\u00fan los par\u00e1metros que hemos preparado.<\/p>\n\n\n\n<p>Por supuesto, al final de todo se libera el objeto.<\/p>\n\n\n\n<p>El procedimiento OnAnimationStop es muy sencillo.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \">procedure TViewMain.OnAnimationStop(const Scene: TCastleSceneCore;\n  const Animation: TTimeSensorNode);\nbegin\n  Scene.PlayAnimation(PlayerAnimationToLoop, True);\nend;\n     <\/pre><\/div>\n\n\n\n<p>Simplemente indicamos a la escena pasada por par\u00e1metros, se ejecute la animaci\u00f3n <em>PlayerAnimationToLoop<\/em>, la cual hemos guardado antes en el procedimiento <em>PlayAnimationOnceAndLoop,<\/em> y que lo haga de modo continuo.<\/p>\n\n\n\n<p>Solo nos queda modificar en la rutina <em>Update<\/em>, la l\u00ednea que para la animaci\u00f3n de Arthur si velocidad en el eje X es cero o no est\u00e1 en el suelo. Y dentro de este condicional a\u00f1ade la condici\u00f3n que solo detenga la animaci\u00f3n si puede disparar.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"610\" height=\"206\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-11.png\" alt=\"\" class=\"wp-image-1185\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-11.png 610w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2025\/11\/image-11-300x101.png 300w\" sizes=\"auto, (max-width: 610px) 100vw, 610px\" \/><\/figure>\n\n\n\n<p>De otra manera, nunca se podr\u00eda ver la animaci\u00f3n ya que esta l\u00ednea detendr\u00eda la animaci\u00f3n.<\/p>\n\n\n\n<p>Tienes todo el c\u00f3digo fuente en el <a href=\"https:\/\/github.com\/Blueicaro\/GhostAndGoblins_CGE-.git\">github<\/a>.<\/p>\n\n\n\n<p>Saludos<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En esta entrada veremos como ejecutar una animaci\u00f3n una sola vez, configurando su funcionamiento por c\u00f3digo, y cuando esta animaci\u00f3n termine, ejecutar otra animaci\u00f3n en bucle.<\/p>\n","protected":false},"author":2,"featured_media":1187,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57,56,25,48],"tags":[49,32,23,21,24],"class_list":["post-1175","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-castle-game-engine","category-cge","category-pascal","category-videojuegos","tag-castle-game-engine","tag-free-pascal","tag-lazarus","tag-pascal","tag-programacion"],"_links":{"self":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/1175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1175"}],"version-history":[{"count":5,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/1175\/revisions"}],"predecessor-version":[{"id":1188,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/1175\/revisions\/1188"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/media\/1187"}],"wp:attachment":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}