<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>We Create Games</title>
	<atom:link href="http://wecreategames.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://wecreategames.com/blog</link>
	<description>Serious games and projects for students and teachers</description>
	<lastBuildDate>Fri, 05 Feb 2010 04:41:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Building applications for Tysons Corner</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=280#comments</comments>
		<pubDate>Thu, 04 Feb 2010 20:30:17 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Maps]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[city]]></category>
		<category><![CDATA[droid]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mall]]></category>
		<category><![CDATA[tysons corner]]></category>
		<category><![CDATA[virginia]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=280</guid>
		<description><![CDATA[I&#8217;ve been asked to build a mobile strategy and prototype for the Tysons Corner area of Northern Virginia.  One of the problems is that Tysons is (combined between Tysons I and Tysons II) one of the two largest malls in the country.  Surrounding it is the intersection of four major roads, along with dozens of [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />I&#8217;ve been asked to build a mobile strategy and prototype for the Tysons Corner area of Northern Virginia.  One of the problems is that Tysons is (combined between <a href="http://www.shoptysons.com/">Tysons I and Tysons II</a>) one of the two largest malls in the country.  Surrounding it is the intersection of four major roads, along with dozens of the top companies in the world.  Traffic is killer, and one wrong turn adds up to an hour to your transit. <a href="http://en.wikipedia.org/wiki/Silver_Line_%28Washington_Metro%29"> Four new Metro stops on the Silver Line</a> are being installed here, and the construction is further holding up traffic.</p>
<p><img class="alignnone" src="http://upload.wikimedia.org/wikipedia/en/b/b0/Dulles_Metrorail_logo.png" alt="" width="250" height="93" /></p>
<p>The thinking is that a better way to get information to users would be to build one or more information services that will assist &#8211; either iPhone/Droid apps, or tailored web sites.  If you could have any piece of conceivable information, what would be most useful?</p>
<p><img class="alignnone" title="USA Today HQ" src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/USA_Today_building.jpg/180px-USA_Today_building.jpg" alt="" width="180" height="106" /></p>
<p>This would include both the Mall as well as the surrounding area and all of the new Metro stops.  We&#8217;ll be building a proposal and prototype to help out the local government.  What do you think we should have in/on it?</p>
<p><strong>For the Mall: </strong></p>
<ol>
<li>Map of parking area with updates on available parking spots.</li>
<li> Means to mark your spot on the map and some way to trace your route back to your car.</li>
<li> Layout of mall.  You are here identification.</li>
<li> Recommendations for non-busy times.</li>
<li> Senior specials.  Maybe special area for Seniors:  exercise suggestions; food suggestion; matinee movie suggestions;</li>
<li> Movie listings.</li>
<li> Special sales or activities in mall stores.  Coupons would be good.  A way to hold your iPhone to a store scanner for them to read your coupon.  Maybe a way to have your name and phone number on your phone be scanned in by stores or sales people for drawings like for a new car or whatever.</li>
<li> Holiday or special activities or presentations.</li>
<li> Food Court identification and other eating facilities.  Ratings on cleanliness.  &#8220;Eat This Not That&#8221; recommendations (maybe tie-in to app for that.)  Vegan or Vegetarian suggestions.</li>
<li> Restaurant reservation system.</li>
<li> Restroom locations.  Elevator or handicap identification.</li>
<li> Mall-walker distance and route suggestions for exercise purposes.</li>
<li> Search capability for items for sale with stores that have availability.  For instance &#8220;shoes&#8221; or &#8220;fondue pot&#8221;</li>
<li> Feedback capability to make suggestions to mall managers and/or stores.</li>
</ol>
<p><strong>For Tysons:</strong></p>
<ol>
<li> Traffic patterns and route planning</li>
<li> Augmented Reality of bus stops, traffic directions, points of interest</li>
<li> Metro delays</li>
<li> Metro and construction status, dollars spent, current plans, expected benefits</li>
<li> Events in the area</li>
<li> Highlight businesses to sponsor key companies in the area that are supporting</li>
<li> Coupons or store bonuses for reporting suggestions or road improvements (light out, pot hole, graffiti, car accident, etc)</li>
<li> Carpooling recommendations</li>
</ol>
<p>I&#8217;d love more requirements or prioritization of what would be best to build!  What would you find useful in the most congested/largest Mall area of the country?<br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?page_id=2'>About Jay</a></li>
<li><a href='http://wecreategames.com/blog/?page_id=77'>Crossler.com</a></li>
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?page_id=100'>Fictional Writing</a></li>
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=219'>HTML5 Databases + Canvas</a></li>
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
<li><a href='http://wecreategames.com/blog/?p=188'>iPhone Geotags</a></li>
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
<li><a href='http://wecreategames.com/blog/?p=203'>Updated FlickrProxy</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=280</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Chumby Advanced Tricks</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=259#comments</comments>
		<pubDate>Fri, 29 Jan 2010 16:37:00 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Home Automation]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Pugs]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[cameras]]></category>
		<category><![CDATA[chumby]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dogs]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[puppe]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=259</guid>
		<description><![CDATA[(check out the above Chumby tiger cover here)

(built on previous Chumby iRemote post here)
Overview
This past month, I extended the web server on my older-style Chumby to add a lot of functionality to my house.  For a while, I’ve wanted to automate a number of my home systems &#8211; X10 to control our home lights [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />(check out the above <a href="http://www.bunniestudios.com/blog/?p=253">Chumby tiger cover here</a>)</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/4_jWLNjp0I0&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/4_jWLNjp0I0&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>(built on previous <a href="http://wecreategames.com/blog/?p=181">Chumby iRemote post here</a>)</p>
<p><strong>Overview</strong><br />
This past month, I extended <a href="http://wecreategames.com/blog/?p=181">the web server</a> on my older-style <a href="http://www.chumby.com">Chumby</a> to add a lot of functionality to my house.  For a while, I’ve wanted to automate a number of my home systems &#8211; X10 to control our home lights (specifically the Living Room lights), the Chumby to play music with, and web cameras to watch our dogs during the day.  As the new Chumby just came out, I thought it would be useful to build all of the control into the Chumby device, so that others could also try the same thing.</p>
<p>I also build a feedback system that would try to monitor the amount of times our dogs jumped and barked at cars, then change music and turn on/off lights to find the combination that calmed them the most.  Unfortunately, I found that there is no magic configuration – rather the dogs seem to relax whenever the lights and music change (possibly because they feel that someone is home).  Either way, it was a cool experiment that I learned a lot from.  It is a bit “fragile”, meaning that there’s a good amount of custom configuration that you would need to use to reuse everything.  Nonetheless,<a href="http://wecreategames.com/apps/chumbrain/ChumbyBrainCode.zip"> I’m posting all code and configuration samples</a> here in case people want to set parts up themselves.  The X10 webpage, for example, is pretty useful even if it is the only piece loaded.</p>
<p><img class="size-full wp-image-265 alignnone" title="ch_brain1" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_brain1.png" alt="ch_brain1" width="390" height="468" /> <img class="alignnone size-full wp-image-266" title="ch_brain2" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_brain2.png" alt="ch_brain2" width="373" height="482" /></p>
<p><strong>Details</strong><br />
I call this marvelous contraption the “Puppy Ubiquitous Pacifying Preference Engine” (PUPPE).  If you want to be all research, the Technology Goal was to build an automation engine that optimizes environmental support for dogs left home alone.  The Research question I set to achieve was: Can an automatic feedback engine be used to optimize relaxation for dogs by controlling home automation electronics?  I was partially able to achieve this goal, though in a way I completely didn’t plan for.  Rather than find an optimal configuration, I found that the more I randomly changed the lights and music throughout the day, the more relaxed our dogs seemed to behave.</p>
<p>The tools I used for this were:</p>
<ul>
<li> X10 Wall Light Switch</li>
<li> X10 Application Switch</li>
<li> X10 Home Automation software on Windows XP (old laptop LAP1)
<ul>
<li> X10 Controller software listening on TCP port 6003</li>
</ul>
</li>
<li> Mobiscope Desktop Webcam controller on Windows XP (old laptop LAP2)
<ul>
<li> copSSH &#8211; ssh server for secure remote connections</li>
<li> ipsecCmd and IP Security Policies to filter IP traffic</li>
</ul>
</li>
<li> Two cheap USB webcams</li>
<li> Mobiscope web site for hosting video</li>
<li>Weather Web Service for determining sunset time</li>
<li> Chumby running ChumbyOS Linux (CHUMBY3)</li>
</ul>
<p><strong>Client devices:<br />
</strong></p>
<ul>
<li>User Laptops (LAP4 and LAP5)</li>
<li> iPhones (PHONE6 and PHONE7)</li>
</ul>
<p>There were a number of moving pieces to this configuration, and each piece took a while to determine the best approach to implement.  I’ll describe the solutions and tricks I came up with below.  Many people probably won’t have two extra laptops laying around, so the configuration will likely change depending on circumstance.  I spent a good portion of overall effort intentionally trying out different approaches and security option, so there are many other ways of having the same effect. The X10 Commander interface is shown below:</p>
<p style="text-align: center;"><img class="size-full wp-image-272 aligncenter" title="ch_x10cmdr" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_x10cmdr.png" alt="ch_x10cmdr" width="614" height="439" /></p>
<p><strong>Technical Architecture</strong></p>
<p style="text-align: center;"><img class="size-large wp-image-263 aligncenter" title="ch_arch" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_arch-1024x762.png" alt="ch_arch" width="500" height="372" /></p>
<p>The picture above shows the logical architecture I came up with.  All the software actually ran on the Chumby (except the Mobiscope viewing page that is hosted on that company’s web server).   I firmly believe that as systems become more complex (some people call this a Service Oriented Architecture – which I’ve studied in depth, but don’t want to go into here), it’s important to build very simple interfaces.  I implemented three main types of API service interfaces, each very simple to work with.  I call these “ramps” or “loose couplers.”</p>
<p><strong>Loose Couplers:</strong><br />
<strong><em>HTTP GET-based web service. </em></strong> In the simplest configuration, a web service is a web page that a machine returns when it receives a certain input.  The Chumby has a CGI-based web server that can be used to run simple sh shell scripts. We pass in variables through an HTTP querystring (the part following a ? in a URL).  This way, when an event.cgi?setVolume0 is called, the cgi file shell command executes a command to mute the radio.  We use x10.cgi to listen for light-switch control messages, event.cgi for Chumby-specific events, and cameras.cgi for commands to control the web cameras.</p>
<p>The Chumby also can act as a hosting web server, using an index.cgi page that points to all of the other commands.  The interface looks like this:</p>
<p style="text-align: center;"><img class="size-full wp-image-265 aligncenter" title="ch_brain1" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_brain1.png" alt="ch_brain1" width="390" height="468" /></p>
<p>And the hosting code looks like (the launch javascript is declared in the full file, see attached code):</p>
<p style="text-align: center;"><img class="size-full wp-image-264 aligncenter" title="ch_brain_code" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_brain_code.png" alt="ch_brain_code" width="524" height="385" /></p>
<p><em><strong>SSH-based camera control service.</strong></em> Secure Shell or SSH is a network protocol that allows data to be exchanged using a secure channel between two networked devices (as described in RFC 4252).  Most linux or unix-based machines (including the Chumby) have an ssh client or an ssh server built in.  As we want to control services on an Windows XP machine, we needed to add an ssh server, so I chose copSSH after testing multiple other options.  By using IP Security policies, we can add a firewall filtering policy to the machine from the command line with a batch file (Cam-Block.bat) that runs `ipseccmd –w REG –p “BlockMobiscope” –x`, where BlockMobiscope is a windows IP filtering policy as shown below:</p>
<p style="text-align: center;"><img class="size-full wp-image-268 aligncenter" title="ch_ipsec" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_ipsec.png" alt="ch_ipsec" width="589" height="421" /></p>
<p>To make remote triggering as simple as possible, we want to enable PKI key exchange on both machines. This allows a single shell command `ssh UserName@192.168.2.3 &#8216;./Cam-Block.bat&#8217;` run on the Chumby to securely turn on or off traffic from USB cameras being sent to the Mobiscope web server.  The home router is configured to always map 192.168.2.3 to the camera server (LAP2), which saves a lot of effort when machines don’t properly identify their hostnames.</p>
<p>One of the most painful steps is setting up the SSH server to run without entering a password at every instance.  Building this PKI key-exchange process uses ssh-keygen command to generate a client and server key.  Because the Chumby does not have ssh-keygen installed, we need to build the ssh keys on another machine and remotely configure both the chumby and LAP2 server with these keys.  Once we do this, we can be reasonable assured that only the Chumby can interact with the XP laptop (LAP2).  Because this machine controls transferring video from our USB cameras out to the web, we want the most amount of security around this interface.</p>
<p><em><strong>TCP-based network injection service. </strong></em>By using the X10 Active Home software with the X10 Commander program, iPhones can send TCP messages to a laptop to turn X10 devices on and off.  Rather than using the iPhone client, we can spoof TCP messages to emulate the same commands that the client would send.  By using WireShark, I found that the TCP commands are simple messages sent on port 6003:</p>
<p style="text-align: center;"><img class="size-full wp-image-271 aligncenter" title="ch_wireshark" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_wireshark.png" alt="ch_wireshark" width="612" height="87" /></p>
<p>Using NetCat ‘nc’ &#8211; (<strong><em>my new favorite linux command!</em></strong>), these messages can easily be replicated using the shell command: echo &#8216;DEVICE~sendplc~&#8221;C4 ON&#8221;&#8216; | nc 192.168.2.4 6003 (this is to the LAP1 Home Server).  This is not very secure, but is based on inherent security limitations of the X10 Commander software.  Given time, I might rewrite a more secure X10 controller.  As only the lights are controlled from this server, I found that was a worthwhile privacy tradeoff.<br />
<strong>Experimentation</strong></p>
<p>Dog owners frequently ask “What are my dogs doing while I’m at work?”  My wife specifically wanted to watch our dogs while she was at work (and her company blocked the firewall connection).  To give her this capability of watching our dogs that are blocked off in the kitchen each day, I set up a pair of USB cameras on an old laptop and purchased the $20 Mobiscope software that is iPhone compatible.  She is able to watch her dogs anytime she wishes on her iPhone.</p>
<p style="text-align: center;"><img class="size-full wp-image-269 aligncenter" title="ch_mobiscope1" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_mobiscope1.png" alt="ch_mobiscope1" width="502" height="197" /></p>
<p>After observing our dogs for a few days, we noticed that they would become more and more agitated throughout the day, and bark at cars and pedestrians walking outside our window. Some days they were more relaxed, and some days they were more agitated.  Every day we played different radio stations, and surmised that different music at different times would help calm them.  Also, we noticed that with shorter winter days, the sunlight dimming early in the evening seemed to agitate them more. We surmised that if we could modulate lighting conditions along with music, we could help minimize the amount of times they got up to bark out the window.</p>
<p style="text-align: center;"><img class="size-full wp-image-273 aligncenter" title="photo2" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/photo2.jpg" alt="photo2" width="320" height="480" /></p>
<p>The experimentation had two phases.  During the first phase, I used the two USB cameras to record the dogs in time-stopped video (3 frames/sec).  By trying a number of algorithms, I determined that a good way to rate the number of “agitations” was to identify an active area of the camera view and to count the amount of pixel change over a period of a second.  As shown in the picture above, if more than 84% of all pixels in the active area changed in a second (out of a max of 300% as there are 3 frames x 100%), then a recording is triggered and an “agitation” is recorded.  Due to varying lighting conditions, this number was not optimal in every case – and recommendations are not to use the Mobiscope to do this process in the future.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-262" title="ch_agitations_per_hr" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_agitations_per_hr.png" alt="ch_agitations_per_hr" width="401" height="215" /><em><br />
Average # of agitations/hour at time-of-day</em></p>
<p>The # of agitations/hour was then used to build an algorithm to remotely turn on and off lights and to change radio stations in the kitchen.  Unfortunately, there was no reliable way to detect agitations as they occurred.  The Mobiscope web page hosted only cycling images and passed recording #s through javascript.  A few attempts to “Screen scrape” the number of recordings only worked intermittently.  I used a greasemonkey script that would read the data, but had many issues with reliability.  (As a note, I just realized yesterday that each recording of an agitation produced a new data file in a directory – and that directory could be watched for updates to trigger the algorithm.  This would be useful in follow on work).</p>
<p>I worked through 5 algorithms that were all sh shell scripts fed through the web page and greasemonkey script. This proved problematic, as the script never ran concurrently throughout the day.  Greasemonkey just wasn’t robust enough to handle web errors or dropped connections from the Mobiscope server.  As these were working locally inside my home intranet, I didn’t have a reliably secure method to tweak and monitor these while I was out of the house (and whenever I was in the house, the dogs’ behavior would change dramatically).</p>
<p>When the algorithms did work, it became quickly apparent that every change was a “good” one.  Any time there was an agitation, if the radio was changed or a light level was adjusted, the dogs immediately calmed down for a period. It didn’t matter which radio station or which light level was set.  Any change seemed to reduce agitations.  The algorithm I now use just rotates radio stations and light levels randomly, without any inputs.  On average, it seems to have reduced # of agitations by 45% (though I haven’t yet had enough testing to ensure it is statistically accurate or will remain lower).<br />
<strong>Privacy Engine</strong></p>
<p>In order to use the system well, we wanted to add two extra capabilities:<br />
1)	When either my wife or I come home, turn off the web cams and radio, and turn on the kitchen lights<br />
2)	As a backup, turn off any recording at sunset (in case the first doesn’t trigger)</p>
<p>To implement the first capability, we need a way to detect when either of us comes home.  I initially tried using an X10 motion sensor in the door way, but it was quite cheap and would sometimes trigger when there was direct sunlight on it, and frequently not trigger when people walked by too quickly.</p>
<p>I&#8217;ve noticed through watching Wireshark that when an iPhone connects to a wifi network, it sends out a few IGMP/Multicast DNS packets to 224.0.0.251 (local multicast to all machines, as specified in RFC 3171).  By listening for this message, I have the Chumby look for the correct identifiers and send out the “turn cameras off”, “mute radios”, and “turn lights on” commands.</p>
<p style="text-align: center;"><img class="size-full wp-image-267 aligncenter" title="ch_cam_block" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_cam_block.png" alt="ch_cam_block" width="353" height="214" /></p>
<p>I would have liked to detect a method for turning the cameras on when no one was home (as we frequently forgot to do so in the morning), but couldn’t find a reliable method.</p>
<p>To implement the second capability of always turning cameras off at sunset, I had a script that pinged a web service daily and asked for the sunset time of the current locale.  The below script illustrates this method (but condenses some of the logic for readability).</p>
<p style="text-align: center;"><img class="size-full wp-image-270 aligncenter" title="ch_sunset" src="http://wecreategames.com/blog/wp-content/uploads/2010/01/ch_sunset.png" alt="ch_sunset" width="626" height="533" /><em><br />
(Note: That should read &#8220;sunset&#8221; not &#8220;sunrise&#8221; in the web service request above&#8230; otherwise things get a little wonky.)</em></p>
<p><strong>Conclusion</strong></p>
<p>This was a fun project that had a lot of moving pieces.  I built some useful functions that we still use daily.  The light and radio controls are very reusable, and I will be releasing all of the source code for others to do so.  I was able to partially prove out that modifying the environment modifies our dog behavior.  More importantly, I gave my wife tools to feel more attached to her dogs throughout the day (and justify my spending money on technical toys).</p>
<p><a href="http://wecreategames.com/apps/chumbrain/ChumbyBrainCode.zip">The code is here, please download</a> &#8211; released <a href="http://creativecommons.org/licenses/by/3.0/">fully creative commons/open source</a> (BY 3.0 license).<br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
<li><a href='http://wecreategames.com/blog/?page_id=100'>Fictional Writing</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?page_id=2'>About Jay</a></li>
<li><a href='http://wecreategames.com/blog/?page_id=102'>Moon Base One Novel</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
<li><a href='http://wecreategames.com/blog/?p=181'>Chumby iRemote</a></li>
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=219'>HTML5 Databases + Canvas</a></li>
<li><a href='http://wecreategames.com/blog/?p=203'>Updated FlickrProxy</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=259</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>App Store for the Army</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=252#comments</comments>
		<pubDate>Sun, 24 Jan 2010 21:46:16 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Maps]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[app store]]></category>
		<category><![CDATA[army]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=252</guid>
		<description><![CDATA[I’ve been working on putting together an “Army App Store” to give to a few soldiers for testing.  I’ve been trying to think of what apps would be best to install on SmartPhones that would have the most utility to soldiers in the field.  One of the biggest misconceptions that people have is [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />I’ve been working on putting together an “Army App Store” to give to a few soldiers for testing.  I’ve been trying to think of what apps would be best to install on SmartPhones that would have the most utility to soldiers in the field.  One of the biggest misconceptions that people have is that soldiers only go out and fight… the reality is that there are thousands of other important, yet more mundane, support tasks that take up most of the time.</p>
<p>Also, many soldiers are age 18-25… and wind up having a large amount of time on their hands when deployed.  I’ve been thinking that many of the useful apps would help with training, study, first aid, language lessons, and other skill development.  Also, the device should contain public domain books and note-taking software.</p>
<p>Assuming that we could spend $100 per device to download apps, which ones should we use on the devices?  Should apps be preinstalled, or should we load a $100 iTunes app account for each device and let soldiers download what they want (probably dangerous… but could help discover some really good use cases).</p>
<div id="attachment_253" class="wp-caption alignleft" style="width: 510px"><img src="http://wecreategames.com/blog/wp-content/uploads/2010/01/wcg_iphone_army.jpg" alt="The newly released Army iPhone App" title="Army iPhone App" width="500" height="332" class="size-full wp-image-253" /><p class="wp-caption-text">The newly released Army iPhone App</p></div>
<p>Here’s the list that I’ve come up with so far for iPhones. Please post any comments on what I’m missing, or what I should use for Droid or Windows Mobile phones:</p>
<p><strong>Combat Assistance</strong><br />
Sniper ($39.99)<br />
Ballistic ($9.99)<br />
KAC Bullet Flight</p>
<p><strong>Navigation</strong><br />
GPS Sport ($2.99)<br />
Google Earth<br />
Weatherbug<br />
wxHere<br />
Map and Land Navigation Reference </p>
<p><strong>Fitness and Health</strong><br />
Army APFT Calculator<br />
Army Body Fat Percentage Calculator<br />
US Army First Aid Manual<br />
MedVideo First Aid<br />
Hand2Hand (Combat training) </p>
<p><strong>Enterprise Support</strong><br />
Good email client<br />
PerDiem calculator<br />
FedTravel ($0.99)<br />
2Do Lite<br />
Note Taker Lite </p>
<p><strong>Training</strong><br />
The Army App<br />
Army Board Study Guide<br />
Language Translators ($14.99)<br />
Arabic Language trainer ($150)<br />
ASVAB Exam (Study guide)<br />
Armystudyguide.com/mobile<br />
Languages – Arabic, Chinese, Japanese, Korean, Spanish, German, </p>
<p><strong>School and Science</strong><br />
Science Glossary<br />
101 Science<br />
SAT Vocab Challenge<br />
SAT Math prep<br />
Conversation English<br />
iCertify (Cisco routers)<br />
Stanza (book reader)<br />
Shakespeare (books)<br />
23,000 great quotes </p>
<p><strong>Government Knowledge</strong><br />
Military Aircraft Recognition Quiz<br />
Army News (general news)<br />
US Armed Forces (General Knowledge)<br />
Squared Away (general Army Knowledge)<br />
US Military Handbook (general DoD knowledge)<br />
DoDComm (News)<br />
White House<br />
Constitution for iPhone<br />
US Military Handbook ($9.99)<br />
Military Slang – ($0.99) – review<br />
Congress+ ($9.99)<br />
CIA World Countries Factbook ($0.99)<br />
US Armed Forces ($0.99)<br />
The Law Pod ($0.99) </p>
<p><strong>Good Citizenship</strong><br />
Amber Alert<br />
FBI Most Wanted ($1.99) </p>
<p><strong>Air Force</strong><br />
Military Pilot Logbook ($19.99) </p>
<p><strong>Hardware for a kit</strong><br />
Case &#8211; Otterbox<br />
Stylus<br />
Extra Charger</p>
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?page_id=2'>About Jay</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
<li><a href='http://wecreategames.com/blog/?page_id=100'>Fictional Writing</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=219'>HTML5 Databases + Canvas</a></li>
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
<li><a href='http://wecreategames.com/blog/?p=188'>iPhone Geotags</a></li>
<li><a href='http://wecreategames.com/blog/?p=203'>Updated FlickrProxy</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=252</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Orrery Game: ver 2</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=237#comments</comments>
		<pubDate>Sat, 01 Aug 2009 21:23:27 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[FOGE]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Volunteering]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[moon]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[orrery]]></category>
		<category><![CDATA[planets]]></category>
		<category><![CDATA[solarsystem]]></category>
		<category><![CDATA[space]]></category>
		<category><![CDATA[torque]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=237</guid>
		<description><![CDATA[
I&#8217;ve posted an updated version of the Orrery Torquescript library.  Thanks for all of the great feedback.  This new version has a few features:

Fully Object Oriented, so you can add multiple orreries or systems
Renders correct positions of the moon
Has a datetime object to show the current universal epoch (date/time)
Allows for different animation speeds [...]]]></description>
			<content:encoded><![CDATA[<p id="top" /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/dk6gI0tnKac&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/dk6gI0tnKac&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>I&#8217;ve posted an updated version of the Orrery Torquescript library.  Thanks for all of the great feedback.  This new version has a few features:</p>
<ul>
<li>Fully Object Oriented, so you can add multiple orreries or systems</li>
<li>Renders correct positions of the moon</li>
<li>Has a datetime object to show the current universal epoch (date/time)</li>
<li>Allows for different animation speeds and interactions</li>
</ul>
<p>The code is at: <a href="http://wecreategames.com/apps/planets/Orrery.v2.zip">http://wecreategames.com/apps/planets/Orrery.v2.zip</a>.  Feel free to download and play with it (it currently works only with Torque3D).</p>
<p>I&#8217;ve also built a version for Torque Gaming Engine.  It&#8217;s a fully compiled project, so should work on any Mac.  Leave a comment if you&#8217;d like me to build a version to work with PC.  <a href="http://wecreategames.com/apps/planets/Orrery.v2.TGE.MacOSX.zip">It&#8217;s a 100Mb download,</a> but has all the files within.  There are a few extra math functions in this one that weren&#8217;t included in TGE (but were in T3D), so I added them to the Functions_Math.cs.</p>
<p>Getting Torquescript (which is a scripting layer on top of Torque&#8217;s C++ engine to support OO behavior was a bit painful, so I used a few of the concepts from JavaScript to make pseudo-classes.</p>
<p>I&#8217;ve released all the code under Creative Commons BY 3.0 license &#8211; you can use and make money from this, just give me credit, please!<br />
Here are the steps to implement:</p>
<p>//=====================================<br />
1) Create a new mission, named Orrery</p>
<p>//=====================================<br />
2) Add Orrery.mis to Orrery/game/levels/<br />
3) Delete the other missions (simple.mis NewMission.mis) in this directory<br />
4) In Orrery/game/scripts/client/init.cs:<br />
Within this function, change:</p>
<p>function loadDefaultMission()<br />
{<br />
   Canvas.setCursor(&#8221;DefaultCursor&#8221;);<br />
   createServer( &#8220;SinglePlayer&#8221;, &#8220;levels/simple.mis&#8221; );</p>
<p>to:</p>
<p>   createServer( &#8220;SinglePlayer&#8221;, &#8220;levels/Orrery.mis&#8221; );</p>
<p>//=====================================<br />
5) Add PlanetsInit.cs and the Functions*.cs to Orrery/game/scripts/server/<br />
6) Update Orrery/game/scripts/server/scriptExec.cs<br />
add to end of file:</p>
<p>//Supporting functions<br />
exec(&#8221;./Functions_Math.cs&#8221;);<br />
exec(&#8221;./Functions_Time.cs&#8221;);<br />
exec(&#8221;./Functions_Objects.cs&#8221;);<br />
//Initialize planets<br />
exec(&#8221;./PlanetsInit.cs&#8221;);</p>
<p>//=====================================<br />
7) Copy planets.cs to Orrery/game/art/datablocks/<br />
exec(&#8221;./planets.cs&#8221;);<br />
8 ) Update Orrery/game/art/datablocks/datablockExec.cs<br />
add to end of file:<br />
exec(&#8221;./planets.cs&#8221;);</p>
<p>9) Add materials.cs to Orrery/game/art/materials.cs<br />
10) Copy the planets directory to Orrery/game/art/shapes/ (so it&#8217;s Orrery/games/shapes/planets)</p>
<p>//=====================================<br />
11) Copy the sky_night directory to Orrery/game/art/skies<br />
12) Copy the three rocks jpgs (rocks_65.jpg, rocks_dark.jpg, rocks_meddark.jpg) to the Orrery/game/art/terrains/WarriorCamp directory<br />
NOTE: If you open the world and there are big orange patches, go into World Editor, Terrain Painter, then select the &#8220;Warning Material&#8221; and choose Edit.  Navigate to the rocks_65 and rocks_dark textures)</p>
<p>Walking forward, you can step on each of the three rocks to change the animation speed of the Orrery.</p>
<p>If you want to make your own orreries through script:<br />
You need to (1) Create an Orrery, (2) Initialize planets in the correct location, (3) Animate them:</p>
<p><code>//Orrery_Create(%orreryHandler, %name, %center, %radius, %numplanets,<br />
	%spacingmode, %planetarchivefile, %timestep, %planetsizing,<br />
	%show_children_of, %levels_of_children, %animationstep)<br />
Examples:<br />
	Orrery_Create("orrery1");<br />
	orrery1.build_planets();<br />
	orrery1.begin_animation();<br />
	Orrery_Create("orrery2", "Mini System", "-233.581 -60.61 196.786", "5 5 5", 5, 4, "", "hour:2", 0.2, "Sol", 1,500);<br />
	orrery2.build_planets();<br />
	orrery2.begin_animation();</code></p>
<p>If you are editing code, a shortcut is to type &#8220;r&#8221; in the console, which reloads the PlanetsInit.cs.  This way, you don&#8217;t need to quit Torque to make sure code compiles/updates correctly</p>
<p>The Orrery/game/art/shapes/solar_system.cs has all of the planet/moon information in it<br />
- You can copy this and make your own solar system (or update to new information).<br />
- Important fields:<br />
	//For a planet<br />
<code>	new ScriptObject() {<br />
		planetName = "Pluto";  //Name of the planet that's shown, also used for lookups<br />
		planetOrder = 9; // The order of the planet out from the star (used as an estimate, as sometimes planet orbits are elongated and some move within others)<br />
		satelliteOf = "Sol"; // What does this orbit around?<br />
		shapeName = "art/shapes/planets/pluto.dts";  // Which DTS file is used? Materials.cs has to describe the texture as well<br />
		scale_mult = "1 1 1";  // Some planets are squished (especially gas giants, which have a smaller Z axis.  Jupiter's is "1 1 .92" for example)<br />
		orbit_calc_method = "major_planet"; // How should the orbits be calculated?<br />
		dist_from_parent = 5900000000; // Average distance from parent.  Not yet used<br />
		days_sidereal_rot = 90767.11; // How many earth days in a rotation?  Not yet used<br />
		diameter_km = 2302;  // Diameter, Not yet used<br />
		obliquity = 119.61;  //How much tilt?  Not yet used<br />
		 //As of 1 Jan 2000, Julian Date = 2451545<br />
		a_semimajor_axis = 39.48168677;  //6 variables are used to calculate planetary axis<br />
		e_eccentricity = 0.24880766;<br />
		i_inclination = 17.14175;<br />
		O_ecliptic_long = 110.30347;<br />
		w_perihelion = 224.06676;<br />
		L_mean_longitude = 238.92881;<br />
		a_per_cy = -0.00076912; //This is how much does they vary per century<br />
		e_per_cy = 0.00006465;<br />
		i_per_cy = 11.07;<br />
		O_per_cy = -37.33;<br />
		w_per_cy = -132.25;<br />
		L_per_cy = 522747.90;<br />
	//Only the Earth's moon is currently implemented - others will be in release #3</code></p>
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
<li><a href='http://wecreategames.com/blog/?p=50'>Cloud Computing paper</a></li>
<li><a href='http://wecreategames.com/blog/?p=46'>Source code to make your own &#8220;Lunar Academy&#8221;</a></li>
<li><a href='http://wecreategames.com/blog/?p=28'>New MoonBaseOne game</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
<li><a href='http://wecreategames.com/blog/?p=50'>Cloud Computing paper</a></li>
<li><a href='http://wecreategames.com/blog/?p=259'>Chumby Advanced Tricks</a></li>
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=237</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interview on GarageGames</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=248#comments</comments>
		<pubDate>Tue, 21 Jul 2009 07:11:53 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[FOGE]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[MoonBaseOne]]></category>
		<category><![CDATA[Video Editing]]></category>
		<category><![CDATA[Volunteering]]></category>
		<category><![CDATA[Writing]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[interview]]></category>
		<category><![CDATA[moonbase]]></category>
		<category><![CDATA[space]]></category>
		<category><![CDATA[t3d]]></category>
		<category><![CDATA[tge]]></category>
		<category><![CDATA[torque]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=248</guid>
		<description><![CDATA[An interview with me was just posted on the GarageGames website.  Garage Games is the company that makes the excellent Torque Game Engine and Torque 3D that I&#8217;ve posted a number of resources for.  They were extremely kind and donated free copies of there software for s to use in making games for [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />An interview with me was just posted on the <a href="http://www.garagegames.com/community/blogs/view/17877">GarageGames website</a>.  <a href="http://www.garagegames.com/">Garage Games</a> is the company that makes the excellent Torque Game Engine and Torque 3D that I&#8217;ve posted a number of resources for.  They were extremely kind and donated free copies of there software for s to use in making games for kids.</p>
<p>The interview was very well done, and they were kind enough to post about our successes in publishing a space game for kids.  In fact, they posted it on the 40th anniversary of the Moon Landing, which was pretty cool.</p>
<p>I hope you enjoy the write-up.  I captured a number of the lessons learned and experiences working on the project.  </p>
<p><img src="http://static.garagegames.com/static/pg/torquepowered/devinterviews/moonbaseone/MoonBaseOne3.jpg" alt="Moon Base One dialogue" /><br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=28'>New MoonBaseOne game</a></li>
<li><a href='http://wecreategames.com/blog/?p=46'>Source code to make your own &#8220;Lunar Academy&#8221;</a></li>
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=28'>New MoonBaseOne game</a></li>
<li><a href='http://wecreategames.com/blog/?p=54'>Cloud Computing Game Vid</a></li>
<li><a href='http://wecreategames.com/blog/?p=25'>Moon Base One v3 Video</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=248</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Orrery &#8211; 3D Planet simulator</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=233#comments</comments>
		<pubDate>Mon, 20 Jul 2009 21:29:21 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[FOGE]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[MoonBaseOne]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[orrery]]></category>
		<category><![CDATA[planets]]></category>
		<category><![CDATA[space]]></category>
		<category><![CDATA[torque]]></category>
		<category><![CDATA[Torquescript]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=233</guid>
		<description><![CDATA[Happy 40th anniversary of the Moon landing!
In honor of this auspicious occasion, I&#8217;m releasing a new &#8220;Orrery&#8221; resource for the Torque programming language.  This isn&#8217;t yet a full-fledged game, rather just a library of celestial mechanics.
I wrote  the instructionsfor integrating within Torque 3D (which is currently in a closed Beta) &#8212; this is [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />Happy 40th anniversary of the Moon landing!</p>
<p>In honor of this auspicious occasion,<a href="http://wecreategames.com/apps/planets/Orrery.zip"> I&#8217;m releasing a new &#8220;Orrery&#8221; resource</a> for the Torque programming language.  This isn&#8217;t yet a full-fledged game, rather just a library of celestial mechanics.</p>
<p>I wrote <a href="http://wecreategames.com/apps/planets/OrreryInstructions.txt"> the instructions</a>for integrating within <a href="http://www.garagegames.com/products/torque-3d">Torque 3D (which is currently in a closed Beta)</a> &#8212; this is a new version of the video Game engine that I&#8217;ve used on many projects.  If you want to integrate this into an older version of Torque (such as TGE/TGEA), it should be pretty easy to do so.</p>
<p>I&#8217;ve intentionally kept all of the calculations in TorqueScript, rather than using the engine C++ code.  This will allow you to make quick changes without having to recompile the game.  Torque uses two layers, a &#8220;crunchy shell&#8221; of TorqueScript (a C++ derivative scripting language) and a &#8220;molten core&#8221; of C++ (which is much faster yet more complex).  If you want to get more accurate calculations of the planets, you should move the code into the C++ engine.  For example, the calculations now are only 32-bit Floating Point, so please don&#8217;t use these to launch interplanetary voyages&#8230; the planetary positions will only be accurate within 1 or 2% for the next 1000 years, and break down to chaos after that.</p>
<p>The way it works is by specifying a Julian Date &#8211; a time specified in centuries down to the second.  You can pass in convertDateTimeToEpoch(2000,1,1,12,0,0) and it returns a JD that is the number of centuries since January 1st, 2000 at noon.  </p>
<p>The <a href="http://wecreategames.com/apps/planets/OrreryInstructions.txt">Instructions code</a> describes how to use this:<br />
<code>	Orrery_Create("orrery1", "Mini System", "-233.581 -60.61 196.786", "5 5 5", 5, 4, "", 0.00004, 0.1, "Sol", 1);<br />
	Orrery_InitPlanets("orrery1");<br />
	Orrery_BeginAnimation("orrery1");</code></p>
<ul>
<li>This will create an orrery at the world points at &#8220;-233.581 -60.61 196.786&#8243;.</li>
<li>It will stretch the orrery to fit within 5 cubic game units (mostly likely 5 cubic meters if you use the standard game settings).</li>
<li>It will only show the first 5 planets</li>
<li>It will render the planets in a realistic configuration</li>
<li>It will use the default planets file (so you can pass in your own settings)</li>
<li>It will animate at 0.00004 (about 2 days every 10th of a second)</li>
<li>It will scale all planets to 10% (0.10) of their scaled size</li>
<li>It will only show children of the object named &#8220;Sol&#8221; (so you can have hundreds of planets and moons in the same file and only use the ones you want</li>
<li>It will only show 1 level of child objects (2 would show planets and moons)</li>
</ul>
<p>You can have multiple Orreries in the same game.  The more you have, the more choppy it gets.  You might want to change the animation to move faster that every 10th of a second.</p>
<p>Let me know if it works for you, or you use it in a game!  I&#8217;m working on another version, where moons and satellites will render.  Let me know if there are any features I can add.<br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
<li><a href='http://wecreategames.com/blog/?p=28'>New MoonBaseOne game</a></li>
<li><a href='http://wecreategames.com/blog/?p=54'>Cloud Computing Game Vid</a></li>
<li><a href='http://wecreategames.com/blog/?p=32'>Mining Robots control code</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
<li><a href='http://wecreategames.com/blog/?p=32'>Mining Robots control code</a></li>
<li><a href='http://wecreategames.com/blog/?p=54'>Cloud Computing Game Vid</a></li>
<li><a href='http://wecreategames.com/blog/?p=50'>Cloud Computing paper</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=233</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Databases + Canvas</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=219#comments</comments>
		<pubDate>Fri, 19 Jun 2009 17:11:33 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Video Editing]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[manifest]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=219</guid>
		<description><![CDATA[I love HTML5!  HTML5 is brand new &#8211; just available on a few browsers.  The new features, especially the use of local SQL databases and canvases bring so much power to web application development.  Before, things that you needed a full web server are now doable all within the browser.  I [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />I love HTML5!  HTML5 is brand new &#8211; just available on a few browsers.  The new features, especially the use of local SQL databases and canvases bring so much power to web application development.  Before, things that you needed a full web server are now doable all within the browser.  I think this is a game changer, especially for iPhone/gPhone development &#8212; we can now build much more complex mobile applications with much less code, and have them all work from the browser (rather than as applications specific to one platform).</p>
<p>There are some new security challenges, though.  The <a href="http://www.w3.org/TR/html5/the-canvas-element.html#dom-context-2d-drawimage">drafters of the specification were pretty smart</a> in thinking through some of these, which makes it more tricky to code things just right.</p>
<p>Below, I&#8217;ll show a demo that uses only a web page to:</p>
<ol>
<li>Go out to a web site, pass in the lat/long</li>
<li>Get a list of images and download them</li>
<li>Write the list of images to a local SQL database</li>
<li>Serialize, and add the images themselves to the database</li>
<li>Allow the user to unconnect their internet connection and still pull the images</li>
</ol>
<p>You might note that this is the same technology that Google Gears offers&#8230; but built standard into the browser.  Apple seems to really be embracing these technologies as an alternative to loading Gears or Flash onto the iPhone.</p>
<p>You can see the demo in action at: <a href="http://wecreategames.com/apps/imagesave/">http://wecreategames.com/apps/imagesave/</a>. Also check it out on your iPhone.  Here&#8217;s <a href="http://wecreategames.com/apps/imagesave/imagesave.zip">a link to a zip file</a> of all the source code.</p>
<p>Also, here&#8217;s a video summarizing how it all works:<br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/PduBDiivIBI&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/PduBDiivIBI&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<h2 id="219_offline-apps-the-man_1" >Offline apps &#8211; The Manifest File </h2>
<p>I&#8217;ve described the manifest file in the past as a way to tell the browser which files are important for caching and which shouldn&#8217;t be cached.  For this app, we only have two files (index.html and imagesave.js) that need to be cached, and then two proxy files that are called to pull data about images and the images themselves.  The manifest can do<a href="https://developer.mozilla.org/en/offline_resources_in_firefox"> alot of other things</a>, but we&#8217;re using it in it&#8217;s simplest form here:</p>
<p><code>CACHE MANIFEST<br />
#ver 0.1<br />
CACHE:<br />
index.html<br />
imagesave.js<br />
NETWORK:<br />
ws_image.php<br />
ws.php</code></p>
<h2 id="219_working-with-the-loc_1" >Working with the local browser database</h2>
<p>The <a href="http://developer.apple.com/safari/library/codinghowtos/Desktop/DataManagement/index.html">local database is a SQLlite database </a>that&#8217;s built into Firefox, Safari, Opera, and Mobile Safari.  It&#8217;s very powerful and easily makes sense if you&#8217;ve built SQL applications in the past.  Very similar to Google Gears, the local database gives you a secure local storage of complex content.  We&#8217;re going to use it to store metadata about the images we pull down (lat, longs, authors, etc) as well as serialized versions of the images themselves.</p>
<p><code>function picsInitDatabase() {<br />
	try {<br />
	    if (!window.openDatabase) {<br />
	        console.log('Databases are not supported in this browser');<br />
	    } else {<br />
	        var shortName = 'picsGeoDB';<br />
	        var version = '1.0';<br />
	        var displayName = 'Pictures Geotagged database';<br />
	        var maxSize = 5000000; // in bytes<br />
	        picsDB = openDatabase(shortName, version, displayName, maxSize);<br />
			console.log("Database is setup: "+picsDB);<br />
	    }</code></p>
<p>In this instance, I&#8217;m telling the db to be 5Mb large.  Any more than that and Mobile Safari asks for permission from the user.</p>
<p>Running SQL is the done through asynchronous transactions:<br />
<code>function picsCreateTables(){<br />
    picsDB.transaction(<br />
        function (transaction) {<br />
            /* The first query causes the transaction to (intentionally) fail if the table exists. */<br />
            transaction.executeSql('CREATE TABLE geopictures(id INTEGER NOT NULL PRIMARY KEY, secret TEXT NOT NULL DEFAULT "747060c06c", server INTEGER NOT NULL DEFAULT "3368",farm INTEGER NOT NULL DEFAULT "4", title TEXT NOT NULL DEFAULT "1 Infinite Loop", latitude TEXT NOT NULL DEFAULT "37.331666", longitude TEXT NOT NULL DEFAULT "-122.030834", accuracy INTEGER NOT NULL DEFAULT "16", datetaken TEXT NOT NULL DEFAULT "2009-06-14", ownername TEXT NOT NULL DEFAULT "avon11");', [], nullDataHandler, errorHandler);<br />
            transaction.executeSql('CREATE TABLE photodata(picid INTEGER NOT NULL PRIMARY KEY, encodedtext TEXT NOT NULL);', [], nullDataHandler, errorHandler);<br />
        }<br />
    );<br />
}<br />
function picsUpdateTables(dataID){<br />
	picsDB.transaction(<br />
	    function (transaction) {<br />
	    	var p = data[dataID];<br />
	        transaction.executeSql("INSERT INTO geopictures (id, secret, server, farm, title, latitude, longitude, accuracy, datetaken, ownername) VALUES (?,?,?,?,?,?,?,?,?,?);",<br />
	        [p.id, p.secret, p.server, p.farm, p.title, p.latitude, p.longitude, p.accuracy, p.datetaken, p.ownername] );<br />
	        transaction.executeSql("INSERT INTO photodata (picid, encodedtext) VALUES (?, ?)", [p.id, serializeCanvasByID(p.id)] );<br />
	    }<br />
	);<br />
}</code></p>
<p>It&#8217;s a bit tricky building your SQL, as you don&#8217;t get any detailed error messages on why things failed.  I recommend you first build it on a local SQL Lite database and then copy in the SQL exactly, otherwise you&#8217;ll spend hours trying to track down small mistakes.</p>
<p>It&#8217;s very easy to call straight SQL commands, though make sure you don&#8217;t build the SQL on the fly and pass it in to be run.  These local databases are susceptible to<a href="http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/RelationalDatabases/RelationalDatabases.html#//apple_ref/doc/uid/TP40007256-CH5-SW16"> SQL injection attacks</a>, just like any database.  As you can see above, I&#8217;m passing in the values as an array.</p>
<p>SELECTing items is a little bit trickier, as you need to build some asynchronous calls.  Also realize that you&#8217;re never sure of the order these calls will finish in.</p>
<p><code>function picsPhotodataSelectHandler(transaction, results)<br />
{<br />
	console.log("Photodata had Results: "+results.rows.length);<br />
    // Handle the results<br />
    for (var i=0; i&lt;results.rows.length; i++) {<br />
        var row = results.rows.item(i);<br />
		var newImage = new Object();<br />
		newImage.picid = row['picid'];<br />
		newImage.encodedtext = row['encodedtext'];<br />
        canvasData.push(newImage);<br />
    }<br />
    showImagesFromDB();<br />
}<br />
function picsSelectAll(){<br />
	picsDB.transaction(<br />
	    function (transaction) {<br />
	        transaction.executeSql("SELECT * from photodata;", [], picsPhotodataSelectHandler, errorHandler);<br />
	    }<br />
	);<br />
}</code></p>
<p>The above code runs a select statement, and passes in a function for what to do when things are finished successfully and another for when there is an error.  The picsPhotodataSelectHandler is called once results are returned.</p>
<h2 id="219_drawing-pixel-by-pix_1" >Drawing pixel by pixel in Javascript: the Canvas</h2>
<p>The last piece of magic is to take images that we download, and to map them onto a canvas tag.  The Canvas object is pretty amazing &#8211; it lets you <a href="https://developer.mozilla.org/en/Canvas_tutorial/Drawing_shapes">either draw on it directly</a>, or to read off individual pixels.  You can also serialize the entire canvas out as an ascii string, which can then be saved to a database and later read back in.  This is how we&#8217;re maintaining full control of our downloaded images.  There are a few other methods of doing this that are a bit easier, but this gives you the most control.</p>
<p> <code>	function serializeCanvasByID(picID) {<br />
		var canvas = document.getElementById('cx'+picID);<br />
		var serializedVal = 'data:,';<br />
		if (canvas.toDataURL) serializedVal = canvas.toDataURL();<br />
	    return serializedVal;<br />
	}<br />
	function drawImageOnCanvas(data, canvas) {<br />
	    var img = new Image();<br />
	    img.onload = function() {<br />
	        canvas.width = img.width;<br />
	        canvas.height = img.height;<br />
	        canvas.getContext("2d").drawImage(img, 0, 0);<br />
	    };<br />
	    img.src = data;<br />
	}<br />
	function getCanvasDataByID(ID){<br />
		for (var i=0; i&lt;canvasData.length;i++){<br />
			if (canvasData<em></em>.picid == ID) {<br />
				return canvasData<em></em>.encodedtext;<br />
			}<br />
		}<br />
		return '';<br />
	}<br />
	function showImagesFromDB() {<br />
		var container = document.getElementById('img-container')<br />
		container.innerHTML='';<br />
		for (var i=0; i&lt;data.length; i++){<br />
			var canvasImg = document.createElement("canvas");<br />
			var imgID = data<em></em>.id;<br />
			canvasImg.setAttribute("id", 'cx'+imgID);<br />
			canvasImg.setAttribute("title", data<em></em>.desc);<br />
			drawImageOnCanvas(getCanvasDataByID(imgID), canvasImg);<br />
			container.appendChild(canvasImg);<br />
		}<br />
	}</code></p>
<p>The canvas.toDataURL(); call serializes out the image data.  You can look at the string and see that it starts with &#8220;data:image/png&#8221; and then a bunch of characters.</p>
<p>The second piece of magic is in the drawImageOnCanvas function.  It&#8217;s basically creating an img with the src either equal to a URL or to the &#8220;data:image/png&#8230;&#8221; text.  Once the image is loaded into memory, it&#8217;s fed into the canvas&#8217;s 2d context to be shown on screen.</p>
<h2 id="219_summary_1" >Summary</h2>
<p>These three technologies can enable some pretty amazing things.  You&#8217;ll be able to build very sophisticated web applications that are fully standards-compliant (so should hopefully work in iPhone, Android, Palm, etc).  This could save thousands of $ as you no longer need to have experts in building apps for each platform.  I could see this as being extremely valuable for making offline mapping applications.</p>
<p>(Back to last post in the series: <a href="http://wecreategames.com/blog/?p=210">Nearly2, iPhone app with 3D transforms</a>)</p>
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
<li><a href='http://wecreategames.com/blog/?p=188'>iPhone Geotags</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=203'>Updated FlickrProxy</a></li>
<li><a href='http://wecreategames.com/blog/?p=259'>Chumby Advanced Tricks</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=219</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>3d iPhone web apps</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=210#comments</comments>
		<pubDate>Thu, 18 Jun 2009 00:18:38 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[3d-transform]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobile safari]]></category>
		<category><![CDATA[os3]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=210</guid>
		<description><![CDATA[For the third post in this series, I&#8217;ll be showing how to do some pretty advanced iPhone applications using Mobile Safari and HTML5.  These should all work on the latest OS3 that came out today.  What&#8217;s special about these is that they are not actual &#8220;Apps&#8221; that get loaded to your phone from [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />For the third post in this series, I&#8217;ll be showing how to do some pretty advanced iPhone applications using Mobile Safari and HTML5.  These should all work on the latest OS3 that came out today.  What&#8217;s special about these is that they are not actual &#8220;Apps&#8221; that get loaded to your phone from the app store.  They&#8217;re completely served through HTML and still have a ton of capabilities.</p>
<p>I got the idea to put the Flickr image results into a 3D &#8220;ring&#8221; from <a href="http://the.fuchsia-design.com/">Antoine Quint</a>, a developer for Apple Europe that I met at WWDC this year.  These <a href="http://webkit.org/specs/MediaQueriesExtensions.html">transform-3d talks</a> were all the rage at the conference, and I plan to heavily use them in future projects.  </p>
<p><img alt="" src="http://farm4.static.flickr.com/3622/3636137495_ccc974a9db_m.jpg" title="Nearly, ver 2" class="alignnone" width="128" height="240" /></p>
<p>You can see the application if you point your iPhone browser to <a href="http://wecreategames.com/apps/nearly2">http://wecreategames.com/apps/nearly2</a>.  Notice that if you look at this page in Firefox, it looks like gibberish (though it does ask for your permission to send geoLocation data).  Even in Safari 4 on Snow Leopard, it doesn&#8217;t look exactly right, but it does give you GeoLocation and the ability to test through logs with the new excellent Web Inspector (you have to go into Preferences, and turn on Developer tools first).  The apple guys assured me that a patch coming out for desktop Safari next week will fix these 3D rendering issues.</p>
<p>The <a href="http://wecreategames.com/apps/nearly2/nearly2.zip">code is available here</a> (please note that some of it is reusing <a href="http://lists.apple.com/archives/safari-iphone-web-dev/2009/Jan/msg00006.html">Apple&#8217;s example code</a>.  While my stuff is Creative Commons, please don&#8217;t tread on their copyright).</p>
<h2 id="210_speeding-up-page-loa_1" >Speeding up page loads:</h2>
<p>So, here are the important new parts of code:<br />
<code >&lt;html manifest="default.manifest"&gt;</code></p>
<p>This tells the page to use a manifest, which is basically a document listing which files should/souldn&#8217;t be cached by the application.  The application is just a text file that looks like:<br />
<code>CACHE MANIFEST<br />
#ver0.03<br />
CACHE:<br />
index.html<br />
square.html<br />
style.css<br />
script.js<br />
data.js<br />
ui/back_button_touched.png<br />
ui/back_button.png<br />
ui/back_button_touched.png<br />
ui/back_button.png<br />
gradient_bottom.png<br />
ui/gradient_top.png<br />
ui/play_button.png<br />
ui/play_button_ring.png<br />
apple-touch-startup-image.png<br />
apple-touch-icon.png<br />
NETWORK:<br />
ws.php</code></p>
<p>This is telling the browser (mobile safari in this case) to download and cache all the files at the top of the list, and that the ws.php file shouldn&#8217;t be cached (as it will constantly be changing and returning different image results).  This is really nice for iPhones, as large websites can be all cached on the first version, drastically speeding up the load time.  I think that after 5mb, the user is prompted to see if the site is allowed to use more space.  Also, there are a few weird things when using the manifests: </p>
<ol>
<li>When you update a file inside (such as data.js), the app won&#8217;t always notice.  Instead, you have to physically change the .manifest file &#8211; I do this by changing the version # inside the file comment</li>
<li>It takes <b>2</b>refreshes of the app for the new manifest to take hold.  This makes sense, as when a page is opened in the browser it will keep on loading.  After it&#8217;s finished loading, it then looks for the new manifest information (so as not to slow things down).  The next refresh then has the new manifest data</li>
<li>You need to <a href="http://www.w3.org/TR/offline-webapps/#offline">change your webserver&#8217;s mime type </a>to return .manifest files as mime type of &#8216;text/cache-manifest&#8217;.  Usually this is done through cPanel or whatever tool you&#8217;re using to manage your site.</li>
</ol>
<h2 id="210_customizing-the-icon_1" >Customizing the icon</h2>
<p>On the iPhone, when users click the &#8220;+&#8221; button at the bottom of the screen, they can add the app to the home page.  When they do, a screen shot of the app is created as the icon.  With HTML5, you can specify which 57px x 57px icon you want to use with the code:<br />
<code >	&lt;link rel="apple-touch-icon" href="apple-touch-icon.png"&gt;</code></p>
<p>When the user adds the icon to the iPhone home page, the icon is given a glassy overlay.  You can use &#8216;apple-touch-icon-precomposed&#8217; if you don&#8217;t want the glass added. </p>
<h2 id="210_tailoring-the-page-t_1" >Tailoring the page to look best on iPhone</h2>
<p>The following css is in style.css:<br />
<code>body {<br />
  -webkit-touch-callout: none;<br />
  -webkit-text-size-adjust: none;<br />
  -webkit-tap-highlight-color: rgba(0,0,0,0);</code></p>
<p>On mobile safari, when you hold down on a link or piece of text for a few seconds, a callout pops up to ask if you want to copy/paste, or email.  The first line disables this for everything in the document, which also helps with catching our custom touch events.  Apple recommends a better practice is to only put these on certain objects on your page, not everything.</p>
<p>Mobile safari also tries to resize text to be helpful to users if it thinks the aspect ratio is too small.  The second line turns off this adjustment.</p>
<p>The third line tells safari to highlight things in black if you click on them to show an action (rather than the default gray).</p>
<h2 id="210_making-the-3d-ring_1" >Making the 3D ring</h2>
<p>The following code was all written by Antoine Quint, so I&#8217;ll only breiefly describe them.</p>
<p>In script.js, the code to calculate the rotation of the wheel and the position back in &#8220;Z&#8221; space is:<br />
<code>    var angle = -i * (FULL_ROTATION / NUM_POSTERS);<br />
    item.style.webkitTransform = 'rotateX(' + angle + 'rad) translateZ(' + RADIUS + 'px)';</code></p>
<p>and in style.css, there are a ton of 3d-specific calls.  Here are some important ones:<br />
<code>#ring-container {<br />
   /* make the perspective origin be the center of the screen */<br />
  -webkit-perspective-origin: 160px 208px;<br />
  /* set up the amount of perspective on the children of this container */<br />
  -webkit-perspective: 1000;<br />
  /* base transform for this container, need a value to transition from */<br />
  -webkit-transform: translateX(0);<br />
}<br />
#ring-aligner {<br />
  /* make sure the content lives in 3D space */<br />
  -webkit-transform-style: preserve-3d;<br />
  /* push back the content in the Z axis to cancel individual transforms set on ring items by script */<br />
  -webkit-transform: translateZ(-235px);<br />
}<br />
/* this matches all items within the ring */<br />
#ring &gt; li {<br />
  /* hide the back of the elements so that we don't see anything but the items currently in the front of the ring */<br />
  -webkit-backface-visibility: hidden;</code></p>
<p>The first call here is to add a &#8220;perspective&#8221; so that in 3d space, it looks like items are falling-back into the screen and getting smaller the farther away they are.  </p>
<p>The last line applies to all list items with the #ring item.  Because items are being rotated around in a circle, we turn off the back faces so that we don&#8217;t see them off in the distance.</p>
<p><code>  -webkit-box-shadow: 0px 0px 3px rgba(255, 255, 255, 0.7);<br />
  -webkit-border-radius: 5px;</code></p>
<p>One of my favorite additions to HTML5 is how easy it is to add a shadow or rounded corners.  Also, notice the 4th number above is the transparency &#8211; making it very easy to create blends.</p>
<h2 id="210_merging-image-lookup_1" >Merging image lookups with the Ring</h2>
<p>It can be a little painful debugging on your iPhone.  The best tool I&#8217;ve found is to use Safari&#8217;s Web inspector, Firefox&#8217;s Firebug, or to just write messages out to the console.  I&#8217;m also going to start playing with DashCode (on the mac), as it seems to have some nice debugging features.  Instead of calling alert()s every time I want to output a variable, I use console.log(&#8217;Error text&#8217;).  Because Firefox doesn&#8217;t have this function, we add it:<br />
<code>if (!console){<br />
 var console = new Object();<br />
 console.log = function(intext){alert(intext);};<br />
}</code></p>
<p>Most of the rest of the code was pretty easy to move over from the first example into the FingerTips example.  One thing I quickly noticed was that as you walk around, new images are being pulled in to the array and it&#8217;s hard to know which ones to show.  I&#8217;ll attack this more on the next post, but for now, a work-around is to just show the last images in the array:<br />
<code>	var data_offset = 0;<br />
	if (data.length&gt;NUM_POSTERS) {<br />
		data_offset = (data.length-NUM_POSTERS);<br />
		console.log('Data Offset is: '+data_offset);<br />
	}</code></p>
<p>How&#8217;s it look?  I would love any feedback or suggestions!</p>
<p>(Back to last post in the series: <a href="http://wecreategames.com/blog/?p=203">FlickrProxy</a>)<br />
(Next post in the series: <a href="http://wecreategames.com/blog/?p=219">Full Offline iPhone apps with HTML Canvas and DBs</a>)<br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
<li><a href='http://wecreategames.com/blog/?p=248'>Interview on GarageGames</a></li>
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=188'>iPhone Geotags</a></li>
<li><a href='http://wecreategames.com/blog/?p=219'>HTML5 Databases + Canvas</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=259'>Chumby Advanced Tricks</a></li>
<li><a href='http://wecreategames.com/blog/?p=203'>Updated FlickrProxy</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=210</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Updated FlickrProxy</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=203#comments</comments>
		<pubDate>Wed, 17 Jun 2009 21:00:58 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[geospatial]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[kml]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[proxy]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=203</guid>
		<description><![CDATA[Thanks to a great suggestion by AbigailG, I&#8217;ve updated the Flickr Proxy I wrote to search on dates as well as tags.  I&#8217;ve found this improves the quality of the images returned.  Great idea, and the code is zipped up here.
You can replace the ws.php into the previous Nearly1 example and you&#8217;ll get [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />Thanks to a great suggestion by AbigailG, I&#8217;ve updated the Flickr Proxy I wrote to search on dates as well as tags.  I&#8217;ve found this improves the quality of the images returned.  Great idea, and the code is <a href="http://wecreategames.com/apps/nearly2/FlickrProxy.zip">zipped up here</a>.</p>
<p>You can replace the ws.php into the previous Nearly1 example and you&#8217;ll get instant improvements and functionality.  This will be the cornerstone of a few of the other iPhone Web Apps I&#8217;ll be releasing over the next few days.</p>
<p>Also, I found that to best test this code and make sure it was returning valid results, I added an option to render the results as KML.  This is nice because you can then <a href="http://googlemapsapi.blogspot.com/2006/11/kml-on-google-maps.html">test it with Google Maps</a> or Google Earth.  Check out <a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=http:%2F%2Fwecreategames.com%2Fapps%2Fnearly2%2Fws.php%3Flat%3D37.331689%26lon%3D-122.030731%26num%3D10%26format%3Dkml%26tags%3Diphone&amp;ie=UTF8&amp;ll=37.33171,-122.027893&amp;spn=0.013701,0.012939&amp;z=16">an example of this in action on Google Maps</a>.</p>
<p>So, without further ado, I&#8217;ll jump into describing how the FlickrProxy works.</p>
<p><code>require_once("phpFlickr/phpFlickr.php");<br />
// Create new phpFlickr object<br />
$f = new phpFlickr("3055e96cbe8a5b33c248afb201bca822");<br />
$f-&gt;enableCache("fs", "/home/bigyak/public_html/apps/nearly2/cache");</code></p>
<p>First, I&#8217;m using the phpFlickr API.  There are good ways of installing it using PEAR (if you&#8217;re a bit more advanced of a PHP user), but it works just as well to copy the directory structure that I&#8217;ve provided.  Enter in your Flickr API key, then put in a path to your cache directory (basically, just make a directory with write access turned on).  You can comment that line out if you&#8217;re not using the cache.</p>
<p><code>if ($_GET["tags"]=="") {<br />
	$tags = "";<br />
} else {<br />
	$tags = $_GET["tags"];<br />
}<br />
if ($_GET["daysago"]=="") {<br />
	if ($tags != "") {<br />
		//If they've entered tags, then don't be so restrictive on the date range<br />
		$daysago = 60;<br />
	} else {<br />
		$daysago = 7;<br />
	}<br />
} else {<br />
	$daysago = $_GET["daysago"];<br />
}<br />
...<br />
if ($_GET["format"]=="") {<br />
	$format = "json";<br />
} else {<br />
	$format = $_GET["format"];<br />
}</code><br />
Next, we check all the variables that the user sent in through the querystring.  If they put in tags to search on, we&#8217;ll look for those.  If they entered a time range, we&#8217;ll search on that, then we&#8217;ll look via Latitude and Longitude as well as some other variables.  For format, you can enter html, json, or kml. I&#8217;ve found that HTML is good for looking at quick results, KML is great for testing with Google Maps, and JSON is the type that our web apps can most easily use.</p>
<p><code>$RADIUS_EXPANSION = 10;<br />
$DATE_EXPANSION = 4;<br />
$PHOTOTRIES = 12;<br />
$radius = 0.01;<br />
for ($i = 1; $i &lt;= $PHOTOTRIES; $i++) {<br />
	if($photos_found &gt;= $MINPHOTOS) break;<br />
	$dateminformat = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d")-$daysago, date("Y")));<br />
	$args = array("tags"=&gt;$tags, "lat"=&gt;$lat, "lon"=&gt;$lon,"sort"=&gt;"interestingness-desc", "per_page"=&gt;$PHOTOTRIES, "radius"=&gt;$radius, "min_taken_date"=&gt;$dateminformat, "extras"=&gt;"geo,date_taken,owner_name");<br />
	$photos_now = $f-&gt;photos_search($args);</code></p>
<p>This is the main loop of our code.  We&#8217;re going to keep asking Flickr until we get the number of pictures back that the user has asked for, or until we&#8217;ve reached the 20mil limit of search.  Notice that each successive query to Flickr is getting a little bigger and asking for older pictures.  We&#8217;re ordering these by interestingness, but that doesn&#8217;t always return the most interesting pictures.</p>
<p><code>	if(count($photos_now['photo']) &gt; 0) {<br />
	    foreach ($photos_now['photo'] as $photo) {<br />
	    	//Look through existing photos<br />
	    	$foundmatch=false;<br />
	    	foreach ($photos['photo'] as $lookingat) {<br />
	    		if ($photo[id]==$lookingat[id]) {<br />
	    			$foundmatch=true;<br />
	    			break;<br />
	    		}<br />
	    	}<br />
	    	if ($foundmatch==false) $photos['photo'][$photos_found++] = $photo;<br />
	    }</p>
<p>		$photos_found=count($photos['photo']);</code></p>
<p>The final part of the loop has us compare all returned pictures with our existing array of pictures.  We throw away any duplicates and increment the count for checking later.</p>
<p><code>if ($format=="json") {<br />
	if(count($photos['photo']) == 0) {<br />
		if($backup=="yes"){<br />
			$html = file_get_contents('./test.json', true);<br />
		} else {<br />
			$html = 'jsonFlickrApi({"photos":"none", "stat":"ok", "requestedlat":"'.$lat.'", "requestedlon":"'.$lon.'"})';	}<br />
	} else {<br />
		$html = 'jsonFlickrApi({"photos":'.json_encode($photos).', "stat":"ok", "requestedlat":"'.$lat.'", "requestedlon":"'.$lon.'"})';;<br />
	}<br />
...</code></p>
<p>I&#8217;ve found that sometimes you just don&#8217;t get any photos returned.  As a last ditch effort, I have a backup file of json that I&#8217;ll just echo out if there are no results returned.  For future versions, if none are returned in the a geo-area, I&#8217;ll experiment with increasign the geo box (rather than the radius).</p>
<p>If you look through the rest of the code, you&#8217;ll see the loops that manually build the KML or HTML for return to the users.</p>
<p>In summary, I&#8217;ve now improved the FlickrProxy to make it easier to ask for nearby images.  For future work, I&#8217;ll be looking at how to further improve the iPhone interface to take advantage of HTML5.</p>
<p>(Back to last post in the series: <a href="http://wecreategames.com/blog/?p=188">Nearly1, the iPhone app</a>)</p>
<p>(Next post in the series: <a href="http://wecreategames.com/blog/?p=210">Nearly2, iPhone app with 3D transforms</a>)<br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=237'>Orrery Game: ver 2</a></li>
<li><a href='http://wecreategames.com/blog/?p=62'>Open Source &#8211; Functions.asp</a></li>
<li><a href='http://wecreategames.com/blog/?p=66'>IESP research</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=188'>iPhone Geotags</a></li>
<li><a href='http://wecreategames.com/blog/?p=219'>HTML5 Databases + Canvas</a></li>
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=259'>Chumby Advanced Tricks</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=203</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iPhone Geotags</title>
		<link></link>
		<comments>http://wecreategames.com/blog/?p=188#comments</comments>
		<pubDate>Tue, 16 Jun 2009 23:28:06 +0000</pubDate>
		<dc:creator>Jay Crossler</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[os3]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://wecreategames.com/blog/?p=188</guid>
		<description><![CDATA[The new iPhone OS3.0 will be coming out soon, and one of my favorite features is updating Mobile Safari to have much better support for HTML5.  HTML5 is still in draft, but basically makes HTML much smarter and more powerful &#8211; by adding features like GeoLocation, 3D-animations, Offline Storage, and more.
This is the first [...]]]></description>
			<content:encoded><![CDATA[<p id="top" />The new iPhone OS3.0 will be coming out soon, and one of my favorite features is updating Mobile Safari to have much better support for HTML5.  HTML5 is still in draft, but basically makes HTML much smarter and more powerful &#8211; by adding features like <a href="http://developer.apple.com/safari/library/codinghowtos/Desktop/DataManagement/index.html">GeoLocation, 3D-animations</a>,<a href="http://dev.w3.org/html5/webstorage/"> Offline Storage</a>, and more.</p>
<p>This is the first in a series of posts about how to write HTML5 applications and the power that they bring to the iPhone and iPod Touch.  I&#8217;ll mostly be concentrating on iPhone applications (ones that use a GPS), and will try to build something useful that you can all have to make even better applications with.  Like everything on this site, we&#8217;ll be releasing this as Open Source &#8211; so feel free to edit, sell it, make it better &#8211; but please just let me know what you create with it.</p>
<p><strong>Nearly, version 1 (4 of the closest images pulled from Flickr)</strong></p>
<p><img class="alignnone" title="Nearly, v1" src="http://farm4.static.flickr.com/3003/3633143429_79fccdea5c_m.jpg" alt="" width="126" height="240" /></p>
<p>For the first writeup in this series, we&#8217;ll create a simple application that uses HTML 5 to ask your browser for the location, and then passes that to Flickr to ask for 4 images.  There is an example at: <a href="http://wecreategames.com/apps/nearly1/">http://wecreategames.com/apps/nearly1/</a> &#8211; you can use this in your iPhone, or in Safari or Firefox Beta (it will ask permission to get your location, which you have to allow)</p>
<p>To get the code working on your own PHP server:</p>
<ol>
<li>Download the <a href="http://wecreategames.com/apps/nearly1/nearly1.zip">Nearly1.zip</a> file, unzip it.</li>
<li>Upload this to a directory in a php server that you control. (notice, this could easily be written in RoR, .Net, or anything else).</li>
<li>Register for a <a href="http://www.flickr.com/services/api/">Flickr API</a>, and then copy the <a href="http://www.flickr.com/services/api/keys/">API Key</a> (which is a text string)</li>
<li>Edit the ws.php file and replace the API key in quotes with yours.</li>
<li>Optionally, add a cache directory, which will make requests run faster</li>
<li>Navigate to http://your.web.server/nearly (or whatever you named it) on a newer browser or your iPhone (notice, doesn&#8217;t work with IE)</li>
</ol>
<p>Here are relevant and important pieces of code that get this to work:</p>
<p>The first line tells Mobile Safari not to allow the user to scroll or zoom the window using touch events when shown on an iPhone.  The second says that it&#8217;s OK that when added to a home page it should function like an app, and not show the navigation bar on an iPhone:<br />
<code >   &lt;meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"&gt;<br />
     &lt;meta name="apple-mobile-web-app-capable" content="yes"&gt;</code></p>
<p>To enable geocoding, we first check if the browser has a navigator object.  If so, we ask it for the current position and pass in two functions: what to do if the location is found, and what to do if there&#8217;s an error.  In all error cases, I have it fake a location (which makes testing much easier).  Notice that just for simplicity sake, I&#8217;m writing out error messages within the innerHTML of the rectangles on screen.<br />
<code>	function getLocOnce() {<br />
		if(navigator.geolocation){<br />
			navigator.geolocation.getCurrentPosition(function(position) {<br />
				current_position=position;<br />
				showLoc(position);<br />
			}, function(error) {<br />
      			document.getElementById('image1').innerHTML = "You are off the radar!  Faking location. Error:" + error.code + error.message;<br />
				var position = new Object();<br />
				position.coords = new Object();<br />
				position.coords.latitude = DEFAULT_LAT;<br />
				position.coords.longitude = DEFAULT_LON;<br />
				showLoc(position);<br />
			}, {enableHighAccuracy:true}<br />
			);<br />
		} else {<br />
  			document.getElementById('image1').innerHTML = "No location on your browser";<br />
			var position = new Object();<br />
			position.coords = new Object();<br />
			position.coords.latitude = DEFAULT_LAT;<br />
			position.coords.longitude = DEFAULT_LON;<br />
			showLoc(position);<br />
		}<br />
	}</code><br />
Notice that because we&#8217;re passing in <em>functions</em>, we&#8217;re setting up the JavaScript to make Asynchronous calls when results are known.  The process is:</p>
<ol>
<li>Ask the browser for the location</li>
<li>When the browser responds (seconds later), give it a block of code to run</li>
<li>Show the results of the location</li>
</ol>
<p>HTML5 has many of these similar asynchronous call structures in it &#8211; which is more complex but enables a lot of advanced functionality.</p>
<p>The showLoc function pulls in values and coordinates from the browser:<br />
<code>	function showLoc(position){<br />
		if (position.coords) {<br />
   				var pos1 = "Lat: " + position.coords.latitude + "&lt;br/&gt;Long:" + position.coords.longitude + "&lt;br/&gt;Accuracy:" + position.coords.accuracy;<br />
   				var pos2 = "Altitude: " + position.altitude + "&lt;br/&gt;Accuracy:" + position.altitudeAccuracy;<br />
   				var pos3 = "Speed: " + position.coords.speed + "&lt;br/&gt; Heading: " + position.coords.heading;<br />
				var pos4 = "Timestamp: " + position.timestamp;<br />
      			document.getElementById('image1').innerHTML = pos1;<br />
      			document.getElementById('image2').innerHTML = pos2;<br />
      			document.getElementById('image3').innerHTML = pos3;<br />
      			document.getElementById('image4').innerHTML = pos4;<br />
 		}<br />
	}</code></p>
<p>The last piece of geoPosition code that we&#8217;ve added is the watchLoc and clearWatch functions.  When calling watchLoc() function, you&#8217;re setting up another asynchronous callback function.  Basically, you&#8217;re asking for a continuous GPS update whenever the phone can give you one.  It&#8217;s very important that you turn off this watching process as it really drains the batteries quickly.  I make sure to clear it when the page ends and as often as possible.<br />
<code>	var watchId = null;<br />
	function watchLoc() {<br />
		btn = document.getElementById('geo_btn');<br />
		if (btn.value == 'Track') {<br />
			watchId = navigator.geolocation.watchPosition(showLoc);<br />
			btn.value='Stop';<br />
		} else {<br />
			clearWatch();<br />
		}<br />
	}<br />
	function clearWatch(){<br />
		if(watchId) {<br />
			navigator.geolocation.clearWatch(watchId);<br />
			watchId = null;<br />
		}<br />
		document.getElementById('geo_btn').value='Track';<br />
	}</code></p>
<p>Telling the page to always unload the request for GPS polling:<br />
<code >  &lt;body onunload="clearWatch()"&gt;</code></p>
<p>The final piece that might require some explanation is not new in HTML5 &#8211; it&#8217;s a standard JSON query back to a server to ask for data.  In this case, we&#8217;re making an XMLHttpRequest call to ask for a list of nearby Flickr Images.  The results are returned to the browser and eval()ed &#8211; which isn&#8217;t the safest way to write JavaScript but works for this demo.</p>
<p>Because you can&#8217;t make requests to multiple servers in the same JavaScript page, I&#8217;ve put in ws.php, which uses the phpFlickr library to ask Flickr for images.  I&#8217;ve found there are a number of places (the horror!) that don&#8217;t have Flickr images geotagged nearby, so the php code tries a number of times to ask for images, each time widening the radius of allowed results.</p>
<p>It&#8217;s a really good idea to turn caching on (uncomment the line) in the ws.php file, as that will speed up response times and lighten the load on Flickr.  I like to join multiple strings together to build a querystring, as it&#8217;s just easier to maintain in the long run.<br />
<code>var api_req = 'ws.php?';<br />
var opt_lat = 'lat='+ lat;<br />
var opt_lon = 'lon='+ lon;<br />
var opt_num = 'num=4';<br />
var opt_tag = 'tags=fun,travel,iphone';<br />
var requestString = api_req + [opt_lat, opt_lon, opt_tag].join('&amp;amp;');<br />
loadJavascript(requestString);</code></p>
<p>Flickr has a <a href="http://www.flickr.com/services/api/explore/?method=flickr.photos.search">pretty useful tool for testing these REST-based API calls</a>.  I spent a lot of time testing with it, which helped me realize there must be tags sent in with the calls, or else no photos are returned.</p>
<p>(Next post in the series:<a href="http://wecreategames.com/blog/?p=203"> An Updated Flickr Proxy</a>)<br />
<h3 class="bsuite_related_bypageviews">People who looked at this item also looked at&#8230;</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=233'>Orrery &#8211; 3D Planet simulator</a></li>
<li><a href='http://wecreategames.com/blog/?p=62'>Open Source &#8211; Functions.asp</a></li>
<li><a href='http://wecreategames.com/blog/?p=252'>App Store for the Army</a></li>
<li><a href='http://wecreategames.com/blog/?p=21'>Star Wars Chess</a></li>
</ul>
<h3 class="bsuite_related">Related items</h3>
<ul class="bsuite_related">
<li><a href='http://wecreategames.com/blog/?p=210'>3d iPhone web apps</a></li>
<li><a href='http://wecreategames.com/blog/?p=219'>HTML5 Databases + Canvas</a></li>
<li><a href='http://wecreategames.com/blog/?p=203'>Updated FlickrProxy</a></li>
<li><a href='http://wecreategames.com/blog/?p=280'>Building applications for Tysons Corner</a></li>
<li><a href='http://wecreategames.com/blog/?p=259'>Chumby Advanced Tricks</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://wecreategames.com/blog/?feed=rss2&amp;p=188</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
