{"id":29,"date":"2011-06-25T01:00:46","date_gmt":"2011-06-25T06:00:46","guid":{"rendered":"http:\/\/www.playwithlua.com\/?p=29"},"modified":"2020-05-22T13:32:08","modified_gmt":"2020-05-22T18:32:08","slug":"a-simple-puzzle-game-part-2","status":"publish","type":"post","link":"http:\/\/www.playwithlua.com\/?p=29","title":{"rendered":"A simple puzzle game (part 2)"},"content":{"rendered":"<p>In part one of this post, I walked through the logic and game rules of a puzzle game, written in functional style. This time I&#8217;m going to turn that into a real game, that you can give to people to play: it will have graphics, animations, and run without installing Lua or any other dependencies.<\/p>\n<p>I&#8217;m going to do this by using a game framework called <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/love2d.org');\"  href=\"http:\/\/love2d.org\">L&ouml;ve<\/a>. I don&#8217;t want this blog to turn into library-of-the-week, but it&#8217;s impossible to do this stuff in a blog entry without using <i>some<\/i> framework, and L&ouml;ve is a good one: it&#8217;s free and open-source, works on all three platforms, and its &#8220;Hello, World&#8221; is under five lines. So let&#8217;s download it and put some game rules into it!<br \/>\n<!--more--><br \/>\nFirst, some organizational issues. L&ouml;ve expects its games to be in folders, and to start with a file called <code>main.lua<\/code>; this is the file that it will run first when it loads the game. So, let&#8217;s make a new directory, <code>fallgame<\/code>, put <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/gist.github.com\/1028685');\"  href=\"http:\/\/gist.github.com\/1028685\">our original file<\/a> in it (called <code>fall.lua<\/code>, say), and put alongside it a file called <code>main.lua<\/code> that L&ouml;ve will actually run. <code>main.lua<\/code> should do <code>require 'fall'<\/code> on the first line, to load in all the code we wrote last time. Now, if you run L&ouml;ve on that same directory, you should get a black window, because you&#8217;ve told it to load in a bunch of code but not actually do anything with it.<\/p>\n<p>How to run it, by the way, is <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/love2d.org\/wiki\/Getting_Started');\"  href=\"http:\/\/love2d.org\/wiki\/Getting_Started\">platform-dependent<\/a>. I strongly recommend adding the directory containing L&ouml;ve to your <code>PATH<\/code> though, so you can just type <code>love .<\/code> every time.<\/p>\n<h2>Callbacks<\/h2>\n<p>L&ouml;ve works around the idea of <i>callbacks<\/i>. Your program doesn&#8217;t touch the flow of control; you define a handful of functions that it calls when it&#8217;s the right time: <code>love.load()<\/code> once during startup, <code>love.mousepressed()<\/code> when the player presses a mouse button, and so on. First thing we want to do is get rid of that ugly gray background, so let&#8217;s define a <code>love.load<\/code> that sets a background color of a nice, tasteful blue-gray:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #0000aa;\">require<\/span> <span style=\"color: #ff6666;\">'fall'<\/span>\n&nbsp;\n<span style=\"color: #aa9900; font-weight: bold;\">function<\/span> love<span style=\"color: #66cc66;\">.<\/span>load<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   love<span style=\"color: #66cc66;\">.<\/span>graphics<span style=\"color: #66cc66;\">.<\/span>setBackgroundColor<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">82<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">82<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">128<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now when you start it, it will load all the code in <code>fall.lua<\/code>, then L&ouml;ve will call <code>love.load<\/code>, which will set the background color. We still need a board though, and <code>love.load<\/code> is the proper place to set that up, so add this into that function:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #0000aa;\">math.randomseed<\/span><span style=\"color: #66cc66;\">&#40;<\/span>love<span style=\"color: #66cc66;\">.<\/span>timer<span style=\"color: #66cc66;\">.<\/span>getMicroTime<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\nboard <span style=\"color: #66cc66;\">=<\/span> populate_board<span style=\"color: #66cc66;\">&#40;<\/span>make_board<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">8<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>The first line makes sure the board is random by seeding the random-number generator, and the second line calls our old functions from last time to make and fill a board (note we don&#8217;t say <code>local board<\/code> anywhere; the board is stored in a global variable). Now we just need to draw it.<\/p>\n<h2>Loading images<\/h2>\n<p>L&ouml;ve has a lot of support for drawing tile-based graphics. The idea is you put all your images on one big tilesheet, and then cut rectangular areas out of it to display. We can load the image with <code>love.graphics.newImage<\/code>, and then each rectangular area we want to draw is called a <i>quad<\/i>. The image I made looks like this:<\/p>\n<p><a onclick=\"javascript:pageTracker._trackPageview('\/downloads\/wp-content\/uploads\/2011\/06\/arrow_blocks.png');\"  href=\"http:\/\/www.playwithlua.com\/wp-content\/uploads\/2011\/06\/arrow_blocks.png\"><img loading=\"lazy\" src=\"http:\/\/www.playwithlua.com\/wp-content\/uploads\/2011\/06\/arrow_blocks.png\" alt=\"\" title=\"tiles\" width=\"192\" height=\"96\" class=\"aligncenter size-full wp-image-30\" \/><\/a><\/p>\n<p>I&#8217;m definitely not an artist, but I think it has a kind of SNES-era appeal. Each tile is 48&#215;48 (blown up 300% from a 16&#215;16 original) and there&#8217;s no spacing between them. Don&#8217;t forget to copy this or an image like it to your game directory.<\/p>\n<p>We want to have a big table of quads, where the keys are the things in our board (1-4 for the blocks and a-d for the crushers) and the values are quads that will cut sections out of this sheet. So we add this to <code>love.load<\/code>:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">   tiles <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">for<\/span> k<span style=\"color: #66cc66;\">,<\/span>v <span style=\"color: #aa9900; font-weight: bold;\">in<\/span> <span style=\"color: #0000aa;\">pairs<\/span><span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #ff6666;\">'a'<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #ff6666;\">'b'<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #ff6666;\">'c'<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #ff6666;\">'d'<\/span><span style=\"color: #66cc66;\">&#125;<\/span> <span style=\"color: #aa9900; font-weight: bold;\">do<\/span>\n      tiles<span style=\"color: #66cc66;\">&#91;<\/span>k<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> love<span style=\"color: #66cc66;\">.<\/span>graphics<span style=\"color: #66cc66;\">.<\/span>newQuad<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span><span style=\"color: #66cc66;\">&#40;<\/span>k<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #808080; font-style: italic;\">-- x, y<\/span>\n                                       <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span><span style=\"color: #cc66cc;\">4<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #808080; font-style: italic;\">-- width, height, image dimensions<\/span>\n      tiles<span style=\"color: #66cc66;\">&#91;<\/span>v<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> love<span style=\"color: #66cc66;\">.<\/span>graphics<span style=\"color: #66cc66;\">.<\/span>newQuad<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span><span style=\"color: #66cc66;\">&#40;<\/span>k<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #808080; font-style: italic;\">-- x, y<\/span>\n                                       <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span><span style=\"color: #cc66cc;\">4<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #808080; font-style: italic;\">-- width, height, image dimensions<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>For that table <code>{'a','b','c','d'}<\/code>, the pairs are (1, &#8216;a&#8217;), (2, &#8216;b&#8217;), and so on. So we can go through the table once and get all the quads we need.<\/p>\n<h2>Drawing the board<\/h2>\n<p>Let&#8217;s draw the board in the center of the screen. We first want to determine the center of the screen, by dividing the screen size by 2 and subtracting half the board size. Since we know the board is 8&#215;8 and it&#8217;s made of 48&#215;48 tiles, it&#8217;s easy to figure that out:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> love<span style=\"color: #66cc66;\">.<\/span>draw<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> g <span style=\"color: #66cc66;\">=<\/span> love<span style=\"color: #66cc66;\">.<\/span>graphics\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> w<span style=\"color: #66cc66;\">,<\/span> h <span style=\"color: #66cc66;\">=<\/span> g<span style=\"color: #66cc66;\">.<\/span>getWidth<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">,<\/span> g<span style=\"color: #66cc66;\">.<\/span>getHeight<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> left<span style=\"color: #66cc66;\">,<\/span> top <span style=\"color: #66cc66;\">=<\/span> w<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span> <span style=\"color: #66cc66;\">-<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span>board<span style=\"color: #66cc66;\">.<\/span>size<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> h<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span> <span style=\"color: #66cc66;\">-<\/span> <span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">*<\/span>board<span style=\"color: #66cc66;\">.<\/span>size<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span>\n&nbsp;\n   <span style=\"color: #808080; font-style: italic;\">-- actually draw the board here<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Actually drawing the board is simple. It&#8217;s a loop just like the ones in <code>fall.lua<\/code>, and we call <code>love.graphics.drawq<\/code> to draw a quad inside it (after looking up the correct quad based on the contents of the cell). This goes in <code>love.draw<\/code>:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">   <span style=\"color: #aa9900; font-weight: bold;\">for<\/span> n<span style=\"color: #66cc66;\">=<\/span><span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #66cc66;\">,<\/span> board<span style=\"color: #66cc66;\">.<\/span>size <span style=\"color: #66cc66;\">*<\/span> board<span style=\"color: #66cc66;\">.<\/span>size <span style=\"color: #66cc66;\">-<\/span> <span style=\"color: #cc66cc;\">1<\/span> <span style=\"color: #aa9900; font-weight: bold;\">do<\/span>\n      <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> x<span style=\"color: #66cc66;\">,<\/span> y <span style=\"color: #66cc66;\">=<\/span> n <span style=\"color: #66cc66;\">%<\/span> board<span style=\"color: #66cc66;\">.<\/span>size<span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #0000aa;\">math.floor<\/span><span style=\"color: #66cc66;\">&#40;<\/span>n <span style=\"color: #66cc66;\">\/<\/span> board<span style=\"color: #66cc66;\">.<\/span>size<span style=\"color: #66cc66;\">&#41;<\/span>\n      <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> board<span style=\"color: #66cc66;\">&#91;<\/span>n<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">~=<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span>\n         g<span style=\"color: #66cc66;\">.<\/span>drawq<span style=\"color: #66cc66;\">&#40;<\/span>img<span style=\"color: #66cc66;\">,<\/span> tiles<span style=\"color: #66cc66;\">&#91;<\/span>board<span style=\"color: #66cc66;\">&#91;<\/span>n<span style=\"color: #66cc66;\">&#93;<\/span><span style=\"color: #66cc66;\">&#93;<\/span><span style=\"color: #66cc66;\">,<\/span>\n                 left <span style=\"color: #66cc66;\">+<\/span> x<span style=\"color: #66cc66;\">*<\/span><span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">,<\/span>\n                 top <span style=\"color: #66cc66;\">+<\/span> y<span style=\"color: #66cc66;\">*<\/span><span style=\"color: #cc66cc;\">48<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n      <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<h2>Taking input, updating the game state<\/h2>\n<p>Right now we can draw the board but that&#8217;s pretty much it. For a first step, let&#8217;s hook up rotating the board. We want to read in mouse clicks (left to rotate counter-clockwise, right for clockwise) and have the board rotate in response, after animating. So, what we&#8217;ll do is, have a global <code>rotation_speed<\/code> variable, and a global <code>angle<\/code> variable. When they click the mouse, we set the rotation speed (either positive or negative):<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> love<span style=\"color: #66cc66;\">.<\/span>mousepressed<span style=\"color: #66cc66;\">&#40;<\/span>x<span style=\"color: #66cc66;\">,<\/span> y<span style=\"color: #66cc66;\">,<\/span> btn<span style=\"color: #66cc66;\">&#41;<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> rotation_speed <span style=\"color: #66cc66;\">~=<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> <span style=\"color: #aa9900; font-weight: bold;\">return<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">elseif<\/span> btn <span style=\"color: #66cc66;\">==<\/span> <span style=\"color: #ff6666;\">'l'<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> rotation_speed<span style=\"color: #66cc66;\">,<\/span> angle <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">elseif<\/span> btn <span style=\"color: #66cc66;\">==<\/span> <span style=\"color: #ff6666;\">'r'<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> rotation_speed<span style=\"color: #66cc66;\">,<\/span> angle <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>And every time <code>love.update<\/code> is called, we&#8217;ll update <code>angle<\/code> based on that.<\/p>\n<p>This is a tricky one. When <code>update<\/code> gets called, it&#8217;s passed the time since the last time it was called. We can use this to determine how much to change our internal model, without actually knowing or caring about our frames-per-second. It sounds tricky, but the rule of thumb is straightforward: just multiply all velocities by <code>dt<\/code>. Here it is:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> love<span style=\"color: #66cc66;\">.<\/span>update<span style=\"color: #66cc66;\">&#40;<\/span>dt<span style=\"color: #66cc66;\">&#41;<\/span>\n   angle <span style=\"color: #66cc66;\">=<\/span> angle <span style=\"color: #66cc66;\">+<\/span> rotation_speed <span style=\"color: #66cc66;\">*<\/span> dt\n&nbsp;\n   <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> rotation_speed &amp;gt<span style=\"color: #66cc66;\">;<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">and<\/span> angle &amp;gt<span style=\"color: #66cc66;\">;=<\/span> <span style=\"color: #0000aa;\">math.pi<\/span><span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span>\n      board<span style=\"color: #66cc66;\">,<\/span> rotation_speed<span style=\"color: #66cc66;\">,<\/span> angle <span style=\"color: #66cc66;\">=<\/span> rotate<span style=\"color: #66cc66;\">&#40;<\/span>board<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">elseif<\/span> rotation_speed &amp;lt<span style=\"color: #66cc66;\">;<\/span> <span style=\"color: #cc66cc;\">0<\/span> <span style=\"color: #aa9900; font-weight: bold;\">and<\/span> angle &amp;lt<span style=\"color: #66cc66;\">;=<\/span> <span style=\"color: #66cc66;\">-<\/span><span style=\"color: #0000aa;\">math.pi<\/span><span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span>\n      board<span style=\"color: #66cc66;\">,<\/span> rotation_speed<span style=\"color: #66cc66;\">,<\/span> angle <span style=\"color: #66cc66;\">=<\/span> rotate<span style=\"color: #66cc66;\">&#40;<\/span>rotate<span style=\"color: #66cc66;\">&#40;<\/span>rotate<span style=\"color: #66cc66;\">&#40;<\/span>board<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span><span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #cc66cc;\">0<\/span>\n   <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>The first line handles the actual rotation, the rest of it is just to detect when the rotation should stop. After we hit 90 degrees (or minus 90) we want to rotate the actual board with the game rules.<\/p>\n<p>One last thing and then we can play with this: we need to make the <code>draw<\/code> function display the board rotated. The way we do this is to actually rotate the coordinate system we draw it in. L&ouml;ve has two functions, <code>translate<\/code> and <code>rotate<\/code>, that we can use for this. We want to rotate the coordinates some around the center of the screen, so first we translate the origin to the center, then rotate by <code>angle<\/code> radians (<code>rotate<\/code> always rotates around the origin, which is why we translate it first), and then translate back:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">   <span style=\"color: #808080; font-style: italic;\">-- Put this in love.draw before the drawing loop<\/span>\n   g<span style=\"color: #66cc66;\">.<\/span>translate<span style=\"color: #66cc66;\">&#40;<\/span>w<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,<\/span> h<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n   g<span style=\"color: #66cc66;\">.<\/span>rotate<span style=\"color: #66cc66;\">&#40;<\/span>angle<span style=\"color: #66cc66;\">&#41;<\/span>\n   g<span style=\"color: #66cc66;\">.<\/span>translate<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">-<\/span>w<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">,-<\/span>h<span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now you can load it up again and watch the board move around in response to your clicks.<\/p>\n<h2>A problem arises<\/h2>\n<p>It may not look like it, but this is actually very bad code. If we tried to write the whole game like this, it would rapidly become very difficult to do. The problem lies in <code>love.update<\/code>: it operates on two different levels of abstraction. On one level, it is responsible for keeping <code>angle<\/code> updated in response to the game state created by <code>love.mousepressed<\/code>, but it&#8217;s also where we put the code to update the actual game rules. This is clean enough when there are only three states the game can be in (rotating left, rotating right, or still) but even our simple game has many more states than that:<\/p>\n<ul>\n<li>Doing nothing; ready for input<\/li>\n<li>Rotating left<\/li>\n<li>Rotating right<\/li>\n<li>Blocks are falling after a rotation<\/li>\n<li>Blocks are falling after a crushing<\/li>\n<li>(eventually) &#8220;Game Over&#8221; screen is flashing<\/li>\n<\/ul>\n<p>Each of these states can only transition to certain other states, and they each involve some change to the game board that must happen <i>after<\/i> animation is finished. Trying to write them all into one <code>love.update<\/code> function is a recipe for disaster.<\/p>\n<p>So how to fix it? Well, I&#8217;ll tell you next time, when I talk about building an actual game engine inside L&ouml;ve. In the meantime, the code from this post is <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/gist.github.com\/1033545');\"  href=\"http:\/\/gist.github.com\/1033545\">here<\/a> and I encourage you to go play around with it!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In part one of this post, I walked through the logic and game rules of a puzzle game, written in functional style. This time I&#8217;m going to turn that into a real game, that you can give to people to play: it will have graphics, animations, and run without installing Lua or any other dependencies. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts\/29"}],"collection":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=29"}],"version-history":[{"count":0,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts\/29\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=29"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=29"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=29"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}