<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
  <title>RightAngleGames</title>
  <link>http://www.rightanglegames.com</link>
  <description>Contains information about Thomas Haaks and his games.&#60;br&#62;Deals with game programming in general and PlayBasic, BlitzMax, Game Maker and Java/LWJGL/Slick specifically.&#60;br&#62;Offers downloads of my games and a blog.</description>
  <generator>Lauyan TOWeb</generator>
  <language>en</language>
  <pubDate>Sat, 11 May 2013 17:18:13 GMT</pubDate>
<item>
  <title>[Game Dev] Refactoring, UI, phase 3 and more</title>
  <description>&#60;i&#62; Saturday, May 11, 2013, 6:46 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Wow, one month gone and a total lack of updates. Sorry for that &#60;img src=&#34;../_frame/icon_doubt.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Real life kept me busy and many evenings I was just too tired to work on &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62;. But just like the Martians &#34;slowly and surely I drew my plans&#34; &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Phase 3 is nearly finished.&#60;br&#62;&#60;ul&#62;&#60;li&#62; aliens move from planet to planet when they conquer them (and also gain an attack bonus!),&#60;/li&#62;&#60;li&#62; aliens spawn from the second vortex if the first alien fleet is successfully destroyed by the human fleet,&#60;/li&#62;&#60;li&#62; winning conditions for aliens are detected,&#60;/li&#62;&#60;li&#62; winning conditions for humans are detected.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Additionally a lot of code refactorings happened:&#60;br&#62;&#60;ul&#62;&#60;li&#62; support for more upgrade devices for the player ship,&#60;/li&#62;&#60;li&#62; improvements of dealing with global variables, which brought me back to the good old &#60;a target=&#34;_blank&#34; href=&#34;http://www.cincomsmalltalk.com/main/products/objectstudio/&#34;&#62;Smalltalk&#60;/a&#62; naming conventions I loved to use for many years: member variables and local variables start with a small letter, globals and classes start with a capital letter and constants are all uppercase,&#60;/li&#62;&#60;li&#62; improved the popup messages,&#60;/li&#62;&#60;li&#62; prepared the code for swapping players during hot seat and fixed the code where the player instance was somewhat &#34;hard coded&#34;...&#60;/li&#62;&#60;li&#62; general code cleanup and simplification.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;The only thing missing to complete phase 3 is the super weapon of the player&#39;s ship that can destroy remaining aliens after they conquered all human planets. This will only work of course if the player has enough credits to use the super weapon! Otherwise the game is lost.&#60;br&#62;&#60;br&#62;The UI is also on my current todo list - having menus, buttons, texts and so on gets more important now that phase 3 nears completion. Because at the end of each level you will come to a score screen where you will receive your reward in credits and be able to upgrade your ship to prepare for the next harder level.&#60;br&#62;&#60;br&#62;Enough update infos for today I guess - I even dare to drop the promised video &#60;img src=&#34;../_frame/icon_eek.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;This will be uploaded when phase 3 is done and I can demo a complete level play through.&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201315</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201315</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] In the middle of phase 3</title>
  <description>&#60;i&#62; Sunday, April 14, 2013, 6:03 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;What did I achieve during the last two weeks?&#60;br&#62;&#60;ul&#62;&#60;li&#62; Fleet control and movement refactored,&#60;/li&#62;&#60;li&#62; the battle controller can now create required fleets and move them to the planets under attack,&#60;/li&#62;&#60;li&#62; fleet arrangement during the battle phase is different from the exploration phase,&#60;/li&#62;&#60;li&#62; the first approach of the combat system is in and working,&#60;/li&#62;&#60;li&#62; laser beams and explosions are in (also first version, need some tweaking and small fixes),&#60;/li&#62;&#60;li&#62; the battle controller already recognizes if the attacker or defender fleet has won the battle,&#60;/li&#62;&#60;li&#62; the battle happens in turns of 2 seconds with visual updates in between.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Now it&#39;s finishing the rest of the battle phase (moving from planet to planet, let aliens spawn from second vortex if it exists after first alien fleet is destroyed and so on).&#60;br&#62;This will take another few evenings.&#60;br&#62;&#60;br&#62;And then I think I&#39;ll start with some UI stuff, add some more functionality and the rest of the list from my previous post.&#60;br&#62;&#60;br&#62;But I&#39;m pretty happy so far! The most complicated stuff is indeed done now! My confidence grows that I will finally manage to finish this game!&#60;br&#62;&#60;br&#62;For the next post I&#39;ll guess it will be video show time again &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;And just for the record: &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; is awesome to work with!&#60;br&#62;Even if I miss some stuff from Java, Object Orientation and my favorite Java IDE Eclipse: the development speed of GM:S is impressive! I can fully concentrate on game logic and functionality. Everything else I might require from a framework or library is already there! Thanks to you guys at YoYo Games!&#60;br&#62;&#60;br&#62;Cheers,&#60;br&#62;Thomas&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201314</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201314</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Proceed to phase 3!</title>
  <description>&#60;i&#62; Friday, March 29, 2013, 6:44 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;I&#39;ve finished implementation of the second phase in my game &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62;. You can now use a given amount of time (currently 10 seconds) to arrange your ships across your connected planets and prepare for the alien onslaught. Some minor tweaks need to be done (like adding your follower fleet to the first planet) but those should be simple to do.&#60;br&#62;&#60;br&#62;So the third phase is about to being coded. Issues on my list are:&#60;br&#62;&#60;ul&#62;&#60;li&#62; refactoring fleet control and movement. This is necessary because the controller class must be able to navigate and arrange the fleets independently from any player data or user interaction,&#60;/li&#62;&#60;li&#62; the battle itself,&#60;/li&#62;&#60;li&#62; properly displaying the progress of the battle (numbers of units alive, statistics values and so on). I still need to think about this,&#60;/li&#62;&#60;li&#62; fleets following the calculated paths between vortex and planets.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;The combat system will be pretty straight forward:&#60;br&#62;&#60;ul&#62;&#60;li&#62; every ship has an attack value of 1 and a defense value of 1,&#60;/li&#62;&#60;li&#62; the player can improve these values by investing in research in phase 1,&#60;/li&#62;&#60;li&#62; the combat happens turn based,&#60;/li&#62;&#60;li&#62; in every turn each ship gets a chance to attack,&#60;/li&#62;&#60;li&#62; at the end of each turn destroyed ships are removed,&#60;/li&#62;&#60;li&#62; attack value of attacker and defense value of defender are added, a random number between one and the sum of attack/defense value is calculated,&#60;/li&#62;&#60;li&#62; if the random number is less or equal the attack value the attacker wins the fight and the defender is marked as &#34;to be destroyed&#34;, if the random number is bigger than the attack value the defender wins and the attacker is marked as &#34;to be destroyed&#34;.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Seems like a good first approach.&#60;br&#62;&#60;br&#62;After implementing all those features for phase 3 it&#39;s tuning time. The game still misses a bunch of animations, graphic effects, a nice GUI, title and menu screen, high scores, achievements and so on. But hey, it&#39;s all for the fun, right? &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Tommy</description>
  <link>http://www.rightanglegames.com/blog/index.html#201313</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201313</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] I&#39;m the master!</title>
  <description>&#60;i&#62; Friday, March 29, 2013, 6:20 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Wait, wait - I meant I&#39;m a proud owner of the &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; Master Collection &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;So I&#39;ve got all available cross platform modules (right now supported platforms are Windows, Windows 8, Windows Phone, Mac, IPhone/IPad/IPod, Android, HTML5, Ubuntu Linux). Additionally I will get all future modules for free!&#60;br&#62;And I expect some new modules to come in the foreseeable future:&#60;br&#62;&#60;ul&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;http://www.ouya.tv/&#34;&#62;Ouya&#60;/a&#62;: although the Ouya console is running Android there are some differences (joypad support for example, inapp purchases) to standard Android. The community already got a working patch and the Ouya guys sent a developer device to YoYoGames &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;/li&#62;&#60;li&#62; PS Vita or PS4: during this year&#39;s GDC Sony announced a partnership with Unity and opened themselves for indie games and therefore indie developers. YoYoGames already had a Sony PSP runner developed two years ago so I guess it would be easy for them to revitalize that one and adopt it at least for the PS Vita. They should also be in a good position to establish some deal with Sony...&#60;/li&#62;&#60;li&#62; Raspberry Pi: Mike Dailly, one of the YoYoGames developers, is already porting the runner to the Raspberry Pi. And although it&#39;s just a fun project and I haven&#39;t found proper usage of a Raspberry Pi, it&#39;s still an option. You never know who sits down in his maker shed and develops some handheld console based on the Raspberry Pi...&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Other things that the YoYoGames guys have on their todo list:&#60;br&#62;&#60;ul&#62;&#60;li&#62; LLVM compiler: moving their interpreted code to native code using LLVM&#39;s cross compiler features removes the decompiler issues older versions of GM had and of course will bring a huge speed improvement (up to factor 10!)&#60;/li&#62;&#60;li&#62; shader support: Yup, cross platform shaders for the platforms that do support FvF shaders (Flexible Vertex Formats)&#60;/li&#62;&#60;li&#62; multiplayer support: a first implementation is already available, higher level functions are to come&#60;/li&#62;&#60;li&#62; debugger improvements: finally a full featured source code debugger with breakpoints, watch windows and remote debugging to devices&#60;/li&#62;&#60;li&#62; improved audio support&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;More info on the &#60;a target=&#34;_blank&#34; href=&#34;http://wiki.yoyogames.com/index.php/GameMaker:Studio_Roadmap&#34;&#62;roadmap&#60;/a&#62;.&#60;br&#62;&#60;br&#62;So you&#39;re getting interested? Why not spend 300$ and get all of that for yourself &#60;b&#62;right now&#60;/b&#62;?&#60;br&#62;&#60;br&#62;Right, even if you don&#39;t own any GameMaker stuff, you can currently buy the entry professional edition of GameMaker:Studio for 99$ and use the current upgrade offer to the master collection for 199$. So for 298$ (you might have to add some VAT) you&#39;re in the game!&#60;br&#62;But hurry, the upgrade offer is only valid until March, 31st!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201312</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201312</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Planets, vortexes, routes and more!</title>
  <description>&#60;i&#62; Saturday, March 23, 2013, 7:16 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Oops, seems I missed a post last week. Real life kept me busy so I didn&#39;t find the time and I had not very much to report.&#60;br&#62;It&#39;s better this week - my mojo was pretty high and I tried to work on &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62; as much as I could in the few spare evenings.&#60;br&#62;&#60;br&#62;So I fixed the floating popup texts which appear now centered at their position and start to float up slowly and get more and more transparent until they disappear - just like I wanted it.&#60;br&#62;&#60;br&#62;The first phase (exploration) of a scenario is mostly complete now (except all this fine tuning of course) and working as expected. After your 80 moves/turns of uncovering the map the second phase starts - the arrangement. Here all remaining tiles will be uncovered and you have ten seconds left to arrange your space fleet and split them between all connected planets to defend them against the arriving aliens. Right now uncovering the tiles is implemented and the countdown from 10 to 0 is also functional. Moving ships between planets is not yet done. But that shouldn&#39;t be too complicated.&#60;br&#62;&#60;br&#62;At the beginning of the third phase the aliens will appear through one or two worm holes or vortexes and head to the nearest planet and attack it. If the aliens overrun your defense fleet they occupy the planet and head for the next nearest planet.&#60;br&#62;The path calculation (from vortex to nearest planet to nearest planet to nearest planet...) is done and working. Now I just need to nicely visualize them and implement the third phase - the space battle!&#60;br&#62;That&#39;s where all those graphical effects like laser beams, glowing torpedoes, flashing shields and impressive explosions should come in...I wonder how I will manage to implement that &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;But for now I declare this day finished - time for a glass of wine or a little dram of whisky.&#60;br&#62;&#60;br&#62;Until later,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201311</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201311</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Planets, credits and text snippets</title>
  <description>&#60;i&#62; Sunday, March 10, 2013, 4:05 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Nearly no time found to work on &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62;. But I managed tiny bits. I added credits (money) to the game which you&#39;ll need later on in the game to buy upgrades for your mother ship. I also finished planet behavior: you can search planets up to two times to find credits and some bonuses for population increase, attack or defense values.&#60;br&#62;And finally I started to implement some text popups which will appear during the game when you find something for example or the game wants to tell you anything important &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;I also bought a Midi controller keyboard to start dabbling with some music (I own Magix Music Maker for several years now, upgraded once in a while but never really used it). Now playing with Magix Music Maker is a completely different story. All those plugins and synthesizers are fun to use because you can record live!&#60;br&#62;I might upload stuff if I consider it good enough...&#60;br&#62;&#60;br&#62;Have a nice week,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201310</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201310</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] The fleet is moving again!</title>
  <description>&#60;i&#62; Saturday, March 02, 2013, 7:38 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;That was a tough one! It took me the whole afternoon (round about 4 hours) to get the fleet code working properly (at least for the first working version).&#60;br&#62;But it&#39;s in now with correctly rotating fleet ships staying in their formation.&#60;br&#62;&#60;br&#62;To celebrate I uploaded a YouTube video which you can also find in this blog entry.&#60;br&#62;&#60;br&#62;Feedback appreciated!&#60;br&#62;&#60;br&#62;Cheers,&#60;br&#62;Tommy&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201309</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201309</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Routes are mine!</title>
  <description>&#60;i&#62; Wednesday, February 27, 2013, 8:32 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;A little spare time this evening was all I needed to port the &#60;a target=&#34;_blank&#34; href=&#34;http://www.blitzbasic.com/Products/blitzmax.php&#34;&#62;BlitzMax&#60;/a&#62; code over to &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker&#39;s&#60;/a&#62; GML code  &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;It worked exactly as I described it in the previous post - I create space route objects on those tiles where a  route is allowed. The space route objects know how to draw themselves (based on their neighbors) - right now they draw simple yellow lines.&#60;br&#62;&#60;br&#62;Later on I will create some buoys or waypoint lights which blink every once in a while instead of those boring yellow lines.&#60;br&#62;&#60;br&#62;You cannot build routes on all possible tiles - there will be no routes across asteroids for example. And you can only establish routes if you have enough followers. The amount of required followers for each route segment is based on available devices that you can buy to enhance your ship.&#60;br&#62;&#60;br&#62;I&#39;ll give you a screenshot with working routes to your and my entertainment &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;If you compare the last two screenshots you can see that the random level generator is indeed working fine too!&#60;br&#62;&#60;br&#62;Next thing on my list is fleet formation code. I could (again) port that from the existing Java code base or search the &#60;a target=&#34;_blank&#34; href=&#34;http://http://gmc.yoyogames.com/&#34;&#62;GMC&#60;/a&#62; forums for some examples. If I remember correctly there were some GameMaker examples available...&#60;br&#62;&#60;br&#62;Have fun,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201308</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201308</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Java code porting is done, but..</title>
  <description>&#60;i&#62; Sunday, February 24, 2013, 12:25 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;All the relevant Java code is now ported over to &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker&#39;s&#60;/a&#62; script language GML. Overall it was a smooth and simple process. Next task is to get everything into a working state again.&#60;br&#62;&#60;br&#62;While I was porting the code I had a vague memory of some existing functionality to draw space routes which can exist between planets and increase population growth of those connected planets.&#60;br&#62;But I couldn&#39;t find the methods - only empty methods throwing NotYetSupportedExceptions...&#60;br&#62;&#60;br&#62;This morning I detected that I completely forgot another WIP of &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62; I&#39;ve started with &#60;a target=&#34;_blank&#34; href=&#34;http://www.blitzbasic.com/Products/blitzmax.php&#34;&#62;BlitzMax&#60;/a&#62; back in 2009/2010. Sigh.&#60;br&#62;&#60;br&#62;You know a game in progress takes too long when you even forget complete WIPs you&#39;ve created over the years in different languages/engines &#60;img src=&#34;../_frame/icon_doubt.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;I guess I&#39;ll port one or two methods of the BlitzMax code over to GML &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;But this time I will solve it different, not just drawing lines but having SpaceRoute objects on top of the tiles where the SpaceRoute objects know how to draw themselves.&#60;br&#62;&#60;br&#62;Screenshot of current WIP state to the right.&#60;br&#62;&#60;br&#62;Have fun,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201307</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201307</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Porting continues...</title>
  <description>&#60;i&#62; Sunday, February 17, 2013, 4:38 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;So I&#39;m still porting Java code over to GML. It&#39;s not complicated at all, just tedious.&#60;br&#62;Some issues I have found so far with GML:&#60;br&#62;&#60;br&#62;&#60;ul&#62;&#60;li&#62; You cannot use return values of scripts in expressions.&#60;/li&#62;&#60;/ul&#62;%CODE_BEGIN% &#60;br&#62;a = (scrCalculateSomething() + 4);&#60;br&#62;%CODE_END% &#60;br&#62;a has value of 4 afterwards, no matter what scrCalculateSomething() returns...&#60;br&#62;&#60;ul&#62;&#60;li&#62; You cannot create arrays in scripts and return them - they are lost because they are in the local scope of the script and don&#39;t survive just because they are return values.&#60;/li&#62;&#60;li&#62; The script editor / code editor does not check if you use undeclared variables in your code...&#60;/li&#62;&#60;li&#62; The script editor gets totally confused if you paste code into it containing &#60;i&#62;real&#60;/i&#62; TAB characters. Don&#39;t do that.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;But in general it&#39;s very easy to modify the Java code base to GML. Just a few scripts are remaining and then I&#39;ve got the old functionality of the Java prototype back.&#60;br&#62;On the other hand I already improved the scripts a bit while porting, added new graphics and due to &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker&#39;s&#60;/a&#62; nature dealing with events, drawing, attaching sprites and all that is way easier than before.&#60;br&#62;&#60;br&#62;One important thing to mention: &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; got a new update. This happens pretty regularly (every two or three weeks at the moment) but this time the guys from YoYo Games fixed a quirk that has been part of GameMaker for years now:&#60;br&#62;&#60;br&#62;the code editor window was &#60;b&#62;modal&#60;/b&#62;!!! This meant you could not open several code editors at once, you could not copy from one code editor window into another without closing and opening them one after the other! That has been a real PITA for years now and I&#39;m so happy that they finally got it fixed!&#60;br&#62;&#60;br&#62;Oh, a WIP screenshot of &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62; to the right &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;You cannot see very much because of the fog of war but there are a lot of new game elements added (and now placed randomly) to the map.&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201306</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201306</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Music musings and more</title>
  <description>&#60;i&#62; Sunday, February 10, 2013, 3:28 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;While I&#39;m still porting the random level generation stuff over (I&#39;m just too tired at night on working days right now so I mainly try to get things done at the weekend) every once in a while I think about music.&#60;br&#62;&#60;br&#62;Just recently I bought &#60;a target=&#34;_blank&#34; href=&#34;https://play.google.com/store/apps/details?id=com.singlecellsoftware.caustic&#38;hl=en&#34;&#62;Caustic 2&#60;/a&#62; for my Nexus 7 tablet. It&#39;s a wonderful pattern based music creation tool, based on synthesizers you can customize to your liking. There are additional presets you can buy if you don&#39;t want to detect synth settings on your own.&#60;br&#62;The best thing is it&#39;s also available for Windows machines. So you can share the stuff between PC and tablet. Cool!&#60;br&#62;&#60;br&#62;Another website I&#39;ve heard about on twitter is &#60;a target=&#34;_blank&#34; href=&#34;http://incompetech.com/&#34;&#62;http://incompetech.com/&#60;/a&#62; where you can get free music. A donation of 5$ per track is highly recommended and if you&#39;ve listened to a few tracks you&#39;ll have to agree that they are all worth it! But officially all music tracks are under the &#60;b&#62;Creative Commons: By Attribution 3.0&#60;/b&#62; license. This means you have to credit the author in your game, video or whatever you want to produce with it but you are not forced to pay for the songs.&#60;br&#62;Still I can only urge you to donate the money - I&#39;ve paid money for songs not even close to the quality of the ones from Incompetech.&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201305</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201305</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Pathfinding working</title>
  <description>&#60;i&#62; Sunday, February 03, 2013, 5:18 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Over the last week I migrated the functionality of planets and laboratories from the Java source code back to the &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; version of &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62;. Worked like a charm. So the planets start to increase their population after they are found by the player and the laboratories start to explore technological features as soon as they get some population (scientists) from the player. Bazinga!&#60;br&#62;&#60;br&#62;This afternoon I started learning the A* path finding implementation of &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GM:S&#60;/a&#62;. It didn&#39;t work immediately as expected because the documentation was a bit wrong regarding path calculation. But after I found out that you have to pass absolute screen coordinates for start end target position instead of grid coordinates all worked fine.&#60;br&#62;&#60;br&#62;You can see some debug result in the screenshot to the right. I was very pleased when I found out that &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GM:S&#60;/a&#62; offers convenience methods to draw the grid with free cells in green and blocking cells in red and also the calculated path. Absolutely perfect for debugging issues and all you need to do is call a method/function!&#60;br&#62;&#60;br&#62;Next on my porting list should be the functionality of the other game tiles I&#39;ve already coded in Java and the random level generator. It took me quite a while to get the random level generation to work in Java and I&#39;m very happy that I now just need to migrate the code &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;More progress information hopefully on the next blog post!&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Thomas&#60;br&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201304</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201304</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Strange things happen...</title>
  <description>&#60;i&#62; Tuesday, January 29, 2013, 10:19 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Surprise, surprise! Somehow I managed over the last few days to work on my endless WIP &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62;. The screenshot is just a proof &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;Of course it&#39;s full of placeholder graphics, the hud is less than rudimentary but still: I make progress!&#60;br&#62;The code is already laid out for multiplayer (hot seat for now), the resolution is resized to 960x640 which fits many mobile devices (adjustments using GameMaker views will come in later to support different resolutions by keeping aspect ratio).&#60;br&#62;The &#34;core&#34; engine is basically working and I continue to transform the existing Java code back to GML, GameMaker&#39;s scripting language, which is comparable with C plus some GameMaker specific enhancements.&#60;br&#62;&#60;br&#62;At least right now I dare to say: I got my game coding mojo back &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201303</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201303</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Fiddling around</title>
  <description>&#60;i&#62; Monday, January 14, 2013, 8:58 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;I made some tiny little baby steps in both directions - back and forth...&#60;br&#62;Some months ago I bought some graphics from &#60;a target=&#34;_blank&#34; href=&#34;http://www.graphicsforgames.com&#34;&#62;http://www.graphicsforgames.com&#60;/a&#62;, different space ship fleets and planets and asteroids for &#60;a href=&#34;../theycome/index.html&#34;&#62;They Come&#60;/a&#62;. Just yesterday I finally managed to convert them to a usable size for the game. Next thing would be recoding the game for &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; with stuff like multiple platforms in mind. This means multiple resolutions for example.&#60;br&#62;Also I learned quite some stuff about GM:S&#39; features and functionalities and I think I can convert the existing Java code base to GM:S pretty well and on the way add many little gizmos to the game.&#60;br&#62;&#60;br&#62;We&#39;ll see how it works out &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201302</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201302</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Real life] Belated happy new year and all this...</title>
  <description>&#60;i&#62; Monday, January 14, 2013, 8:51 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Sigh, three months without &#60;b&#62;any&#60;/b&#62; update - what a pity! As some of you have heard I got a new day job which requires a lot of time and energy. So my spare time for the website and game development is reduced.&#60;br&#62;&#60;br&#62;I&#39;m pretty sure this will change over time but at the moment it&#39;s a situation I have to learn how to deal with.&#60;br&#62;&#60;br&#62;But nevertheless, a happy new year to all of you, keep fingers crossed for game dev time and all the best to you!&#60;br&#62;&#60;br&#62;Cheers,&#60;br&#62;Thomas</description>
  <link>http://www.rightanglegames.com/blog/index.html#201301</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201301</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] GameMaker:Studio goes Steam!</title>
  <description>&#60;i&#62; Saturday, October 06, 2012, 4:10 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;What a surprise and smart deal from YoYoGames!&#60;br&#62;&#60;br&#62;&#60;a target=&#34;_blank&#34; href=&#34;http://store.steampowered.com/&#34;&#62;Steam&#60;/a&#62;, the biggest online portal and community for downloadable games (there are approximately 4 million users online each day) opened their shop for applications just recently.&#60;br&#62;&#60;br&#62;And those YoYo guys managed to get &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; added to the list of the first few apps that are prominently featured on the Steam website!&#60;br&#62;Even better they got it added to the Steam Workshop too. This means that &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; owners can upload their games to the Steam Workshop and get them seen and played by several million people! That&#39;s just amazing!&#60;br&#62;&#60;br&#62;You can download the (feature limited) free version of &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; from the Steam store and play all games from the Workshop for free.&#60;br&#62;Of course you can upgrade your free copy of GameMaker:Studio to the Standard or Professional or Master edition if you want, just as you can do from the YoYoGames website.&#60;br&#62;But even games created with the free version of GameMaker:Studio can be uploaded to Steam&#39;s Workshop!&#60;br&#62;&#60;br&#62;All customers who bought &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; from YoYoGames directly receive Steam keys to unlock their modules for the Steam version of &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; too. So no additional costs at all but just more features (upload to Workshop, play all Workshop games, sync your stuff with Steam&#39;s cloud)!&#60;br&#62;&#60;br&#62;Pretty cool and hopefully a great marketing move for YoYoGames!&#60;br&#62;&#60;br&#62;Oh, before I forget: there&#39;s a 10% discount on each &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; package on Steam currently,  running til 9th of October. So if you want to join the fun of coding games with this great tool now would be a good time to start and jump the boat!&#60;br&#62;&#60;br&#62;Let&#39;s make more games &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Which reminds me that I have some stuff to code! &#60;a href=&#34;../backtothepast/index.html&#34;&#62;Back to the past&#60;/a&#62; is still in porting progress...</description>
  <link>http://www.rightanglegames.com/blog/index.html#201221</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201221</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Proper integration of HTML5 games on my site!</title>
  <description>&#60;i&#62; Saturday, September 01, 2012, 10:13 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;I love the &#60;a target=&#34;_blank&#34; href=&#34;http://gmc.yoyogames.com&#34;&#62;GMC&#60;/a&#62; and the huge amount of information you can get there. And the smart chaps of YoYoGames too. Mike Dailly just posted an information about properly integrating &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; games into nearly any blog.&#60;br&#62;And guess what - it&#39;s also working for &#60;a target=&#34;_blank&#34; href=&#34;http://www.lauyan.com&#34;&#62;TOWeb&#60;/a&#62;!&#60;br&#62;&#60;br&#62;Have a look over here at my special &#60;a href=&#34;../penandpaper/index.html&#34;&#62;PenAndPaper&#60;/a&#62; game page or use the top menu entry of &#60;a href=&#34;../penandpaper/index.html&#34;&#62;PenAndPaper&#60;/a&#62; in the Games menu.&#60;br&#62;&#60;br&#62;How cool is that?&#60;br&#62;&#60;br&#62;Now let me quickly take a few months of vacation and finish some games to place them on my site (or anywhere else and earn tons of money) &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;No just kidding, back to real life work on monday - and that&#39;s fun too!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201220</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201220</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] First HTML5 stuff to play around with</title>
  <description>&#60;i&#62; Wednesday, August 01, 2012, 9:12 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;It took some time but finally my reported bug in &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62; was fixed. So I uploaded a first version of my rogue like maze generator.&#60;br&#62;&#60;br&#62;Use the cursor keys to walk around, press Space to generate a new maze.&#60;br&#62;&#60;br&#62;You can have a play &#60;a target=&#34;_blank&#34; href=&#34;http://www.rightanglegames.com/webgames/PenAndPaper/index.html&#34;&#62;here&#60;/a&#62;.&#60;br&#62;&#60;br&#62;Some feedback or questions are appreciated.&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Tommy&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201219</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201219</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Games] Steam summer sale - I could resist!</title>
  <description>&#60;i&#62; Sunday, July 22, 2012, 10:03 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;The &#60;a target=&#34;_blank&#34; href=&#34;http://store.steampowered.com/&#34;&#62;Steam summer sale&#60;/a&#62; is pretty much over and up to now I only bought 3 games:&#60;br&#62;&#60;ul&#62;&#60;li&#62; Trine 2, which looks and plays marvelous and their physics engine and lighting stuff is just amazing,&#60;/li&#62;&#60;li&#62; Insanely Twisted Shadow Planet, because the graphics and music are so much Tim Burton style that I simply could not resist and finally&#60;/li&#62;&#60;li&#62; Legend of Grimrock, because I love those old school RPGs. Although I haven&#39;t played Dungeon Master from FTL for very long, I played through all old Might and Magic RPGs (up to version 5 or 6) which were pretty similar.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Most of the Indie titles I already owned so they weren&#39;t really interesting for me and finally I wasn&#39;t interested in all those AAA titles either.&#60;br&#62;I can&#39;t stand WW2 shooters, the only FPS I like is Unreal Tournament and that I play twice a year &#60;img src=&#34;../_frame/icon_doubt.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;No reason to spend money on that kind of games.&#60;br&#62;&#60;br&#62;I would love to see Magic the Gathering with a reduced price but it already is at 9 Euros so I could afford that anyway...&#60;br&#62;&#60;br&#62;Thanks Steam and better luck next time (US Thanksgiving or Christmas maybe)...</description>
  <link>http://www.rightanglegames.com/blog/index.html#201218</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201218</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Progress with GameMaker:Studio</title>
  <description>&#60;i&#62; Sunday, July 22, 2012, 9:58 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;I worked a bit on my GM:S remake of &#60;a href=&#34;../backtothepast/index.html&#34;&#62;Back to the past&#60;/a&#62; and made some pretty satisfying progress. The basic jump&#39;n&#39;run part is working properly. Also the auto tiling of the platform blocks is working.&#60;br&#62;&#60;br&#62;Next will be the timing of the animation, not sure if I use the builtin step mechanism (GM:S uses a fixed frame rate, so the update or step logic would be called 30 times a second by default). The other alternative is the newly added &#60;b&#62;delta&#60;/b&#62; variable of GM:S which contains the delta value in milliseconds, similar to Slick or other game engines with a time based update loop.&#60;br&#62;&#60;br&#62;Then I will add the other features (bots, shooting, acid, collectables, exit) one by one.&#60;br&#62;&#60;br&#62;Overall it&#39;s working pretty easy and I will upload a HTML5 alpha version to play around with it very soon. Stay tuned &#60;img src=&#34;../_frame/icon_smile.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;As a little teaser and proof I added a little screenshot of &#60;a href=&#34;../backtothepast/index.html&#34;&#62;Back to the past&#60;/a&#62; running in a web browser, made with &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com/gamemaker/studio&#34;&#62;GameMaker:Studio&#60;/a&#62;.</description>
  <link>http://www.rightanglegames.com/blog/index.html#201217</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201217</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Website] All machines full stop!</title>
  <description>&#60;i&#62; Sunday, July 22, 2012, 9:53 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;A few days ago I sent an email to the &#60;a target=&#34;_blank&#34; href=&#34;http://lauyan.com&#34;&#62;TOWeb&#60;/a&#62; developer regarding some kind of &#34;dynamic online publishing&#34; similar to Wordpress or Joomla. Because that&#39;s the only missing feature of &#60;a target=&#34;_blank&#34; href=&#34;http://lauyan.com&#34;&#62;TOWeb&#60;/a&#62; that could massively speed up my posting behavior &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;To my surprise the developer told me he&#39;s already thinking about adding this and other more &#34;dynamic online&#34; features! How cool is that?&#60;br&#62;I guess I will just wait a little bit longer and continue using &#60;a target=&#34;_blank&#34; href=&#34;http://lauyan.com&#34;&#62;TOWeb&#60;/a&#62; because it&#39;s usage is dead simple and more than comfortable compared to Wordpress or Joomla. AAAND I don&#39;t have to convert all or most of the content of my existing site!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201216</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201216</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Bugs and fiddling around</title>
  <description>&#60;i&#62; Tuesday, July 17, 2012, 3:29 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;My plan was to publish a first HTML5 alpha version of &#34;Pen and Paper&#34; just to demonstrate the level generation, minimap and wandering around.&#60;br&#62;Unfortunately I found a GameMaker:Studio bug which breaks the HTML5 build (but works under Windows).&#60;br&#62;So I&#39;ll have to wait until this bug is fixed by YoYoGames. Should be fixed in one or two weeks if they keep their current bugfix release timeline.&#60;br&#62;&#60;br&#62;To get more used to GameMaker:Studio I started porting of some other games of mine (&#60;a href=&#34;../backtothepast/index.html&#34;&#62;Back to the past&#60;/a&#62; and &#60;a href=&#34;../10seconds/index.html&#34;&#62;10 seconds&#60;/a&#62;).&#60;br&#62;First challenge was the tweening stuff I use for the splash screen of my games. Luckily several topics on the &#60;a target=&#34;_blank&#34; href=&#34;http://gmc.yoyogames.com&#34;&#62;GMC&#60;/a&#62; cover tweening and I quickly had a running solution. It&#39;s a mixture of Marte&#39;s tweening code and some GameMaker approaches. Working fine!&#60;br&#62;&#60;br&#62;The GUI is another issue, especially for &#60;a href=&#34;../10seconds/index.html&#34;&#62;10 seconds&#60;/a&#62; where I used a cool BlitzMax framework that allowed nice movements of complex GUI dialogs and stuff like that. But I&#39;ll get that sorted with GameMaker:Studio, I&#39;m pretty confident here.&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201215</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201215</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Website] Decisions are evolving...</title>
  <description>&#60;i&#62; Tuesday, July 17, 2012, 3:26 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;My current idea is to make the content of this site available via my &#34;old&#34; domain &#60;a target=&#34;_blank&#34; href=&#34;http://www.haaks.net&#34;&#62;http://www.haaks.net&#60;/a&#62; and move &#60;a target=&#34;_blank&#34; href=&#34;http://www.rightanglegames.com&#34;&#62;http://www.rightanglegames.com&#60;/a&#62; over to Wordpress and redo the website from there.&#60;br&#62;&#60;br&#62;So I could take my time, get used to Wordpress and rearrange the contents and still add new blog entries faster than before, add mobile support (browsing from your smartphone or tablet) and so on but still allow visitors to read and search my old site.&#60;br&#62;&#60;br&#62;Right now I just need to organize some stuff beforehand and then get brave enough to do the switch &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201214</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201214</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Random level generation working!</title>
  <description>&#60;i&#62; Sunday, May 20, 2012, 8:00 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;After twiddling with several level generation algorithms (and their source code in several different programming languages) I finally settled down with a simple verbose description and coded it all on my own (using GameMaker&#39;s builtin GML).&#60;br&#62;&#60;br&#62;Here&#39;s the description:&#60;br&#62;&#60;br&#62;&#60;i&#62;Divide the map into a grid (Rogue uses 3x3, but any size will work).&#60;br&#62;Give each grid a flag indicating if it&#39;s &#34;connected&#34; or not, and an array of which grid numbers it&#39;s connected to.&#60;br&#62;Pick a random room to start with, and mark it &#34;connected&#34;.&#60;br&#62;While there are unconnected neighbor rooms, connect to one of them, make that the current room, mark it &#34;connected&#34;, and repeat.&#60;br&#62;While there are unconnected rooms, try to connect them to a random connected neighbor (if a room has no connected neighbors yet, just keep cycling, you&#39;ll fill out to it eventually).&#60;br&#62;All rooms are now connected at least once.&#60;br&#62;Make 0 or more random connections to taste; I find rnd(grid_width) random connections looks good.&#60;br&#62;Draw the rooms onto the map, and draw a corridor from the center of each room to the center of each connected room, changing wall blocks into corridors. If your rooms fill most or all of the space of the grid, your corridors will very short - just holes in the wall.&#60;/i&#62;&#60;br&#62;&#60;br&#62;You can see an example in the screenshot to the right. Click on it for full size.&#60;br&#62;&#60;br&#62;That&#39;s it for this sunday, have a nice week &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201213</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201213</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Website] Changes ahead?</title>
  <description>&#60;i&#62; Sunday, May 06, 2012, 9:35 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Oh, it&#39;s this time of the year again?&#60;br&#62;&#60;br&#62;Yup, I&#39;m thinking about redoing the website (again). And I&#39;m thinking about switching to Wordpress (again).&#60;br&#62;We&#39;ll see how far I come this time. A local version of &#60;a target=&#34;_blank&#34; href=&#34;http://www.wordpress.org&#34;&#62;Wordpress&#60;/a&#62; using &#60;a target=&#34;_blank&#34; href=&#34;http://www.apachefriends.org/en/index.html&#34;&#62;XAMPP&#60;/a&#62; will be installed on my laptop and I will use that to create and fill the initial Wordpress version of my site.&#60;br&#62;&#60;br&#62;And as usual I&#39;m afraid there are several reasons against Wordpress but currently I&#39;m really annoyed about the long deployment cycle of &#60;a target=&#34;_blank&#34; href=&#34;http://www.lauyan.com&#34;&#62;TOWeb&#60;/a&#62;. For every single article you have to publish the whole site. It&#39;s optimized and only updating changed stuff but still... it lasts several minutes until it&#39;s done. And I have to start an additional application to write an article (with lots of comfort I must admit) and get it published. It would be so much easier to just use the web browser and write and publish anything just instantly...&#60;br&#62;&#60;br&#62;I&#39;ll have a go with &#60;a target=&#34;_blank&#34; href=&#34;http://www.wordpress.org&#34;&#62;Wordpress&#60;/a&#62; on my local machine and depending on the (hopefully quick) progress or not I&#39;ll might decide to make the switch. One issue will be trying to keep the old content and (if possible) some of the old static URLs...&#60;br&#62;&#60;br&#62;You and me will find out.</description>
  <link>http://www.rightanglegames.com/blog/index.html#201212</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201212</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Another competition, maybe another game?!</title>
  <description>&#60;i&#62; Sunday, May 06, 2012, 9:27 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Over at &#60;a target=&#34;_blank&#34; href=&#34;http://www.64digits.com&#34;&#62;http://www.64digits.com&#60;/a&#62; they are having a contest which started 1st of May and ends 2nd of August. It&#39;s about creating a RPG. See &#60;a target=&#34;_blank&#34; href=&#34;http://www.64digits.com/users/index.php?userid=Toast&#38;cmd=comments&#38;id=272934&#34;&#62;here&#60;/a&#62; for details. The contest is still open for joining (you need to join the forums and announce your intent in the above topic as a comment).&#60;br&#62;&#60;br&#62;I decided to give it a try, mainly because I always wanted to code a little roguelike game and second because I needed a reason to play around with Game Maker and third because it&#39;s a family friendly time span of 3 months.&#60;br&#62;&#60;br&#62;Although I planned to give libGDX a try I couldn&#39;t motivate myself. Instead I downloaded Ludum Dare 23 entries made with Game Maker, I read my two Game Maker books, I browsed the Game Maker forums and updated my Game Maker:Studio beta every time the YoYo Games guys released a new beta.&#60;br&#62;&#60;br&#62;Sigh. Seems to me like a signal. So without further ado I decided to give in to myself and have fun with Game Maker instead of forcing me to do something I obviously try to avoid for unknown reasons &#60;img src=&#34;../_frame/icon_doubt.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;For the game graphics I have something special in my mind which fits the RPG theme and the roots of RPG: pen and paper &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;More details hopefully later!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201211</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201211</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev]Ludum Dare is looong over...</title>
  <description>&#60;i&#62; Sunday, May 06, 2012, 9:22 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;...but there are 1402 games for you to play &#60;img src=&#34;../_frame/icon_eek.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;Amazing, isn&#39;t it? More than 1400 games created in one weekend! What&#39;s even better is that most of the competition entries (not the jam entries which lasted one day longer) come with full source!&#60;br&#62;So should you ever think about coding games yourself (and honestly, why shouldn&#39;t you?) there&#39;s a lot of source code to learn from &#60;a target=&#34;_blank&#34; href=&#34;http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&#34;&#62;right here&#60;/a&#62;!!!&#60;br&#62;&#60;br&#62;Have fun downloading and browsing the code, learn what you can and improve your knowledge!&#60;br&#62;&#60;br&#62;Oh, and don&#39;t forget to play a game in between &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62; Many of them are really worth it!&#60;br&#62;&#60;br&#62;I downloaded several Game Maker games to learn from as I intend to give Game Maker Studio a test run. See my post above.</description>
  <link>http://www.rightanglegames.com/blog/index.html#201210</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201210</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Ludum Dare weekend!</title>
  <description>&#60;i&#62; Tuesday, April 17, 2012, 9:35 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;The next weekend (20th to 23rd of April) is &#60;a target=&#34;_blank&#34; href=&#34;http://www.ludumdare.com&#34;&#62;Ludum Dare&#60;/a&#62; again. Create a game in 48 hours (72 hours for the jam) with a given theme all on your own.&#60;br&#62;&#60;br&#62;I&#39;m afraid I won&#39;t have enough time to join the competition. So as usual I will spend a few minutes here and there and read the blogs on the Ludum Dare website or watch some time lapse videos or live webcams &#60;img src=&#34;../_frame/icon_smile.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;On the other hand I don&#39;t put myself under too much self made stress trying to create a game under bad conditions...&#60;br&#62;&#60;br&#62;But maybe &#60;b&#62;YOU&#60;/b&#62; want to jump in? It&#39;s just a few minutes for registration and off you go!&#60;br&#62;&#60;br&#62;Have fun on the &#60;a target=&#34;_blank&#34; href=&#34;http://www.ludumdare.com&#34;&#62;Ludum Dare&#60;/a&#62; competition or have a nice weekend anyway &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Later,&#60;br&#62;Tommy</description>
  <link>http://www.rightanglegames.com/blog/index.html#201209</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201209</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Spriter on Kickstarter and libGDX</title>
  <description>&#60;i&#62; Tuesday, April 17, 2012, 9:17 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;&#60;a target=&#34;_blank&#34; href=&#34;http://www.kickstarter.com/projects/539087245/spriter&#34;&#62;Spriter&#60;/a&#62; is a 2D animation tool. It&#39;s currently a beta version and looking for funding via &#60;a target=&#34;_blank&#34; href=&#34;http://www.kickstarter.com&#34;&#62;Kickstarter&#60;/a&#62;. Because it is such a powerful tool, a great idea and a downloadable working beta as proof of concept is also available the funding of the project is already successful (at the time of writing they achieved over 40,000$ while asking for 25,000$)!&#60;br&#62;&#60;br&#62;I became a backer a few days ago and thought about asking for a libGDX (or indeed any Java) binding. Because in general the magic behind Spriter is just XML files describing the transformation of the separate sprite graphics with some timing/frame information. Nothing every game coder could create in a few weeks except the UI tool of course. A good interface does take time (that&#39;s why they are asking for funding, doh!).&#60;br&#62;But it&#39;s not too difficult to create some code that reads and interprets the XML and draws the sprite graphics accordingly. But of course I didn&#39;t want to spend the time at all - I just want to use it &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Luckily an implementation already popped up over at the libGDX forums (&#60;a target=&#34;_blank&#34; href=&#34;http://www.badlogicgames.com/forum/viewtopic.php?f=17&#38;t=3863&#34;&#62;here&#60;/a&#62;).&#60;br&#62;I think we can assume that even enhancements and extensions of the Spriter XML format will follow in short time frames now that some base code for libGDX already exists.&#60;br&#62;&#60;br&#62;Now all I need is more spare time and I can create games with my own graphics, animations and music &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201208</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201208</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Music creation on the fly...</title>
  <description>&#60;i&#62; Tuesday, April 17, 2012, 8:51 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Yesterday I bought  &#60;a target=&#34;_blank&#34; href=&#34;http://www.soundtrends.com/apps/gruvtron/&#34;&#62;grüvtron&#60;/a&#62; for my Android. A simple tool to create music and to have tons of fun. I commute an hour every day so I used the time in the train and gave it a little test run. Headphones on and off we go &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;The great thing is you can record your life playing! Changing notes, chords, distortion with your fingertips and save it all as a wav file.&#60;br&#62;A few minutes ago I converted my &#34;demo&#34; track to mp3 format and here it is.&#60;br&#62;&#60;br&#62;Enjoy a bit (it&#39;s not that good but as I said: it&#39;s been fun to create &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;)...&#60;br&#62;&#60;br&#62;That sounds like a great option to create music tracks for example for Ludum Dare competition games when you&#39;re in a hurry and not talented at all, like me &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;One dollar well spent!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201207</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201207</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] libGDX - how did I miss that one?</title>
  <description>&#60;i&#62; Monday, April 09, 2012, 2:59 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Just a few days ago I talked with a friend about &#60;a target=&#34;_blank&#34; href=&#34;http://code.google.com/p/libgdx/&#34;&#62;libGDX&#60;/a&#62;. My memories were &#34;some Android lib for Java, also running on the desktop&#34;. But now I own an Android cell phone, I love coding games in Java and sharing the same code base for desktop and Android sounds cool (isn&#39;t that the reason why I looked at GameMaker:Studio? &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;).&#60;br&#62;&#60;br&#62;Additionally I started to follow Mario Zechner, the creator of libGDX, on Twitter. And just recently he announced that libGDX can now also create HTML5 output!&#60;br&#62;&#60;br&#62;So &#60;a target=&#34;_blank&#34; href=&#34;http://code.google.com/p/libgdx/&#34;&#62;libGDX&#60;/a&#62; offers all the features I want to have plus the coding power of Java! But libGDX contains even more:&#60;br&#62;&#60;ul&#62;&#60;li&#62; a 2D scene graph,&#60;/li&#62;&#60;li&#62; UI elements for game related GUIs (plus support for TWL and Nifty),&#60;/li&#62;&#60;li&#62; particle stuff,&#60;/li&#62;&#60;li&#62; tweening functionality,&#60;/li&#62;&#60;li&#62; 3D stuff, should I ever want to code a 3D game,&#60;/li&#62;&#60;li&#62; physics engine (Box2D) support,&#60;/li&#62;&#60;li&#62; device abstraction for settings, files and input handling&#60;/li&#62;&#60;li&#62; and more things I simply forgot &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;I&#39;ll have a look at &#60;a target=&#34;_blank&#34; href=&#34;http://code.google.com/p/libgdx/&#34;&#62;libGDX&#60;/a&#62; over the next days or weeks and keep you posted! My trial project will be a port of &#60;a href=&#34;../10seconds/index.html&#34;&#62;10 seconds&#60;/a&#62; to libGDX!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201206</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201206</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] GameMaker:Studio and testing on Android</title>
  <description>&#60;i&#62; Monday, March 12, 2012, 9:22 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;It works! It simply works!&#60;br&#62;&#60;br&#62;So it took me 2 minutes to configure GameMaker:Studio to use my installed Android SDK, my Java JDK and to generate a keystore file for my GameMaker games.&#60;br&#62;&#60;br&#62;Afterwards I created a little test game (just some bouncing apples in a room enclosed with walls) and hit the &#34;&#60;b&#62;Run&#60;/b&#62;&#34; button. GameMaker:Studio started compiling and deployed the game to my Android phone which was running with USB debugging enabled and connected via cable.&#60;br&#62;&#60;br&#62;Just seconds later I could &#34;play&#34; this little test game. Even changing orientation of my phone worked.&#60;br&#62;&#60;br&#62;Now that&#39;s what I call a great beta test &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Hopefully the &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com&#34;&#62;YoYo Games&#60;/a&#62; guys decide to offer some discount for early adopters - otherwise I&#39;ll have to wait a bit longer until I can spend the 200$ for the Android module...&#60;br&#62;&#60;br&#62;But honestly, this is a pretty cool 2D cross platform development tool. Hats off, &#60;a target=&#34;_blank&#34; href=&#34;http://www.yoyogames.com&#34;&#62;YoYo Games&#60;/a&#62;!</description>
  <link>http://www.rightanglegames.com/blog/index.html#201205</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201205</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Real life] Is this site dead or what???</title>
  <description>&#60;i&#62; Sunday, March 11, 2012, 8:04 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Nope, obviously it&#39;s not. But to be honest, real life kept me busy over the last few months and still does. And some things are simply more important than updating a website &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;But today I spent some time and wrote a few things up. Hopefully you won&#39;t have to wait this long until the next update!&#60;br&#62;&#60;br&#62;Have fun,&#60;br&#62;Tommy</description>
  <link>http://www.rightanglegames.com/blog/index.html#201204</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201204</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Unity for iOS and Android - free for a while</title>
  <description>&#60;i&#62; Sunday, March 11, 2012, 8:04 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;If you want to develop games for Windows, Mac, Web, iOS and Android for free you couldn&#39;t do better than to jump over to &#60;a target=&#34;_blank&#34; href=&#34;http://unity3d.com/&#34;&#62;http://unity3d.com/&#60;/a&#62; and get the free version of Unity (including Windows, Mac and Web) and get the base modules for iOS and Android for free!!!&#60;br&#62;But hurry up, the offer ends at April, 8.&#60;br&#62;&#60;br&#62;Here is the direct link to the Unity store: &#60;a target=&#34;_blank&#34; href=&#34;https://store.unity3d.com/index.html&#34;&#62;https://store.unity3d.com/index.html&#60;/a&#62;. Just select the free Unity version plus the two modules and check out. A registration email containing the serial number will be sent to you.&#60;br&#62;&#60;br&#62;Have fun,&#60;br&#62;Tommy</description>
  <link>http://www.rightanglegames.com/blog/index.html#201203</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201203</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] GameMaker stuff</title>
  <description>&#60;i&#62; Sunday, March 11, 2012, 8:03 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Last year I told you that I bought GameMaker:HTML to create HTML5 games. I still haven&#39;t used it properly but it&#39;s on my hard disk &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;Recently I got an email invitation to the beta test for GameMaker:Studio.&#60;br&#62;Basically GameMaker:Studio is the generic version of GameMaker:HTML and it allows you to generate Windows and Mac executables plus HTML5, iOS and Android games if you buy the proper modules.&#60;br&#62;GameMaker:Studio without modules will cost 99$ and each module will cost 200$ (which is a bit too expensive if you&#39;d ask me).&#60;br&#62;&#60;br&#62;Luckily all purchasers of the GameMaker:HTML version (currently available for 99$ too) will get GameMaker:Studio plus the HTML5 module for free.&#60;br&#62;So if you purchase GameMaker:HTML now you&#39;ll get the improved version for free plus Mac export (Windows and HTML is already included in GameMaker:HTML).&#60;br&#62;&#60;br&#62;So currently I&#39;m trying to test the Android code generation which is enabled for a limited period in the GameMaker:Studio beta (but apk generation is not so you have to use debug tools, a wire connected Android phone and so on).&#60;br&#62;&#60;br&#62;Sounds like a simple (but not cheap) approach to get cross platform 2D game development with a really sophisticated game dev oriented IDE.&#60;br&#62;&#60;br&#62;Let&#39;s see if they keep their pricing ideas &#60;img src=&#34;../_frame/icon_doubt.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201202</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201202</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>[Game Dev] Slick development</title>
  <description>&#60;i&#62; Sunday, March 11, 2012, 7:43 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Kev Glass has moved the Slick source repository over to &#60;a target=&#34;_blank&#34; href=&#34;http://www.bitbucket.org&#34;&#62;http://www.bitbucket.org&#60;/a&#62; and passed the development responsibility over to several guys that want to help improve &#60;a target=&#34;_blank&#34; href=&#34;http://slick.cokeandcode.com/&#34;&#62;Slick&#60;/a&#62;.&#60;br&#62;&#60;br&#62;After some organizing and hickups the team has now started working on fixing bugs and adding features into a develoment branch on bitbucket. The plan is to regularly update the master/default branch with the stable results from the development branch. Currently scheduled time frame is once a month. We&#39;ll see how that plan works out &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#201201</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#201201</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Quick shortcuts</title>
  <description>&#60;ul&#62;&#60;li&#62; &#60;a href=&#34;../topdownshootertu/index.html&#34;&#62;Top down shooter tutorial&#60;/a&#62;, my first BlitzMax tutorial in the making&#60;/li&#62;&#60;li&#62; &#60;a href=&#34;../spaceinvaders1/index.html&#34;&#62;Space Invaders tutorial part 1&#60;/a&#62;, a nice tutorial for PlayBasic&#60;/li&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;https://github.com/Gornova/MarteEngine&#34;&#62;Marte Engine&#60;/a&#62;, a Flashpunk and Game Maker inspired extension library for Slick where I am a co-developer&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000055</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000055</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Twitter</title>
  <description>%TWITTER% </description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000064</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000064</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Other game developers</title>
  <description>&#60;ul&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;http://www.cokeandcode.com&#34;&#62;Kevin Glass (Slick)&#60;/a&#62;&#60;/li&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;http://randomtower.blogspot.com&#34;&#62;Gornova&#39;s blog&#60;/a&#62;&#60;/li&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;http://games.code4life.de/&#34;&#62;TheMatrix154&#60;/a&#62;&#60;/li&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;http://www.angryoctopus.co.nz&#34;&#62;Angry Octopus&#60;/a&#62;&#60;/li&#62;&#60;li&#62; &#60;a target=&#34;_blank&#34; href=&#34;http://www.anotherearlymorning.com&#34;&#62;Another early morning&#60;/a&#62;&#60;/li&#62;&#60;/ul&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000031</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000031</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Blog Archives</title>
  <description>&#60;a href=&#34;../blogarchive2011/index.html&#34;&#62;Blog Archive 2011&#60;/a&#62;&#60;br&#62;&#60;a href=&#34;../home1/index.html&#34;&#62;Blog Archive 2010&#60;/a&#62;&#60;br&#62;&#60;a href=&#34;../blog2009/index.html&#34;&#62;Blog Archive 2009&#60;/a&#62;&#60;br&#62;&#60;a href=&#34;../blog2008/index.html&#34;&#62;Blog Archive 2008&#60;/a&#62;&#60;br&#62;&#60;a href=&#34;../blog2007/index.html&#34;&#62;Blog Archive 2007&#60;/a&#62;&#60;br&#62;&#60;a href=&#34;../blog2006/index.html&#34;&#62;Blog Archive 2006&#60;/a&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000001</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000001</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Search my site!</title>
  <description>Looking for something on my home page I mentioned years ago?&#60;br&#62;Don&#39;t worry - use the builtin search engine &#60;img src=&#34;../_frame/icon_eek.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;%TW-SEARCH% </description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000008</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000008</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Bookmark this site</title>
  <description>Feel free to bookmark my site in your web browser.&#60;br&#62;&#60;br&#62;%TW-FAVORITE-BTN% </description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000005</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000005</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>Contact me!</title>
  <description>If you want to discuss any topic or content you can contact me.&#60;br&#62;Just click on the icon above to send me an email!</description>
  <link>http://www.rightanglegames.com/blog/index.html#bv000003</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/blog/index.html#bv000003</guid>
  <category>What&#39;s going on?</category>
</item>
<item>
  <title>This year I made 151!</title>
  <description>&#60;i&#62; Tuesday, December 28, 2010, 10:42 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Oh boy, one year gone and no other posts on this topic. Sigh. Am I not improving? Sure I am. But it was all private stuff that I don&#39;t want to post here &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Instead you can read about my 2010 &#34;ride my bike to work&#34; record: It&#39;s 151 days! Given the tough last winter and the early winter this year it&#39;s not too bad! And I had a longer vacation this year so there&#39;s no reason to moan about.&#60;br&#62;&#60;br&#62;But I think I will try to get back to my 2009 record in 2011. Let&#39;s see if I can manage that!</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#bv000018</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#bv000018</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>I made 175!</title>
  <description>&#60;i&#62; Thursday, December 31, 2009, 4:18 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Yup, the year is nearly over and I&#39;m enjoying my Christmas holidays so no way to improve my current score of &#60;b&#62;175&#60;/b&#62; rides to work with my bike.&#60;br&#62;I&#39;m very proud on myself if I am allowed to say so &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Unfortunately I&#39;m afraid I won&#39;t break this record next year - our office will be closed end of 2010 and I&#39;m going to have to take a car to the new office or (yikes!) change the employer and look for a job in Hamburg. Then I would ride to the train station on my bike and continue by train. We&#39;ll see.&#60;br&#62;&#60;br&#62;As one of our former CEOs said: &#34;Change is constant. Change is opportunity.&#34;...</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#bv000017</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#bv000017</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>New personal bicycle record!</title>
  <description>&#60;i&#62; Monday, October 19, 2009, 8:58 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Today I reached 141. This means I rode to work on my bike 141 days this year. That&#39;s exactly the number of days I used my bike to ride to the office the whole last year! So I have more than two months left to increase my personal &#34;use your bike to get to the office&#34; record!&#60;br&#62;&#60;br&#62;Will I reach 160? Or maybe 175? We&#39;ll see. I&#39;m telling you at the end of this year &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#bv000016</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#bv000016</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Mind mapping tools?</title>
  <description>&#60;i&#62; Tuesday, July 28, 2009, 10:54 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Can anyone of you recommend a good mind mapping tool?&#60;br&#62;Criteria are:&#60;br&#62;&#60;ul&#62;&#60;li&#62; free or low cost,&#60;/li&#62;&#60;li&#62; fast,&#60;/li&#62;&#60;li&#62; can export to some formats like PDF or HTML.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;I already looked at &#60;a target=&#34;_blank&#34; href=&#34;http://freemind.sourceforge.net/wiki/index.php/Main_Page&#34;&#62;FreeMind&#60;/a&#62; which is pretty cool but sooooo slow on startup. Next - you are dismissed &#60;img src=&#34;../_frame/icon_doubt.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Can you recommend a web based mind mapping tool? I&#39;ve read that there are some popping up here and there but I&#39;m afraid they&#39;ll turn into payable ones sooner or later or they force you to give them the right to use your private maps (or their content)! Not very polite - sounds like a business model &#60;img src=&#34;../_frame/icon_sad.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better15</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better15</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Your personal finance</title>
  <description>&#60;i&#62; Sunday, May 17, 2009, 10:40 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Here is the link to a free document which tells you &#34;Everything You Ever Really Needed to Know About Personal Finance On Just One Page&#34;.&#60;br&#62;&#60;br&#62;The document itself is free but the author asks for a donation.&#60;br&#62;&#60;br&#62;&#60;a target=&#34;_blank&#34; href=&#34;http://www.thesimpledollar.com/onepage/&#34;&#62;http://www.thesimpledollar.com/onepage/&#60;/a&#62;</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better14</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better14</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>A notebook with exchangeable content?</title>
  <description>&#60;i&#62; Sunday, May 17, 2009, 10:33 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Do you use a notebook like a Moleskine or a ring folder to jot down your notes?&#60;br&#62;I own two notebooks similar to a Moleskine, one for game ideas and notes and the other one for personal stuff.&#60;br&#62;&#60;br&#62;In the past I used to have a ring folder but those have some disadvantages:&#60;br&#62;&#60;ul&#62;&#60;li&#62; they are thick,&#60;/li&#62;&#60;li&#62; you can&#39;t write on the left side because of the metal rings that keep your sheets of paper,&#60;/li&#62;&#60;li&#62; the pages always move a little bit.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Recently I read on &#60;a target=&#34;_blank&#34; href=&#34;http://www.imgriff.com&#34;&#62;http://www.imgriff.com&#60;/a&#62; about the advantages of a real Moleskine. But the smartest thing was mentioned in one of the comments to this specific blog post.&#60;br&#62;&#60;br&#62;&#60;a target=&#34;_blank&#34; href=&#34;http://www.myx17.com&#34;&#62;http://www.myx17.com&#60;/a&#62; is a site where you can buy a note book that allows you to use different fill-ins and that does not have metal rings inside.&#60;br&#62;Just jump to the site and have a look - the idea is just great!&#60;br&#62;&#60;br&#62;A friend of mine is going to buy one and I&#39;ll have a detailed look at it - but I&#39;m already pretty sure I&#39;m going to buy me one anyway &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better13</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better13</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Getting to work by bike</title>
  <description>&#60;i&#62; Tuesday, March 10, 2009, 9:00 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Just wanted to tell you that in 2008 I took the bike on 141 days to drive into the office! So more than 2/3 of my working days last year I used my bicycle!&#60;br&#62;&#60;br&#62;Makes me a bit proud as I am just a couch potato &#60;img src=&#34;../_frame/icon_smile.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better12</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better12</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Basics</title>
  <description>&#60;i&#62; Last update Tuesday, March 10, 2009, 9:00 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;On &#60;a target=&#34;_blank&#34; href=&#34;http://www.imgriff.com&#34;&#62;www.imgriff.com&#60;/a&#62; there is a series about basics: &#60;a target=&#34;_blank&#34; href=&#34;http://imgriff.com/serien/das-kleine-einmaleins/&#34;&#62;http://imgriff.com/serien/das-kleine-einmaleins/&#60;/a&#62; (in german).&#60;br&#62;&#60;br&#62;I will summarize them here in english in short paragraphs for you and me in the following weeks.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better11</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better11</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Everything gets a timestamp</title>
  <description>Every note that you make (on a piece of paper, in your moleskine, in your software tool, PIM, mobile phone) gets a timestamp.&#60;br&#62;Many times you won&#39;t need it but in those rare cases you will be lucky that you wrote it down.&#60;br&#62;So just get used to it.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better10</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better10</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>The famous 2 minute rule</title>
  <description>Whatever is on your todo list or needs to be done and takes only two minutes: do it &#60;b&#62;now&#60;/b&#62;!&#60;br&#62;Watering your flowers, answering an email (a short answer!) - do it immediately. Don&#39;t waste time to put it on a todo list or schedule it. Just get it done immediately and forget it.&#60;br&#62;&#60;br&#62;That also implies that you should take your time for all things that take longer. Plan them, find time slots when you can do those tasks without being disturbed or distracted. This helps you to stay focused.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better09</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better09</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Do similar jobs together</title>
  <description>Do phone call after phone call, email reply after email reply. Simply try to batch process tasks that are nearly identical.&#60;br&#62;That should help you to stay more focused and get faster on each single task.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better08</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better08</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Quiet, please!</title>
  <description>Switch off all disturbing noises that you can control (don&#39;t try to stop the caterpillar in front of your house, except when your name&#39;s Arthur Dent!).&#60;br&#62;Whenever you need all your concentration switch off your mobile phone and normal phone, your &#34;you have mail&#34; tone, your bell at the front door and other disturbing noises.&#60;br&#62;If it doesn&#39;t disturb you let the music play - at least you can control the kind of music and the volume.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better07</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better07</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Singletasking</title>
  <description>Negotiating a contract with your mobile phone in your left hand, doing online banking with your right hand, use eye contact with an office mate to agree on a meeting date - that&#39;s busy. But is it productive?&#60;br&#62;&#60;br&#62;If you&#39;re trying to get a job done that needs all of your concentration - then do only this one job.&#60;br&#62;&#60;br&#62;Multitasking at work is a myth. Of course you can put a chewing gum into your mouth while reading emails but trying to work on two jobs that both require your full concentration? Come on. That will never work.&#60;br&#62;&#60;br&#62;Oh, and while we&#39;re at it: to get a difficult single task done well, read the paragraph above this one once more.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better06</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better06</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Salami tactics</title>
  <description>&#34;How do you eat an elephant?&#34;&#60;br&#62;&#34;Piece by piece.&#34;&#60;br&#62;&#60;br&#62;If there is a huge overwhelming project ahead of you how can you deal with it? Right, piece by piece (or to stay with our salami, slice by slice).&#60;br&#62;Try to separate the project into many reasonable and precise steps or tasks and finish them one after the other.&#60;br&#62;This approach comes with several advantages: you&#39;ll constantly progress and you&#39;ll get faster results.&#60;br&#62;&#60;br&#62;The huge impregnable project shrunk into a pile of smaller tasks you can cope with.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better05</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better05</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Check your mailbox(es) only three times a day</title>
  <description>I&#39;ll bet no one will notice a difference if you check your email inboxes and RSS feeds only three times a day.&#60;br&#62;Be honest: Are mails this important that you need to answer them immediately. The advantage of emails is that they are asynchronous! No one should expect that they are answered immediately.&#60;br&#62;&#60;br&#62;Of course it&#39;s a personal preference if you check your mailbox 2, 3 or 5 times a day. But try to close your webmailer, email client and RSS feed in those periods in between.&#60;br&#62;It will help you to stay more focused on your real work!</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better04</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better04</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>To be continued</title>
  <description>More to come in the next time.</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better03</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better03</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Pushups</title>
  <description>&#60;i&#62; Monday, September 08, 2008, 11:42 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Three months ago I discovered the site &#60;a target=&#34;_blank&#34; href=&#34;http://hundredpushups.com/&#34;&#62;http://hundredpushups.com/&#60;/a&#62;. There is this guy who promises that you (or me) can do 100 push ups in one go after six weeks. Muhahahahaha.&#60;br&#62;&#60;br&#62;To be perfectly honest: I am a couch potato. I did sports (skateboarding, badminton, table tennis) until I was around 20. But then university and job and all the pubs in Berlin and girl friends and such did their job: I became a lazy chair guy.&#60;br&#62;&#60;br&#62;Three years ago I started to ride to work by bike (bicycle). Unfortunately not every day (yet). But I&#39;m getting better. This year I will improve my bicycle work days and reach at least around 120 (currently I&#39;m at 90) days out of 220 working days.&#60;br&#62;&#60;br&#62;But I&#39;m drifting away &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Beginning of August I read the &#60;a target=&#34;_blank&#34; href=&#34;http://www.ludumdare.com&#34;&#62;ludum dare&#60;/a&#62; blog. It&#39;s about a 48 hour game coding contest that takes place two or three times a year. And one guy mentioned the &#60;a target=&#34;_blank&#34; href=&#34;http://hundredpushups.com/&#34;&#62;http://hundredpushups.com/&#60;/a&#62; site again. I got hooked. So I printed out the complete program and took it with me into my vacation.&#60;br&#62;&#60;br&#62;And I started. In my initial test I managed 12 push ups. Stop laughing, down to the ground and do it better!&#60;br&#62;After two weeks (you train 3 days a week and rest in between) there is another maximum test. This time I managed 30 push ups. Now I finished my third week and I&#39;m doing around 70 push ups in one training session (takes around 10 minutes). &#60;br&#62;&#60;br&#62;I doubt that I will manage 100 push ups after six week but I&#39;m pretty sure it will be more than 50.&#60;br&#62;&#60;br&#62;But I will continue the training until I can do 100 push ups. You&#39;ll see when I add the badge on my website &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Positive points are:&#60;br&#62;&#60;ul&#62;&#60;li&#62; I don&#39;t need to go to a gym&#60;/li&#62;&#60;li&#62; I only train three days a week&#60;/li&#62;&#60;li&#62; Each training session takes max. 10 minutes&#60;/li&#62;&#60;li&#62; I do improve&#60;/li&#62;&#60;li&#62; I feel good &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;/li&#62;&#60;li&#62; It&#39;s fun&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Will you give it a try?</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better02</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better02</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Getting things done and Zen to done</title>
  <description>&#60;i&#62; Monday, September 08, 2008, 11:29 PM &#60;/i&#62;&#60;br&#62;&#60;br&#62;Yup - it&#39;s the famous stuff by David Allen (Link here &#60;a target=&#34;_blank&#34; href=&#34;http://www.davidco.com/&#34;&#62;http://www.davidco.com/&#60;/a&#62;).&#60;br&#62;It&#39;s pretty much all about getting organized in your life and keeping track of lists, organizing those lists and so on.&#60;br&#62;&#60;br&#62;To be honest: It&#39;s way too complicated for me to live it.&#60;br&#62;&#60;br&#62;But at my favorite &#34;Getting better&#34; website (&#60;a target=&#34;_blank&#34; href=&#34;http://www.imgriff.com&#34;&#62;www.imgriff.com&#60;/a&#62;, a german blog) I found a much simpler version: &#60;b&#62;Zen to done&#60;/b&#62;.&#60;br&#62;Here is a link to the german article of &#60;a target=&#34;_blank&#34; href=&#34;http://www.imgriff.com&#34;&#62;www.imgriff.com&#60;/a&#62;: &#60;a target=&#34;_blank&#34; href=&#34;http://imgriff.com/2008/01/09/zen-to-done-teil-1-das-ultimativ-einfache-produktivitaetssystem/&#34;&#62;http://imgriff.com/2008/01/09/zen-to-done-teil-1-das-ultimativ-einfache-produktivitaetssystem/&#60;/a&#62;&#60;br&#62;&#60;br&#62;The german link also offers a downloadable ebook version - very nice &#60;img src=&#34;../_frame/icon_smile.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;For all you english readers: the original version can be found here: &#60;a target=&#34;_blank&#34; href=&#34;http://zenhabits.net/2007/04/zen-to-done-ztd-the-ultimate-simple-productivity-system/&#34;&#62;http://zenhabits.net/2007/04/zen-to-done-ztd-the-ultimate-simple-productivity-system/&#60;/a&#62;&#60;br&#62;&#60;br&#62;Of course you don&#39;t have to follow all those guide lines. At least I don&#39;t and won&#39;t. But it&#39;s a motivating read and I think even adopting one or two habits is already an improvement. And that&#39;s what it&#39;s all about, right?</description>
  <link>http://www.rightanglegames.com/gettingbetter/index.html#better01</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/gettingbetter/index.html#better01</guid>
  <category>Getting better - tips and links to improve one&#39;s life</category>
</item>
<item>
  <title>Coding conventions and short introduction</title>
  <description>Okay, so you want to code a game with BlitzMax?&#60;br&#62;Great choice!&#60;br&#62;&#60;br&#62;BlitzMax is a &#60;b&#62;BASIC&#60;/b&#62; like language offering object oriented (OO) extensions. Those will help you organize and simplify your code a lot compared to the &#34;old&#34; procedural versions of BlitzBasic (and other Basics).&#60;br&#62;BlitzMax offers &#60;b&#62;Types&#60;/b&#62; which is the BlitzMax name of a &#60;b&#62;class&#60;/b&#62; in other OO languages like Java or C++. It might happen during this tutorial that I mix the usage of &#60;b&#62;type&#60;/b&#62; and &#60;b&#62;class&#60;/b&#62; as they are identical and &#60;b&#62;class&#60;/b&#62; is the more often used phrase to me &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;What is a &#60;b&#62;Type&#60;/b&#62; now? It&#39;s nothing more but a template for new objects. Every object you create with that type has all the fields as the type describes.&#60;br&#62;A &#60;b&#62;Type&#60;/b&#62; in BlitzMax can also have methods which can be called for each object of that type. There are some more features of types which I&#39;ll explain later on in the tutorial.&#60;br&#62;&#60;br&#62;&#60;ul&#62;&#60;li&#62; A good way to structure your code is to use a separate file in your project for each new type.&#60;/li&#62;&#60;li&#62; As already mentioned in my &#60;a href=&#34;../spaceinvaders1/index.html&#34;&#62;Space Invaders tutorial part 1&#60;/a&#62; you should write constants in capital letters.&#60;/li&#62;&#60;li&#62; Keep your naming conventions for types, methods, variables consistent. Use underlines like &#60;b&#62;my_age&#60;/b&#62; or &#60;b&#62;the_var&#60;/b&#62; or avoid them and use upper/lower case notation like &#60;b&#62;myAge&#60;/b&#62; or &#60;b&#62;theVar&#60;/b&#62;. I prefer the upper/lower case notation.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Oh, and before I forget: Your first command in &#60;b&#62;any&#60;/b&#62; BlitzMax game you code should be&#60;br&#62;%CODE_BEGIN% &#60;br&#62;SuperStrict&#60;br&#62;%CODE_END% &#60;br&#62;&#60;b&#62;SuperStrict&#60;/b&#62; forces you to declare all variables in your game with their type and also declare the return type of all methods and functions in your game.&#60;br&#62;Simply said it helps you to get more readable code &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Enough intro, we&#39;ll do the rest while we work through the code.&#60;br&#62;&#60;br&#62;It doesn&#39;t matter if you use the standard BlitzMax IDE or the community edition of the BlitzMax IDE or if you use &#60;a target=&#34;_blank&#34; href=&#34;http://www.blide.org/&#34;&#62;BLIde Plus&#60;/a&#62; like I do. But I will not explain how to create a project or create a new file as it&#39;s all pretty self explaining. If you don&#39;t manage to figure that out on your own you shouldn&#39;t yet consider coding your own games &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds116</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds116</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Simple game design</title>
  <description>The idea is to create a simple version of a top down shooter which we extend later on.&#60;br&#62;So we use a simple single screen game without any scrolling maps or tiled background or such things.&#60;br&#62;The player controls a turret or a base in the center of the screen. The turret rotates following the mouse pointer and clicking the left mouse button will fire a bullet in the turret&#39;s direction.&#60;br&#62;Enemies will return in random intervals from the screen boundaries and move directly towards the player&#39;s turret. They do not fire and might require several hits before they die or explode.&#60;br&#62;As soon as an enemy touches the turret the game ends.&#60;br&#62;The enemies attack in phases. After all enemies of a phase have been destroyed the next phase starts with more enemies, harder enemies, faster enemies and so on.&#60;br&#62;&#60;br&#62;Later on we will extend the game and replace the turret with a moving player sprite, add keyboard control for movement, better room graphics, add several rooms, different weapons and what else I can come up with while coding this tutorial &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Very important: we need a nice name for the game of course! I chose &#60;b&#62;ComeGetMe&#60;/b&#62;!</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds115</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds115</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Some thoughts about the main game loop</title>
  <description>Each game you code has some basic main loop looking like this (in pseudo language)&#60;br&#62;%CODE_BEGIN% &#60;br&#62;do&#60;br&#62;    clear screen&#60;br&#62;    update all game objects and handle game logic&#60;br&#62;    render all remaining game objects&#60;br&#62;while (forever)&#60;br&#62;%CODE_END% &#60;br&#62;Unfortunately game developer&#39;s life isn&#39;t that easy. Because different computers have different speeds (older ones are generally slower than the newest high end quad core machines) this main loop would run at different speeds too.&#60;br&#62;Your game would become unplayable on faster machines. Too bad.&#60;br&#62;&#60;br&#62;There are several approaches to solve this problem. One is called &#60;b&#62;delta timing&#60;/b&#62;. A game loop using delta timing would look similar to this one:&#60;br&#62;%CODE_BEGIN% &#60;br&#62;last_time = currentTimeInMilliSeconds()&#60;br&#62;do&#60;br&#62;    now = currentTimeInMilliSeconds()&#60;br&#62;    delta = now - last_time&#60;br&#62;    clear screen&#60;br&#62;    update all game objects and handle game logic and use delta for all calculations&#60;br&#62;    render all remaining game objects&#60;br&#62;while (forever)&#60;br&#62;%CODE_END% &#60;br&#62;You have to use the delta, which is the time that passed since the last update and rendering, for all your speed and position change calculations in the update functions of your game objects.&#60;br&#62;For example you would calculate a new position of your space ship like this:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;newpos = oldpos + (speed * delta)&#60;br&#62;%CODE_END% &#60;br&#62;On a fast machine the delta will be very small and so will be the product (speed * delta). So on a fast computer your ship will move in small steps but often because your main loop is executing really quick.&#60;br&#62;On a slow machine the delta will be comparably bigger and the same for the product (speed * delta). Your ship will move in bigger steps but not as often because the main loop takes a longer time to process.&#60;br&#62;But on both machines you&#39;ll get the same distance over the same amount of time!&#60;br&#62;So this is a great working method!&#60;br&#62;&#60;br&#62;But it has two disadvantages: you update a lot on fast machines with only minimal impact on game objects (because the machines are sooo fast) and physics engines don&#39;t like it &#60;img src=&#34;../_frame/icon_sad.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;Physics engines most of the times expect to be called at certain identical time intervals, say every 20 milliseconds. This way you&#39;ll avoid too many too complicated calculations and nearly no game player would realize a difference if the physics engines were called faster.&#60;br&#62;&#60;br&#62;So people came up with another method of game loop: &#60;b&#62;fixed rate logic plus tweening&#60;/b&#62;.&#60;br&#62;What you do here is calling the update methods with a given fixed rate all the time, for example every 20 milliseconds. Of course it could happen that your game logic needs more time or the Garbage collector interrupts a bit or your game is synchronizing with the vertical monitor sync signal to avoid flickering and you don&#39;t exactly match the 20 milliseconds. So the next call to your update would be a few milliseconds too late. You would still call the update for all pending amounts of 20 milliseconds and the remainder (the tweening value) would be passed as input to all drawing methods. The drawing methods would then interpolate between last position and current position of all moving game objects and the distance travelled is dependent on the tweening value.&#60;br&#62;&#60;br&#62;So instead of having a different value each call in the update routine as in the delta timing approach we now have a different value in the drawing routines.&#60;br&#62;Visually the output is pretty much identical but the advantage of the fixed rate logic approach is indeed what the name says: your game logic is called with fixed intervals all the time.&#60;br&#62;A pseudo code game loop using fixed rate logic would look like this:&#60;br&#62;%CODE_BEGIN% &#60;br&#62;last_time = currentTimeInMilliSeconds()&#60;br&#62;do&#60;br&#62;    now = currentTimeInMilliSeconds()&#60;br&#62;    delta = now - last_time&#60;br&#62;    accumulator = accumulator + delta&#60;br&#62;    clear screen&#60;br&#62;    while accumulator &#62; fixed rate&#60;br&#62;        update all game objects and handle game logic and use fixed rate for all calculations&#60;br&#62;        accumulator = accumulator - fixed rate&#60;br&#62;    endwhile&#60;br&#62;    tween = accumulator / fixed rate&#60;br&#62;    render all remaining game objects and use the tween value for interpolation where current drawing pos = newpos * tween + oldpos * ( 1.0 - tween)&#60;br&#62;while (forever)&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;As the drawing functions do the interpolation all your moving game elements need to have two positions: the last position on screen and the new position on screen. The new position on screen is calculated in the update phase and in the drawing phase your code will have to interpolate between those two positions based on the size of the tween value. Each drawing or rendering phase will move your game elements closer to their new position that was calculated in the update phase. Finally, when the new position is reached time is up for a new update phase and we&#39;ll start all over again.&#60;br&#62;&#60;br&#62;There is a nice long thread in the BlitzMax forum &#60;a target=&#34;_blank&#34; href=&#34;http://www.blitzbasic.com/Community/posts.php?topic=83511&#34;&#62;here&#60;/a&#62; and a really good explanation of fixed rate logic in games can be found on &#60;a target=&#34;_blank&#34; href=&#34;http://gafferongames.com/game-physics/fix-your-timestep/&#34;&#62;Gaffer&#39;s Blog&#60;/a&#62;.&#60;br&#62;&#60;br&#62;For this tutorial we will use the &#60;b&#62;fixed rate logic plus tweening&#60;/b&#62; approach - mainly just because I want to give it a try &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds114</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds114</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>First approach to main loop</title>
  <description>So let&#39;s have some code now, shall we?&#60;br&#62;&#60;br&#62;I want to mention that some of the code is adopted and modified or simplified from Chroma&#39;s public domain BlitzMax framework which you can find on Google code pages &#60;a target=&#34;_blank&#34; href=&#34;http://code.google.com/p/bmax2dframework/&#34;&#62;here&#60;/a&#62;. It seems to be no longer maintained but it gave me a good starting point.&#60;br&#62;&#60;br&#62;Ok, create an empty directory for your project on your hard disk and fire up your preferred BlitzMax IDE.&#60;br&#62;&#60;br&#62;First we&#39;ll start with the main loop code base. You can just copy and paste it into a file named &#60;b&#62;ComeGetMe.bmx&#60;/b&#62;.&#60;br&#62;%CODE_BEGIN% &#60;br&#62;SuperStrict&#60;br&#62;&#60;br&#62;Import &#34;TFRLTimer.bmx&#34;&#60;br&#62;&#60;br&#62;Const GFX_WIDTH:Int = 640, GFX_HEIGHT:Int = 480&#60;br&#62;&#60;br&#62;Const UPDATE_FREQUENCY:Float = 100.0, SPIKE_SUPPRESSION:Int = 20&#60;br&#62;&#60;br&#62;Graphics GFX_WIDTH, GFX_HEIGHT, 0&#60;br&#62;&#60;br&#62;SetBlend ALPHABLEND&#60;br&#62;&#60;br&#62;Local gameTime:TFRLTimer = New TFRLTimer.CreateFRL(UPDATE_FREQUENCY, SPIKE_SUPPRESSION)     &#39;1st number is logic updates per second and 2nd number is how much spike suppression you want&#60;br&#62;&#60;br&#62;&#60;br&#62;&#39; the main loop starts here&#60;br&#62;While Not KeyDown(KEY_ESCAPE) And AppTerminate() = False&#60;br&#62;    Cls&#60;br&#62;    &#60;br&#62;&#60;br&#62;    &#39; update part of the main loop with constant speed&#60;br&#62;    Local delta:Float = gameTime.GetDelta()&#60;br&#62;    While gameTime.accumulator &#62; gameTime.logicFPS&#60;br&#62;        doGameLogic(gameTime.LogicFPS)              &#39;Update Game Logic Here&#60;br&#62;        gameTime.accumulator:-gameTime.logicFPS     &#39;update the accumulator&#60;br&#62;    Wend&#60;br&#62;    &#60;br&#62;    &#39; rendering with additional tweening    &#60;br&#62;    Local tween:Float = gameTime.GetTween()         &#39;calc the tween for smooth graphics&#60;br&#62;    doGameRender(tween)                             &#39;Render Game Here&#60;br&#62;    &#60;br&#62;    Flip 1                                          &#39; synchronize graphics buffer flipping with vsync of monitor&#60;br&#62;Wend&#60;br&#62;EndGraphics&#60;br&#62;End&#60;br&#62;&#60;br&#62;&#60;br&#62;Function DoGameLogic(fixedRate:Float)&#60;br&#62;    &#39; nothing here yet&#60;br&#62;End Function&#60;br&#62;&#60;br&#62;Function DoGameRender(tween:Float)&#60;br&#62;    &#39; nothing here yet&#60;br&#62;End Function&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;So what does that code do?&#60;br&#62;First we switch on &#34;SuperStrict&#34; as I already recommended. The second line imports another source code file named &#60;b&#62;TFRLTimer.bmx&#60;/b&#62; which we&#39;ll have a look at in a minute.&#60;br&#62;We then define constants for the screen size and the update frequency which is the fixed frame rate. So we plan to call the update functions 100 times a second which means every 10 milliseconds.&#60;br&#62;The last constant &#60;b&#62;SPIKE_SUPPRESSION&#60;/b&#62; is a cool one as it is another feature of the &#60;b&#62;TFRLTimer&#60;/b&#62; type that is defined in the &#60;b&#62;TFRLTimer.bmx&#60;/b&#62; file. It allows us to smooth the tweening value a bit to avoid spikes that may arise while other background processes on your PC start or terminate while playing the game. So the game play will appear even more smooth &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62; The number (20 in our example) just tells the type to store the last 20 values and use them for smoothing.&#60;br&#62;&#60;br&#62;We open the graphics mode with given width and height and stay in windowed mode (the 0 at the end of the &#60;b&#62;Graphics&#60;/b&#62; command). We set the active blend mode to ALPHABLEND right at the beginning because that&#39;s the blend mode we are mainly going to use in the game and it&#39;s not the default blend mode when you start a BlitzMax application so we do it right at the beginning.&#60;br&#62;&#60;br&#62;Then we create a TFRLTimer object named &#60;b&#62;gameTime&#60;/b&#62;. This object will help us to keep track of all this fixed rate logic and the tweening value and all that.&#60;br&#62;&#60;br&#62;Finally we start our main loop which we&#39;ll only leave if the player presses the Escape key or clicks on the upper right close button of our game window.&#60;br&#62;&#60;br&#62;The loop itself is pretty simple: we clear the screen first. Then we ask the &#60;b&#62;gameTime&#60;/b&#62; object how many milliseconds have passed since the last call to &#60;b&#62;GetDelta()&#60;/b&#62;. The inner while loop helps us to call all outstanding updates. The &#60;b&#62;gameTime.accumulator&#60;/b&#62; stores how many milliseconds are left as we are only interested in multiples of &#60;b&#62;gameTime.LogicFPS&#60;/b&#62; which is exactly our fixed time rate (the update frequency, here 60).&#60;br&#62;&#60;br&#62;We then need to do all drawing but we need to pass the &#60;b&#62;tween&#60;/b&#62; value into the draw methods as explained in the previous paragraph.&#60;br&#62;&#60;br&#62;The main loop finishes with a call to &#60;b&#62;Flip 1&#60;/b&#62; which switches the two drawing buffers of BlitzMax synchronized with the screen&#39;s next vertical sync (vsync) to avoid flickering.&#60;br&#62;&#60;br&#62;If the player presses Escape or clicks into the close box of our window we leave the main loop, call &#60;b&#62;EndGraphics&#60;/b&#62; to switch off BlitzMax&#39; graphics mode and terminate the game.&#60;br&#62;&#60;br&#62;I already added two empty functions &#60;b&#62;DoGameUpdate(fixedRate:Float)&#60;/b&#62; and &#60;b&#62;DoGameRender(tween:Float)&#60;/b&#62; which will contain all required calls to update and render the game objects.&#60;br&#62;&#60;br&#62;So that&#39;s the first approach of the main loop. Save the file as &#60;b&#62;ComeGetMe.bmx&#60;/b&#62; and be prepared to create the second file in a second!&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#mainloop</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#mainloop</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>The TFRLTimer type</title>
  <description>The name &#60;b&#62;TFRLTimer&#60;/b&#62; stands for &#60;b&#62;F&#60;/b&#62;ixed &#60;b&#62;R&#60;/b&#62;ate &#60;b&#62;L&#60;/b&#62;ogic &#60;b&#62;Timer&#60;/b&#62; and the first leading &#60;b&#62;T&#60;/b&#62; just stands for a &#60;b&#62;Type&#60;/b&#62;. It&#39;s good coding practise to always start your Types with a &#60;b&#62;T&#60;/b&#62; and create a new source code file for each type.&#60;br&#62;&#60;br&#62;Shall we have a look at it?&#60;br&#62;%CODE_BEGIN% &#60;br&#62;&#39;==============================================================&#60;br&#62;&#39;===FIXED RATE LOGIC  TWEEN  DELTA SPIKE SUPPRESSION (DSS)===&#60;br&#62;&#39;==============================================================&#60;br&#62;Type TFRLTimer&#60;br&#62;    Field newTime:Float = MilliSecs()&#60;br&#62;    Field oldTime:Float = MilliSecs()&#60;br&#62;    Field delta:Float&#60;br&#62;&#60;br&#62;    Field dssOn:Int     &#39; do we use delta spike suppression?&#60;br&#62;    Field dssIndex:Int      &#39; index into DSS_Array where next delta value is written&#60;br&#62;    Field dssArray:Float[]  &#39; this array contains the delta values to smooth&#60;br&#62;    Field dssLenArray:Int   &#39; how big is the array of delta values&#60;br&#62;&#60;br&#62;    Field logicFPS:Float&#60;br&#62;    Field accumulator:Float, tween:Float&#60;br&#62;&#60;br&#62;    Function CreateFRL:TFRLTimer(logicCyclesPerSec:Float, numSamples:Int = 0)&#60;br&#62;        Local frl:TFRLTimer = New TFRLTimer&#60;br&#62;        frl.logicFPS = 1.0 / logicCyclesPerSec&#60;br&#62;        If numSamples&#60;br&#62;            frl.dssOn = True&#60;br&#62;            frl.dssArray = New Float[numSamples]&#60;br&#62;            frl.dssLenArray = numSamples&#60;br&#62;        EndIf&#60;br&#62;        Return frl&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;    Method GetDelta:Float()&#60;br&#62;        Self.newTime = MilliSecs()&#60;br&#62;        Self.delta = Float (Self.newTime - Self.oldTime) * 0.001&#60;br&#62;        Self.oldTime = Self.newTime&#60;br&#62;        &#60;br&#62;        If Self.dssOn = True&#60;br&#62;            Self.dssArray[Self.dssIndex] = Self.delta&#60;br&#62;            &#60;br&#62;            Local smoothDelta:Float = 0&#60;br&#62;            &#60;br&#62;            For Local i:Int = 0 To Self.dssLenArray - 1&#60;br&#62;                smoothDelta:+Self.dssArray[i]&#60;br&#62;            Next&#60;br&#62;            Self.delta = Float smoothDelta / dssLenArray&#60;br&#62;            &#60;br&#62;            Self.dssIndex:+1&#60;br&#62;            If Self.dssIndex &#62; dssLenArray - 1 Then Self.dssIndex = 0&#60;br&#62;        EndIf&#60;br&#62;        &#60;br&#62;        Self.accumulator:+Self.delta&#60;br&#62;        &#60;br&#62;        Return Self.delta&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;&#60;br&#62;    Method GetTween:Float()&#60;br&#62;        Return Self.accumulator / Self.logicFPS&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;&#60;br&#62;    Method ShowSpikeSuppression(x:Int, y:Int)&#60;br&#62;        DrawText &#34;Delta Spike Suppressor:&#34;, x, y&#60;br&#62;        For Local i:Int = 0 To Self.dssLenArray - 1&#60;br&#62;            DrawText Self.dssArray[i], x, y + (i + 1) * 25&#60;br&#62;        Next&#60;br&#62;        DrawText &#34;Final Delta: &#34; + Self.delta, x, y + (Self.dssLenArray + 1) * 25&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;End Type&#60;br&#62;%CODE_END% </description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds112</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds112</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Explanation of the TFRLTimer class</title>
  <description>If the code looks just too complicated and you don&#39;t want to delve into it that&#39;s fine. Just create the file &#60;b&#62;TFRLTimer.bmx&#60;/b&#62;, copy the source code into the file and save it. It will work and you don&#39;t have to understand the source code to get a running game.&#60;br&#62;&#60;br&#62;But if you want to learn how your game system ticks and also want to know about some more BlitzMax features you should read this paragraph &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Every type declaration starts with the keyword &#60;b&#62;Type&#60;/b&#62; and the type&#39;s name and ends with the keyword &#60;b&#62;End Type&#60;/b&#62;. All code between those keywords belongs to the type.&#60;br&#62;&#60;br&#62;We start with some field declarations. You can imagine fields as properties of objects. For example every car has a color and a number of doors. So &#60;b&#62;color&#60;/b&#62; and &#60;b&#62;nrOfDoors&#60;/b&#62; would be fields of a type &#60;b&#62;TCar&#60;/b&#62;. As I already mentioned every type is mainly a template for objects. So if you create an object of type &#60;b&#62;TXYZ&#60;/b&#62; it will have all the fields that are declared in the type. And if you have two or more objects of type &#60;b&#62;TXYZ&#60;/b&#62; all of those objects have their unique values inside the fields, just like you can have a red car with three doors and a blue car with five doors.&#60;br&#62;&#60;br&#62;The fields we define for our type &#60;b&#62;TFRLTimer&#60;/b&#62; are &#60;b&#62;newTime&#60;/b&#62; and &#60;b&#62;oldTime&#60;/b&#62; to store the current time in milliseconds (set when we call &#60;b&#62;GetDelta()&#60;/b&#62;) and the last time we called &#60;b&#62;GetDelta()&#60;/b&#62;. The &#60;b&#62;delta&#60;/b&#62; field should be self explaining.&#60;br&#62;&#60;br&#62;All fields starting with &#60;b&#62;dss&#60;/b&#62; are used for smoothing the delta values. Finally we store the &#60;b&#62;accumulator&#60;/b&#62; and &#60;b&#62;tween&#60;/b&#62; values as Floats.&#60;br&#62;&#60;br&#62;Then we meet something new: a &#60;b&#62;Function&#60;/b&#62;. I already told you that methods can be called for each instance of a type. But what if you don&#39;t have an instance yet? Stuck? No. There are methods that you can send to the type directly without having an instance of that type. Those are called &#60;b&#62;Functions&#60;/b&#62;.&#60;br&#62;And one of the most used kind of function is a &#60;b&#62;Create&#60;/b&#62; function which is commonly used in BlitzMax to create instances of a given type.&#60;br&#62;%CODE_BEGIN% &#60;br&#62;Function CreateFRL:TFRLTimer(logicCyclesPerSec:Float, numSamples:Int = 0)&#60;br&#62;%CODE_END% &#60;br&#62;This function does exactly that: it will return an instance of &#60;b&#62;TFRLTimer&#60;/b&#62; which is specified as the return type of this function. So the syntax for functions is:&#60;br&#62;%CODE_BEGIN% &#60;br&#62;&#60;b&#62;Function&#60;/b&#62; NameOfYourFunction:ReturnTypeOfFunction(parameterOne:TypeOfParameterOne, ParameterTwo:TypeOfParameterTwo = DefaultValueIfNotGiven)&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;A function can have zero to many parameters, not only two as in my example. You can also give default values to parameters which will be used if you omit this parameter in the function call. Those default parameters must be used from &#60;b&#62;right to left&#60;/b&#62; in your function declaration - you cannot have a default value for the first parameter. That&#39;s because the compiler can&#39;t know if you want to use the default value or the first passed in value for the first parameter. So you can only omit parameters starting at the right end of your function declaration.&#60;br&#62;&#60;br&#62;Anyway, back to the &#60;b&#62;CreateFRL()&#60;/b&#62; function. First it creates an empty instance of a &#60;b&#62;TFRLTimer&#60;/b&#62; and then it takes the logic cycles per second and calculates the milliseconds per logic cycle and stores it in the field logicFPS.&#60;br&#62;%CODE_BEGIN% &#60;br&#62;Local frl:TFRLTimer = New TFRLTimer&#60;br&#62;frl.LogicFPS = 1.0 / logicCyclesPerSec&#60;br&#62;%CODE_END% &#60;br&#62;There&#39;s another thing to mention here: &#60;b&#62;Local&#60;/b&#62;. With this keyword you define a local variable which means this variable can only be used inside the function or method where it was defined. Outside of the function &#60;b&#62;CreateFRL()&#60;/b&#62; you cannot access the local variable &#60;b&#62;frl&#60;/b&#62; but you would get a compiler error!&#60;br&#62;&#60;br&#62;On with the remaining lines. If &#60;b&#62;numSamples&#60;/b&#62; is bigger than zero (so we passed in a value to the &#60;b&#62;CreateFRL()&#60;/b&#62; call) we store the information to use samples in &#60;b&#62;dssOn&#60;/b&#62; and store the number of entries in &#60;b&#62;dssLenArray&#60;/b&#62; and allocate an array for the values in &#60;b&#62;dssArray&#60;/b&#62;.&#60;br&#62;Whoops! Another new thing to learn: Arrays in types are not automatically allocated when you create a new type instance. You&#39;ll have to do that on your own, for example in the &#60;b&#62;Create&#60;/b&#62; function of your type.&#60;br&#62;&#60;br&#62;At the end the &#60;b&#62;CreateFRL()&#60;/b&#62; function returns the properly initialized instance of type &#60;b&#62;TFRLTimer&#60;/b&#62; to the caller.&#60;br&#62;&#60;br&#62;Next we find a method named &#60;b&#62;GetDelta()&#60;/b&#62;.&#60;br&#62;%CODE_BEGIN% &#60;br&#62;    Method GetDelta:Float()&#60;br&#62;        Self.newTime = MilliSecs()&#60;br&#62;        Self.delta = Float (Self.newTime - Self.oldTime) * 0.001&#60;br&#62;        Self.oldTime = Self.newTime&#60;br&#62;        &#60;br&#62;        If Self.dssOn = True&#60;br&#62;            Self.dssArray[Self.dssIndex] = Self.delta&#60;br&#62;            &#60;br&#62;            Local smoothDelta:Float = 0&#60;br&#62;            &#60;br&#62;            For Local i:Int = 0 To Self.dssLenArray - 1&#60;br&#62;                smoothDelta:+Self.dssArray[i]&#60;br&#62;            Next&#60;br&#62;            Self.delta = Float smoothDelta / dssLenArray&#60;br&#62;            &#60;br&#62;            Self.dssIndex:+1&#60;br&#62;            If Self.dssIndex &#62; dssLenArray - 1 Then Self.dssIndex = 0&#60;br&#62;        EndIf&#60;br&#62;        &#60;br&#62;        Self.accumulator:+Self.delta&#60;br&#62;        &#60;br&#62;        Return Self.delta&#60;br&#62;    End Method&#60;br&#62;%CODE_END% &#60;br&#62;We know that a method is bound to an instance of a type. So with every instance of &#60;b&#62;TFRLTimer&#60;/b&#62; we can call its &#60;b&#62;GetDelta()&#60;/b&#62; method.&#60;br&#62;The method returns a float value, the delta and the method takes no parameters. Look back into the &#60;a href=&#34;../Topdownshootertu/index.html#mainloop&#34;&#62;main loop&#60;/a&#62; to see where we call&#60;br&#62;%CODE_BEGIN% &#60;br&#62;gameTime.GetDelta()&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;The method calculates the &#60;b&#62;delta&#60;/b&#62; time which is the amount of milliseconds between the last and current calls to &#60;b&#62;GetDelta()&#60;/b&#62;. If &#60;b&#62;dssOn&#60;/b&#62; is true we store the current &#60;b&#62;delta&#60;/b&#62; value in the &#60;b&#62;dssArray&#60;/b&#62; and immediately calculate the smoothed delta. The &#60;b&#62;dssArray&#60;/b&#62; is a wrapping array where the index restarts at 0 when the array size limit is reached. The &#60;b&#62;accumulator&#60;/b&#62; is increased by the &#60;b&#62;delta&#60;/b&#62; value so that the &#60;b&#62;accumulator&#60;/b&#62; always contains the milliseconds since the last completed update call.&#60;br&#62;&#60;br&#62;The last method in this class/type is&#60;br&#62;%CODE_BEGIN% &#60;br&#62;    Method GetTween:Float()&#60;br&#62;        Return Self.accumulator / Self.logicFPS&#60;br&#62;    End Method&#60;br&#62;%CODE_END% &#60;br&#62;Here we simply return the &#60;b&#62;tween&#60;/b&#62; value which is the &#60;b&#62;accumulator&#60;/b&#62; divided by logicFPS.</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds111</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds111</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>First test</title>
  <description>Now that you have &#60;b&#62;ComeGetMe.bmx&#60;/b&#62; and &#60;b&#62;TFRLTimer.bmx&#60;/b&#62; stored in your project folder you should be able to compile the main file &#60;b&#62;ComeGetMe.bmx&#60;/b&#62; which will also compile &#60;b&#62;TFRLTimer.bmx&#60;/b&#62; and the result should be an executable. If you start it a simple black window should open.&#60;br&#62;Press the &#39;Escape&#39; key or use your mouse to close the window.&#60;br&#62;&#60;br&#62;Great! We now got a working code base.</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds110</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds110</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Already the first refactoring!</title>
  <description>After reading the tutorial for several times now (proof reading while adding new content) I detected what was nagging me all the time. I didn&#39;t like the implementation of the &#60;b&#62;TFRLTimer&#60;/b&#62; class. The main class in it&#39;s main loop had constant access to some fields of the &#60;b&#62;TFRLTimer&#60;/b&#62; and even modified them!&#60;br&#62;This breaks many OO rules like &#60;i&#62;encapsulation&#60;/i&#62; and &#60;i&#62;information hiding&#60;/i&#62; of course. So I just had to refactor the class. And while I was at it I also added some FPS code to show the amount of logic update calls and render calls per second.&#60;br&#62;&#60;br&#62;Let&#39;s look at the modified main class &#60;b&#62;ComeGetMe&#60;/b&#62; and the new &#60;b&#62;TFRLTimer&#60;/b&#62; class.&#60;br&#62;&#60;br&#62;&#60;b&#62;ComeGetMe.bmx&#60;/b&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;SuperStrict&#60;br&#62;&#60;br&#62;Import &#34;TFRLTimer.bmx&#34;&#60;br&#62;&#60;br&#62;Const GFX_WIDTH:Int = 640, GFX_HEIGHT:Int = 480&#60;br&#62;&#60;br&#62;Const UPDATE_FREQUENCY:Float = 100.0, SPIKE_SUPPRESSION:Int = 20&#60;br&#62;&#60;br&#62;Graphics GFX_WIDTH, GFX_HEIGHT, 0&#60;br&#62;&#60;br&#62;SetBlend ALPHABLEND&#60;br&#62;&#60;br&#62;AutoMidHandle(True)&#60;br&#62;&#60;br&#62;Global gameTime:TFRLTimer = New TFRLTimer.CreateFRL(UPDATE_FREQUENCY, SPIKE_SUPPRESSION)        &#39;1st number is logic updates per second and 2nd number is how much spike suppression you want&#60;br&#62;&#60;br&#62;Global player:TPlayer = TPlayer.Create(TCoordinate.Create(GFX_WIDTH / 2, GFX_HEIGHT / 2, 0))&#60;br&#62;&#60;br&#62;&#60;br&#62;&#39; the main loop starts here&#60;br&#62;While Not KeyDown(KEY_ESCAPE) And AppTerminate() = False&#60;br&#62;    Cls&#60;br&#62;    &#60;br&#62;&#60;br&#62;    &#39; update part of the main loop with constant speed&#60;br&#62;    Local delta:Float = gameTime.ProcessTime()&#60;br&#62;    While gameTime.LogicUpdateRequired()&#60;br&#62;        DoGameLogic(gameTime.GetLogicFPS())             &#39;Update Game Logic Here&#60;br&#62;    Wend&#60;br&#62;    &#60;br&#62;    &#39; rendering with additional tweening    &#60;br&#62;    Local tween:Float = gameTime.GetTween()         &#39;calc the tween for smooth graphics&#60;br&#62;    doGameRender(tween)                             &#39;Render Game Here&#60;br&#62;    &#60;br&#62;    Flip 0                                          &#39; synchronize graphics buffer as soon as possible&#60;br&#62;Wend&#60;br&#62;EndGraphics&#60;br&#62;End&#60;br&#62;&#60;br&#62;&#60;br&#62;Function DoGameLogic(fixedRate:Float)&#60;br&#62;    &#39; nothing here yet&#60;br&#62;End Function&#60;br&#62;&#60;br&#62;Function DoGameRender(tween:Float)&#60;br&#62;    &#39; nothing here yet&#60;br&#62;    gameTime.ShowFPS(0, 0)&#60;br&#62;End Function&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;So the interesting part is the modified main loop. Notice that I only call methods of the &#60;b&#62;gameTime&#60;/b&#62; object. No field of the &#60;b&#62;TFRLTimer&#60;/b&#62; is exposed to the calling class. I also renamed the method &#60;b&#62;GetDelta()&#60;/b&#62; because the method name is misleading. We don&#39;t only retrieve the delta value but the most important thing is that this method also calculates the passed time and updates a lot of internal stuff inside the &#60;b&#62;TFRLTimer&#60;/b&#62; instance. So I decided to rename this method to &#60;b&#62;ProcessTime()&#60;/b&#62; which better describes what the method really does. And as a return value we retrieve the delta time that passed since the last call to &#60;b&#62;ProcessTime()&#60;/b&#62;. Voila. Much better.&#60;br&#62;Also I don&#39;t access the accumulator field of the timer instance. Instead I encapsulated that in a method named &#60;b&#62;LogicUpdateRequired()&#60;/b&#62;. It returns true if enough time passed to at least call the update routines of the game elements once. Also all internal fields like the accumulator are updated. I also added a accessor method &#60;b&#62;GetLogicFPS()&#60;/b&#62; which only returns the field &#60;b&#62;logicFPS&#60;/b&#62; of the &#60;b&#62;TFRLTimer&#60;/b&#62; instance. But this way I can hide all information inside the class. The caller does not know if the &#60;b&#62;logicFPS&#60;/b&#62; is calculated for each call or precalculated on instance creation time.&#60;br&#62;&#60;br&#62;I also added a call to &#60;b&#62;gameTime.ShowFPS()&#60;/b&#62; in the function &#60;b&#62;DoGameRender()&#60;/b&#62;. When we compile &#60;b&#62;ComeGetMe.bmx&#60;/b&#62; we should see a black window with logic and render FPS shown at the top of the screen.&#60;br&#62;&#60;br&#62;Now finish the refactoring by looking at the refactored &#60;b&#62;TFRLTimer&#60;/b&#62; class.</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds109</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds109</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>The refactored TFRLTimer class</title>
  <description>Let&#39;s start with the complete source code for &#60;b&#62;TFRLTimer.bmx&#60;/b&#62;:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;&#39;==============================================================&#60;br&#62;&#39;===FIXED RATE LOGIC  TWEEN  DELTA SPIKE SUPPRESSION (DSS)===&#60;br&#62;&#39;==============================================================&#60;br&#62;Type TFRLTimer&#60;br&#62;    Field newTime:Float = MilliSecs()&#60;br&#62;    Field oldTime:Float = MilliSecs()&#60;br&#62;    Field delta:Float&#60;br&#62;&#60;br&#62;    Field dssOn:Int     &#39; do we use delta spike suppression?&#60;br&#62;    Field dssIndex:Int      &#39; index into DSS_Array where next delta value is written&#60;br&#62;    Field dssArray:Float[]  &#39; this array contains the delta values to smooth&#60;br&#62;    Field dssLenArray:Int   &#39; how big is the array of delta values&#60;br&#62;&#60;br&#62;    Field logicFPS:Float&#60;br&#62;    Field accumulator:Float, tween:Float&#60;br&#62;    &#60;br&#62;    Field fpsAccumulator:Float&#60;br&#62;    Field updateCount:Int&#60;br&#62;    Field renderCount:Int&#60;br&#62;    Field updatesPerSecond:Int&#60;br&#62;    Field rendersPerSecond:Int&#60;br&#62;    &#60;br&#62;&#60;br&#62;    Function CreateFRL:TFRLTimer(logicCyclesPerSec:Float, numSamples:Int = 0)&#60;br&#62;        Local frl:TFRLTimer = New TFRLTimer&#60;br&#62;        frl.logicFPS = 1.0 / logicCyclesPerSec&#60;br&#62;        If numSamples&#60;br&#62;            frl.dssOn = True&#60;br&#62;            frl.dssArray = New Float[numSamples]&#60;br&#62;            frl.dssLenArray = numSamples&#60;br&#62;        EndIf&#60;br&#62;        Return frl&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;    Method ProcessTime:Float()&#60;br&#62;        Self.newTime = MilliSecs()&#60;br&#62;        Self.delta = Float (Self.newTime - Self.oldTime) * 0.001&#60;br&#62;        Self.oldTime = Self.newTime&#60;br&#62;        &#60;br&#62;        If Self.dssOn = True&#60;br&#62;            Self.dssArray[Self.dssIndex] = Self.delta&#60;br&#62;            &#60;br&#62;            Local smoothDelta:Float = 0&#60;br&#62;            &#60;br&#62;            For Local i:Int = 0 To Self.dssLenArray - 1&#60;br&#62;                smoothDelta:+Self.dssArray[i]&#60;br&#62;            Next&#60;br&#62;            Self.delta = Float smoothDelta / dssLenArray&#60;br&#62;            &#60;br&#62;            Self.dssIndex:+1&#60;br&#62;            If Self.dssIndex &#62; dssLenArray - 1 Then Self.dssIndex = 0&#60;br&#62;        EndIf&#60;br&#62;        &#60;br&#62;        Self.accumulator:+Self.delta&#60;br&#62;        &#60;br&#62;        Self.fpsAccumulator:+Self.delta&#60;br&#62;        If Self.fpsAccumulator &#62; 1.0&#60;br&#62;            Self.fpsAccumulator:-1.0&#60;br&#62;            Self.updatesPerSecond = Self.updateCount&#60;br&#62;            Self.updateCount = 0&#60;br&#62;            Self.rendersPerSecond = Self.renderCount&#60;br&#62;            Self.renderCount = 0&#60;br&#62;        End If&#60;br&#62;        &#60;br&#62;        Return Self.delta&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;    &#60;br&#62;    Method LogicUpdateRequired:Int()&#60;br&#62;        If Self.accumulator &#62; Self.logicFPS&#60;br&#62;            Self.updateCount:+1&#60;br&#62;            Self.accumulator:-Self.logicFPS&#60;br&#62;            Return True&#60;br&#62;        End If&#60;br&#62;        Return False&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;    &#60;br&#62;    Method GetLogicFPS:Float()&#60;br&#62;        Return Self.logicFPS&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    &#60;br&#62;    Method GetTween:Float()&#60;br&#62;        Self.renderCount:+1&#60;br&#62;        Return Self.accumulator / Self.logicFPS&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;&#60;br&#62;    Method ShowSpikeSuppression(x:Int, y:Int)&#60;br&#62;        DrawText &#34;Delta Spike Suppressor:&#34;, x, y&#60;br&#62;        For Local i:Int = 0 To Self.dssLenArray - 1&#60;br&#62;            DrawText Self.dssArray[i], x, y + (i + 1) * 20&#60;br&#62;        Next&#60;br&#62;        DrawText &#34;Final Delta: &#34; + Self.delta, x, y + (Self.dssLenArray + 1) * 20&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    &#60;br&#62;    Method ShowFPS(x:Int, y:Int, showUpdateFPS:Int = True, showRenderFPS:Int = True)&#60;br&#62;        Local ty = y&#60;br&#62;        &#60;br&#62;        If showUpdateFPS&#60;br&#62;            DrawText &#34;Logic FPS:  &#34; + updatesPerSecond, x, ty&#60;br&#62;            ty:+20&#60;br&#62;        End If&#60;br&#62;        If showRenderFPS&#60;br&#62;            DrawText &#34;Render FPS: &#34; + rendersPerSecond, x, ty&#60;br&#62;        End If&#60;br&#62;    End Method&#60;br&#62;End Type&#60;br&#62;&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;As you can see I added some more fields to do the FPS calculation.&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Field fpsAccumulator:Float&#60;br&#62;    Field updateCount:Int&#60;br&#62;    Field renderCount:Int&#60;br&#62;    Field updatesPerSecond:Int&#60;br&#62;    Field rendersPerSecond:Int&#60;br&#62;%CODE_END%&#60;br&#62;The &#60;b&#62;fpsAccumulator&#60;/b&#62; is increased every time the method &#60;b&#62;ProcessTime()&#60;/b&#62; is called. This way we can detect when one second passed.&#60;br&#62;As I already mentioned &#60;b&#62;ProcessTime()&#60;/b&#62; is just the renamed method &#60;b&#62;GetDelta()&#60;/b&#62; with some minor enhancements.&#60;br&#62;As soon as a second is over the fields &#60;b&#62;updatesPerSecond&#60;/b&#62; and &#60;b&#62;rendersPerSecond&#60;/b&#62; are set with the current values of &#60;b&#62;updateCount&#60;/b&#62; and &#60;b&#62;renderCount&#60;/b&#62;. The two counting variables &#60;b&#62;updateCount&#60;/b&#62; and &#60;b&#62;renderCount&#60;/b&#62; are reset to zero to start again counting the update and render calls for the next second.&#60;br&#62;&#60;br&#62;&#60;b&#62;updatesPerSecond&#60;/b&#62; and &#60;b&#62;rendersPerSecond&#60;/b&#62; are shown when you call the new method &#60;b&#62;ShowFPS()&#60;/b&#62;. They keep their values for one second and then they are overwritten by the new values of &#60;b&#62;updateCount&#60;/b&#62; and &#60;b&#62;renderCount&#60;/b&#62;.&#60;br&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Method LogicUpdateRequired:Int()&#60;br&#62;        If Self.accumulator &#62; Self.logicFPS&#60;br&#62;            Self.updateCount:+1&#60;br&#62;            Self.accumulator:-Self.logicFPS&#60;br&#62;            Return True&#60;br&#62;        End If&#60;br&#62;        Return False&#60;br&#62;    End Method&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;The method &#60;b&#62;LogicUpdateRequired:Int()&#60;/b&#62; is new. It is called from the main loop to detect if at least one update call is pending. If that&#39;s the case the &#60;b&#62;updateCount&#60;/b&#62; is incremented by one and the accumulator is decreased by the update time &#60;b&#62;logicFPS&#60;/b&#62;.&#60;br&#62;&#60;br&#62;The &#60;b&#62;renderCount&#60;/b&#62; is incremented in the &#60;b&#62;GetTween()&#60;/b&#62; method because this method is called for each render phase to retrieve the tween value that needs to go into every render call to tween the movement of game elements.&#60;br&#62;&#60;br&#62;That&#39;s pretty much all for the important and mentionable changes in the &#60;b&#62;TFRLTimer&#60;/b&#62; class.&#60;br&#62;&#60;br&#62;Compile the two source files and if all went well you should see a screen similar to the one below.&#60;br&#62;&#60;br&#62;Those two files can be reused as the base for all your games - consider it the beginning of a small library to help you creating your own games &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds108</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds108</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Introducing the player - not yet!</title>
  <description>Before we start with the code for the player we&#39;ll need to think a bit about the types we are going to create:&#60;br&#62;&#60;br&#62;&#60;ul&#62;&#60;li&#62; we need an old x/y position and a new x/y position for every game element&#60;/li&#62;&#60;li&#62; we need old and new angles for every game element&#60;/li&#62;&#60;li&#62; we need to copy new to old positions in a simple way&#60;/li&#62;&#60;li&#62; we need to calculate distances and angles between positions (for aiming and firing)&#60;/li&#62;&#60;li&#62; we do have game elements that share quite some functionality&#60;/li&#62;&#60;li&#62; all game elements should be forced to implement an update and a render method&#60;/li&#62;&#60;li&#62; we want to share and reuse as much code as possible. Coding by using copy and paste is bad &#60;img src=&#34;../_frame/icon_cool.gif&#34; border=&#34;0&#34;&#62;&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;So how do we put those requirements into types?&#60;br&#62;&#60;br&#62;One approach is to have a simple class for x/y positions or coordinates and the angle. It could contain x/y position, the current angle or direction, some methods to copy coordinates and methods for angle and distance calculations.&#60;br&#62;Let&#39;s name this new class/type &#60;b&#62;TCoordinate&#60;/b&#62;.&#60;br&#62;&#60;br&#62;The second class could be called &#60;b&#62;TGameElement&#60;/b&#62; and contains old and new &#60;b&#62;TCoordinate&#60;/b&#62;s and directions and will have all methods that are shared between all different &#60;b&#62;TGameElement&#60;/b&#62;s.&#60;br&#62;&#60;br&#62;To force the programmer to implement proper update and render methods we make those methods &#60;b&#62;abstract&#60;/b&#62; and also we make the whole type &#60;b&#62;abstract&#60;/b&#62;.&#60;br&#62;That&#39;s another OO feature you&#39;ll use frequently.&#60;br&#62;&#60;br&#62;&#60;ul&#62;&#60;li&#62; If a type is abstract you cannot create instances of that type. So there will never be an instance of &#60;b&#62;TGameElement&#60;/b&#62;.&#60;/li&#62;&#60;li&#62; You will have to &#60;b&#62;extend&#60;/b&#62; or &#60;b&#62;subclass&#60;/b&#62; this type and create your own derived type of &#60;b&#62;TGameElement&#60;/b&#62;. For example a type &#60;b&#62;TPlayer&#60;/b&#62; will be a subclass of &#60;b&#62;TGameElement&#60;/b&#62; and automatically inherit all fields and all methods of &#60;b&#62;TGameElement&#60;/b&#62; without writing or copying a single line of code!&#60;/li&#62;&#60;li&#62; If a method is abstract the programmer is forced to implement this method in his subclass of the abstract class (so you can only have abstract methods in abstract types).&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;So let&#39;s start with the &#60;b&#62;TCoordinate&#60;/b&#62; class.&#60;br&#62;&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#baseclass</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#baseclass</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>TCoordinate or &#34;Where am I?&#34;</title>
  <description>The &#60;b&#62;TCoordinate&#60;/b&#62; type in it&#39;s first incarnation looks like this:&#60;br&#62;&#60;br&#62;&#60;b&#62;TCoordinate.bmx&#60;/b&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Type TCoordinate&#60;br&#62;    Field x:Float&#60;br&#62;    Field y:Float&#60;br&#62;    Field angle:Int &#39; we simplify here and just use an integer for angles between 0 and 359 degrees&#60;br&#62;    &#60;br&#62;    Function Create:TCoordinate(x:Float, y:Float, angle:Int)&#60;br&#62;        Local coord:TCoordinate = New TCoordinate&#60;br&#62;        coord.x = x&#60;br&#62;        coord.y = y&#60;br&#62;        coord.angle = angle&#60;br&#62;        Return coord&#60;br&#62;    End Function&#60;br&#62;    &#60;br&#62;    &#60;br&#62;    Function Copy:TCoordinate(original:TCoordinate)&#60;br&#62;        Local copy:TCoordinate = New TCoordinate&#60;br&#62;        copy.x = original.x&#60;br&#62;        copy.y = original.y&#60;br&#62;        copy.angle = original.angle&#60;br&#62;        Return copy&#60;br&#62;    End Function&#60;br&#62;    &#60;br&#62;    Method setPosition(x:Float, y:Float)&#60;br&#62;        Self.x = x&#60;br&#62;        Self.y = y&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method setAngle(angle:Int)&#60;br&#62;        self.angle = angle&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method getDistance:Float(otherPos:TCoordinate)&#60;br&#62;        Local l1:Float = Abs(Self.x - otherPos.x)&#60;br&#62;        Local l2:Float = Abs(Self.y - otherPos.y)&#60;br&#62;        Return Sqr((l1 * l1) + (l2 * l2))&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method getAngle:Int(otherPos:TCoordinate)&#60;br&#62;         Local dx:Float = otherPos.x - Self.x&#60;br&#62;         Local dy:Float = otherPos.y - Self.y&#60;br&#62;         Return Int((ATan2(dy:Float, dx:Float) + 360) Mod 360)&#60;br&#62;    End Method&#60;br&#62;End Type&#60;br&#62;%CODE_END%</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds106</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds106</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Explanation of the TCoordinate type</title>
  <description>The &#60;b&#62;TCoordinate&#60;/b&#62; type is not very complicated.&#60;br&#62;First we have three fields: &#60;b&#62;x&#60;/b&#62;, &#60;b&#62;y&#60;/b&#62; and &#60;b&#62;angle&#60;/b&#62;. This means that every instance of &#60;b&#62;TCoordinate&#60;/b&#62; has it&#39;s own x and y position and it&#39;s own angle it is targeting at.&#60;br&#62;&#60;br&#62;Then we find two functions that return a &#60;b&#62;TCoordinate&#60;/b&#62; type and are our two valid creator functions.&#60;br&#62;&#60;br&#62;The first function &#60;b&#62;Create:TCoordinate(x:Float, y:Float, angle:Int)&#60;/b&#62; takes the x, y and angle values we want to have in our new instance as parameters.&#60;br&#62;The line&#60;br&#62;%CODE_BEGIN%&#60;br&#62;        Local coord:TCoordinate = New TCoordinate&#60;br&#62;%CODE_END% &#60;br&#62;creates an empty &#60;b&#62;TCoordinate&#60;/b&#62; instance and stores it in the local variable &#60;b&#62;coord&#60;/b&#62;. We then fill the three fields with the parameter values and return the properly initialized instance by returning &#60;b&#62;coord&#60;/b&#62;.&#60;br&#62;&#60;br&#62;For simplification I added another function that creates a &#60;b&#62;TCoordinate&#60;/b&#62; instance. But this function doesn&#39;t take x, y and angle but another &#60;b&#62;TCoordinate&#60;/b&#62; instance that is simply copied into a new instance.&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Function Copy:TCoordinate(original:TCoordinate)&#60;br&#62;        Local copy:TCoordinate = New TCoordinate&#60;br&#62;        copy.x = original.x&#60;br&#62;        copy.y = original.y&#60;br&#62;        copy.angle = original.angle&#60;br&#62;        Return copy&#60;br&#62;    End Function&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;There are two methods &#60;b&#62;SetPosition(x:Float, y:Float)&#60;/b&#62; and &#60;b&#62;SetAngle(angle:Int)&#60;/b&#62; which allow to modify the fields of an &#60;b&#62;TCoordinate&#60;/b&#62; instance.&#60;br&#62;&#60;br&#62;And finally there are two methods that calculate the distance between two &#60;b&#62;TCoordinate&#60;/b&#62; instances (&#60;b&#62;GetDistance:Float(otherPos:TCoordinate)&#60;/b&#62;) and the angle between two  &#60;b&#62;TCoordinate&#60;/b&#62; instances (&#60;b&#62;GetAngle:Int(otherPos:TCoordinate)&#60;/b&#62;).&#60;br&#62;&#60;br&#62;That&#39;s basic math I copied from somewhere of the Internet &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Now let&#39;s move on to the next class.</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds105</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds105</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>TGameElement or &#34;Who&#39;s in the game?&#34;</title>
  <description>To share common fields and functionality I explained &#60;a href=&#34;../Topdownshootertu/index.html#baseclass&#34;&#62;here&#60;/a&#62; we&#39;ll use the class &#60;b&#62;TGameElement&#60;/b&#62;.&#60;br&#62;It&#39;s not big yet so let&#39;s look at the source:&#60;br&#62;&#60;br&#62;&#60;b&#62;TGameElement.bmx&#60;/b&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Import &#34;TCoordinate.bmx&#34;&#60;br&#62;&#60;br&#62;Type TGameElement Abstract&#60;br&#62;    Field pos:TCoordinate&#60;br&#62;    Field oldPos:TCoordinate&#60;br&#62;    Field angle:Int&#60;br&#62;    Field oldAngle:Int&#60;br&#62;    &#60;br&#62;    Method Update(fixedRate:Float) Abstract&#60;br&#62;    &#60;br&#62;    Method Render(tween:Float) Abstract&#60;br&#62;End Type&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;We need to import the file &#60;b&#62;TCoordinate.bmx&#60;/b&#62; because we use &#60;b&#62;TCoordinate&#60;/b&#62;s in our &#60;b&#62;TGameElement&#60;/b&#62; instance so we need to tell BlitzMax how a &#60;b&#62;TCoordinate&#60;/b&#62; looks like. The &#60;b&#62;Import&#60;/b&#62; statement is just some kind of hint for BlitzMax where to look for the definition of a &#60;b&#62;TCoordinate&#60;/b&#62;.&#60;br&#62;&#60;br&#62;The Type declaration line ends with the keyword &#60;b&#62;Abstract&#60;/b&#62; which tells BlitzMax two things:&#60;br&#62;&#60;ul&#62;&#60;li&#62; There must never be an instance of &#60;b&#62;TGameElement&#60;/b&#62;. Only instances of non abstract subclasses are allowed!&#60;/li&#62;&#60;li&#62; This type/class may contain abstract methods which force subclasses to implement them exactly with the given parameters and return types.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;Now let&#39;s look at the fields. Not very much surprising - we have two &#60;b&#62;TCoordinate&#60;/b&#62; fields to store the current and the last position of a game element and the same for the angle.&#60;br&#62;&#60;br&#62;Finally we define two abstract methods, &#60;b&#62;Update(fixedRate:Float)&#60;/b&#62; and &#60;b&#62;Render(tween:Float)&#60;/b&#62;. Again, there is no implementation for these methods required. We will have to implement those methods in the subclasses of &#60;b&#62;TGameElement&#60;/b&#62;.&#60;br&#62;&#60;br&#62;That does make sense because the subclasses know best what to update and what to render.&#60;br&#62;&#60;br&#62;Let&#39;s finish the first part of the tutorial by introducing the &#60;b&#62;TPlayer&#60;/b&#62; type, updating the main class &#60;b&#62;ComeGetMe&#60;/b&#62; and have the first rotating turret on screen.</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds104</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds104</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>The player - our first visible object on screen</title>
  <description>Time for the complete source code of the &#60;b&#62;TPlayer&#60;/b&#62; type.&#60;br&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Import &#34;TGameElement.bmx&#34;&#60;br&#62;Import &#34;TCoordinate.bmx&#34;&#60;br&#62;&#60;br&#62;Incbin &#34;gfx/turret.png&#34;&#60;br&#62;&#60;br&#62;Type TPlayer Extends TGameElement&#60;br&#62;    Global playerImg:TImage&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Function Create:TPlayer(pos:TCoordinate)&#60;br&#62;        Local player:TPlayer = New TPlayer&#60;br&#62;        player.pos = pos&#60;br&#62;        player.oldPos = TCoordinate.Copy(pos)&#60;br&#62;        If playerImg = Null&#60;br&#62;            playerImg = LoadImage(&#34;incbin::gfx/turret.png&#34;)&#60;br&#62;        End If&#60;br&#62;        Return player&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Update(fixedRate:Float)&#60;br&#62;        Local mousePos:TCoordinate&#60;br&#62;        mousePos = TCoordinate.Create(MouseX(), MouseY(), 0)&#60;br&#62;        &#39; let&#39;s rotate to always look at the mouse&#60;br&#62;        Self.oldAngle = Self.angle&#60;br&#62;        Self.angle = pos.getAngle(mousePos)&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Render(tween:Float)&#60;br&#62;        SetRotation(self.angle)&#60;br&#62;        DrawImage(playerImg, pos.x, pos.y)&#60;br&#62;        SetRotation(0)&#60;br&#62;    End Method&#60;br&#62;End Type&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;Because the &#60;b&#62;TPlayer&#60;/b&#62; uses a &#60;b&#62;TCoordinate&#60;/b&#62; for its position and inherits from (or extends) &#60;b&#62;TGameElement&#60;/b&#62; we need to import both files to tell BlitzMax what they are.&#60;br&#62;&#60;br&#62;The next line&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Incbin &#34;gfx/turret.png&#34;&#60;br&#62;%CODE_END% &#60;br&#62;shows a cool feature of BlitzMax. You can tell BlitzMax to include &#60;b&#62;any&#60;/b&#62; binary file into your executable with the command &#60;b&#62;Incbin&#60;/b&#62;. This means you do not have to release all your valuable assets like images, animation strips or sounds as separate files but you can include all of them into your game executable and distribute just that single file!&#60;br&#62;&#60;br&#62;Notice that I used a &#34;/&#34; instead of a &#34;\&#34; for the directory path. This is because BlitzMax is a multi platform solution and under MacOS and Linux the directory separator character is the &#34;/&#34;. So BlitzMax does some automatic platform dependent conversion and you can simply use the &#34;/&#34; to happily retrieve all of your files on any platform.&#60;br&#62;&#60;br&#62;To finish the long description of this single command: I told BlitzMax to load the file &#34;gfx/turret.png&#34; and store it into the executable of our game. Of course the file must be existant under the given directory and filename...&#60;br&#62;&#60;br&#62;Let&#39;s continue with the declaration of the &#60;b&#62;Tplayer&#60;/b&#62; type, making it an extension of the &#60;b&#62;TGameElement&#60;/b&#62; type. That means we need to implement the &#60;b&#62;Update()&#60;/b&#62; and &#60;b&#62;Render()&#60;/b&#62; methods later on in our type.&#60;br&#62;But first we define a global&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Global playerImg:TImage&#60;br&#62;%CODE_END% &#60;br&#62;A &#60;b&#62;Global&#60;/b&#62; is a field that is exactly the same for all instances. In other languages like C++ or Java such a variable is a &#60;b&#62;static&#60;/b&#62; variable. It belongs to the type and should only be accessed by using the type prefix (&#60;b&#62;TPlayer.playerImg&#60;/b&#62;) from outside of the type itself.&#60;br&#62;&#60;br&#62;As we reuse the image for the player every time we draw it loading and storing the image once is fine.&#60;br&#62;&#60;br&#62;Let&#39;s have a short look at the &#60;b&#62;Create&#60;/b&#62; method which is used to create a &#60;b&#62;TPlayer&#60;/b&#62; instance.&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Function Create:TPlayer(pos:TCoordinate)&#60;br&#62;        Local player:TPlayer = New TPlayer&#60;br&#62;        player.pos = pos&#60;br&#62;        player.oldPos = TCoordinate.Copy(pos)&#60;br&#62;        If playerImg = Null&#60;br&#62;            playerImg = LoadImage(&#38;#34;incbin::gfx/turret.png&#38;#34;)&#60;br&#62;        End If&#60;br&#62;        Return player&#60;br&#62;    End Function&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;We want to create the player instance at the center of the screen so we let the &#60;b&#62;Create&#60;/b&#62; method take the position as a parameter. A new empty &#60;b&#62;TPlayer&#60;/b&#62; instance is created and it&#39;s fields &#60;b&#62;pos&#60;/b&#62; and &#60;b&#62;oldPos&#60;/b&#62; (inherited from &#60;b&#62;TGameElement&#60;/b&#62;) are initialized with the parameter position.&#60;br&#62;The line&#60;br&#62;%CODE_BEGIN%&#60;br&#62;        If playerImg = Null&#60;br&#62;%CODE_END%&#60;br&#62;checks if we already loaded the image. By default all fields that take a type (like &#60;b&#62;TImage&#60;/b&#62;, the BlitzMax type for images) are initialized with &#60;b&#62;Null&#60;/b&#62;. So we can compare against it.&#60;br&#62;If the image is loaded the global &#60;b&#62;playerImg&#60;/b&#62; is &#34;pointing&#34; to an image and thus no longer &#60;b&#62;Null&#60;/b&#62;.&#60;br&#62;When loading the image we need to tell BlitzMax that the image was initially &#60;b&#62;incbin&#60;/b&#62;ed and needs to be loaded from inside the executable and not from a directory. So we prefix the file path with incbin::&#60;br&#62;%CODE_BEGIN%&#60;br&#62;            playerImg = LoadImage(&#38;#34;incbin::gfx/turret.png&#38;#34;)&#60;br&#62;%CODE_END%&#60;br&#62; At the end of the &#60;b&#62;Create&#60;/b&#62; function the initialized player object is returned.&#60;br&#62;&#60;br&#62;The &#60;b&#62;Update()&#60;/b&#62; method is not very complicated to understand. Let&#39;s look at it:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Method Update(fixedRate:Float)&#60;br&#62;        Local mousePos:TCoordinate&#60;br&#62;        mousePos = TCoordinate.Create(MouseX(), MouseY(), 0)&#60;br&#62;        &#39; let&#39;s rotate to always look at the mouse&#60;br&#62;        Self.oldAngle = Self.angle&#60;br&#62;        Self.angle = pos.getAngle(mousePos)&#60;br&#62;    End Method&#60;br&#62;%CODE_END%&#60;br&#62;We declare a local variable &#60;b&#62;mousePos&#60;/b&#62; which is a &#60;b&#62;TCoordinate&#60;/b&#62;. In the next line we create a new &#60;b&#62;TCoordinate&#60;/b&#62; that is placed on the current mouse pointer position (retrieved by calling &#60;b&#62;MouseX()&#60;/b&#62; and &#60;b&#62;MouseY()&#60;/b&#62;). We store the last &#60;b&#62;angle&#60;/b&#62; in &#60;b&#62;oldAngle&#60;/b&#62; and calculate the new angle by using the &#60;b&#62;TCoordinate&#60;/b&#62; method &#60;b&#62;getAngle()&#60;/b&#62; between the turret&#39;s position and the mouse pointer position.&#60;br&#62;&#60;br&#62;The &#60;b&#62;Render()&#60;/b&#62; method is even simpler:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;    Method Render(tween:Float)&#60;br&#62;        SetRotation(self.angle)&#60;br&#62;        DrawImage(playerImg, pos.x, pos.y)&#60;br&#62;        SetRotation(0)&#60;br&#62;    End Method&#60;br&#62;%CODE_END%&#60;br&#62;With the BlitzMax &#60;b&#62;SetRotation()&#60;/b&#62; function we assure that all following drawing commands will be rotated by the given angle (&#60;b&#62;self.angle&#60;/b&#62; is the angle of the player instance).&#60;br&#62;Then we draw the image &#60;b&#62;playerImg&#60;/b&#62; at the turret&#39;s position and finally switch back to a rotation of zero to assure that all following drawing commands are not affected by our rotated drawing of the player image.&#60;br&#62;&#60;br&#62;And that was about it. We finish the first part of the tutorial with a look at the updated main loop code.&#60;br&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds103</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds103</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>The updated main file ComeGetMe.bmx</title>
  <description>%CODE_BEGIN%&#60;br&#62;SuperStrict&#60;br&#62;&#60;br&#62;Import &#34;TFRLTimer.bmx&#34;&#60;br&#62;Import &#34;TPlayer.bmx&#34;&#60;br&#62;&#60;br&#62;Const GFX_WIDTH:Int = 640, GFX_HEIGHT:Int = 480&#60;br&#62;&#60;br&#62;Const UPDATE_FREQUENCY:Float = 100.0, SPIKE_SUPPRESSION:Int = 20&#60;br&#62;&#60;br&#62;Graphics GFX_WIDTH, GFX_HEIGHT, 0&#60;br&#62;&#60;br&#62;SetBlend ALPHABLEND&#60;br&#62;&#60;br&#62;AutoMidHandle(True)&#60;br&#62;&#60;br&#62;Global gameTime:TFRLTimer = New TFRLTimer.CreateFRL(UPDATE_FREQUENCY, SPIKE_SUPPRESSION)        &#39;1st number is logic updates per second and 2nd number is how much spike suppression you want&#60;br&#62;&#60;br&#62;Global player:TPlayer = TPlayer.Create(TCoordinate.Create(GFX_WIDTH / 2, GFX_HEIGHT / 2, 0))&#60;br&#62;&#60;br&#62;&#60;br&#62;&#39; the main loop starts here&#60;br&#62;While Not KeyDown(KEY_ESCAPE) And AppTerminate() = False&#60;br&#62;    Cls&#60;br&#62;    &#60;br&#62;&#60;br&#62;    &#39; update part of the main loop with constant speed&#60;br&#62;    Local delta:Float = gameTime.ProcessTime()&#60;br&#62;    While gameTime.LogicUpdateRequired()&#60;br&#62;        DoGameLogic(gameTime.GetLogicFPS())             &#39;Update Game Logic Here&#60;br&#62;    Wend&#60;br&#62;    &#60;br&#62;    &#39; rendering with additional tweening    &#60;br&#62;    Local tween:Float = gameTime.GetTween()         &#39;calc the tween for smooth graphics&#60;br&#62;    doGameRender(tween)                             &#39;Render Game Here&#60;br&#62;    &#60;br&#62;    Flip 0                                          &#39; synchronize graphics buffer as soon as possible&#60;br&#62;Wend&#60;br&#62;EndGraphics&#60;br&#62;End&#60;br&#62;&#60;br&#62;&#60;br&#62;Function DoGameLogic(fixedRate:Float)&#60;br&#62;    player.Update(fixedRate)&#60;br&#62;End Function&#60;br&#62;&#60;br&#62;Function DoGameRender(tween:Float)&#60;br&#62;    player.Render(tween)&#60;br&#62;    gameTime.ShowFPS(0, 0)&#60;br&#62;End Function&#60;br&#62;%CODE_END% &#60;br&#62;What&#39;s new here?&#60;br&#62;We added the import of the &#60;b&#62;TPlayer&#60;/b&#62; type at the beginning of the file.&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Import &#34;TPlayer.bmx&#34;&#60;br&#62;%CODE_END%&#60;br&#62;A few lines below we added the line&#60;br&#62;%CODE_BEGIN%&#60;br&#62;AutoMidHandle(True)&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;This line places the &#60;i&#62;hot spot&#60;/i&#62; of any image to it&#39;s center. The default &#60;i&#62;hot spot&#60;/i&#62; of an image is the top left corner. The &#60;i&#62;hot spot&#60;/i&#62; is used for drawing commands. When you draw an image with the &#60;b&#62;DrawImage&#60;/b&#62; command the hot pot is placed at the position you pass as the parameters of the &#60;b&#62;DrawImage&#60;/b&#62; command. Also rotating an image uses the hot spot as the rotation position. So placing it at the center of the image helps us to properly place our player at the center of the screen and smoothly rotate the player turret around it&#39;s center and not around it&#39;s top left corner.&#60;br&#62;&#60;br&#62;To access the player everywhere in our main file (and also in all other source code files) we declare a global variable for the player. It&#39;s name is &#60;b&#62;player&#60;/b&#62; and it is created by calling the &#60;b&#62;TPlayer.Create()&#60;/b&#62; function. As you can see we place the player in the middle of the screen.&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Global player:TPlayer = TPlayer.Create(TCoordinate.Create(GFX_WIDTH / 2, GFX_HEIGHT / 2, 0))&#60;br&#62;%CODE_END%&#60;br&#62;The &#60;b&#62;TPlayer.Create()&#60;/b&#62; function expects a &#60;b&#62;TCoordinate&#60;/b&#62; instance as the only parameter. Instead of creating a temporary variable for a &#60;b&#62;TCoordinate&#60;/b&#62; we just do some nested call by creating a new &#60;b&#62;TCoordinate&#60;/b&#62; instance inside the &#60;b&#62;TPlayer.Create()&#60;/b&#62; call.&#60;br&#62;BlitzMax first creates the &#60;b&#62;TCoordinate&#60;/b&#62; instance (which is the result of the &#60;b&#62;TCoordinate.Create()&#60;/b&#62; function) and passes that into the &#60;b&#62;TPlayer.Create()&#60;/b&#62; function call.&#60;br&#62;This is a bit tricky to understand at first but it&#39;s a very common way in OO world and helps you to avoid unneccessary declaration of local variables in methods and functions.&#60;br&#62;&#60;br&#62;The last thing we need to do is add the &#60;b&#62;player.Update()&#60;/b&#62; and &#60;b&#62;player.render()&#60;/b&#62; calls to the two functions &#60;b&#62;DoGameLogic()&#60;/b&#62; and &#60;b&#62;DoGameRender()&#60;/b&#62;. See the code below.&#60;br&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Function DoGameLogic(fixedRate:Float)&#60;br&#62;    player.Update(fixedRate)&#60;br&#62;End Function&#60;br&#62;&#60;br&#62;Function DoGameRender(tween:Float)&#60;br&#62;    player.Render(tween)&#60;br&#62;    gameTime.ShowFPS(0, 0)&#60;br&#62;End Function&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;And that&#39;s about it for the first part. Find the download of the source code below. And also the link to the second part where we will add bullets and enemies and some sound.&#60;br&#62;&#60;br&#62;Stay tuned!</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#tds102</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#tds102</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Download part one</title>
  <description>You can grab the first part of the tutorial including the graphics and all the source code if you click on the button below.&#60;br&#62;&#60;br&#62;Have fun with it &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;&#60;a href=&#34;../tdstutorialpart2/index.html&#34;&#62;Part 2 of the tutorial&#60;/a&#62;</description>
  <link>http://www.rightanglegames.com/topdownshootertu/index.html#downloadpartone</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/topdownshootertu/index.html#downloadpartone</guid>
  <category>Top down shooter tutorial with BlitzMax</category>
</item>
<item>
  <title>Welcome back to the tutorial and to TGameElements!</title>
  <description>Welcome to the second part of the tutorial.&#60;br&#62;&#60;br&#62;I will reduce the details of explanation in this second part and only mention issues that I consider worth mentioning. Code that is similar to stuff in the first part will not be explained as detailed again.&#60;br&#62;&#60;br&#62;Let&#39;s begin with enhancing the &#60;b&#62;TGameElement&#60;/b&#62; type. I&#39;ve added a function &#60;b&#62;Tween()&#60;/b&#62; that takes the old and new position of the moving game element and the current tween value and it returns the proper position for the current place to render.&#60;br&#62;Position can be any tweening value like x or y coordinate or an angle.&#60;br&#62;&#60;br&#62;I also added a boolean field &#60;b&#62;dead&#60;/b&#62; to indicate if the game element is dead or alive. Dead game elements will not be rendered but will be removed from their appropriate list (the list of all bullets or all enemies).&#60;br&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Import &#34;TCoordinate.bmx&#34;&#60;br&#62;&#60;br&#62;Type TGameElement Abstract&#60;br&#62;    Field pos:TCoordinate&#60;br&#62;    Field oldPos:TCoordinate&#60;br&#62;    Field angle:Int&#60;br&#62;    Field oldAngle:Int&#60;br&#62;    Field dead:Int = false&#60;br&#62;    &#60;br&#62;    Method Update(fixedRate:Float) Abstract&#60;br&#62;    &#60;br&#62;    Method Render(tween:Float) Abstract&#60;br&#62;    &#60;br&#62;    Function Tween:Float(oldpos:Float, newpos:Float, tween:Float)&#60;br&#62;        &#39;drawing pos = newpos * tween + oldpos * ( 1.0 - tween)&#60;br&#62;        Local tweenpos:Float&#60;br&#62;        tweenpos = newpos * tween + oldpos * (1.0 - tween)&#60;br&#62;        Return tweenpos&#60;br&#62;    End Function&#60;br&#62;End Type&#60;br&#62;%CODE_END% </description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds201</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds201</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
<item>
  <title>TCoordinates also modified</title>
  <description>If you look at &#60;b&#62;TCoordinate&#60;/b&#62; it doesn&#39;t contain methods to set one &#60;b&#62;TCoordinate&#60;/b&#62; instance&#39;s x and y and angle identical to those of a second &#60;b&#62;TCoordinate&#60;/b&#62; instance.&#60;br&#62;I changed that with the new methods &#60;b&#62;SetPositionLike(otherPos:TCoordinate)&#60;/b&#62;, &#60;b&#62;SetAngleLike(otherPos:TCoordinate)&#60;/b&#62; and &#60;b&#62;SetLike(otherPos:TCoordinate)&#60;/b&#62;.&#60;br&#62;&#60;br&#62;Also added are two more methods:&#60;br&#62;&#60;b&#62;Normalize()&#60;/b&#62; treats a &#60;b&#62;TCoordinate&#60;/b&#62; instance as a vector and modifies x and y values so that the &#34;length&#34; of this vector is 1 (do you remember Pythagoras and his triangles? &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;). This method is helpful and required for the next method.&#60;br&#62;&#60;br&#62;&#60;b&#62;GetDirection(toPos:TCoordinate)&#60;/b&#62; returns a &#34;normalized&#34; &#60;b&#62;TCoordinate&#60;/b&#62; instance that points into the direction of the given &#60;b&#62;TCoordinate&#60;/b&#62; instance &#60;b&#62;toPos&#60;/b&#62;.&#60;br&#62;We use a direction vector to let an enemy move to the player&#39;s turret as you will see later.&#60;br&#62;&#60;br&#62;So here comes the complete new &#60;b&#62;TCoordinate&#60;/b&#62; code:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Type TCoordinate&#60;br&#62;    Field x:Float&#60;br&#62;    Field y:Float&#60;br&#62;    Field angle:Int &#39; we simplify here and just use an integer for angles between 0 and 359 degrees&#60;br&#62;    &#60;br&#62;    Function Create:TCoordinate(x:Float, y:Float, angle:Int)&#60;br&#62;        Local coord:TCoordinate = New TCoordinate&#60;br&#62;        coord.x = x&#60;br&#62;        coord.y = y&#60;br&#62;        coord.angle = angle&#60;br&#62;        Return coord&#60;br&#62;    End Function&#60;br&#62;    &#60;br&#62;    &#60;br&#62;    Function Copy:TCoordinate(original:TCoordinate)&#60;br&#62;        Local copy:TCoordinate = New TCoordinate&#60;br&#62;        copy.x = original.x&#60;br&#62;        copy.y = original.y&#60;br&#62;        copy.angle = original.angle&#60;br&#62;        Return copy&#60;br&#62;    End Function&#60;br&#62;    &#60;br&#62;    Method SetPosition(x:Float, y:Float)&#60;br&#62;        Self.x = x&#60;br&#62;        Self.y = y&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method SetPositionLike(otherPos:TCoordinate)&#60;br&#62;        Self.x = otherPos.x&#60;br&#62;        Self.y = otherPos.y&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method SetAngle(angle:Int)&#60;br&#62;        self.angle = angle&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method SetAngleLike(otherPos:TCoordinate)&#60;br&#62;        Self.angle = otherPos.angle&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method SetLike(otherPos:TCoordinate)&#60;br&#62;        SetPositionLike(otherPos)&#60;br&#62;        SetAngleLike(otherPos)&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method GetDistance:Float(otherPos:TCoordinate)&#60;br&#62;        Local l1:Float = Abs(Self.x - otherPos.x)&#60;br&#62;        Local l2:Float = Abs(Self.y - otherPos.y)&#60;br&#62;        Return Sqr((l1 * l1) + (l2 * l2))&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Method GetAngle:Int(otherPos:TCoordinate)&#60;br&#62;         Local dx:Float = otherPos.x - Self.x&#60;br&#62;         Local dy:Float = otherPos.y - Self.y&#60;br&#62;         Return Int((ATan2(dy:Float, dx:Float) + 360) Mod 360)&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Rem&#60;br&#62;    BBDoc: calculate a normalized direction vector pointing from self to given toPos&#60;br&#62;    EndRem&#60;br&#62;    Method GetDirection:TCoordinate(toPos:TCoordinate)&#60;br&#62;        Local xdiff:Float = toPos.x - Self.x&#60;br&#62;        Local ydiff:Float = toPos.y - Self.y&#60;br&#62;        Local angle:Int = Self.GetAngle(toPos)&#60;br&#62;        Local dir:TCoordinate = TCoordinate.Create(xdiff, ydiff, angle)&#60;br&#62;        dir.Normalize()&#60;br&#62;        Return dir&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;    Rem&#60;br&#62;    BBDoc: normalizes this vector&#60;br&#62;    endrem&#60;br&#62;    Method Normalize()&#60;br&#62;        Local magnitude:Float = Sqr(Self.x * Self.x + Self.y * Self.y)&#60;br&#62;        Self.x = Self.x / magnitude&#60;br&#62;        Self.y = Self.y / magnitude&#60;br&#62;    End Method&#60;br&#62;    &#60;br&#62;End Type&#60;br&#62;%CODE_END% </description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds202</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds202</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
<item>
  <title>Bullets here we come</title>
  <description>It&#39;s about time to introduce some weapon stuff.&#60;br&#62;&#60;br&#62;For this we&#39;ll add a &#60;b&#62;TBullet&#60;/b&#62; type.&#60;br&#62;&#60;br&#62;It looks like this:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Import &#34;TGameElement.bmx&#34;&#60;br&#62;Import &#34;TCoordinate.bmx&#34;&#60;br&#62;&#60;br&#62;Incbin &#34;gfx/whitecircle.png&#34;&#60;br&#62;&#60;br&#62;Type TBullet Extends TGameElement&#60;br&#62;&#60;br&#62;    Global bulletImg:TImage&#60;br&#62;    Global allBullets:TList = New TList&#60;br&#62;    Global defaultspeed:Float = 3.0 &#39; with a logical framerate of 100 and a speed of 3.0 our bullets move 300 pixel per second&#60;br&#62;    &#60;br&#62;    Field dir:TCoordinate&#60;br&#62;    Field speed:Float&#60;br&#62;    Field shotBy:Int&#60;br&#62;    &#60;br&#62;&#60;br&#62;    Function Create:TBullet(pos:TCoordinate, direction:TCoordinate, speed:Float)&#60;br&#62;        Local bullet:TBullet = New TBullet&#60;br&#62;        bullet.pos = TCoordinate.Copy(pos)&#60;br&#62;        bullet.oldPos = TCoordinate.Copy(pos)&#60;br&#62;        If bulletImg = Null&#60;br&#62;            bulletImg = LoadImage(&#34;incbin::gfx/whitecircle.png&#34;)&#60;br&#62;        End If&#60;br&#62;        bullet.angle = direction.angle&#60;br&#62;        bullet.dir = direction&#60;br&#62;        bullet.speed = speed&#60;br&#62;        allBullets.AddLast(bullet)&#60;br&#62;        Return bullet&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Update(fixedRate:Float)&#60;br&#62;        &#39; move in direction dir with given bullet speed&#60;br&#62;        Self.oldPos.SetLike(Self.pos) &#39; store current pos in oldPos&#60;br&#62;        Self.pos.x:+(Self.dir.x * Self.speed)&#60;br&#62;        Self.pos.y:+(Self.dir.y * Self.speed)&#60;br&#62;        &#60;br&#62;        If (Self.pos.x &#60; 0 Or Self.pos.y &#60; 0 Or Self.pos.x &#62; GraphicsWidth()  Or Self.pos.y &#62; GraphicsHeight() or self.dead)&#60;br&#62;            &#39; delete this bullet&#60;br&#62;            allBullets.Remove(Self)&#60;br&#62;        End If&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Render(tween:Float)&#60;br&#62;        SetRotation(Self.angle)&#60;br&#62;        &#39; calculate proper tween position here&#60;br&#62;        SetColor(255, 0, 0)&#60;br&#62;        DrawImage(bulletImg, TGameElement.Tween(oldpos.x, pos.x, tween), TGameElement.Tween(oldpos.y, pos.y, tween))&#60;br&#62;        SetRotation(0)&#60;br&#62;        SetColor(255, 255, 255)&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Function UpdateAllBullets(fixedRate:Float)&#60;br&#62;        For Local bullet:TBullet = EachIn allBullets&#60;br&#62;            bullet.Update(fixedRate)&#60;br&#62;        Next&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Function RenderAllBullets(tween:Float)&#60;br&#62;        For Local bullet:TBullet = EachIn allBullets&#60;br&#62;            bullet.Render(tween)&#60;br&#62;        Next&#60;br&#62;        &#39; DrawText &#34;Nr of bullets &#34; + allBullets.Count(), 10, 400&#60;br&#62;    End Function&#60;br&#62;End Type&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;As &#60;b&#62;TBullet&#60;/b&#62; inherits from &#60;b&#62;TGameElement&#60;/b&#62; and uses &#60;b&#62;TCoordinate&#60;/b&#62;s we import those two files. And we use an image for the bullets so we &#60;b&#62;IncBin&#60;/b&#62; that.&#60;br&#62;&#60;br&#62;Every &#60;b&#62;TBullet&#60;/b&#62; instance has a direction (&#60;b&#62;dir&#60;/b&#62;) it&#39;s flying to and a speed and should know who shot it (an enemy or the player, not used yet). So those are fields.&#60;br&#62;The &#60;b&#62;bulletImg&#60;/b&#62;, the &#60;b&#62;defaultSpeed&#60;/b&#62; and the list &#60;b&#62;allBullets&#60;/b&#62; containing all &#60;b&#62;TBullet&#60;/b&#62; instances are used by all &#60;b&#62;TBullet&#60;/b&#62; instances so they are defined as &#60;b&#62;Global&#60;/b&#62;.&#60;br&#62;&#60;br&#62;The &#60;b&#62;Create&#60;/b&#62; method is not very spectacular: it takes the starting position, the direction and speed as parameters and simply initializes a new &#60;b&#62;TBullet&#60;/b&#62; instance with those values.&#60;br&#62;&#60;br&#62;Because &#60;b&#62;TBullet&#60;/b&#62; inherits from &#60;b&#62;TGameElement&#60;/b&#62; we implement an &#60;b&#62;Update&#60;/b&#62; and a &#60;b&#62;Render&#60;/b&#62; method.&#60;br&#62;An important part of the &#60;b&#62;Update&#60;/b&#62; method is the code that removes a bullet from the list of all active bullets if it leaves the screen or is marked as &#60;i&#62;dead&#60;/i&#62;.&#60;br&#62;&#60;br&#62;The &#60;b&#62;Render&#60;/b&#62; method uses the &#60;b&#62;TGameElement.Tween&#60;/b&#62; function to properly calculate the tweened coordinates where the bullet is to be drawn.&#60;br&#62;&#60;br&#62;The functions &#60;b&#62;UpdateAllBullets&#60;/b&#62; and &#60;b&#62;RenderAllBullets&#60;/b&#62; are declared as Functions so that they can be called from everywhere (for example in the main loop of our &#60;b&#62;ComeGetMe.bmx&#60;/b&#62; as we will see later.&#60;br&#62;&#60;br&#62;Not very complicated at all, right?&#60;br&#62;&#60;br&#62;So let&#39;s proceed with the enemies.</description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds203</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds203</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
<item>
  <title>Enemies are eeeeevil!</title>
  <description>Of course they are - this is a computer game &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Code wise enemies are not very different from bullets. Strange isn&#39;t it?&#60;br&#62;&#60;br&#62;Let&#39;s get on with it.&#60;br&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;Import &#34;TGameElement.bmx&#34;&#60;br&#62;Import &#34;TCoordinate.bmx&#34;&#60;br&#62;Import &#34;TBullet.bmx&#34;&#60;br&#62;&#60;br&#62;Incbin &#34;gfx/soldier.png&#34;&#60;br&#62;&#60;br&#62;Type TEnemy Extends TGameElement&#60;br&#62;    Global enemyImg:TImage&#60;br&#62;    Global allEnemies:TList = New TList&#60;br&#62;    Global defaultspeed:Float = 1.0 &#39; with a logical framerate of 100 and a speed of 1.0 our enemies move 100 pixel per second&#60;br&#62;    Global frameChange:Int = 20 &#39; with a logical framerate of 100 we change the animation frame every fifth of a second&#60;br&#62;    Global frameCount:Int = 0&#60;br&#62;    Global frameInc:Int = 1&#60;br&#62;    &#60;br&#62;    Field dir:TCoordinate&#60;br&#62;    Field speed:Float&#60;br&#62;    Field frame:Int = 0 &#39; first frame of animated image that we show&#60;br&#62;&#60;br&#62;&#60;br&#62;    Function Create:TEnemy(pos:TCoordinate, direction:TCoordinate, speed:Float)&#60;br&#62;        Local enemy:TEnemy = New TEnemy&#60;br&#62;        enemy.pos = TCoordinate.Copy(pos)&#60;br&#62;        enemy.oldPos = TCoordinate.Copy(pos)&#60;br&#62;        If enemyImg = Null&#60;br&#62;            enemyImg = LoadAnimImage(&#34;incbin::gfx/soldier.png&#34;, 40, 40, 0, 3)&#60;br&#62;        End If&#60;br&#62;        enemy.angle = direction.angle&#60;br&#62;        enemy.dir = direction&#60;br&#62;        enemy.speed = speed&#60;br&#62;        allEnemies.AddLast(enemy)&#60;br&#62;        Return enemy&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;    &#60;br&#62;    Method Update(fixedRate:Float)&#60;br&#62;        &#39; move in direction dir with given enemy speed&#60;br&#62;        Self.oldPos.SetLike(Self.pos) &#39; store current pos in oldPos&#60;br&#62;        Self.pos.x:+(Self.dir.x * Self.speed)&#60;br&#62;        Self.pos.y:+(Self.dir.y * Self.speed)&#60;br&#62;        Self.frameCount:+1&#60;br&#62;        If Self.frameCount &#62; Self.frameChange&#60;br&#62;            Self.frameCount = 0&#60;br&#62;            Self.frame:+Self.frameInc&#60;br&#62;            If Self.frame &#62; 2&#60;br&#62;                Self.frame = 0&#60;br&#62;                Self.frameInc = -Self.frameInc&#60;br&#62;            End If&#60;br&#62;            If Self.frame &#60; 0&#60;br&#62;                Self.frame = 2&#60;br&#62;                Self.frameInc = -Self.frameInc&#60;br&#62;            End If&#60;br&#62;        End If&#60;br&#62;&#60;br&#62;        &#39; check for collisions with bullets&#60;br&#62;        For Local bullet:TBullet = EachIn TBullet.allBullets&#60;br&#62;            If ImagesCollide(Self.enemyImg, Self.pos.x, Self.pos.y, Self.frame, bullet.bulletImg, bullet.pos.x, bullet.pos.y, 0)&#60;br&#62;                Self.dead = True&#60;br&#62;                bullet.dead = True&#60;br&#62;            End If&#60;br&#62;        Next&#60;br&#62;        &#60;br&#62;        If (Self.pos.x &#60; 0 Or Self.pos.y &#60; 0 Or Self.pos.x &#62; GraphicsWidth() Or Self.pos.y &#62; GraphicsHeight() Or Self.dead)&#60;br&#62;            &#39; delete this enemy&#60;br&#62;            allEnemies.Remove(Self)&#60;br&#62;        End If&#60;br&#62;        &#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Render(tween:Float)&#60;br&#62;        SetRotation(Self.angle)&#60;br&#62;        &#39; calculate proper tween position here&#60;br&#62;        SetColor(255, 255, 255)&#60;br&#62;        DrawImage(enemyImg, TGameElement.Tween(oldpos.x, pos.x, tween), TGameElement.Tween(oldpos.y, pos.y, tween), Self.frame)&#60;br&#62;        SetRotation(0)&#60;br&#62;        SetColor(255, 255, 255)&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Function UpdateAllEnemies(fixedRate:Float, playerPos:TCoordinate)&#60;br&#62;        If allEnemies.Count() = 0&#60;br&#62;            Local randomvalue = Rand(0, 100)&#60;br&#62;            If randomvalue &#62; 95&#60;br&#62;                Local borderPos:TCoordinate = GetRandomBorderPos()&#60;br&#62;                Local dirToPlayer:TCoordinate = borderPos.GetDirection(playerPos)&#60;br&#62;                TEnemy.Create(borderPos, dirToPlayer, defaultspeed)&#60;br&#62;            End If&#60;br&#62;        End If&#60;br&#62;&#60;br&#62;        For Local enemy:TEnemy = EachIn allEnemies&#60;br&#62;            enemy.Update(fixedRate)&#60;br&#62;        Next&#60;br&#62;    End Function&#60;br&#62;    &#60;br&#62;    Function GetRandomBorderPos:TCoordinate()&#60;br&#62;        Local border:Int = Rand(1, 4)&#60;br&#62;        Local pos:TCoordinate, xp:Int, yy:Int&#60;br&#62;        &#60;br&#62;        Select border&#60;br&#62;            Case 1 &#39;from the top&#60;br&#62;                yp = 0&#60;br&#62;                xp = Rand(0, GraphicsWidth() - 40)&#60;br&#62;            Case 2 &#39;from below&#60;br&#62;                yp = GraphicsHeight()&#60;br&#62;                xp = Rand(0, GraphicsWidth() - 40)&#60;br&#62;            Case 3 &#39; from the left&#60;br&#62;                xp = 0&#60;br&#62;                yp = Rand(0, GraphicsHeight() - 40)&#60;br&#62;            Case 4 &#39; from the right&#60;br&#62;                xp = GraphicsWidth()&#60;br&#62;                yp = Rand(0, GraphicsHeight() - 40)&#60;br&#62;        End Select&#60;br&#62;        pos = TCoordinate.Create(xp, yp, 0)&#60;br&#62;        Return pos&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Function RenderAllEnemies(tween:Float)&#60;br&#62;        For Local enemy:TEnemy = EachIn allEnemies&#60;br&#62;            enemy.Render(tween)&#60;br&#62;        Next&#60;br&#62;        &#39; DrawText &#34;Nr of enemies &#34; + allEnemies.Count(), 10, 430&#60;br&#62;    End Function&#60;br&#62;        &#60;br&#62;End Type&#60;br&#62;%CODE_END%&#60;br&#62;&#60;br&#62;Because of inheritance and usage we import the obvious files. &#60;b&#62;TBullet.bmx&#60;/b&#62; is imported because we want to check for collisions later on so we&#39;d better know about bullets.&#60;br&#62;Similar to the &#60;b&#62;TBullet&#60;/b&#62;s we have some globals for the enemy image, the default speed and the list of all enemies on screen.&#60;br&#62;Additionally we need some globals because the enemy is an animated one and we need to store information about the number of animation frames and the step amount we&#39;ll use to find the next frame image.&#60;br&#62;Of course each instance of &#60;b&#62;TEnemy&#60;/b&#62; needs to have it&#39;s own direction, speed and the current frame that is displayed so those are fields of the type.&#60;br&#62;&#60;br&#62;Let&#39;s have a look at the functions and methods:&#60;br&#62;&#60;ul&#62;&#60;li&#62; &#60;b&#62;Create:TEnemy(pos:TCoordinate, direction:TCoordinate, speed:Float)&#60;/b&#62; Nothing special here; allocating and initializing a new &#60;b&#62;TEnemy&#60;/b&#62; instance and adding it to the global list of all enemies (&#60;b&#62;allEnemies&#60;/b&#62;)&#60;/li&#62;&#60;li&#62; &#60;b&#62;Update(fixedRate:Float)&#60;/b&#62; Here we move the enemy instance based on it&#39;s speed. Then we check if the next animation frame needs to be shown. We traverse the animation array back and forth to get a proper animation sequence. Afterwards we check for collisions with bullets. To do so we get the list of all bullets and check each bullet against the current frame of our enemy using the BlitzMax builtin function &#60;b&#62;ImagesCollide()&#60;/b&#62;. If we have a collision we mark the enemy and the bullet as dead so that they will be removed in their &#60;b&#62;Update&#60;/b&#62; methods. Finally we check if the enemy left the screen or was marked as dead. If that&#39;s the case we remove it from the global list.&#60;/li&#62;&#60;li&#62; &#60;b&#62;Render(tween:Float)&#60;/b&#62; As usual: setting proper rotation of the enemy image, calculating tweened position and drawing of the current animation frame of the enemy instance. Easy going.&#60;/li&#62;&#60;li&#62; &#60;b&#62;UpdateAllEnemies(fixedRate:Float, playerPos:TCoordinate)&#60;/b&#62; The convenience function not only traverses the global list and calls &#60;b&#62;Update()&#60;/b&#62; for each enemy, it also generates a new enemy if the list of enemies is empty.&#60;/li&#62;&#60;li&#62; &#60;b&#62;GetRandomBorderPos:TCoordinate()&#60;/b&#62; This is the function that helps to find a random start position for a new enemy. First a random value between 1 and 4 is created to decide on which border of the screen the enemy shall appear. Then we randomly generate the second missing coordinate value to decide where on the selected border the enemy should appear. The randomly generated coordinate is returned.&#60;/li&#62;&#60;li&#62; &#60;b&#62;RenderAllEnemies(tween:Float)&#60;/b&#62; Call &#60;b&#62;Render()&#60;/b&#62; for all enemy instances to have them drawn.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;So even if the &#60;b&#62;TEnemy&#60;/b&#62; is the biggest type currently it&#39;s not too complicated.&#60;br&#62;&#60;br&#62;Let&#39;s have a look at the modified &#60;b&#62;TPlayer&#60;/b&#62; where we teach the player to shoot.</description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds204</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds204</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
<item>
  <title>Shoot &#39;em up!</title>
  <description>Let&#39;s start with the complete &#60;b&#62;TPlayer.bmx&#60;/b&#62; file:&#60;br&#62;&#60;br&#62;%CODE_BEGIN%&#60;br&#62;rem&#60;br&#62;    bbdoc: Type description&#60;br&#62;end rem&#60;br&#62;&#60;br&#62;Import &#34;TGameElement.bmx&#34;&#60;br&#62;Import &#34;TCoordinate.bmx&#34;&#60;br&#62;Import &#34;TBullet.bmx&#34;&#60;br&#62;&#60;br&#62;Incbin &#34;gfx/turret.png&#34;&#60;br&#62;&#60;br&#62;Type TPlayer Extends TGameElement&#60;br&#62;    Global playerImg:TImage&#60;br&#62;    &#60;br&#62;    Field dir:TCoordinate&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Function Create:TPlayer(pos:TCoordinate)&#60;br&#62;        Local player:TPlayer = New TPlayer&#60;br&#62;        player.pos = pos&#60;br&#62;        player.oldPos = TCoordinate.Copy(pos)&#60;br&#62;        If playerImg = Null&#60;br&#62;            playerImg = LoadImage(&#34;incbin::gfx/turret.png&#34;)&#60;br&#62;        End If&#60;br&#62;        Return player&#60;br&#62;    End Function&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Update(fixedRate:Float)&#60;br&#62;        Local mousePos:TCoordinate&#60;br&#62;        mousePos = TCoordinate.Create(MouseX(), MouseY(), 0)&#60;br&#62;        &#39; let&#39;s rotate to always look at the mouse&#60;br&#62;        Self.oldAngle = Self.angle&#60;br&#62;        Self.angle = pos.getAngle(mousePos)&#60;br&#62;        Self.dir = Self.pos.GetDirection(mousePos)&#60;br&#62;        If MouseHit(1)&#60;br&#62;            &#39;create a bullet&#60;br&#62;            TBullet.Create(Self.pos, TCoordinate.Copy(self.dir), TBullet.defaultspeed)&#60;br&#62;        End If&#60;br&#62;    End Method&#60;br&#62;&#60;br&#62;        &#60;br&#62;    Method Render(tween:Float)&#60;br&#62;        SetRotation(self.angle)&#60;br&#62;        DrawImage(playerImg, pos.x, pos.y)&#60;br&#62;        SetRotation(0)&#60;br&#62;        rem&#60;br&#62;        If dir &#60;&#62; Null&#60;br&#62;            DrawText (&#34;angle: &#34; + dir.angle, 0, 100)&#60;br&#62;            DrawText (&#34;x dir: &#34; + dir.x, 0, 120)&#60;br&#62;            DrawText (&#34;y dir: &#34; + dir.y, 0, 140)&#60;br&#62;        EndIf&#60;br&#62;        end rem&#60;br&#62;    End Method&#60;br&#62;End Type&#60;br&#62;%CODE_END% &#60;br&#62;What&#39;s new now?&#60;br&#62;The &#60;b&#62;Import&#60;/b&#62; of &#60;b&#62;TBullet.bmx&#60;/b&#62; is required because the player needs to know about bullets if he is ever going to shoot, right? No bullets, no shooting. Yo mama.&#60;br&#62;&#60;br&#62;A field named &#60;b&#62;dir&#60;/b&#62; is also new. It will be used to calculate the direction from the player&#39;s position to the mouse cursor position. Because that is not only the direction we&#39;re looking at but also the direction we want to shoot. And that&#39;s what the &#60;b&#62;Create&#60;/b&#62; method of the bullet needs!&#60;br&#62;&#60;br&#62;The &#60;b&#62;Update()&#60;/b&#62; method is changed of course. We&#39;re constantly tracking the current mouse position and storing it in some &#60;b&#62;TCoordinate&#60;/b&#62; instance named &#60;b&#62;mousePos&#60;/b&#62;. If the left mouse button is pressed we create a new &#60;b&#62;TBullet&#60;/b&#62; instance that moves into the direction from the player to the mouse cursor.&#60;br&#62;&#60;br&#62;The &#60;b&#62;Render()&#60;/b&#62; method didn&#39;t change at all except the new lines of code between the lines &#60;b&#62;rem&#60;/b&#62; and &#60;b&#62;end rem&#60;/b&#62;. Those were only included for debugging to keep track of the changing direction that&#39;s following the mouse cursor. You can safely ignore and delete those lines, including the &#60;b&#62;rem&#60;/b&#62; and &#60;b&#62;end rem&#60;/b&#62; lines.&#60;br&#62;&#60;br&#62;Done with the player. There&#39;s only one thing left, the updated &#60;b&#62;ComeGetMe.bmx&#60;/b&#62; that glues everything together. Let&#39;s finish it.&#60;br&#62;&#60;b&#62; TO BE CONTINUED WHEN I&#39;M AWAKE AGAIN &#60;/b&#62; &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;</description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds205</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds205</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
<item>
  <title>All together now!</title>
  <description>&#60;b&#62;ComeGetMe.bmx&#60;/b&#62; contains a few changes to let everything work together: the player, the enemies and the bullets.&#60;br&#62;&#60;br&#62;Again, let&#39;s first look at the complete source code:&#60;br&#62;%CODE_BEGIN%&#60;br&#62;SuperStrict&#60;br&#62;&#60;br&#62;Import &#34;TFRLTimer.bmx&#34;&#60;br&#62;Import &#34;TPlayer.bmx&#34;&#60;br&#62;Import &#34;TBullet.bmx&#34;&#60;br&#62;Import &#34;TEnemy.bmx&#34;&#60;br&#62;&#60;br&#62;AppTitle = &#34;BlitzMax Top down shooter tutorial&#34;&#60;br&#62;&#60;br&#62;Const GFX_WIDTH:Int = 640, GFX_HEIGHT:Int = 480&#60;br&#62;&#60;br&#62;Const UPDATE_FREQUENCY:Float = 100.0, SPIKE_SUPPRESSION:Int = 20&#60;br&#62;&#60;br&#62;Global gameTime:TFRLTimer = New TFRLTimer.CreateFRL(UPDATE_FREQUENCY, SPIKE_SUPPRESSION)        &#39;1st number is logic updates per second and 2nd number is how much spike suppression you want&#60;br&#62;&#60;br&#62;Global player:TPlayer = TPlayer.Create(TCoordinate.Create(GFX_WIDTH / 2, GFX_HEIGHT / 2, 0))&#60;br&#62;&#60;br&#62;&#60;br&#62;Graphics GFX_WIDTH, GFX_HEIGHT, 0&#60;br&#62;&#60;br&#62;SetBlend ALPHABLEND&#60;br&#62;&#60;br&#62;AutoMidHandle(True)&#60;br&#62;&#60;br&#62;SeedRnd MilliSecs()&#60;br&#62;&#60;br&#62;&#60;br&#62;SetClsColor(200, 100, 100)&#60;br&#62;&#60;br&#62;&#39; the main loop starts here&#60;br&#62;While Not KeyDown(KEY_ESCAPE) And AppTerminate() = False&#60;br&#62;    Cls&#60;br&#62;    &#60;br&#62;&#60;br&#62;    &#39; update part of the main loop with constant speed&#60;br&#62;    Local delta:Float = gameTime.ProcessTime()&#60;br&#62;    While gameTime.LogicUpdateRequired()&#60;br&#62;        DoGameLogic(gameTime.GetLogicFPS())             &#39;Update Game Logic Here&#60;br&#62;    Wend&#60;br&#62;    &#60;br&#62;    &#39; rendering with additional tweening    &#60;br&#62;    Local tween:Float = gameTime.GetTween()         &#39;calc the tween for smooth graphics&#60;br&#62;    doGameRender(tween)                             &#39;Render Game Here&#60;br&#62;    &#60;br&#62;    Flip 0                                          &#39; synchronize graphics buffer as soon as possible&#60;br&#62;Wend&#60;br&#62;EndGraphics&#60;br&#62;End&#60;br&#62;&#60;br&#62;&#60;br&#62;Function DoGameLogic(fixedRate:Float)&#60;br&#62;    player.Update(fixedRate)&#60;br&#62;    TEnemy.UpdateAllEnemies(fixedRate, player.pos)&#60;br&#62;    TBullet.UpdateAllBullets(fixedRate)&#60;br&#62;End Function&#60;br&#62;&#60;br&#62;Function DoGameRender(tween:Float)&#60;br&#62;    player.Render(tween)&#60;br&#62;    TEnemy.RenderAllEnemies(tween)&#60;br&#62;    TBullet.RenderAllBullets(tween)&#60;br&#62;    gameTime.ShowFPS(0, 0)&#60;br&#62;End Function&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;Of course we need to update our list of &#60;b&#62;Import&#60;/b&#62;s, we add &#60;b&#62;TBullet.bmx&#60;/b&#62; and &#60;b&#62;TEnemy.bmx&#60;/b&#62;.&#60;br&#62;&#60;br&#62;The &#60;b&#62;AppTitle&#60;/b&#62; is a global variable that is used at some places internally by BlitzMax and allows us to set the name of our game into the title bar of the game&#39;s window. Cool!&#60;br&#62;%CODE_BEGIN% &#60;br&#62;AppTitle = &#34;BlitzMax Top down shooter tutorial&#34;&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;Another line is important for games:&#60;br&#62;%CODE_BEGIN% &#60;br&#62;SeedRnd MilliSecs()&#60;br&#62;%CODE_END% &#60;br&#62;The random numbers that a BlitzMax application (and any other application too) is based on a very long sequence of random values. Whenever you call &#60;b&#62;rnd()&#60;/b&#62; it returns the next value of this sequence.&#60;br&#62;The command &#60;b&#62;SeedRnd&#60;/b&#62; allows you to initialize the start position of this sequence with any value. A good one is the current time in milliseconds (&#60;b&#62;MilliSecs()&#60;/b&#62;) as it is different whenever you start the game. This makes it look like the game really behaves &#60;i&#62;randomly&#60;/i&#62;.&#60;br&#62;&#60;br&#62;The new line&#60;br&#62;%CODE_BEGIN% &#60;br&#62;SetClsColor(200, 100, 100)&#60;br&#62;%CODE_END% &#60;br&#62;is another builtin function of BlitzMax and tells BlitzMax what color to use whenever you call &#60;b&#62;Cls&#60;/b&#62; to clear (and fill) the screen. The default color is black (0,0,0) and we set it to some terrible orange/pink/whatever color to see the enemies better. Change this to a value you can bear &#60;img src=&#34;../_frame/icon_lol.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;The last code change is in these two functions:&#60;br&#62;%CODE_BEGIN% &#60;br&#62;Function DoGameLogic(fixedRate:Float)&#60;br&#62;    player.Update(fixedRate)&#60;br&#62;    TEnemy.UpdateAllEnemies(fixedRate, player.pos)&#60;br&#62;    TBullet.UpdateAllBullets(fixedRate)&#60;br&#62;End Function&#60;br&#62;&#60;br&#62;Function DoGameRender(tween:Float)&#60;br&#62;    player.Render(tween)&#60;br&#62;    TEnemy.RenderAllEnemies(tween)&#60;br&#62;    TBullet.RenderAllBullets(tween)&#60;br&#62;    gameTime.ShowFPS(0, 0)&#60;br&#62;End Function&#60;br&#62;%CODE_END% &#60;br&#62;&#60;br&#62;In &#60;b&#62;DoGameLogic()&#60;/b&#62; we added the functions to update all enemies and all bullets and in &#60;b&#62;DoGameRender()&#60;/b&#62; we added the similar stuff to render all enemies and all bullets.&#60;br&#62;&#60;br&#62;And that&#39;s about it.&#60;br&#62;&#60;br&#62;What is still missing?&#60;br&#62;&#60;ul&#62;&#60;li&#62; Sound. Whenever the player fires a bullet we want to hear a sound. Also some explosion or hit sound would be nice when a bullet hits an enemy.&#60;/li&#62;&#60;li&#62; Some scoring would be nice and some code to deal with something like levels where the number of approaching enemies increases, the enemies become faster and so on.&#60;/li&#62;&#60;li&#62; A game over functionality to restart the game when the player is hit by an enemy and to show the current high score for example.&#60;/li&#62;&#60;/ul&#62;&#60;br&#62;This will come next.&#60;br&#62;&#60;br&#62;But for now you can download the second part of the tutorial with all sources and graphics we&#39;ve used so far.</description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds206</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds206</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
<item>
  <title>Enjoy the silence!</title>
  <description>Or not &#60;img src=&#34;../_frame/icon_wink.gif&#34; border=&#34;0&#34;&#62;&#60;br&#62;&#60;br&#62;Let&#39;s add some sound effects to the game.&#60;br&#62;&#60;br&#62;&#60;b&#62;TO BE CONTINUED WHEN TIME ALLOWS AGAIN!&#60;/b&#62;</description>
  <link>http://www.rightanglegames.com/tdstutorialpart2/index.html#tds207</link>
  <guid isPermaLink="true">http://www.rightanglegames.com/tdstutorialpart2/index.html#tds207</guid>
  <category>Top down shooter tutorial with BlitzMax, part 2</category>
</item>
</channel>
</rss>