{"id":386,"date":"2025-07-08T16:31:19","date_gmt":"2025-07-08T06:31:19","guid":{"rendered":"https:\/\/nonlinearexperience.com\/?p=386"},"modified":"2025-08-11T08:54:50","modified_gmt":"2025-08-10T22:54:50","slug":"movement","status":"publish","type":"post","link":"https:\/\/nonlinearexperience.com\/index.php\/2025\/07\/08\/movement\/","title":{"rendered":"Movement"},"content":{"rendered":"<h1 class=\"wp-block-post-title\">Movement<\/h1>\n\n\n<p>See also: collision<\/p>\n\n\n\n<p>System: input<\/p>\n\n\n\n<p>The basics:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>user input<\/li>\n\n\n\n<li>character key frame animation<\/li>\n\n\n\n<li>position on screen<\/li>\n<\/ul>\n\n\n\n<p>Moving left &#8211; then flipping the direction<\/p>\n\n\n\n<p>Movement is context based &#8211; for example, the background moves when in an &#8216;over world&#8217; type map (such as map in LTTP), but not necessarily if you are in a small room which will totally fit with the game screen (like links house in the opening scene from LTTP)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">For TOP DOWN style games<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">4 directions &#8211; constant movement<\/h3>\n\n\n\n<p>always respond to current key that is being pressed (the &#8216;last key&#8217; pressed<\/p>\n\n\n\n<p>if (keys.w.pressed &amp;&amp; lastKey === &#8216;w&#8217;) background.position.y += 3<\/p>\n\n\n\n<p>keys.w.pressed = true<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastKey = &#8216;w&#8217;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4 directions &#8211; turn-based movement (rogue-like style)<\/h3>\n\n\n\n<p>determine if you can move there &#8211; then animate the char there &#8211; see porklike movement for an example<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">8 directions<\/h3>\n\n\n\n<p>Examples<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zelda: A link to the past\n<ul class=\"wp-block-list\">\n<li>moves in 8 directions<\/li>\n\n\n\n<li>sprites for 4 directions<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Earthbound\n<ul class=\"wp-block-list\">\n<li>moves in 8 directions<\/li>\n\n\n\n<li>spites for 8 directions<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>easing?<\/p>\n\n\n\n<p>calculate vector<\/p>\n\n\n\n<p>apply vector<\/p>\n\n\n\n<p>no gravity<\/p>\n\n\n\n<p>moving in 8 directions<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Platformer<\/p>\n\n\n\n<p>Hang time<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>GODOT<\/p>\n\n\n\n<p>&nbsp;var input_vector = Vector2.ZERO<\/p>\n\n\n\n<p>input_vector.x = Input.get_action_strength(&#8220;ui_right&#8221;) &#8211; Input.get_action_strength(&#8220;ui_left&#8221;)<\/p>\n\n\n\n<p>input_vector.y = Input.get_action_strength(&#8220;ui_down&#8221;) &#8211; Input.get_action_strength(&#8220;ui_up&#8221;)<\/p>\n\n\n\n<p>JS<\/p>\n\n\n\n<p>&nbsp;&#8211; is there a clean and simple solution for this?<\/p>\n\n\n\n<p>\/\/Move the cat and keep it inside the boundaries<\/p>\n\n\n\n<p>cat.x = Math.max(0, Math.min(cat.x + cat.vx, canvas.width &#8211; cat.width));<\/p>\n\n\n\n<p>cat.y = Math.max(0, Math.min(cat.y + cat.vy, canvas.height &#8211; cat.height));<\/p>\n\n\n\n<p>velocity\/easing in\/out<\/p>\n\n\n\n<p>usually applied to movement, but could be for anything really<\/p>\n\n\n\n<p>snap to pixel<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Movement correction<\/h3>\n\n\n\n<p>\u201cWhile Link can move a single pixel at a time, in any direction, the longer he continously moves in any direction the more he gravitates toward aligning himself with the underlying grid of the screen. The tile grid for LoZ is 16 tiles wide by 14 tiles high (including 3 tiles for the status display at the top of the screen). Each tile is 16\u00d716 pixels. Link operates on a half-tile grid, though (32\u00d728 tiles, 8\u00d78 pixels each). As Link moves, if he\u2019s not currently aligned with the half-tile grid, he is adjusted, one pixel at a time, toward the closest correction. As a result, if Link is 4 pixels off alignment he\u2019ll line back up with the grid after moving 4 pixels.\u201d &#8211; from <a href=\"https:\/\/troygilbert.com\/deconstructing-zelda\/movement-mechanics\/#:~:text=The%20tile%20grid%20for%20LoZ,8%C3%978%20pixels%20each\">https:\/\/troygilbert.com\/deconstructing-zelda\/movement-mechanics\/#:~:text=The%20tile%20grid%20for%20LoZ,8%C3%978%20pixels%20each<\/a>).<\/p>\n\n\n\n<p>This is somewhat the case in Earthbound too\u2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">For SIDE ON&nbsp; &#8216;mario&#8217; style games<\/h2>\n\n\n\n<p>has gravity<\/p>\n\n\n\n<p>fixed &#8216;x&#8217; position or not fixed (a range)<\/p>\n\n\n\n<p>jump in &#8216;y&#8217; position<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sub-pixel (fixed-point number) movement &#8211; ala mario 3<\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"The Code That Makes Mario Move\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/ZuKIUjw_tNU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>(1 pixel is divided into 16 sub pixels)<\/p>\n\n\n\n<p>Store values and do calculations using sub-pixels &#8211; then convert to screen coordinates for rendering\u2026<\/p>\n\n\n\n<p>Celeste<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Why Does Celeste Feel So Good to Play?\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/yorTG9at90g?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p><br \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>See also: collision System: input The basics: Moving left &#8211; then flipping the direction Movement is context based &#8211; for example, the background moves when in an &#8216;over world&#8217; type map (such as map in LTTP), but not necessarily if you are in a small room which will totally fit with the game screen (like [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"wp-custom-template-nlx-the-knowledge-page","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-386","post","type-post","status-publish","format-standard","hentry","category-the-knowledge"],"_links":{"self":[{"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/posts\/386","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/comments?post=386"}],"version-history":[{"count":3,"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/posts\/386\/revisions"}],"predecessor-version":[{"id":747,"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/posts\/386\/revisions\/747"}],"wp:attachment":[{"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/media?parent=386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/categories?post=386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nonlinearexperience.com\/index.php\/wp-json\/wp\/v2\/tags?post=386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}