<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Perspectives : Writings from The Killswitch Collective</title>
    <link>http://www.killswitchcollective.com/blog/index.xml</link>
    <description>Perspectives is the blog of The Killswitch Collective, a Chicago-based web development, design and communication firm.</description>
    <language>en-us</language>
    <item>
      <title>Happy Birthday, Perspectives!</title>
      <category>Perspectives</category>
      <description>&lt;h3&gt;One Year Down...&lt;/h3&gt;

&lt;p&gt;Today, Killswitch is celebrating the 1-year birthday of our blog &lt;em&gt;Perspectives&lt;/em&gt;! Since &lt;a href="http://killswitchcollective.com/articles/6" target="_blank"&gt;its introduction&lt;/a&gt;, &lt;em&gt;Perspectives&lt;/em&gt; has been our outlet for giving back to the communities we rely on. It has been a lot of fun sharing our thoughts and ideas with you, so be assured that we will continue delivering hot, fresh content on a weekly basis.&lt;/p&gt;

&lt;p&gt;Over the last twelve months I have been asked a few times:&lt;/p&gt; 

&lt;blockquote&gt;Why go to so much trouble to blog? Aren't you just giving away your trade secrets?&lt;/blockquote&gt; 

&lt;p&gt;It's true that &lt;em&gt;Perspectives&lt;/em&gt; is no money maker &amp;mdash; obviously no one is paying to read these articles, and we certainly wouldn't want them to! So why do we continue to ask our entire staff at Killswitch to spend valuable man-hours writing?&lt;/p&gt;

&lt;h3&gt;And Many More&lt;/h3&gt;

&lt;p&gt;As I mentioned before, a big part of it is the importance of giving back to the communities that support our business. From a development standpoint, we solely use &lt;a href="http://en.wikipedia.org/wiki/Open_source" target="_blank"&gt;Open Source&lt;/a&gt; coding languages, libraries and programs, which means that these tools have been provided free of charge. In stark contrast to Microsoft tools like .NET which are supported internally and leased to developers, Open Source code is maintained by a community of volunteers who are concerned enough about the success of the industry to pitch in and help.&lt;/p&gt;

&lt;p&gt;Every time I run into a bug while developing a Web app, my first inclination is to Google my issue and see if someone has already written a blog article with a fitting solution &amp;mdash; and often times that works! Maintaining &lt;em&gt;Perspectives&lt;/em&gt; with helpful tutorials and free downloadable code is our way of saying 'thank you' to the community and giving something back.&lt;/p&gt;

&lt;h3&gt;Keep It Coming&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Perspectives&lt;/em&gt; is a place where we can show you a more candid, honest look at the people who make The Killswitch Collective what it is. This is our opportunity to express our passion for &lt;a href="http://www.killswitchcollective.com/blog/categories/Design" target="_blank"&gt;intuitive design&lt;/a&gt;, &lt;a href="http://www.killswitchcollective.com/blog/categories/Development" target="_blank"&gt;clever development&lt;/a&gt; and &lt;a href="http://www.killswitchcollective.com/blog/categories/Perspectives" target="_blank"&gt;fruitful business relationships&lt;/a&gt;. We want to show our readers how we think, how we work through problems and how we strive to make the Web a better place.&lt;/p&gt;

&lt;p&gt;With one year under our belts, we're just starting to get warmed up. Keep checking back each week for more articles about development, design and anything else we're thinking about. If you are new to &lt;em&gt;Perspectives&lt;/em&gt;, here are a few tips to help get you started:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://feeds.feedburner.com/killswitchcollective/perspectives" target="_blank"&gt;Subscribe&lt;/a&gt; to &lt;em&gt;Perspectives&lt;/em&gt; by adding this URL to your RSS reader: http://feeds.feedburner.com/killswitchcollective/perspectives. Not using an RSS reader yet? &lt;a href="http://reader.google.com" target="_blank"&gt;Try Google Reader!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Start following &lt;code&gt;@KSCollective&lt;/code&gt; on Twitter for up-to-the-minute updates about what we are working on and thinking about.&lt;/li&gt;
  &lt;li&gt;Use the Category links in the sidebar to narrow down articles to topics that interest you (&lt;a href="http://killswitchcollective.com/blog/categories/Design" target="_blank"&gt;design&lt;/a&gt;,  &lt;a href="http://killswitchcollective.com/blog/categories/Development" target="_blank"&gt;development&lt;/a&gt;, etc).&lt;/li&gt;
  &lt;li&gt;Click on an author's picture at the bottom of their articles to read their other entries.&lt;/li&gt;
  &lt;li&gt;&lt;a href="mailto:info@killswitchcollective.com"&gt;Drop us a note&lt;/a&gt;, we'd love to answer any questions!&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Fri, 30 Jan 2009 07:27:43 -0800</pubDate>
      <link>http://www.killswitchcollective.com/articles/52</link>
      <guid>http://www.killswitchcollective.com/articles/52</guid>
    </item>
    <item>
      <title>Automatic Admin Interface with ActsAsAdminable</title>
      <category>Development</category>
      <description>&lt;p&gt;&lt;a href="http://github.com/ColinK/acts_as_adminable/tree/master"&gt;Just get ActsAsAdminable now!&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Admin Interfaces&lt;/h3&gt;

&lt;p&gt;I was recently working on a site for a client, which was just six simple pages and a CMS in the back-end to administrate content.   Our CMS let you add and edit the FAQs on the FAQ page, add/remove downloads on the "Resources" page, etc.  I took it to the client and his first question was, "How do I edit the footer?".  After discussing, it turned out the client needed the ability to edit any piece of text on the entire site, which was very rich in detail.  Every element on the page had a different layout or position, and so on.  It's a very graphically complex site!&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;could&lt;/em&gt; have extended the admin interface to support this.  But it wouldn't have fit well with the style of the rest of the admin interface. What would I call that page, "Scattered Bits of Miscellaneous Text"?  Something simpler, cleaner and more intuitive was needed.&lt;/p&gt;

&lt;h3&gt;Enter the Plugin&lt;/h3&gt;

&lt;p&gt;I searched for a plugin that would solve my problem but didn't find anything that exactly fit my situation, and I didn't look TOO hard because I was already excited at the prospect of writing my own. Long story short, I did, and it's called &lt;code&gt;acts_as_adminable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using it couldn't be simpler.   After you install it (or run &lt;code&gt;script/runner vendor/plugins/acts_as_adminable/install.rb&lt;/code&gt; if you got it via &lt;code&gt;git clone&lt;/code&gt;), you just go into your view, find the bit of text you want to replace, and turn it into a &lt;code&gt;content_tag&lt;/code&gt; with a &lt;code&gt;:key&lt;/code&gt; attribute &amp;mdash; and that's it! &lt;/p&gt;

&lt;h3&gt;An Example&lt;/h3&gt;

&lt;p&gt;Let's say you have code like this:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div class="header"&amp;gt;
  &amp;lt;h1&amp;gt;At Company Inc., our mission is to meet your needs&amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;To administrate this with &lt;code&gt;ActsAsAdminable&lt;/code&gt;, first rewrite it like so:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div class="header"&amp;gt;
  &amp;lt;%= &lt;span class="ident"&gt;content_tag&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:h1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;At Company Inc., our mission is to meet your needs&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:key&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;mission_statement&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;At this point your page should look exactly the same as it did a minute ago; &lt;code&gt;ActsAsAdminable&lt;/code&gt; is designed to be easily removed or disabled. Now you just need to tell your controller to make this page adminable:&lt;/p&gt;

&lt;pre&gt;
&lt;span style="color:#CC7833"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PagesController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#DA4939"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="ident"&gt;acts_as_adminable&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:if=&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#DA4939"&gt;Proc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;session&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span style="color:#6E9CBE"&gt;:current_user&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;is_admin?&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="punct"&gt;...&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;if&lt;/code&gt; parameter is a code snippet that you customize to match whatever you use for authentication.  After all, you don't want just &lt;em&gt;anybody&lt;/em&gt; to be able to edit your page!&lt;/p&gt;

&lt;h3&gt;Results&lt;/h3&gt;

&lt;p&gt;Now when you visit the page, you get a visual clue on mousing over any admin-enabled element.  And a single click pops up an Ajax control for editing its contents! Any changes you make will be reflected instantly and for all subsequent visitors.  There are only a few caveats:&lt;/p&gt;

&lt;ol style="padding-left: 40px; list-style-type: decimal;"&gt;
&lt;li&gt;The &lt;code&gt;:key&lt;/code&gt; argument must be a globally unique string.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;content_tag&lt;/code&gt; should also have a unique &lt;code&gt;id&lt;/code&gt; HTML attribute, although by default &lt;code&gt;ActsAsAdminable&lt;/code&gt; will use the &lt;code&gt;:key&lt;/code&gt; for that purpose if you didn't specify your own.  So also make sure that you either specify a unique "id" HTML attribute, or that the ":key" does not collide with any other element's "id" attribute.&lt;/li&gt;
&lt;li&gt;The edit field uses markdown for formatting, so &lt;a href="http://daringfireball.net/projects/markdown/basics"&gt;read up&lt;/a&gt; if you're not familiar with its syntax.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you know what to do with it, head over to &lt;a href="http://github.com/ColinK/acts_as_adminable/tree/master"&gt;github&lt;/a&gt; and simplify your site!&lt;/p&gt;
</description>
      <pubDate>Mon, 26 Jan 2009 12:45:25 -0800</pubDate>
      <link>http://www.killswitchcollective.com/articles/51</link>
      <guid>http://www.killswitchcollective.com/articles/51</guid>
    </item>
    <item>
      <title>Pool Party: Playing With Physics in Flash</title>
      <category>Development</category>
      <description>&lt;p&gt;Every once in a while we are asked to make a game for a client. I recently worked on a game that centered&amp;mdash;as many games do&amp;mdash;around a bouncing ball. I thought this would be a good opportunity to put together the first Killswitch multi-part flash tutorial. In this tutorial we'll build a simple but highly customizable billiards game. Credit goes to &lt;a href='http://www.tonypa.pri.ee/vectors/index.html'&gt;Tonypa's vector tutorial&lt;/a&gt; for some of the concepts and techniques on which this game is based. There is also a helpful article on &lt;a href='http://en.wikipedia.org/wiki/Euclidean_vector'&gt;Euclidean vectors&lt;/a&gt; on Wikipedia.&lt;/p&gt;

&lt;p&gt;In this first installment we&amp;apos;ll get things started with vectors&amp;mdash;the basic building block of the game&amp;mdash;and get a ball bouncing around inside a confined space.&lt;/p&gt;

&lt;h3&gt;So, What&amp;apos;s a Vector?&lt;/h3&gt;

&lt;p&gt;This isn&amp;apos;t drawing with vectors that we&amp;apos;re talking about here. This is physics. A vector is essentially a point (x and y coordinates) and a direction. It can be used to describe the position, direction and velocity of an object, describe forces like wind or gravity, describe obstacles like walls, determining collisions and so on. &lt;/p&gt;

&lt;p&gt;For this game I&amp;apos;ve created a Vector class which has a number of useful methods that are helpful for manipulating vectors. Ultimately they boil down to things like the pythagorean theorem, sine and cosine&amp;mdash;trigonometry stuff.&lt;/p&gt; 

&lt;p&gt;The constructor takes 4 attributes: x and y coordinates, deltaX (horizontal movement component) and deltaY (vertical movement component).&lt;/p&gt; 

&lt;pre&gt;var myVector:Vector = new Vector(1, 1, 4, 3);&lt;/pre&gt;

&lt;h3&gt;Vector Playground&lt;/h3&gt;

&lt;p&gt;Let's try it out. &lt;a href='http://www2.killswitchcollective.com/articles/physics1/actionscript/vectorPlayground.fla'&gt;Download&lt;/a&gt; a finished version of this movie for reference if you like.&lt;/p&gt;

&lt;p&gt;You&amp;apos;ll want to &lt;a href='http://www2.killswitchcollective.com/articles/physics1/actionscript/vector.as'&gt;download the Vector.as&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;Create a new flash (AS3) project. Name it something like &amp;ldquo;vectorPlayground.fla&amp;rdquo;. Save the project in the same directory as Vector.as or be sure to set the classpath to the directory of Vector.as (in publish settings). Directions on how to do this can be found in &lt;a href='http://livedocs.adobe.com/flash/9.0/UsingFlash/help.html?content=WS06D23361-54E6-4ac2-9D24-081C181BD2DF.html'&gt;Adobe's Flash documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a Sprite called &amp;ldquo;canvas&amp;rdquo; and add it to the stage. We&amp;apos;ll use the graphics package to draw the vectors.&lt;/p&gt;

&lt;pre&gt;
var canvas:Sprite = new Sprite();
addChild(canvas);&lt;/pre&gt;

&lt;p&gt;Write a function for drawing vectors:&lt;/p&gt;

&lt;pre&gt;
function drawVector(vector:Vector, color:uint):void{
	canvas.graphics.lineStyle(1, color);
	canvas.graphics.moveTo(vector.x, vector.y);
	canvas.graphics.lineTo(vector.x + vector.deltaX, vector.y + vector.deltaY);
}&lt;/pre&gt;

&lt;p&gt;This function takes a vector and a color for the lines it will draw.&lt;/p&gt;

&lt;p&gt;Now create a vector and draw it on the canvas:&lt;/p&gt;

&lt;pre&gt;
var myVector:Vector = new Vector(10, 10, 50, 300);
drawVector(myVector, 0x3F3F39);&lt;/pre&gt;

&lt;p&gt;try out some of the Vector methods:&lt;/p&gt;

&lt;pre&gt;
// set the vector's angle in degrees
myVector.setAngle(45);
drawVector(myVector, 0xFF55BB); // a pink line

// set the vector's length
myVector.setLength(50); 
drawVector(myVector, 0x5555FF); // a short blue line drawn on top of the pink one

// resets the vectors length and angle respectively
myVector.setPolar(200, 10);
drawVector(myVector, 0x55FF55); // a green line

// the getIntersection() method is used to find the point where two vectors intersect. 
var vector2:Vector = new Vector(100, 10, -20, 200);
drawVector(vector2, 0xDD2200); // a dark red line
var intersection:Point = vector2.getIntersection(myVector);
// draw a circle at the intersection point (x, y, radius)
canvas.graphics.drawCircle(intersection.x, intersection.y, 2);
&lt;/pre&gt;

&lt;p&gt;Ok, enough of that for now. It&amp;apos;s time start building the pool game.&lt;/p&gt; 

&lt;h3&gt;The Game&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://www2.killswitchcollective.com/articles/physics1/actionscript/poolParty.fla'&gt;Download&lt;/a&gt; a finished version of this movie for reference if you like. &lt;a href='http://www2.killswitchcollective.com/articles/physics1/preview_party.html' target='_blank'&gt;Preview the finished movie&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;apos;s start with a clean FLA. Call it &amp;ldquo;poolParty.fla&amp;rdquo;. Create a folder named &amp;ldquo;classes&amp;rdquo; in the same directory as pollParty.as and put Vector.as in there. Make sure that you set the classpath to the classes directory. Set the size of the document to 250x380. Set the background color to something dark (pool table green perhaps) because we&amp;apos;ll be playing with the (white) cue ball to start.&lt;/p&gt;

&lt;p&gt;I&amp;apos;ve created a Ball class that is essentially a circle that has its own vector. In a later installment we&amp;apos;ll spice it up a bit with some nicer graphics. This iteration of the Ball class has a method that draws a circle at the x and y coordinates of the Vector. The other method of note is &lt;code&gt;moveAlongVector()&lt;/code&gt;.&lt;/p&gt; 

&lt;pre&gt;
// Ball.as

public function moveAlongVector():void{
	drawMe();
	// put a cap on how fast the ball can move.
	if(vector.getLength() &gt; radius){
		vector.setLength(radius);
	}
	vector.x += vector.deltaX;
	vector.y += vector.deltaY;
	x = vector.x;
	y = vector.y;
}&lt;/pre&gt;

&lt;p&gt;This method draws the ball at its current location and then sets the vectors coordinates to the endpoint of the vector and moves the sprite to that point. Calling this repeatedly animates the ball along a line defined by its vector.&lt;/p&gt; 

&lt;p&gt;&lt;a href='http://www2.killswitchcollective.com/articles/physics1/actionscript/Ball.as'&gt;Download Ball.as&lt;/a&gt; and save it in the classes folder.&lt;/p&gt;

&lt;p&gt;Create a ball and add it to the stage. The constructor takes x and y coordinates, deltaX and deltaY, a radius and a color:&lt;/p&gt;

&lt;pre&gt;
// a global radius for all balls
var radius:Number = 7;

var cueBall:Ball = new Ball(180, 50, 1, 4, radius, 0xFFFFFF); 
addChild(cueBall);&lt;/pre&gt;

&lt;p&gt;This places a ball on the stage and sets its vector pointing down and to the right. The Ball constructor function draws the ball for us with a call to the private method &lt;code&gt;drawMe()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;apos;s make it move. In poolParty.fla set the frame rate to something high like 60fps. Write an event listener to move the ball along its vector:&lt;/p&gt;

&lt;pre&gt;
addEventListener(Event.ENTER_FRAME, updateMovement);

function updateMovement(e:Event):void{
	cueBall.moveAlongVector();
}&lt;/pre&gt;

&lt;p&gt;Test this and you should see the ball glide off the table. &lt;/p&gt;

&lt;p&gt;Create some borders for the table by making vectors that run along the edges of the stage. I set a margin variable (roughly the diameter of the ball) to set off the borders so there will be room to add in pockets later.&lt;/p&gt;

&lt;pre&gt;
var margin:Number = 16;

// borders
var top:Vector = new Vector(margin, margin, 250 - margin*2, 0);
var right:Vector = new Vector(250 - margin, margin, 0, 380 - margin*2);
var bottom:Vector = new Vector(margin, 380 - margin, 250 - margin*2, 0);
var left:Vector = new Vector(margin, margin, 0, 380 - margin*2);
var walls:Array = [top, right, bottom, left];

You may find it reassuring to know where your vectors are. Feel free to draw them in using the drawVector() function that we used earlier. Don't forget to add the canvas first: 

var canvas:Sprite = new Sprite();
canvas.graphics.lineStyle(1, 0x000000);
addChild(canvas);

for each(var w in walls){
	drawVector(w, 0xFF00EE);
}&lt;/pre&gt;

&lt;p&gt;In our &lt;code&gt;updateMovement()&lt;/code&gt; function we&amp;apos;ll want to add something to check for collisions. Because a ball might hit more than one thing at a time (other balls for example) we&amp;apos;ll call this function &lt;code&gt;determineFinalBounce()&lt;/code&gt; and pass it the ball and walls as arguments:&lt;/p&gt;

&lt;pre&gt;
function updateMovement(e:Event):void{
	cueBall.moveAlongVector();
	determineFinalBounce(cueBall, walls);
}&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;determineFinalBounce()&lt;/code&gt; function itself looks like this:&lt;/p&gt;

&lt;pre&gt;
function determineFinalBounce(ball:Ball, obstacles:Array):void{
	var vector = ball.getVector();
	var radius = ball.getRadius();
	var willBounce:Boolean = false; 

	// check walls for collisions and bounce accordingly
	for each(var o in obstacles){
		var vectorToObstacle:Vector = shortestDistance(vector, o);
		if(vectorToObstacle.getLength() &lt;= radius){
			bounce(vector, vectorToObstacle, radius);
		}
	}
}&lt;/pre&gt;

&lt;p&gt;This function checks all of the obstacles (walls) to see if the ball is close enough to any wall such that it should bounce off of it.&lt;/p&gt; 

&lt;p&gt;You&amp;apos;ll notice that there are two functions missing from the picture still: &lt;code&gt;shortestDistance()&lt;/code&gt; and &lt;code&gt;bounce()&lt;/code&gt;. Let&amp;apos;s look at &lt;code&gt;shortestDistance()&lt;/code&gt; first.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shortestDistance()&lt;/code&gt; is used to figure out the point of the wall that is closest to the ball.&lt;/p&gt; 

&lt;pre&gt;
function shortestDistance(v1:Vector, v2:Vector):Vector{
	// vector from start of v2 to start of v1
	var v2ToV1:Vector = new Vector(v2.x, v2.y, v1.x - v2.x, v1.y - v2.y);
	// create vector from ball to closest part of v2
	var shortest:Vector = v2ToV1.project(v2.normalLeft());
	// move start of shortest to start of v1.
	shortest.x = v1.x;
	shortest.y = v1.y;
	// rotate shortest 180&#176;
	shortest.deltaX *= -1;
	shortest.deltaY *= -1;

	return shortest;
}&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;shortestDistance()&lt;/code&gt; uses two Vector methods that we haven't seen before:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;normalLeft()&lt;/code&gt; returns a vector that runs perpendicular to the given vector. Think of it as the same vector rotated 90&amp;deg; counterclockwise.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;project()&lt;/code&gt; returns a vector that is a &amp;ldquo;projection&amp;rdquo; of one vector onto another. Imagine one vector casting a shadow onto the other.&lt;/p&gt;

&lt;p&gt;The whole function looks something like this if we drew all of the vectors involved line by line:&lt;/p&gt;

&lt;script type="text/javascript" src="http://www2.killswitchcollective.com/articles/physics1/javascript/swfobject.js"&gt; &lt;/script&gt;
&lt;script type="text/javascript"&gt;
swfobject.registerObject("sortestDistanceContent", "9.0.0", "swfs/expressInstall.swf");
swfobject.registerObject("bounceSlideShowContent", "9.0.0", "swfs/expressInstall.swf");
&lt;/script&gt;


&lt;object id="myId" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="550" height="210"&gt;
				&lt;param name="movie" value="http://www2.killswitchcollective.com/articles/physics1/swfs/shortestDistanceSlideShow.swf" /&gt;
        		&lt;!--[if !IE]&gt;--&gt;
				&lt;object type="application/x-shockwave-flash" data="http://www2.killswitchcollective.com/articles/physics1/swfs/shortestDistanceSlideShow.swf" width="550" height="210"&gt;
				&lt;!--&lt;![endif]--&gt;
				&lt;div&gt;
					&lt;h4&gt;This diagram requires flash.&lt;/h4&gt;
					&lt;p&gt;&lt;a href="http://www.adobe.com/go/getflashplayer"&gt;&lt;img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /&gt;&lt;/a&gt;&lt;/p&gt;
				&lt;/div&gt;
				&lt;!--[if !IE]&gt;--&gt;
				&lt;/object&gt;
				&lt;!--&lt;![endif]--&gt;
			&lt;/object&gt;

&lt;p&gt;if the length of the vector returned by &lt;code&gt;shortestDistance()&lt;/code&gt; is less than the radius of the ball, then we know that it has come in contact with the wall. Once we have figured out which wall the ball has most immediately come into contact with, we need to make it bounce off of that wall.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bounce()&lt;/code&gt; takes the vector of the ball, &lt;code&gt;shortest&lt;/code&gt; (the vector representing the shortest distance between the ball and the wall), and the ball's radius as arguments.&lt;/p&gt;

&lt;pre&gt;
// given a vector and the shortest distance between vector's endpoint and an obstacle
// move the vector back to the point where it makes contact (assuming a radius), 
// and reflect its path.
function bounce(v1:Vector, v2:Vector, radius:Number):void{
	// the amount and direction to back up
	var reverse:Vector = new Vector(v2.x, v2.y, -v2.deltaX, -v2.deltaY);
	reverse.setLength( (radius+1) - v2.getLength() );
	var reverseEP:Point = reverse.getEndpoint();

	//surface off of  which reflection will occur
	var surface:Vector = v2.normalLeft();
	var proj1:Vector =  v1.project(v2);
	var proj2:Vector = v1.project(surface);
	proj1.deltaX *= -1;
	proj1.deltaY *= -1;
	var reflection:Vector = proj1.sum(proj2);
	reflection.x = reverseEP.x;
	reflection.y = reverseEP.y;

	if(proj1.dotProduct(v2) &gt; 0){
		reflection.deltaX = v1.deltaX;
		reflection.deltaY = v1.deltaY;
	}
	v1.resetFromVector(reflection);
}&lt;/pre&gt;

&lt;p&gt;This function does the following:&lt;/p&gt;

&lt;p&gt;It finds the point at which the ball makes contact with the wall. It does this by creating a vector &lt;code&gt;reverse&lt;/code&gt;, starting at the center of the ball and at an angle of 180&amp;deg; from the balls current vector. The length is set to the difference between the radius and the shortest distance to the wall. The endpoint of &lt;code&gt;reverse&lt;/code&gt; is the point where the ball is when it makes contact with the wall.&lt;/p&gt;

&lt;p&gt;Then the ball&amp;apos;s vector is reflected at an angle found by summing the projection of the ball&amp;apos;s vector onto a line parallel to the wall, and the projection of the ball&amp;apos;s vector onto a line perpendicular to the wall. &lt;code&gt;sum()&lt;/code&gt; is a method of Vector that simply adds the &lt;code&gt;deltaX&lt;/code&gt; and &lt;code&gt;deltaY&lt;/code&gt; components of two vectors returning a vector with an angle and length somewhere between the two.&lt;/p&gt; 

&lt;p&gt;There are two other new methods here. The first is &lt;code&gt;dotProduct()&lt;/code&gt; which returns a number. I won't go into the details of how the dot product is found. The important part is that if the dot product of two vectors is positive it means that they are pointing toward each other, if it is negative then they are pointing away. &lt;code&gt;bounce()&lt;/code&gt; checks the dot product of &lt;code&gt;v2&lt;/code&gt; (shortest) and the reversed projection of &lt;code&gt;v1&lt;/code&gt; onto &lt;code&gt;v2&lt;/code&gt;. If it is greater than 0 then we know that the ball was moving away from the wall to begin with, and that reflecting it would be a bad idea because it would turn the ball back toward the wall, which would result in unnatural behavior. &lt;/p&gt;

&lt;p&gt;The function looks something like this:&lt;/p&gt;

&lt;object id="myId" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="550" height="210"&gt;
				&lt;param name="movie" value="http://www2.killswitchcollective.com/articles/physics1/swfs/bounceSlideShow.swf" /&gt;
        		&lt;!--[if !IE]&gt;--&gt;
				&lt;object type="application/x-shockwave-flash" data="http://www2.killswitchcollective.com/articles/physics1/swfs/bounceSlideShow.swf" width="550" height="210"&gt;
				&lt;!--&lt;![endif]--&gt;
				&lt;div&gt;
					&lt;h4&gt;This diagram requires flash.&lt;/h4&gt;
					&lt;p&gt;&lt;a href="http://www.adobe.com/go/getflashplayer"&gt;&lt;img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /&gt;&lt;/a&gt;&lt;/p&gt;
				&lt;/div&gt;
				&lt;!--[if !IE]&gt;--&gt;
				&lt;/object&gt;
				&lt;!--&lt;![endif]--&gt;
			&lt;/object&gt;

&lt;p&gt;Add the &lt;code&gt;shortestDistance()&lt;/code&gt; and &lt;code&gt;bounce()&lt;/code&gt; functions to &lt;code&gt;poolParty.fla&lt;/code&gt; and test it out. You should see your ball bouncing around the screen like an old-school screen saver.&lt;/p&gt; 

&lt;p&gt;Now, I know someone is asking &amp;ldquo;Hang on, why do we need to mess around with all of these vectors? Why not just check the ball&amp;apos;s coordinates against the borders of the table and tell it to bounce back when it&amp;apos;s gone too far? That would be a lot easier.&amp;rdquo; That is true, it would be easier and it would work. But the vector technique allows for borders that are not strictly horizontal or vertical. It allows the game designer to build a table with 3, 5, 6 or however many sides they want. Go ahead and try it. Maybe you want to rotate the table a bit or give it a three-dimensional feel with some pseudo-perspective. We will also be using the vectors to determine the correct angle of bouncing when two or more balls collide with another.&lt;/p&gt; 

&lt;p&gt;That does it for this stage of the the tutorial. Next time we'll add some more balls and smack 'em around. &lt;/p&gt;
</description>
      <pubDate>Mon, 19 Jan 2009 07:37:57 -0800</pubDate>
      <link>http://www.killswitchcollective.com/articles/50</link>
      <guid>http://www.killswitchcollective.com/articles/50</guid>
    </item>
  </channel>
</rss>
