{"id":370,"date":"2014-02-24T01:42:58","date_gmt":"2014-02-24T01:42:58","guid":{"rendered":"http:\/\/www.vidarholen.net\/contents\/blog\/?p=370"},"modified":"2014-04-16T14:34:59","modified_gmt":"2014-04-16T14:34:59","slug":"basics-of-a-bash-action-game","status":"publish","type":"post","link":"https:\/\/www.vidarholen.net\/contents\/blog\/?p=370","title":{"rendered":"Basics of a Bash action game"},"content":{"rendered":"<p>If you want to write an action game in bash, you need the ability to check for user input without actually waiting for it. While bash doesn&#8217;t let you poll the keyboard in a great way, it does let you wait for input for a miniscule amount of time with <code>read -t 0.0001<\/code>. <\/p>\n<p>Here&#8217;s a snippet that demonstrates this by bouncing some text back and forth, and letting the user control position and color. It also sets (and unsets) the necessary terminal settings for this to look good:<\/p>\n<p><code><\/p>\n<pre>\r\n#!\/usr\/bin\/env bash\r\n\r\n# Reset terminal on exit\r\ntrap 'tput cnorm; tput sgr0; clear' EXIT\r\n\r\n# invisible cursor, no echo\r\ntput civis\r\nstty -echo\r\n\r\ntext=\"j\/k to move, space to color\"\r\nmax_x=$(($(tput cols) - ${#text}))\r\ndir=1 x=1 y=$(($(tput lines)\/2))\r\ncolor=3\r\n\r\nwhile sleep 0.05 # GNU specific!\r\ndo\r\n    # move and change direction when hitting walls\r\n    (( x == 0 || x == max_x )) && \\\r\n        ((dir *= -1))\r\n    (( x += dir ))\r\n\r\n\r\n    # read all the characters that have been buffered up\r\n    while IFS= read -rs -t 0.0001 -n 1 key\r\n    do\r\n        [[ $key == j ]] && (( y++ ))\r\n        [[ $key == k ]] && (( y-- ))\r\n        [[ $key == \" \" ]] && color=$((color%7+1))\r\n    done\r\n\r\n    # batch up all terminal output for smoother action\r\n    framebuffer=$(\r\n        clear\r\n        tput cup \"$y\" \"$x\"\r\n        tput setaf \"$color\"\r\n        printf \"%s\" \"$text\"\r\n    )\r\n\r\n    # dump to screen\r\n    printf \"%s\" \"$framebuffer\"\r\ndone\r\n<\/pre>\n<p><\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you want to write an action game in bash, you need the ability to check for user input without actually waiting for it. While bash doesn&#8217;t let you poll the keyboard in a great way, it does let you wait for input for a miniscule amount of time with read -t 0.0001. Here&#8217;s a &hellip; <a href=\"https:\/\/www.vidarholen.net\/contents\/blog\/?p=370\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Basics of a Bash action game&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[5,23],"tags":[11,48,53,21],"class_list":["post-370","post","type-post","status-publish","format-standard","hentry","category-advanced-linux","category-programming","tag-bash","tag-games","tag-linux","tag-shell-script"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts\/370","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=370"}],"version-history":[{"count":5,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts\/370\/revisions"}],"predecessor-version":[{"id":376,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=\/wp\/v2\/posts\/370\/revisions\/376"}],"wp:attachment":[{"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=370"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=370"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vidarholen.net\/contents\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=370"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}