{"id":424,"date":"2022-10-06T10:58:26","date_gmt":"2022-10-06T08:58:26","guid":{"rendered":"http:\/\/quadern-programacio.recursos.uoc.edu\/?page_id=424"},"modified":"2022-11-13T13:39:09","modified_gmt":"2022-11-13T11:39:09","slug":"7-2-movimiento-lineal","status":"publish","type":"page","link":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/7-2-movimiento-lineal\/","title":{"rendered":"7.2. Movimiento lineal"},"content":{"rendered":"<p>El ejemplo m\u00e1s sencillo que podemos crear es el de una variable que aumente a lo largo del tiempo y que usemos para determinar alg\u00fan par\u00e1metro de nuestro dibujo.<\/p>\n<figure id=\"attachment_188\" aria-describedby=\"caption-attachment-188\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-188\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_077.jpg\" alt=\"\" width=\"800\" height=\"355\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_077.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_077-300x133.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_077-768x341.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-188\" class=\"wp-caption-text\">Figura 78. Movimiento lineal<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>En la figura 78 vemos que hemos creado al principio del c\u00f3digo una variable <span class=\"courier\">posX<\/span> que hemos inicializado con el valor 100 y que luego en el <span class=\"courier\">draw()<\/span> estamos utilizando para determinar la posici\u00f3n en el eje <em>x<\/em> de la elipse que dibujamos. Tras dibujarla, aumentamos el valor de <span class=\"courier\">posX<\/span> en una unidad (recordemos que <span class=\"courier\">posX ++<\/span> es equivalente a <span class=\"courier\">posX = posX + 1<\/span>), por lo que nuestra elipse comienza en la posici\u00f3n <em>x<\/em> 100 y, puesto que el <span class=\"courier\">draw()<\/span> se ejecuta 60 veces por segundo, su posici\u00f3n va aumentando 60 unidades cada segundo, desplaz\u00e1ndose hacia la derecha del <em>canvas<\/em>. En el ejemplo no estamos redibujando el fondo para que se aprecie la estela que deja el movimiento de la figura.<\/p>\n<p>Podemos controlar f\u00e1cilmente la velocidad y la direcci\u00f3n de este movimiento variando la cantidad que le sumamos a la posici\u00f3n en cada <em>frame<\/em>. Para ello, podemos utilizar una variable que almacene esta \u00abvelocidad\u00bb. Cuanta mayor cantidad sumemos a la posici\u00f3n, m\u00e1s r\u00e1pido ser\u00e1 el movimiento. Para cambiar la direcci\u00f3n del movimiento, basta con cambiar el signo del valor que sumamos: si sumamos valores negativos en lugar de positivos a la posici\u00f3n, el movimiento ser\u00e1 hacia la izquierda en lugar de hacia la derecha.<\/p>\n<figure id=\"attachment_190\" aria-describedby=\"caption-attachment-190\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-190\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_078.jpg\" alt=\"\" width=\"800\" height=\"392\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_078.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_078-300x147.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_078-768x376.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-190\" class=\"wp-caption-text\">Figura 79. Modificando la velocidad del movimiento<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>En este ejemplo vemos claramente la diferencia de velocidad entre el movimiento de las dos elipses. Veamos a continuaci\u00f3n un ejemplo manteniendo la misma velocidad, pero cambiando su direcci\u00f3n:<\/p>\n<figure id=\"attachment_192\" aria-describedby=\"caption-attachment-192\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-192\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_079.jpg\" alt=\"\" width=\"800\" height=\"352\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_079.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_079-300x132.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_079-768x338.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-192\" class=\"wp-caption-text\">Figura 80. Modificando la direcci\u00f3n del movimiento<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>La clave a la hora de cambiar la direcci\u00f3n del movimiento la tenemos en la l\u00ednea 15: en lugar de utilizar el operador <span class=\"courier\">+=<\/span> estamos utilizando el <span class=\"courier\">-=<\/span>, de manera que las 5 unidades de la variable <span class=\"courier\">speed<\/span> se est\u00e1n restando en cada <em>frame <\/em>al valor de initPos2 en lugar de estar sum\u00e1ndose. Podr\u00edamos obtener el mismo resultado manteniendo el operador <span class=\"courier\">+=<\/span> pero cambiando el signo de <span class=\"courier\">speed<\/span>:<\/p>\n<pre>initPos2 += -speed;<\/pre>\n<h3>En dos dimensiones<\/h3>\n<p>Hasta ahora, el movimiento que hemos programado en nuestras formas ha sido en una \u00fanica dimensi\u00f3n, solo se est\u00e1n moviendo en el eje<em> x<\/em>, pero podemos incluir una nueva variable para que el movimiento de produzca tanto en el eje <em>x<\/em> como en el <em>y<\/em>.<\/p>\n<figure id=\"attachment_194\" aria-describedby=\"caption-attachment-194\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-194\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_080.jpg\" alt=\"\" width=\"800\" height=\"409\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_080.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_080-300x153.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_080-768x393.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-194\" class=\"wp-caption-text\">Figura 81. Movimiento diagonal<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>En este caso, como estamos utilizando el mismo valor <span class=\"courier\">speed<\/span> para aumentar la posici\u00f3n tanto en el eje <em>x<\/em> como en el <em>y<\/em>, el movimiento es diagonal a exactamente 45\u00ba, pero si utilizamos valores distintos de velocidad para un eje y para otro, la pendiente del movimiento cambiar\u00e1.<\/p>\n<h3>Condiciones de borde<\/h3>\n<p>Ahora mismo, seg\u00fan tenemos nuestro c\u00f3digo, la variable que determina la posici\u00f3n del c\u00edrculo aumenta (o disminuye) hasta el infinito haciendo que el c\u00edrculo desaparezca del <em>canvas<\/em>. En muchos casos, este comportamiento no ser\u00e1 el deseado y querremos controlar qu\u00e9 ocurre cuando nuestra figura alcanza los l\u00edmites del <em>canvas<\/em>.<\/p>\n<p>Para ello, podemos ayudarnos de las ya conocidas estructuras condicionales para detectar cu\u00e1ndo la variable que almacena la posici\u00f3n de la figura llega a determinado valor. Uno de los comportamientos que podemos programar es que nuestra figura reaparezca por el lado contrario del <em>canvas<\/em>; veamos c\u00f3mo llevarlo a cabo:<\/p>\n<figure id=\"attachment_196\" aria-describedby=\"caption-attachment-196\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-196\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_081.jpg\" alt=\"\" width=\"800\" height=\"455\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_081.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_081-300x171.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_081-768x437.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-196\" class=\"wp-caption-text\">Figura 82. Condiciones de borde<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>En el ejemplo anterior hemos creado una condici\u00f3n que detecta cu\u00e1ndo la posici\u00f3n en y del c\u00edrculo rebasa el l\u00edmite inferior del <em>canvas<\/em> y, cuando lo hace, resetea la posici\u00f3n a la parte superior del <em>canvas<\/em>. Debemos tener en cuenta que el c\u00edrculo se dibuja desde su centro, por lo que para que rebase completamente el l\u00edmite del <em>canvas<\/em> debemos considerar tambi\u00e9n el tama\u00f1o del c\u00edrculo.<\/p>\n<p>Una vez que tenemos definida esta estructura condicional que detecta cu\u00e1ndo el c\u00edrculo rebasa el l\u00edmite inferior del <em>canvas<\/em>, podemos variar dentro del condicional otro tipo de par\u00e1metros adem\u00e1s de la posici\u00f3n en el eje <em>y<\/em>. Podr\u00edamos crear una especie de lluvia aleatoria de c\u00edrculos de distintos tama\u00f1os, colores y velocidades cambiando un par de par\u00e1metros.<\/p>\n<figure id=\"attachment_198\" aria-describedby=\"caption-attachment-198\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-198\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_082.jpg\" alt=\"\" width=\"800\" height=\"552\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_082.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_082-300x207.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_082-768x530.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-198\" class=\"wp-caption-text\">Figura 83. Lluvia aleatoria<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>En lugar de hacer que el c\u00edrculo reaparezca por el lado contrario del <em>canvas<\/em>, podr\u00edamos querer que rebotase. Para ello, lo que debemos hacer es simplemente cambiar de signo su velocidad cuando detectemos que ha llegado al l\u00edmite:<\/p>\n<figure id=\"attachment_200\" aria-describedby=\"caption-attachment-200\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-200\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_083.jpg\" alt=\"\" width=\"800\" height=\"461\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_083.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_083-300x173.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_083-768x443.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-200\" class=\"wp-caption-text\">Figura 84. Rebote<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n<p>En el caso de la figura anterior, solo estamos detectando la colisi\u00f3n con el borde inferior del <em>canvas<\/em>, por lo que cuando el c\u00edrculo vaya hacia arriba rebasar\u00e1 el l\u00edmite superior del <em>canvas<\/em> sin rebotar. Para a\u00f1adir la nueva condici\u00f3n, podemos usar el operador l\u00f3gico <span class=\"courier\">OR<\/span>:<\/p>\n<pre>if(posY &gt;= height \u2013 size \/ 2 || posY &lt;= 0 + size \/ 2) {\r\n  speed = -speed;\r\n}<\/pre>\n<p>Podemos realizar esta comprobaci\u00f3n en los cuatro bordes del <em>canvas<\/em> si tenemos movimiento en dos dimensiones a\u00f1adiendo una nueva condici\u00f3n:<\/p>\n<pre>\/\/ REBOTE VERTICAL\r\nif(posY &gt;= height \u2013 size \/ 2 || posY &lt;= 0 + size \/ 2) { speedY = -speedY; }\r\n\r\n\/\/ REBOTE HORIZONTAL\r\nif(posX &gt;= width \u2013 size \/ 2 || posX &lt;= 0 + size \/ 2) {\r\n  speedX = -speedX;\r\n}<\/pre>\n<p>Y para que el c\u00f3digo quede m\u00e1s limpio y organizado, podemos encapsular todas estas comprobaciones en una funci\u00f3n:<\/p>\n<pre>function checkBorders(){\r\n  \/\/ REBOTE VERTICAL\r\n  if(posY &gt;= height \u2013 size \/ 2 || posY &lt;= 0 + size \/ 2) { speedY = -speedY; } \/\/ REBOTE HORIZONTAL if(posX &gt;= width \u2013 size \/ 2 || posX &lt;= 0 + size \/ 2) {\r\n    speedX = -speedX;\r\n  }\r\n}<\/pre>\n<p>Veamos un ejemplo completo con rebote en los cuatro bordes del <em>canvas<\/em>:<\/p>\n<figure id=\"attachment_202\" aria-describedby=\"caption-attachment-202\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"size-full wp-image-202\" src=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_084.jpg\" alt=\"\" width=\"800\" height=\"564\" srcset=\"\/wp-content\/uploads\/2022\/10\/PID_00290094_084.jpg 800w, \/wp-content\/uploads\/2022\/10\/PID_00290094_084-300x212.jpg 300w, \/wp-content\/uploads\/2022\/10\/PID_00290094_084-768x541.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-202\" class=\"wp-caption-text\">Figura 85. Rebote en todos los bordes<br \/>Fuente: elaboraci\u00f3n propia.<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>El ejemplo m\u00e1s sencillo que podemos crear es el de una variable que aumente a lo largo del tiempo y que usemos para determinar alg\u00fan par\u00e1metro de nuestro dibujo. En la figura 78 vemos que hemos creado al principio del c\u00f3digo una variable que hemos inicializado con el valor 100 y que luego en el [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"acf":[],"_links":{"self":[{"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/pages\/424"}],"collection":[{"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/comments?post=424"}],"version-history":[{"count":3,"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/pages\/424\/revisions"}],"predecessor-version":[{"id":781,"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/pages\/424\/revisions\/781"}],"wp:attachment":[{"href":"http:\/\/quadern-programacio.recursos.uoc.edu\/es\/wp-json\/wp\/v2\/media?parent=424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}