{"id":1060,"date":"2013-02-24T17:28:47","date_gmt":"2013-02-24T16:28:47","guid":{"rendered":"http:\/\/mehm.net\/blog\/?p=1060"},"modified":"2013-07-23T15:34:41","modified_gmt":"2013-07-23T14:34:41","slug":"pongbreakout-progress","status":"publish","type":"post","link":"https:\/\/mehm.net\/blog\/?p=1060","title":{"rendered":"Pong\/Breakout &#8211; Progress"},"content":{"rendered":"<p>Not that much to show at the moment for the <a href=\"http:\/\/mehm.net\/blog\/?p=1041\">Pong\/Breakout<\/a> game, as the first milestone I&#8217;m aiming for is a black and white version including the web-based editor, with fancier graphics being added in a second step.<\/p>\n<p>The screenshot here is from the editor part, featuring PowerPoint-style alignment lines to help you align bricks with each other.<\/p>\n<p><a href=\"http:\/\/mehm.net\/blog\/wp-content\/uploads\/2013\/02\/pongout_editor.png\"><img loading=\"lazy\" width=\"480\" height=\"431\" class=\"alignnone size-large wp-image-1068\" alt=\"pongout_editor\" src=\"http:\/\/mehm.net\/blog\/wp-content\/uploads\/2013\/02\/pongout_editor-480x431.png\" srcset=\"https:\/\/mehm.net\/blog\/wp-content\/uploads\/2013\/02\/pongout_editor-480x431.png 480w, https:\/\/mehm.net\/blog\/wp-content\/uploads\/2013\/02\/pongout_editor-300x269.png 300w, https:\/\/mehm.net\/blog\/wp-content\/uploads\/2013\/02\/pongout_editor.png 1070w\" sizes=\"(max-width: 480px) 100vw, 480px\" \/><\/a><\/p>\n<p><strong>PHP<\/strong><\/p>\n<p>Actually this is my first time programming PHP, but despite my impression that the language was haphazardly built and adapted whenever a need for changes became clear, at least for such a small project I like it and actually prefer it to Ruby, my only other experience of server-side programming so far. I&#8217;m running <a href=\"http:\/\/www.apachefriends.org\/en\/xampp.html\">xampp<\/a> which allows me to quickly test everything locally with minimal time spent for setup. A pretty cool feature of <a href=\"brackets.io\">Brackets<\/a> is the live preview which figured out that I had pages that needed to be served to make use of the PHP bits and automatically loaded them from the local xampp http server.<\/p>\n<p>Actually, really working on the details of the server-client connection and AJAX made me realize that starting out with Ruby is a bit like learning to run before you can walk. It&#8217;s a powerful tool, but if you don&#8217;t know where it&#8217;s coming from you&#8217;re left in the dark about the things that Ruby handles for you in the background.<\/p>\n<p><strong>Fancy HTML 5<\/strong><\/p>\n<p>My rendering code so far isn&#8217;t doing that much fancy things with HTML 5, but for the editing code I&#8217;ve thought of a nifty way of saving a preview image so you can see your levels when choosing which one to edit or play.<\/p>\n<p>The magic happens in the <a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/the-canvas-element.html#dom-canvas-toblob\">Canvas.toBlob()<\/a> function, which saves the content of a HTML 5 canvas to an image file that can be uploaded to a server. Below is the code that does this conversion and upload. With the same system, the relevant parameters of the level are saved and serialized to a JSON file, which is also uploaded as a file.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfunction blobEncoded(blob) {\r\nvar fd = new FormData(document.forms[0]);\r\nvar xhr = new XMLHttpRequest();\r\n\r\nxhr.onreadystatechange = function () {\r\nif (xhr.readyState == 4 &amp;&amp; xhr.status == 200) {\r\n\/\/ Handle the upload\r\n}\r\n}\r\n\r\n\/\/ Save all relevant variables from the arrays &quot;paddles&quot;, &quot;balls&quot; and &quot;bricks&quot;\r\nvar level = { &quot;paddles&quot;: paddles, &quot;balls&quot;: balls, &quot;bricks&quot;: bricks };\r\n\r\n\/\/ Convert it to json\r\nvar json = JSON.stringify(level);\r\n\r\n\/\/ Upload the json as a file\r\nvar jsonBlob = new Blob([json], { type: &quot;text\/json;charset=&quot; + document.characterSet });\r\n\r\nfd.append(&quot;levelFile&quot;, jsonBlob);\r\nfd.append(&quot;preview&quot;, blob);\r\nfd.append(&quot;id&quot;, id);\r\nxhr.open('POST', 'uploadLevel.php', true);\r\nxhr.send(fd);\r\n}\r\n\r\nfunction saveLevel() {\r\n\/\/ Initiate the encoding of the canvas to a blob\r\ncanvas.toBlob(blobEncoded);\r\n}\r\n\r\n<\/pre>\n<p>Since all of this is still so new not all browsers support it. This is where the development community and the so-called &#8220;polyfills&#8221; come in, libraries which provide the missing functions in those browsers that have not yet implemented them. In this case, the necessary libraries are <a href=\"https:\/\/github.com\/eligrey\/canvas-toBlob.js\/\">canvas-toBlob.js<\/a> as well as <a href=\"https:\/\/github.com\/eligrey\/Blob.js\/\">Blob.js<\/a>. With this, the whole thing runs on the current versions of Chrome and Firefox (with Firefox being seriously slower though &#8211; there will be some optimization coming my way I guess. But that is a different topic&#8230;)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updates to the editor and background info on the server and client programming.<\/p>\n","protected":false},"author":2,"featured_media":1137,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,3],"tags":[94,95,96,97,93],"_links":{"self":[{"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1060"}],"collection":[{"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1060"}],"version-history":[{"count":10,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1060\/revisions"}],"predecessor-version":[{"id":1134,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1060\/revisions\/1134"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=\/wp\/v2\/media\/1137"}],"wp:attachment":[{"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1060"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1060"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mehm.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1060"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}