{"id":3055,"date":"2023-09-20T15:54:56","date_gmt":"2023-09-20T06:54:56","guid":{"rendered":"https:\/\/hirake.link\/?p=3055"},"modified":"2023-09-20T15:58:42","modified_gmt":"2023-09-20T06:58:42","slug":"clojure-quil-flappy-bird-part1","status":"publish","type":"post","link":"https:\/\/hirake.link\/en\/clojure-quil-flappy-bird-part1\/","title":{"rendered":"Building a Flappy Bird in Clojure Quil #1"},"content":{"rendered":"\n<p>I recently got my hands on the book &#8220;Nature of Code &#8211; Simulating Natural Phenomena with Processing&#8221; and decided to dive into it using Clojure&#8217;s Quil library. I&#8217;ve completed the first chapter, and now, as a review, I&#8217;m planning to create a Flappy Bird game. Given the concepts from &#8220;Nature of Code,&#8221; this Flappy Bird implementation might involve some additional processing.<\/p>\n\n\n\n<p>Since I&#8217;m still learning Clojure, I welcome any suggestions or feedback if you think there&#8217;s a better way to approach this.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">What is Quil?<\/h2>\n\n\n\n<p>Quil is an environment for Processing written in Clojure, a functional Lisp dialect that runs on the JVM (Java Virtual Machine). You can even run it in your web browser through its official website.<\/p>\n\n\n\n<div class=\"blogcard\"><a href=\"http:\/\/quil.info\/\" target=\"_blank\" rel=\"noopener noreferrer\" data-blogcard=\"1\"><\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up the Project<\/h2>\n\n\n\n<p>First, let&#8217;s create a project using Leiningen. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lein new quil flappy-bird<\/code><\/pre>\n\n\n\n<p>Sample code is created in src\/flappy_bird\/core.clj with comments.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\u251c\u2500  .gitignore\n\u251c\u2500  LICENSE\n\u251c\u2500  project.clj\n\u251c\u2500  README.md\n\u2514\u2500 \/src\n    \u2514\u2500 \/flappy_bird\n            \u2514 core.clj<\/code><\/pre>\n\n\n\n<p>The following is an automatically generated sample code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(ns flappy-bird.core\n  (:require &#91;quil.core :as q]\n            &#91;quil.middleware :as m]))\n\n(defn setup &#91;]\n  (q\/frame-rate 30)\n  (q\/color-mode :hsb)\n {:color 0   \n   :angle 0})                          ;;Returns initial color and rotation angle\n\n(defn update-state &#91;state]\n  {:color (mod (+ (:color state) 0.7) 255)\n   :angle (+ (:angle state) 0.1)})     ;;Returns a new value \n                                       ;;based on the value received in the argument\n\n(defn draw-state &#91;state]\n  (q\/background 240)\n  (q\/fill (:color state) 255 255)     ;;Drawing based on the value received as an argument\n  (let &#91;angle (:angle state)\n        x (* 150 (q\/cos angle))\n        y (* 150 (q\/sin angle))]\n    (q\/with-translation &#91;(\/ (q\/width) 2)\n                         (\/ (q\/height) 2)]\n      (q\/ellipse x y 100 100))))\n\n(q\/defsketch flappy-bird               ;;Basic settings such as screen size\n  :title \"You spin my circle right round\"\n  :size &#91;500 500]\n  :setup setup\n  :update update-state\n  :draw draw-state\n  :features &#91;:keep-on-top]\n :middleware &#91;m\/fun-mode])\n<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>When you run it, you&#8217;ll see a rotating circle changing colors.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"280\" height=\"300\" src=\"https:\/\/hirake.link\/wp-content\/uploads\/2023\/04\/image-1-280x300.png\" alt=\"\" class=\"wp-image-2663\" srcset=\"https:\/\/hirake.link\/wp-content\/uploads\/2023\/04\/image-1-280x300.png 280w, https:\/\/hirake.link\/wp-content\/uploads\/2023\/04\/image-1.png 493w\" sizes=\"auto, (max-width: 280px) 100vw, 280px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding the Overall Workflow<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">In the Case of Processing<\/h3>\n\n\n\n<p>In Processing, which Quil is based on, there are two essential functions: <code>setup<\/code> and <code>draw<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>In <code>setup<\/code>, you set up things like the screen size, and it runs once at the beginning.<\/li><li>In <code>draw<\/code>, you handle continuous tasks like changing coordinates and drawing shapes.<\/li><\/ul>\n\n\n\n<p>Data such as coordinates are typically stored in global variables.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">In the Case of Quil<\/h3>\n\n\n\n<p>Quil introduces three functions: <code>setup<\/code>, <code>update-state<\/code>, and <code>draw-state<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>In <code>setup<\/code>, you perform initialization and return data to be passed to the <code>draw-state<\/code> function.<\/li><li>In <code>update-state<\/code>, you receive data as an argument, modify it, and return it.<\/li><li>In <code>draw-state<\/code>, you use the received data to draw shapes.<\/li><\/ul>\n\n\n\n<p>Quil follows a functional programming paradigm, avoiding global variables. Instead, it passes data through function arguments, updates it, and returns it in a structured way.<\/p>\n\n\n\n<p>The flow goes like this: <code>setup (initial data)<\/code> \u2192 <code>draw-state (drawing)<\/code> \u2192 <code>update-state (modification)<\/code> \u2192 <code>draw-state (drawing)<\/code> \u2192 <code>update<\/code> &#8230; Each function has its specific role, and even if you modify data in <code>draw-state<\/code>, it won&#8217;t automatically transfer to <code>update-state<\/code>. (However, if you draw inside <code>update-state<\/code>, it will appear on the screen.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> show the player character <\/h2>\n\n\n\n<p>First, remove any unnecessary code and show the player character (for now, represented as a square).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(ns flappy-bird.core\n  (:require &#91;quil.core :as q]\n            &#91;quil.middleware :as m]))\n\n(defn setup &#91;]\n  (q\/frame-rate 30)\n  {:bird &#91;100 100]})     ;;Holds the xy-coordinates of the ship as a vector\n\n(defn update-state &#91;status]\n  status)                  ;;Receive xy coordinates and return them as is\n\n(defn draw-state &#91;{:keys &#91;bird]}]\n  (q\/background 240) \n  (let &#91;&#91;x y] bird] \n    (q\/rect x y 30 30)))     ;;Draw a 30 30 rectangle at the received XY coordinates\n\n(q\/defsketch flappy-bird\n  :title \"flappy bird\"\n  :size &#91;400 600]             ;;Set screen to portrait\n  :setup setup\n  :update update-state\n  :draw draw-state\n  :features &#91;:keep-on-top]\n  :middleware &#91;m\/fun-mode])\n<\/code><\/pre>\n\n\n\n<p>You should see a square displayed on the screen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"191\" height=\"300\" src=\"https:\/\/hirake.link\/wp-content\/uploads\/2023\/04\/image-2-191x300.png\" alt=\"\" class=\"wp-image-2664\" srcset=\"https:\/\/hirake.link\/wp-content\/uploads\/2023\/04\/image-2-191x300.png 191w, https:\/\/hirake.link\/wp-content\/uploads\/2023\/04\/image-2.png 597w\" sizes=\"auto, (max-width: 191px) 100vw, 191px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In the next post, we&#8217;ll work on enabling the player character to move. Stay tuned for more!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently got my hands on the book &#8220;Nature of Code &#8211; Simulating Natural Phenomena with Processing&#8221; and decided to dive into it using Clojure&#8217;s Quil library. I&#8217;ve completed the first chapter, and now, as a review, I&#8217;m planning to create a Flappy Bird game. Given the concepts from &#8220;Nature of Code,&#8221; this Flappy Bird [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"en_US","_original_post":"https:\/\/hirake.link\/?p=2662","footnotes":""},"categories":[11],"tags":[27,90,29],"class_list":["post-3055","post","type-post","status-publish","format-standard","hentry","category-programming","tag-clojure","tag-game","tag-quil","en-US"],"_links":{"self":[{"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/posts\/3055","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/comments?post=3055"}],"version-history":[{"count":3,"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/posts\/3055\/revisions"}],"predecessor-version":[{"id":3059,"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/posts\/3055\/revisions\/3059"}],"wp:attachment":[{"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/media?parent=3055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/categories?post=3055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hirake.link\/wp-json\/wp\/v2\/tags?post=3055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}