tag:blogger.com,1999:blog-42582099817371574402024-02-18T19:06:48.745-08:00TreadGaming - Run in Games - LiterallyUse your exercise tool such as a treadmill and a computer to enjoy exercising!Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.comBlogger145125tag:blogger.com,1999:blog-4258209981737157440.post-85538897635607108972019-03-27T08:41:00.002-07:002019-03-27T08:41:36.917-07:00TreadGaming v2 Research ModeHey!<br />
<br />
I just wanted to make a quick post saying that this TreadGaming project of mine has been very fun to work with and I had a new sparkle to work towards doing TreadGaming v2.<br />
<br />
I'm currently in "research mode", finding hardware and thinking about what to do to make this new version even better and easier than previous version. If you have ideas/suggestions or any feedback, please do let me know over at <a href="mailto:treadgaming@gmail.com">treadgaming@gmail.com</a>Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-57489858809799099882016-09-29T01:02:00.000-07:002016-09-29T01:02:09.947-07:00A Map to Perfection: Using D3.js to Make Beautiful Web Maps<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-size: large;"><b><i>Writer's Note</i>: In Game development, effective mapping has proven to be more useful, as it has been a key component of games such as Pokemon Go and the like. This guide would help readers to create maps of their own. Take note, however, that there are various ways to do this though and this is one of those ways.</b></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Data Driven Documents, or <a href="http://d3js.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">D3.js</a>, is “a JavaScript library for manipulating documents based on data”. Or to put it more simply, D3.js is a data visualization library. It was developed by <a href="http://bost.ocks.org/mike/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Mike Bostock</a> with the idea of bridging the gap between static display of data, and <a href="https://www.toptal.com/designers/interactive" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">interactive</a> and animated data visualizations.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
D3 is a <a href="http://bl.ocks.org/mbostock/3231307" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">powerful library</a> with a ton of uses. In this tutorial, I’ll discuss one particularly compelling application of D3: map making. We’ll go through the common challenges of building a useful and informative web map, and show how in each case, D3.js gives <a href="https://www.toptal.com/javascript" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">capable JavaScript developers</a> everything they need to <a href="https://www.toptal.com/web/the-roadmap-to-roadmaps-a-survey-of-the-best-online-mapping-tools" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">make maps</a> look and feel beautiful.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Use this D3.js tutorial to develop web maps" src="https://assets.toptal.io/uploads/blog/image/700/toptal-blog-image-1418135533053.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="what-is-d3js-used-for" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What is D3.js used for?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
D3.js can bind any arbitrary data to a Document Object Model (DOM), and then, through the use of JavaScript, CSS, HTML and SVG, apply transformations to the document that are driven by that data. The result can be simple HTML output, or interactive SVG charts with dynamic behavior like animations, transitions, and interaction. All the data transformations and renderings are done client-side, in the browser.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
At its simplest, D3.js can be used to manipulate a DOM. Here is a simple example where D3.js is used to add a paragraph element to an empty document body, with “Hello World” text:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-html hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-doctype" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><!DOCTYPE html></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">html</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">meta</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">charset</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"utf-8"</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">title</span>></span>D3 Hello World<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">title</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"http://d3js.org/d3.v3.min.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">type</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"text/javascript"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
d3.select(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"body"</span>).append(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"p"</span>).text(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"Hello World"</span>);
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">html</span>></span>
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The strength of D3.js, however, is in its data visualization ability. For example, it can be used to create <a href="http://bl.ocks.org/mbostock/3885304" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">charts</a>. It can be used to create <a href="http://bost.ocks.org/mike/nations/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">animated charts</a>. It can be even used to <a href="http://www.nytimes.com/interactive/2014/01/11/us/politics/who-controls-the-states-and-where-they-stand.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">integrate and animate different connected charts</a>.</div>
<h2 id="d3-for-web-maps-and-geographic-data-visualization" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
D3 for Web Maps and Geographic Data Visualization</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But D3.js can be used for much more than just DOM manipulation, or to draw charts. D3.js is extremely powerful when it comes to handling <a href="http://svemir.co/2013/05/18/is-d3-a-new-web-mapping-tool/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">geographical information</a>. Manipulating and presenting geographic data can be very tricky, but building a map with a D3.js is quite simple.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Here is a D3.js example that will draw a world map based on the data stored in a JSON-compatible data format. You just need to define the size of the map and the geographic projection to use (more about that later), define an SVG element, append it to the DOM, and load the map data using JSON. Map styling is done via CSS.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-html hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-doctype" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><!DOCTYPE html></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">html</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">meta</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">charset</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"utf-8"</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">title</span>></span>D3 World Map<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">title</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">style</span>></span><span class="css" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">path</span> <span class="hljs-rules" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">{
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stroke</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> white</span></span>;
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stroke-width</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.5</span>px</span></span>;
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fill</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> black</span></span>;
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">}</span></span>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">style</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"http://d3js.org/d3.v3.min.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"http://d3js.org/topojson.v0.min.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">type</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"text/javascript"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> width = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">900</span>;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> height = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">600</span>;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> projection = d3.geo.mercator();
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> svg = d3.select(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"body"</span>).append(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"svg"</span>)
.attr(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"width"</span>, width)
.attr(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"height"</span>, height);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> path = d3.geo.path()
.projection(projection);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> g = svg.append(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"g"</span>);
d3.json(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"world-110m2.json"</span>, <span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(error, topology)</span> {</span>
g.selectAll(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"path"</span>)
.data(topojson.object(topology, topology.objects.countries)
.geometries)
.enter()
.append(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"path"</span>)
.attr(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"d"</span>, path)
});
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">html</span>></span></code></pre>
<h2 id="geographic-data-for-d3" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Geographic Data for D3</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For this D3.js tutorial, keep in mind that map building works best with data formatted in JSON formats, particularly the <a href="http://geojson.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">GeoJSON</a> and <a href="https://github.com/mbostock/topojson" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">TopoJSON</a> specifications.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
GeoJSON is “a format for encoding a variety of geographic data structures”. It is designed to represent discrete geometry objects grouped into feature collections of name/value pairs.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
TopoJSON is an extension of GeoJSON, which can encode topology where geometries are “stitched together from shared line segments called arcs”. TopoJSON eliminates redundancy by storing relational information between geographic features, not merely spatial information. As a result, geometry is much more compact and combined where geometries share features. This results with 80% smaller typical TopoJSON file than its GeoJSON equivalent.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So, for example, given a map with several countries bordering each other, the shared parts of the borders will be stored twice in GeoJSON, once for each country on either side of the border. In TopoJSON, it will be just one line.</div>
<h2 id="map-libraries-google-maps-and-leafletjs" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Map Libraries: Google Maps and Leaflet.js</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Today, the most popular mapping libraries are <a href="https://developers.google.com/maps/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Google Maps</a> and <a href="http://leafletjs.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Leaflet</a>. They are designed to get “slippy maps” on the web fast and easy. “Slippy maps” is a term referring to modern JavaScript-powered web maps that allow zooming and panning around the map.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Leaflet is a great alternative to Google Maps. It is an open source JavaScript library designed to make mobile-friendly interactive maps, with simplicity, performance and usability in mind. Leaflet is at its best when leveraging the big selection of raster-based maps that are available around the internet, and brings the simplicity of working with tiled maps and their presentation capabilities.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Leaflet can be used with great success when <a href="http://bost.ocks.org/mike/leaflet/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">combined with D3.js’s data manipulation features</a>, and for utilizing D3.js for vector based graphics. Combining them together brings out the best in both libraries.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Maps are more difficult to combine with D3.js, since Google Maps are not open source. It is possible to use <a href="http://bl.ocks.org/mbostock/899711" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Google Maps and D3</a> together, but this is mostly limited to overlaying data with D3.js over Google Maps background maps. Deeper integration is not really possible, without hacking.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/javascript/a-map-to-perfection-using-d3-js-to-make-beautiful-web-maps#" style="border: 0px; box-sizing: border-box; color: #3976cb; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptal" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h2 id="projections---beyond-spherical-mercator" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Projections - Beyond Spherical Mercator</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The question of how to project maps of the 3-dimensional spherical Earth onto 2-dimensional surfaces is an <a href="https://en.wikipedia.org/wiki/Map_projection" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">old and complex problem</a>. Choosing the best projection for a map is an important decision to make for every web map.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In our simple world map D3.js tutorial above, we used the <a href="http://wiki.openstreetmap.org/wiki/EPSG:3857" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Spherical Mercator</a> projection coordinate system by calling <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">d3.geo.mercator()</code>. This projection is also known as <a href="https://en.wikipedia.org/wiki/Web_Mercator" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Web Mercator</a>. This projection was popularized by Google when they introduced <a href="https://developers.google.com/maps/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Google Maps</a>. Later, other web services adopted the projection too, namely<a href="http://www.openstreetmap.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">OpenStreetMap</a>, <a href="http://www.bing.com/maps/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bing Maps</a>, <a href="http://here.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Here Maps</a> and <a href="http://www.mapquest.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">MapQuest</a>. This has made Spherical Mercator a very popular projection for online slippy maps.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
All mapping libraries support the Spherical Mercator projection out of the box. If you want to use other projections, you will need to use, for example, the <a href="http://trac.osgeo.org/proj4js/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Proj4js</a> library, which can do any transformation from one coordinate system to another. In the case of Leaflet, there is a <a href="https://github.com/kartena/Proj4Leaflet" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Proj4Leaflet</a> plugin. In the case of Google Maps, there is, well, nothing.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
D3.js brings cartographic projections to a whole new level with built-in support for many different <a href="https://github.com/mbostock/d3/releases/v3.0.0" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">geographic projections</a>. D3.js models geographic projections as full geometric transformations, which means that when straight lines are projected to curves, D3.js applies configurable adaptive resampling to subdivide lines and eliminate projection artifacts. The <a href="https://github.com/d3/d3-geo-projection/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Extended Geographic Projections D3 plugin</a> brings the number of supported projections to over 40. It is even possible to create a whole new custom projection using <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">d3.geo.projection</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">d3.geo.projectionMutator</code>.</div>
<h2 id="raster-maps" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Raster Maps</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As mentioned before, one of the main strengths of D3.js is in working with vector data. To use raster data there is an option to combine D3.js with Leaflet. But there is also an option to do everything with just D3.js using <a href="https://github.com/d3/d3-plugins/tree/master/geo/tile" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">d3.geo.tile</a> to create <a href="http://bl.ocks.org/mbostock/5342063" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">slippy maps</a>. Even with just D3.js alone, people are doing <a href="http://bl.ocks.org/dwtkns/4710879" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">amazing things</a> with raster maps.</div>
<h2 id="vector-manipulation-on-the-fly" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Vector Manipulation on the Fly</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One of the biggest challenges in classic cartography is <a href="https://en.wikipedia.org/wiki/Cartographic_generalization" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">map generalization</a>. You want to have as much detailed geometry as you can, but that data needs to adapt to the scale of the displayed map. Having too high a data resolution increases download time and slows down rendering, while too low a resolution ruins details and topological relations. Slippy maps using vector data can run into a big problem with map generalization.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One option is to do map generalization beforehand: to have different datasets in different resolutions, and then display the appropriate dataset for the current selected scale. But this multiplies datasets, complicates data maintenance, and is prone to errors. Yet most mapping libraries are limited to this option.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The better solution is to do map generalization on the fly. And here comes D3.js again, with its powerful data manipulation features. D3.js enables <a href="http://bost.ocks.org/mike/simplify/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">line simplification to be done in browser</a>.</div>
<h2 id="i-want-more" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I want more!</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="D3 data visualization is a great solution for map building projects like this example." src="https://assets.toptal.io/uploads/blog/image/701/toptal-blog-image-1418135547803.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
D3.js is not easy to master and it has a steep learning curve. It is necessary to be familiar with a lot of technologies, namely JavaScript objects, the jQuery chaining syntax, SVG and CSS, and of course <a href="https://github.com/mbostock/d3/wiki/API-Reference" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">D3’s API</a>. On top of that, one needs to have a bit of design skill to create nice graphics in the end. Luckily, D3.js has a big community, and there are a lot of resources for people to dig into. A great starting point for learning D3 is<a href="https://github.com/mbostock/d3/wiki/Tutorials" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">these tutorials</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you like learning by examining examples, Mike Bostock has shared <a href="http://bost.ocks.org/mike/example/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">more than 600 D3.js examples</a> on his webpage. All D3.js examples have git repository for version control, and are forkable, cloneable and commentable.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you are using CartoDB, you’ll be glad to hear that <a href="http://blog.cartodb.com/post/39680106243/cartodb-makes-d3-maps-a-breeze" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">CartoDB makes D3 maps a breeze</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And for a little bonus at the end, here’s one of my favorite examples showing off the amazing things D3 is capable of:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="http://svemir.co/2014/01/24/earth-global-wind-map/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">earth</a>, a global animated 3D wind map of the entire world made with D3.js. Earth is a visualization of global weather conditions, based on weather forecasts made by supercomputers at the National Centers for Environmental Prediction, NOAA / National Weather Service and converted to JSON. You can customize displayed data such as heights for the wind velocity readings, change overlaid data, and even change Earth projection.</li>
</ul>
<div>
<span style="color: #303030; font-family: Proxima Nova, Arial, sans-serif;"><span style="font-size: 19.2px;"><br /></span></span></div>
<div>
<span style="color: #303030; font-family: Proxima Nova, Arial, sans-serif;"><span style="font-size: 19.2px;">Source: <a href="https://www.toptal.com/javascript/a-map-to-perfection-using-d3-js-to-make-beautiful-web-maps">Toptal</a></span></span></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-26249493206271134482016-09-21T01:19:00.002-07:002016-09-21T01:19:40.174-07:00The 10 Most Common Mistakes That Unity Developers Make<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unity is a great and straightforward tool to use for multi-platform development. Its principles are easy to understand, and you can intuitively begin to create your products. However, if some things are not taken in mind, they’ll slow your progress when you proceed with your work to the next level, as you are moving from initial prototype phase or approaching a final release. This article will provide advice on how to overcome most common problems and how to avoid fundamental mistakes in your new or existing projects. Please note, the perspective of this article is focused more on 3D application development, but everything mentioned is applicable for 2D development as well.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Unity" src="https://assets.toptal.io/uploads/blog/image/92534/toptal-blog-image-1463999901470-890f01e4c68a2bc84d05a8c2c59f5264.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="background-color: #fafafa; color: #505050; font-size: 1.3em; text-align: center;">Unity is a great and straightforward tool to use for multi-platform development.</span></div>
<h2 id="common-unity-mistake-1-underestimating-project-planning-phase" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #1: Underestimating Project Planning Phase</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For every project, it’s crucial to determine several things before the application design and programming part of the project even begins. These days, when product marketing is an important part of the whole process, it’s also important to have a clear idea of what the business model of the implemented application will be. You have to be sure what platforms you will be releasing product for, and what platforms are in your plan. It’s also necessary to set the minimal supported devices specifications (will you support older low-end devices or just more recent models?) to have the idea of what performance and visuals you can afford. Every topic in this article is influenced by this fact.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
From a more technical point of view, it should be necessary to set in advance the whole workflow of creating assets and models while providing them to the programmer, with particular attention to iteration process when the models will need some more changes and refinements. You should have a clear idea about desired frame rate and vertex budget, so the 3D artist can know in what maximal resolution the models have to be, and how many LOD variations he has to do. It should also be specified how to unify all the measurements to have a consistent scale, and import process throughout the whole application.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The way the levels will be designed is crucial for future work because the division of the level influences the performance a lot. Performance concerns have to always be in your mind when designing new levels. Don’t go with unrealistic visions. It’s always important to ask yourself the question “can it be reasonably achieved?” If not, you shouldn’t waste your precious resources on something hardly achievable (in case it’s not part of your business strategy to have it as your main competitive advantage, of course).</div>
<h2 id="common-unity-mistake-2-working-with-unoptimized-models" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #2: Working with Unoptimized Models</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s critical to have all your models well prepared to be able to use them in your scenes without further modifications. There are several things that the good model should fulfill.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s important to set the scale correctly. Sometimes it’s not possible to have this correctly set from your 3D modeling software because of different units these applications are using. To make everything right, set the scale factor in models import settings (leave 0.01 for 3dsMax and Modo, set 1.0 for Maya), and note that sometimes you will need to re-import objects after changing the scale setting. These settings should assure that you can use just basic scale 1,1,1 in your scenes to get consistent behavior and no physics problems. Dynamic batching will also more likely work correctly. This rule should also be applied on every subobject in the model, not just the main one. When you need to tweak object dimensions, do it with regards to other objects in 3D modeling application rather than in Unity. However, you can experiment with scale in Unity to find out appropriate values, but for the final application and consistent workflow, it’s good to have everything well prepared before importing to Unity.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Regarding object’s functionality and their dynamic parts - have your models well divided. The fewer subobjects, the better. Separate parts of the object just in case when you need them, for example, to move or rotate dynamically, for animation purposes, or other interactions. Every object and its subobjects should have its pivot properly aligned and rotated with regards to its main function. The main object should have the Z axis pointing forward and pivot should be at the bottom of the object for better placement to the scene. Use as few materials on objects as possible (more on this below).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
All assets should have proper names which will easily describe its type and functionality. Keep this consistency throughout all of your projects.</div>
<h2 id="common-unity-mistake-3-building-interdependent-code-architecture" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #3: Building Interdependent Code Architecture</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Prototyping and implementation of functionality in Unity is quite easy. You can easily drag and drop any references to other objects, address every single object in the scene, and access every component it has. However, this can also be potentially dangerous. On top of noticeable performance issues (finding an object in the hierarchy and access to components has its overhead), there is also great danger in making parts of your code entirely dependent on each other. Or being dependent on other systems and scripts unique to your application, or even on the current scene, or current scenario. Try to take a more modular approach and create reusable parts which can be used in other parts of your application, or even shared across your whole application portfolio. Build your framework and libraries on top of Unity API the same way you are building your knowledge base.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There’s a lot of different approaches to ensure this. A good starting point is the Unity component system itself. Complications may appear when particular components need to communicate with other systems of the application. For this, you can use interfaces to make parts of your system more abstract and reusable. Alternatively, you can use an event-driven approach for reacting to particular events from outside scope, either by creating a messaging system or by registering directly to parts of the other system as listeners. The right approach will be trying to separate gameObject properties from program logic (at least something like model-controller principle), because it’s tough to identify which objects are modifying its transform properties, like position and rotation. It should be exclusively its controller’s responsibility.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Try to make everything well documented. Treat it always like you should return to your code after a long time and you need to understand quickly what exactly this part of the code is doing. Because in reality, you will quite often get to some parts of your application after some time and it’s an unnecessary obstacle for quickly jumping into the problem. But do not overdo this. Sometimes, an appropriate class, method or property name is quite sufficient.</div>
<h2 id="common-unity-mistake-4-wasting-your-performance" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #4: Wasting Your Performance</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The latest product line of mobile phones, consoles, or desktop computers will never be so advanced that there will be no need to care about performance. Performance optimizations are always needed, and they provide the foundation for making the difference in how your game or application looks like in comparison to others on the market. Because when you save some performance in one part, you can use that to polish other parts of your application.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are a lot of areas for optimizations. The whole article would be needed just to scratch the surface about this topic. At least, I will try to divide this domain into some core areas.</div>
<h3 id="update-loops" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Update Loops</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Don’t use performance intensive things in update loops, use caching instead. A typical example is an access to components or other objects in a scene or intensive calculations in your scripts. If possible, cache everything in <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Awake()</code> methods, or change your architecture to a more event-driven approach to trigger things just when they’re needed.</div>
<h3 id="instantiations" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Instantiations</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For objects that are instantiated quite often (for example, bullets in an FPS game), make a pre-initialized pool of them and just pick one already initialized when you need it and activate it. Then, instead of destroying it when it is not required anymore, deactivate it and return it to the pool.</div>
<h3 id="rendering" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rendering</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Use occlusion culling or LOD techniques to limit rendered parts of the scene. Try to use optimized models to be able to keep vertex count in the scene under control. Be aware, vertex count isn’t just the number of vertices on the model itself, but it’s influenced by other things like normals (hard edges), UV coordinates (UV seams) and vertex colors. Also, a number of dynamic lights in the scene will dramatically influence overall performance, so try to bake everything in advance whenever possible.</div>
<h3 id="draw-calls" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Draw Calls</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Try to reduce draw calls count. In Unity, you can achieve draw calls reduction by using static batching for still objects and dynamic batching for the moving ones. However, you have to prepare your scenes and models first (batched objects have to share same materials), and batching of dynamic objects works only for low-res models. Alternatively, you could combine meshes by the script into one (<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Mesh.CombineMeshes</code>) instead of using batching, but you have to be careful not to create too large objects which can’t take advantage of view frustum culling on some platforms. In general, the key is to use as little materials as possible and share them across the scene. You will sometimes need to create atlases from textures to be able to share one material between distinct objects. A good <a href="https://www.toptal.com/unity-unity3d/tips-and-practices" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tip</a> is also to use higher resolution of scene lightmaps textures (not generated resolution, but texture output resolution) to lower their number when you are baking light in larger environments.</div>
<h3 id="overdraw-problems" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Overdraw Problems</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Don’t use transparent textures when not necessary, as it will cause fill-rate problems. It is okay to use it for complicated and more distant geometry, like trees or bushes. When you need to use it, prefer alpha blended shaders instead of shaders with alpha testing or instead of cutout shaders for mobile platforms. For identifying these problems in general, try to lower the resolution of your application. If it helps, it might be possible that you have these fill-rate problems, or you need to optimize your shaders more. Otherwise, it can be a more memory problem.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptal" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h3 id="shaders" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Shaders</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Optimize your shaders for better performance. Reduce the number of passes, use variables with lower precision, replace complicated math calculations with pre-generated lookup textures.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Always use a profiler to determine the bottlenecks. It’s a great tool. For rendering, you can also use awesome Frame Debugger, which will help you learn a lot about how things work in general when decomposing rendering processes with it.</div>
<h2 id="common-unity-mistake-5-ignoring-garbage-collection-problems" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #5: Ignoring Garbage Collection problems</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is necessary to realize that despite the fact that Garbage Collector (GC) itself helps us to be really efficient and focused on important things in programming, there are a few things we should be explicitly aware of. The usage of GC isn’t free. Generally, we should avoid unnecessary memory allocations to prevent GC from firing itself too often and thus spoiling performance by framerate spikes. Ideally, there shouldn’t be any new memory allocations happening regularly each frame at all. However, how can we achieve this goal? It’s really determined by application architecture, but there are some rules you could follow which help:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Avoid unnecessary allocations in update loops.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Use structs for simple property containers, as they’re not allocated on the heap.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Try to preallocate arrays or lists or other collections of objects, instead of creating them inside update loops.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Avoid using mono problematic things (like LINQ expressions or foreach loops, for example) because Unity is using an older, not ideally optimized version of Mono (at the time of writing it is modified version 2.6, with upgrade on the roadmap).</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Cache strings in <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Awake()</code> methods or in events.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">If update of string property in update loop is necessary, use StringBuilder object instead of string.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Use profiler to identify potential problems.</li>
</ul>
<h2 id="common-unity-mistake-6-optimizing-memory-and-space-usage-last" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #6: Optimizing Memory and Space Usage Last</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is necessary to keep the attention on the lowest memory and space usage of the application from the beginning of the project, as it is more complicated to do it when you leave optimization for pre-release phase. On mobile devices, this is even more important, because we are quite short on resources there. Also, by exceeding 100MB size of the installation, we can lose a significant amount of our customers. This is because of the 100MB limit for cellular network downloads, and also because of psychological reasons. It is always better when your application doesn’t waste customer’s precious phone resources, and they will be more likely to download or buy your app when its size is smaller.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For finding resource drainers, you can use editor log where you can see (after every new build) the size of resources divided into separate categories, like audio, textures, and DLLs. For better orientation, there are editor extensions on the Unity Asset Store, which will provide you a detailed summary with referenced resources and files in your filesystem. Actual memory consumption can also be seen in the profiler, but it is recommended to test it when connected to build on your target platform because there are a lot of inconsistencies when testing in an editor or on anything other than your target platform.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The biggest memory consumers are often textures. Preferably, use compressed textures as they take much less space and memory. Make all textures squared, ideally, make the length of both sides power of two (POT), but keep in mind Unity can also scale NPOT textures to POT automatically. Textures can be compressed when being in the POT form. Atlas textures together to fill the whole texture. Sometimes you can even use texture alpha channel for some extra information for your shaders to save additional space and performance. And of course, try to reuse textures for your scenes as much as possible, and use repeating textures when it is possible to retain good visual appearance. For low-end devices, you can lower the resolution of textures in Quality Settings. Use compressed audio format for longer audio clips, like the background music.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When you are dealing with different platforms, resolutions or localizations, you can use asset bundles for using different sets of textures for different devices or users. These asset bundles can be loaded dynamically from the internet after the application was installed. This way, you can exceed the 100MB limit by downloading resources during the game.</div>
<h2 id="common-unity-mistake-7-common-physics-mistakes" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #7: Common Physics Mistakes</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sometimes, when moving objects in the scene, we don’t realize that the object has a collider on it and that changing its position will force the engine to recalculate the whole physical world all over again. In that case, you should add <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Rigidbody</code> component to it (you can set it to non-kinematic if you don’t want external forces to be involved).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To modify the position of the object with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Rigidbody</code> on it, always set <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Rigidbody.position</code> when a new position doesn’t follow the previous one, or <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Rigidbody.MovePosition</code> when it is a continuous movement, which also takes interpolation into account. When modifying it, apply operations always in <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">FixedUpdate</code>, not in <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Update</code>functions. It will assure consistent physics behaviors.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If possible, use primitive colliders on gameObjects, like sphere, box, or cylinder, and not mesh colliders. You can compose your final collider from more than one of these colliders. Physics can be a performance bottleneck of your application because of its CPU overhead and collisions between primitive colliders are much faster to calculate. You can also adjust Fixed Timestep setting in Time manager to reduce the frequency of physics fixed updates when the accuracy of physics interaction isn’t so necessary.</div>
<h2 id="common-unity-mistake-8-manually-testing-all-functionality" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #8: Manually Testing All Functionality</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sometimes there might be a tendency to test functionality manually by experimenting in the play mode because it is quite fun and you have everything under your direct control. But this cool factor can decrease quite quickly. The more complex the application becomes, the more tedious tasks the programmer has to repeat and think about to assure that the application behaves as it was originally intended. It can easily become the worst part of the whole development process, because of its repetitive and passive character. Also, because the manual repetition of testing scenarios isn’t that fun, so there’s a higher chance that some bugs will make it through the whole testing process.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unity has great testing tools to automate this. With appropriate architectural and code <a href="https://www.toptal.com/designers/web/portfolios">design</a>, you can use unit tests for testing isolated functionality, or even integration tests for testing more complex scenarios. You can dramatically reduce <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">try-and-check</em> approach where you’re logging actual data and comparing it with its desired state.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Manual testing is without a doubt a critical part of the development. But its amount can be reduced, and the whole process can be more robust and faster. When there’s no possible way to automate it, prepare your test scenes to be able to get into the problem you are trying to solve as quickly as possible. Ideally, a few frames after hitting the play button. Implement shortcuts or cheats to set the desired state for testing. Also, make the testing situation isolated to be sure what’s causing the problem. Every unnecessary second in the play mode when testing is accumulated, and the bigger the initial bias of testing the problem, the more likely you won’t test the problem at all, and you will hope that all works just fine. But it probably won’t.</div>
<h2 id="common-unity-mistake-9-thinking-unity-asset-store-plugins-will-solve-all-your-problems" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #9: Thinking Unity Asset Store Plugins Will Solve All Your Problems</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Trust me; they won’t. When working with some clients, I sometimes faced the tendency or relicts from the past of using asset store plugins for every single little thing. I don’t mean there aren’t useful Unity extensions on the <a href="https://www.assetstore.unity3d.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Unity Asset Store</a>. There are many of them, and sometimes it’s even hard to decide which one to choose. But for every project, it is important to retain consistency, which can be destroyed by unwisely using different pieces that do not fit well together.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
On the other hand, for functionality which would take a long time for you to implement, it is always useful to use well-tested products from Unity Asset Store, which can save you a huge amount of your development time. However, pick carefully, use the proven ones which won’t bring a lot of uncontrollable and weird bugs to your final product. Five-star reviews are a good measure for a start.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If your desired functionality isn’t hard to implement, just add it to your constantly growing personal (or company’s) libraries, which can be used in all of your projects later again. That way you are improving your knowledge and your toolset at the same time.</div>
<h2 id="common-unity-mistake-10-having-no-need-to-extend-unity-basic-functionality" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Common Unity Mistake #10: Having No Need to Extend Unity Basic Functionality</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sometimes it may seem that Unity Editor environment is quite sufficient for basic game testing and level design, and extending it is a waste of time. But trust me, it is not. Unity’s great extension potential comes from being able to adapt it to specific problems which need to be solved in various projects. This can either improve the user experience when working in Unity or dramatically speed up the entire development and level design workflow. It would be unfortunate not to use built-in features, like built-in or custom Property Drawers, Decorator Drawers, custom component inspector settings, or even to not build whole plugins with its own Editor Windows.</div>
<h2 id="conclusion" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Conclusion</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I hope these topics will be useful for you as you move your Unity projects further. There are a lot of things which are project specific, so they can’t be applied, but it’s always useful to have some basic rules in mind when trying to solve more difficult and specific problems. You might have different opinions or procedures on how to solve these problems in your projects. The most important is to keep your idioms consistent throughout your project so that anyone in your <a href="https://www.toptal.com/unity-unity3d" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">team</a> can clearly understand how the particular domain should have been solved correctly.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a href="https://www.toptal.com/resume/tomas-macek" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Tomas Macek</a>, a <a href="https://www.toptal.com/unity-unity3d/top-unity-development-mistakes">Toptal</a><a href="https://www.toptal.com/technical-writers"> freelance developer</a>.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-50495683062797126022016-09-15T02:47:00.001-07:002016-09-15T02:47:49.590-07:00Ultimate Guide to the Processing Language Part I: The Fundamentals<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You are struggling with boredom, and itching to use your creativity. You want to build something, something visually impressive, something artsy. Or maybe you want to learn programming and make something impressive as soon as possible. If so, then the Processing language is the way to go.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Among all the programming languages I have worked with so far, Processing was without a doubt one of the most entertaining ones. It is a straightforward language - easy to learn, understand and use, yet it is very powerful. It is almost like you are painting on an empty canvas with lines of code. There are no rigid rules or guidelines whatsoever to limit your creativity, the only limit is your imagination.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Ultimate Guide to the Processing language Part I: The Fundamentals" src="https://assets.toptal.io/uploads/blog/image/91817/toptal-blog-image-1448633072046-a4d16767df10603e31a696ae39aa74b4.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In college I was a teaching assistant of a program that gathered high school students and taught them Processing. Most of them didn’t have a strong programming background, some hadn’t even written a single line of code before. In only five days, they were expected to learn the language and build simple games of their own. The success rate was almost a hundred percent, we rarely faced failure. In this article, this is exactly what we’ll be doing. I shrank down the entire program into two parts. First part, I will be talking about the language. I will give a basic overview, a walkthrough for Processing and I will give some tips & tricks. Then in the next part, we will build a simple game step by step, each step will be explained in detail. I will also convert the code of the game into <a href="https://www.toptal.com/javascript/tips-and-practices" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">JavaScript</a> using p5js, so that our game can run in a web browser.</div>
<h3 id="what-you-should-already-know" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What You Should Already know</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To understand and easily follow these articles, you should have a basic knowledge of programming, as I will not be talking about programming fundamentals. I will mostly not be touching any advanced programming concepts though, so a superficial understanding will do. There are some parts where I talk about some low level ideas and concepts such as object-oriented programming (OOP), but they are not crucial. Those are for curious readers who are interested in the structure of the language. If you don’t want to know, you can just skip those parts. Other than that, the only thing you should have is the ambition to learn this awesome language and enthusiasm to create your own game!</div>
<h3 id="how-to-follow" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How to Follow</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I’m always in favor of learning programming by trying and experimenting. The sooner you dive into your own game, the faster you’ll get comfortable with Processing. So that will be my first suggestion, try each and every step in your own environment. Processing has a simple and easy to use IDE (i.e. a code editor), it is the only thing you’ll need to download & install to follow. You can download it <a href="https://processing.org/download/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">from here</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So let’s get started!</div>
<h2 id="what-is-the-processing-language" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What is the Processing Language?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This section includes a brief technical overview of the language, its structure and some notes on the compilation and execution process. The details will include some advanced knowledge on programming and the Java environment. If you don’t mind about details for now and can’t wait to learn and code your own game, you can skip to the “Fundamentals of Processing” section.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Processing is a visual programming language that allows you to sketch with codes, so to speak. However it is not exactly a programming language on its own, it is what they call a “Java-esque” programming language, which means the language is built on top of the Java platform, but is not exactly Java per se. It is based on Java and all your code gets preprocessed and converted directly into Java code when you hit the run button. Java’s PApplet class is the base class for all Processing sketches. To give an example, let’s take a couple of basic processing code blocks:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">public void setup() {
// setup codes goes here
}
public void draw() {
// draw codes goes here
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
These code blocks will be converted into something like this:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-java hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-class" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ExampleFrame</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">extends</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Frame</span> {</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ExampleFrame</span>() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">super</span>(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"Embedded PApplet"</span>);
setLayout(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> BorderLayout());
PApplet embed = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Embedded();
add(embed, BorderLayout.CENTER);
embed.init();
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-class" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Embedded</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">extends</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">PApplet</span> {</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">setup</span>() {
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// setup codes goes here</span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">draw</span>() {
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// draw codes goes here</span>
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You can see that the processing code block was wrapped with a class that extends from Java’s <a href="http://processing.googlecode.com/svn/trunk/processing/build/javadoc/core/processing/core/PApplet.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">PApplet</a>. Therefore, all the classes you define in your processing code, if any, will be treated as inner classes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The fact that Processing is Java based gives us a lot of advantages, especially if you are a <a href="https://www.toptal.com/java" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Java developer</a>. Not only is the syntax familiar, but it also gives you the ability to do things like embedding Java code, libraries, JAR files in your sketches, using your Processing applets directly in your Java applications, defining classes and using standard data types such as int, float, char and so on. You can even write your Pocessing code directly from Eclipse, if you want to <a href="https://processing.org/tutorials/eclipse/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">spend some time</a> to set it up. One thing you can’t do is use AWT or Swing components in your Processing sketches, because they conflict with the looping nature of Processing. But don’t worry, we will not be doing any of that fancy stuff in this article.</div>
<h2 id="fundamentals-of-processing" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Fundamentals of Processing</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Processing code consists of two main parts, <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">setup</span> and <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">draw</span> blocks. Setup block runs once when the code gets executed, and the draw blocks runs continuously. The main idea behind Processing is, <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">what you write within the draw block will be executed 60 times per second from top to bottom, until your program terminates</span>. We will build everything by taking advantage of this this very idea. We will make our objects move, keep our scores, detect collisions, implement gravity, and do pretty much everything else using this feature. <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">This refresh loop is the heartbeat of our project</span>. I will be explaining how to use this heartbeat to bring your code to life in later sections. First, let me introduce you to the Processing IDE.</div>
<h3 id="processing-ide" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Processing IDE</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91818/toptal-blog-image-1448633127924-e3fb6e37d307575b33158f9bccba4358.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you have read until this point and still didn’t download the Processing IDE, please go ahead and <a href="https://processing.org/download/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">do it</a>. Throughout the article, I will outline some easy tasks for you to try on your own, you can only practice if you have the IDE up and running. Here is a brief introduction of the processing IDE. It is very simple and self explanatory, so I will keep it short.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As you’d expect, run and stop buttons do what they suggest. When you click on the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">run</span> button, your code will get compiled and executed. By nature, processing programs never get terminated, they run forever and ever until they get disturbed. You can terminate it programmatically, however if you don’t, you can use the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stop</span>button.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The button that looks like a butterfly on the right of the run & stop is the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">debugger</span>. Using the debugger needs a whole other article dedicated to it. It is out of the scope of this article, so you can ignore it for now. The dropdown next to debugger button is where you add / set mods. <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Mods</span> provide you some certain functionality, allow you to write code for Android, allow you to write code in Python, and so on and so forth. Mods are also out of the scope, so you can keep it in the default Java mode and ignore it as well.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The window on the code editor is where your sketches normally run. In the image it is blank, because we haven’t set any property like size or background color, or we didn’t draw anything.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is nothing much to talk about the code editor, it is simply where you write your code. There are line numbers<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(!)</span> Older versions of Processing didn’t have that and you can’t imagine how happy I was when I first saw them.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The black box below is the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">console</span>. We will use it to print out stuff for quick debugging purposes. The <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">errors</span>tab next to the console is where your errors will appear. This is also a new useful feature that came with Processing 3.0. In the older versions, the errors were printed to the console and it was hard to keep track of them.</div>
<h3 id="setup-block" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Setup Block</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As stated before, setup blocks get executed once when the program starts. You can use it for making configurations and for things that you’d like to run only once, for instance, loading images or sounds. Here is an example setup block. Run this code in your own environment and see the results for yourself.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">public void setup() {
// Size of our sketch will be 800x600,
// and use the P2D rendering engine.
size(800, 600, P2D);
// We could have used this function instead of size()
// fullScreen(P2D);
// The background color of our sketch will be black
// by default, unless specified otherwise
background(0);
// We could have used this to set a background image.
// Note that size of our sketch should be the same as the image.
// background(loadImage("test.jpg"));
// Shapes and objects will be filled with red by default,
// unless specified otherwise.
fill(255,0,0);
// Shaped and objects will have a white border by default,
// unless specified otherwise.
stroke(255);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The methods related with styling (background, fill, stroke) will be explained at the properties & settings sections. For now, what you need to know is how the settings and configurations we set here affects our whole sketch. Codes written here are used to set some base rulesets applicable throughout the sketch. What you should also understand in this section are the methods listed below:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">size()</span> - As the name suggests, this function is used to configure the size of our sketch. It has to be in the first line of the setup code block. It could be used in the following forms:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">size(width,height);</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">size(width, height, renderer);</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The width and height values could be given in pixels. Size function accepts a third parameter, renderer, which is used to set which rendering engine our sketch will use. By default, the renderer is set to P2D. The available renderers are P2D (Processing 2D), P3D (Processing 3D, should be used if your sketches will include 3D graphics) and PDF (2D graphics are drawn directly into an Acrobat PDF file. More inforation can be found<a href="https://processing.org/reference/libraries/pdf/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>). P2D and P3D renderers make use of OpenGL compatible graphics hardware.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fullScreen()</span> - As of Processing 3.0, fullScreen function can now be used instead of the size() function. Just like the size() function, it should be in the first line of the setup block as well. The usage is as follows:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fullScreen();</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fullScreen(display);</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fullScreen(renderer);</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fullScreen(display, renderer);</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you use it without any parameters, your processing sketch will simply run in fullscreen, and will run on your main display. The ‘display’ parameter is used to set on which display your sketch will run. For example if you connect external monitors to your computer, you can set the display variable to 2 (or 3, 4 etc.) and your sketch will run there. The ‘renderer’ parameter is as explained at the size() part above.</div>
<h3 id="settings-block" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Settings Block</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is another feature that is introduced with the new release of Processing. It is a code block, just like setup and draw. It is useful when you want to define size() or fullScreen() methods with variable parameters. It is also necessary to define size() and other styling properties such as smooth() in this code block if you are using any environment other than Processing’s own IDE, such as Eclipse. But you will not be needing it in most cases, definitely not in this article.</div>
<h3 id="draw-block" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Draw Block</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is nothing special to talk about the draw block, yet everything is special about it. Draw block is where all the magic happens. It is the heart of your program, beating 60 times a second. This code block houses all your code logic. All your shapes, objects etc. will be written in here.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Most of the code we will talk about in this article is going to be from the draw block, so it is important that you clearly understand how this code block works. To give you a demonstration, here is something you can try. First note that we can print anything to the console by using the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">print()</span> or <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">println()</span> methods. Print methods only print to the console, println however prints and appends a newline at the end, so each println() will print in separate rows.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So, take a look at the following code block. First, try to guess what it will print in the console. Then, go ahead and try it out:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">void setup(){
}
void draw(){
int x = 0;
x += 1;
print(x+" ");
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you guessed “1 2 3 4…”, I got you! This is one of the confusions in Processing. Remember this block repeatedly gets executed? When you define a variable here, it gets defined on each loop over and over again. On each iteration, x is set to 0, gets incremented by 1 and gets printed to the console. Therefore we get the result “1 1 1 1…”. This example was somewhat obvious, but it may be confusing when things get a little complicated.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We don’t want x to get overwritten, so how can we achieve this and get the result “1 2 3 4…” ? By using <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">global variables</span>. This is nothing fancy, we only define the variable outside of draw block so it doesn’t get re-defined on each iteration. Also, the scope of the variable will be reachable throughout the sketch. See the code below:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">int x = 0;
void setup(){
}
void draw(){
x += 1;
print(x+" ");
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You might be asking yourself, how can a variable defined outside of our blocks work? And why didn’t we use the setup() block since it gets executed once at the beginning? The answer is related with object-oriented programming and scopes, if you are not familiar, you may skip this paragraph. Refer to the part where I explained how Processing code gets converted into Java. Remember how they get wrapped with a Java class? The variables we write outside of setup() and draw() block also gets wrapped, therefore they are treated as <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fields</span> of the outer class that wraps our code. Using x+=1 is the same as using this.x+=1. It also functions the same in our case, no variable called x is defined in the scope of draw() and an outer scope is searched, which is the scope of <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>. And why didn’t we define our variable x in the setup() section? If we did, the scope of which x is defined would be the scope of the setup function and it wouldn’t be accessible from the draw() block.</div>
<h3 id="drawing-shapes--texts" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Drawing Shapes & Texts</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91822/toptal-blog-image-1448633489960-773f96a1286d06000527d184b9212638.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now we know how to configure our sketch using the setup block, and we know what draw block does. So it is time to get a little visual and learn about the fun parts of processing: how to draw shapes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before we begin, you should understand the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">coordinate system</span>. In Processing, you determine the coordinates of every object you draw on the screen. The coordinate system is in pixels. The origin (ie. starting point) is the top left corner, you should give your coordinates relative to that point. Another thing you should know is, each shape has a different reference point. For example, rect() has its top left corner as a reference point. For ellipse(), it is the center. These reference points can be changed with methods like rectMode() and ellipseMode(), which I will be explaining in the properties & settings section. An example figure is provided to help you understand better.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article is a basic overview of Processing, so we will not be touching any complex shapes like vertexes or 3D shapes. Basic 2D shapes will actually be more than enough for us to create our own game. In the figure, you can see examples of how shapes are drawn. Each shape has its own syntax to be created, but the basic idea is to give either its coordinates or its sizes or both. Here are some shapes you should be familiar with (for all values given below, ‘x’ and ‘y’ means x and y coordinates in pixels, ‘w’ and ‘h’ means width and height values also in pixels):</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">point()</span> - Simple point, only needs a single coordinate. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">point(x, y)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">point(x, y, z) - In case you are using 3 dimensions.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">line()</span> - For creating a line. You can create a line with only a starting and ending point. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">line(x1, y1, x2, y2)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">line(x1, y1, z1, x2, y2, z2) - In case you are using 3 dimensions.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">triangle()</span> - For creating a triangle. Usage: triangle(x1, y1, x2, y2, x3, y3)</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">quad()</span> - For creating a quadrilateral. Usage: quad(x1, y1, x2, y2, x3, y3, x4, y4)</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rect()</span> - For creating a rectangle. The reference point is top left corner by default (refer to the figure). Here is the usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rect(x, y, w, h)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rect(x, y, w, h, r) - ‘r’ mean the radius in pixels to make the corners rounded.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rect(x, y, w, h, tl, tr, br, bl) - Radius for top left, top right, bottom right, bottom left corners respectively. This is also in pixels.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ellipse()</span> - For creating an ellipse shape. This is also used to create a circle, same width and height values should be given. The reference point for this shape is the center by default (refer to the figure). Here is the usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ellipse(x, y, w, h)</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">arc()</span> - Draw an arc. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">arc(x, y, w, h, start, stop) - ‘start’ and ‘stop’ is used to determine the angle to start and stop drawing the arc. Values are in radians. Constants such as “PI, HALF_PI, QUARTER_PI and TWO_PI” can be used.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">arc(x, y, w, h, start, stop, mode) - ‘mode’ variable is to determine the rendering style of the arc (string). Available options are “OPEN, CHORD, PIE”. OPEN will leave the non-drawn parts borderless. CHORD will complete the non-drawn parts with a border. PIE will make your arc look like a pie chart.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Displaying texts on the screen is similar to displaying shapes, the basic idea is that you determine a coordinate at which you want your text to be displayed. There is however more to handling texts. You will have more control over your texts after the properties & settings section, where you’ll learn how to apply settings and properties to objects. For now, I will show the basics of displaying texts. There are many ways to do it, I’ll only show the essentials.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text()</span> - Display texts. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text(c, x, y) - ‘c’ means character, any alphanumeric character will be displayed.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text(c, x, y, z) - In case you are working with 3 dimensions.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text(str, x, y) - ‘str’ is the string to be displayed.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text(str, x, y, z) - In case you are working with 3 dimensions.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text(num, x, y) - ‘num’ is the numeric value to be displayed.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">text(num, x, y, z) - In case you are working with 3 dimensions.</li>
</ul>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/game/ultimate-guide-to-processing-the-fundamentals#" style="border: 0px; box-sizing: border-box; color: #3976cb; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptal" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-image: initial; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-right-color: initial; border-right-style: initial; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h3 id="properties--settings" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Properties & Settings</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First thing that should be explained in this section would be the logic behind setting properties of objects. Fill color, background color, border, border width, border color, alignment of the shapes, border styles etc. could be some examples of these properties.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When you set a property, you have to remember that the code will be executing from <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">top to bottom</span>. Say, you set the “fill” property to red, all the objects drawn below that line will be filled with red until it gets overwritten by another fill property. Same thing applies for other properties as well, however note that not all properties will overwrite each other. For example “stroke” property doesn’t overwrite “fill” property, instead they work together. Here is a visual representation for you to comprehend the logic:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91820/toptal-blog-image-1448633259843-00c25f8cc6434290dcbf0baf28a7191a.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As you can see in the image, first line sets the fill color to red and the second line sets the stroke color to blue. We now have two active settings: fill red and blue strokes. As you’d expected, whatever our object may be on the next line, it will be filled with red and have blue strokes (if applicable). You can keep examining the image this way, and you will grasp the logic.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Here are some essential properties & settings that are commonly used:</div>
<h4 id="styling-settings" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Styling settings</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fill()</span> - Sets the fill color to objects. This setting is also used to color texts. For now, we only need to know the following usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fill(r, g, b) - Red, green and blue values as integer</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fill(r, g, b, a) - Additional alpha value, max is 255</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">noFill()</span> - Sets the fill color to transparent.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stroke()</span> - Sets the stroke color to objects. Stroke property is applicable for lines and borders around objects. For now, we only need to know the following usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stroke(r, g, b) - Red, green and blue values as integer.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stroke(r, g, b, a) - Additional alpha value, max is 255</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">noStroke()</span> - Removes the stroke.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">strokeWeight()</span> - Sets the width of the stroke. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">strokeWeight(x) - x is an integer and represents the width of stroke in pixels.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">background()</span> - Sets the background color. For now, we only need to know the following usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">background(r, g, b) - Red, green and blue values as integer.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">background(r, g, b, a) - Additional alpha value, max is 255</li>
</ul>
<h4 id="alignment-settings" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Alignment Settings</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ellipseMode()</span> - Sets where to take as reference point aligning ellipses. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ellipseMode(mode) - ‘mode’ is the parameter, here are the available parameters:<ul style="border: 0px; box-sizing: border-box; font-size: 1em; list-style: none; margin: 1em 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">CENTER (default): Take the center as the reference point.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">RADIUS: This also takes the center as a the reference point, but in this mode, the w and h values you specify are treated as half (ie. radius instead of diameter)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">CORNER: Takes top left corner as a reference point.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0px 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">CORNERS: Sets the first two parameters (x and y) as the location of the top-left corner, and last two parameters (w and h) as the location of the bottom left corner of the ellipse. So this mode, “width” and “height” is irrelevant. Thinking it as ellipse(x_tl,y_tl,x_br,y_br) makes more sense in this case.</li>
</ul>
</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rectMode()</span> - Sets where to take as reference point aligning rectangles. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rectMode(mode) - ‘mode’ is the parameter, here are the available parameters:<ul style="border: 0px; box-sizing: border-box; font-size: 1em; list-style: none; margin: 1em 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">CENTER: Take the center as the reference point.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">RADIUS: This also takes the center as a the reference point, but in this mode, the w and h values you specify are treated as half</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">CORNER (default): Takes top left corner as a reference point.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0px 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">CORNERS: Sets the first two parameters (x and y) as the location of the top-left corner, and last two parameters (w and h) as the location of the bottom left corner of the ellipse. So this mode, “width” and “height” is irrelevant. Thinking of it as rect(x_tl,y_tl,x_br,y_br) makes more sense in this case.</li>
</ul>
</li>
</ul>
<h4 id="text-related-settings" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Text Related Settings</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textSize()</span> - Sets the font size of text. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textSize(size) - Integer value of the desired size.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textLeading()</span> - Sets the line height of your texts. Usage:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textLeading(lineheight) - Pixel value of the space between lines.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textAlign()</span> - Sets where to take as reference point aligning texts. Usage.</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textAlign(alignX) - ‘alignX’ is for horizontal alignment. Available: LEFT, CENTER, RIGHT</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">textAlign(alignX, alignY) - ‘alignY’ is for vertical alignment. Available: TOP, BOTTOM, CENTER, BASELINE.</li>
</ul>
<h3 id="animations" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Animations</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So far, we learned how to draw objects and texts. But the problem with them is that they are static. Now how do we make them move? Simple, <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">instead of giving coordinates as integers, we use variables so that we can increment / decrement them</span>. Make sense? Take a look at the following code:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">// initialize x and y as 0
int x=0;
int y=0;
void setup(){
size(800,600);
background(255); // set background color to white
}
void draw(){
fill(255,0,0); // fill color red
stroke(0,0,255); // stroke color blue
ellipseMode(CENTER); // ref. point to ellipse is its center
ellipse(x, y, 20, 20); // draw the ellipse
// increment x and y
x+=5;
y+=5;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Do you see how we managed the animation? We set x and y as global variables and their initial value to 0. In our draw loop, we created our ellipse, set the fill color to red, stroke color to blue and coordinates to x and y. When we increment x and y, the ball simply changes its location. But there is a problem with this code, can you notice it? As an easy challenge for yourself, try to figure what the problem is, and test it out. Here is the outcome:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91821/toptal-blog-image-1448633400679.screen.22-1a86a42b9af96ac38e7e7d285ab93ca6.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
My intention for letting this happen was to make you realise how the looping nature of Processing works. Refer to example at the “Draw Block” section, do you remember why we got “1 1 1…” instead of “1 2 3…” ? The same reason why the ball is leaving marks behind. Each time the draw block iterates, x and y gets incremented by 5 and therefore the ball gets redrawn to 5 pixels down and right. However the ball is drawn from the previous iterations remain in the view. How do we make them go away? Any guesses?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To get rid of the marks the ball leaves behind, we simply remove the background(255) from setup block, and paste it to be the very first line of the draw block. When our background code was in the setup block, it ran one time at the beginning, making our background white. But that isn’t enough, we need it to set our background to white on each loop to cover the balls drawn from the previous loops. Background being the first line means it runs first, it becomes the base layer. On each loop, our canvas is painted white, and new elements gets drawn on top of the white background. So we have no marks.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
That is the idea behind animating things in Processing, manipulating the objects’ coordinates programmatically to change their location. But how will we do fancy stuff, such as keeping the ball in the screen? Or maybe implementing gravity? I will teach how to do this stuff in next part of this article. We will learn by trying and building. We will learn how to do it and apply them to our game immediately. At the end, we will have a complete, playable, and hopefully fun game.</div>
<h3 id="keyboard--mouse-interactions" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Keyboard & Mouse Interactions</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Keyboard & mouse interactions in Processing are very easy and straightforward. There are methods you can call for each event, and what you write inside will be executed once when the event occurs. Also there are global variables such as mousePressed and keyPressed you can use in your draw block to take advantage of the loop. Here are some of the methods with explanations:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">void setup() {
size(500, 500);
}
void draw() {
if (mousePressed) {
// Codes here will be executed as long as the mouse
// button is pressed
if (mouseButton == LEFT){
// This lines will be executed as long as
// the clicked mouse button is the left mouse
// button.
}
}
if (keyPressed) {
// Codes here will be executed as long as a key
// on the keyboard is pressed
if (key == CODED) {
// This if statement checks if the pressed key
// is recognised by Processing.
if (keyCode == ENTER) {
// This lines will be executed if the pressed key
// is the enter key.
}
}
else{
// This lines will be executed if the pressed key
// is not recognised by processing.
}
}
}
void mousePressed() {
// These codes will be executed once, when mouse
// is clicked. Note that mouseButton variable is
// also be used here.
}
void keyPressed() {
// These codes will be executed once, when a key
// is pressed. Note that key and keyCode variables
// are also usable here.
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As you can see, it is pretty easy to check whether the mouse is clicked or which key is being pressed. There are however more options available for mousePressed and keyCode variables. Available options for<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">mousePressed</span> are LEFT, RIGHT and CENTER. There are many more available for <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">keyCode</span>; UP, DOWN, LEFT, RIGHT, ALT, CONTROL, SHIFT, BACKSPACE, TAB, ENTER, RETURN, ESC and DELETE.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One thing to know about the mouse variables, and we will use this a lot, is how to get the coordinates of the mouse. To get the exact coordinates of the cursor, we can use <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">mouseX</span> and <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">mouseY</span> variables directly in the draw() block. Last but not least, there are a lot of other useful methods that you should take a look at. They are all documented in the <a href="https://processing.org/reference/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Processing Reference</a>.</div>
<h2 id="conclusion" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Conclusion</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You should be getting familiar with Processing by now. However if you stop here, all this knowledge will <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">fly</em>away. I strongly recommend you continue practicing, playing around with what you have learned. To help you practice, I will provide you with two exercises. You should try your best to do it on your own. If you get stuck,<a href="http://google.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Google</a> and <a href="https://processing.org/reference/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Processing Reference</a> should be your best friends. I will provide the code for the first one, but looking at them should be the last thing that you do.</div>
<h4 id="recommended-exercise-1" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Recommended Exercise 1</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You should make <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4 balls</span> with <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">different colors</span>, starting from <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4 corners</span> of the screen <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">traveling through the center</span> with <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">different speeds</span>. When you click and hold the mouse button, the balls should <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">freeze</span>. And when you let go of the mouse, the balls could go back to their initial position and keep moving. So, I am looking for something like <a href="http://i.imgur.com/XuppyGg.gif" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">this</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After you try the exercise yourself, you may check out the code <a href="https://gist.github.com/oguzgelal/13d2e0b1cd98b62c3986" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>.</div>
<h4 id="recommended-exercise-2" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Recommended Exercise 2</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Remember the famous <a href="https://www.youtube.com/watch?v=B6mtmlX7Vrw" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">DVD screensaver</a> which the DVD logo bounces around the screen and we all waited desperately for it to hit the corner? I want you to replicate that screensaver, but only using a rectangle instead of the DVD logo. When you start the app, the screen should be black and the rectangle should start at a random location. Each time the rectangle hits the corner, it should change its color (and obviously direction). When you move the mouse around, the rectangle should disappear and the background color should turn white (it is a screensaver, isn’t it?). I will not give the code for this exercise in this article. You should try your best to implement it, and the code will be provided in the second part of this article.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">The second part of the ultimate guide to Processing, <a href="https://www.toptal.com/game/ultimate-guide-to-processing-simple-game" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a step-by-step tutorial</a> to building a simple game, has been published on a prior article on <a href="http://treadgaming.blogspot.com/2016/07/ultimate-guide-to-processing-part-ii.html">Treadgaming</a>.</em></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">This article was written by </em><a href="https://www.toptal.com/resume/oguz-gelal" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Oguz Gelal</a>, a <a href="https://www.toptal.com/game/ultimate-guide-to-processing-the-fundamentals">Toptal</a><a href="https://www.toptal.com/technical-writers"> freelance developer</a>.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-25392160955554453572016-09-06T03:23:00.001-07:002016-09-06T03:23:35.108-07:00Mastering 2D Cameras in Unity: A Tutorial for Game Developers<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For a developer, the camera is one of the cornerstones of the game development process. From just showing your game view in a chess app to masterfully directing camera movement in a 3D AAA game to obtain cinematic effects, cameras are basically used in any video game ever made, even before actually being called “cameras”.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this article I’m going to explain how to design a camera system for 2D games, and I’m also going to explain some points on how to go about implementing it in one of the most popular game engines out there, <a href="https://unity3d.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Unity</a>.</div>
<h2 id="from-2d-to-25d-an-extensible-camera-system" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
From 2D to 2.5D: An Extensible Camera System</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The camera system we are going to design together is modular and extensible. It has a basic core consisting of several components which will ensure the basic functionality, and then various components/effects that can be optionally used, depending on the situation at hand.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The camera system we are building here is targeted at 2D platform games, but can easily extended to other types of 2D games, 2.5D games or even 3D games.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Mastering 2D Camera in Unity: A Tutorial for Game Developers" src="https://assets.toptal.io/uploads/blog/image/92295/toptal-blog-image-1459426983370-1fc070dd29272b79bda1f255e384ff46.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="background-color: #fafafa; color: #505050; font-size: 1.3em; line-height: 1.5em; text-align: center;">Mastering 2D Camera in Unity: A Tutorial for Game Developers</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I am going to split the camera functionality into two main groups: camera tracking and camera effects.</div>
<h3 id="tracking" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Tracking</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Most of the camera movement we’ll do here will be based on tracking. That is the ability of an object, in this case the camera, to track other objects as they move about in the game scene. The types of tracking that we’ll be implementing are going to solve some common scenarios encountered in 2d platform games, but they can be extended with new types of tracking for other particular scenarios you might have.</div>
<h3 id="effects" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Effects</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We will be implementing some cool effects like camera shake, camera zoom, camera fade, and color overlay.</div>
<h2 id="getting-started" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Getting Started</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Create a new 2D project in Unity and import standard assets, especially the RobotBoy character. Next, create a ground box and add a character instance. You should be able to walk and jump with your character in your current scene. Make sure the camera is set to Orthographic mode (it is set to Perspective by default).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92296/toptal-blog-image-1459427126197-16574a9c6f4cf7dcb7dc8cf6e9727c39.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="tracking-a-target" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Tracking a Target</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The following script will add basic tracking behavior to our main camera. The script must be attached as a component to the main camera in your scene and it exposes a field for assigning a target object to track. Then the script ensures the x and y coordinates of the camera are the same with the object it tracks. All this processing is done during the Update step.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">protected</span> Transform trackingTarget;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
transform.position = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Vector3(trackingTarget.position.x,
trackingTarget.position.y, transform.position.z);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Drag the RobotBoy character from your scene hierarchy over the “Tracking Target” field exposed by our following behavior in order to enable tracking of the main character.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92297/toptal-blog-image-1459427180546-b240a261afddb6a07cf455d35ecfe2ff.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="adding-offset" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Adding Offset</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
All good, but we can see a limitation straight off the bat: the character is always in the center of our scene. We can see a lot behind the character, which is usually stuff we are not interested in, and we are seeing too little of what is ahead of our character, which might be detrimental to the gameplay.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To solve this, we are adding some new fields to the script that will allow the positioning of the camera at an offset from its target.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> xOffset;
[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> yOffset;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
transform.position = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Vector3(trackingTarget.position.x + xOffset,
trackingTarget.position.y + yOffset, transform.position.z);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Below you can see a possible configuration for the two new fields:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92298/toptal-blog-image-1459427216755-dcfcfb381fbbc6100acbaab9613654ab.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="smoothing-things-out" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Smoothing Things Out</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The camera movement is pretty stiff and will also produce dizziness in some players from the constant perceived movement of the environment. In order to fix this we’ll be adding some delay in camera tracking using linear interpolation, and a new field to control how fast the camera gets into place after the character starts changing its position.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">protected</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> followSpeed;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">protected</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">override</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Update</span>()
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> xTarget = trackingTarget.position.x + xOffset;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> yTarget = trackingTarget.position.y + yOffset;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> xNew = Mathf.Lerp(transform.position.x, xTarget, Time.deltaTime * followSpeed);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> yNew = Mathf.Lerp(transform.position.y, yTarget, Time.deltaTime * followSpeed);
transform.position = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Vector3(xNew, yNew, transform.position.z);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92299/toptal-blog-image-1459427246898-7ec836367444be2e1e2c381d5a52e577.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="stop-the-dizziness-axis-locking" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Stop the Dizziness: Axis Locking</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since it is not pleasant for your brain to watch the camera going up and down all the time along with the character, we are introducing axis locking. This means we can limit the tracking to only one axis. Then we’ll separate our tracking code into axis independent tracking, and we’ll take the new locking flags into account.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">protected</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bool</span> isXLocked = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">protected</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bool</span> isYLocked = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> xNew = transform.position.x;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (!isXLocked)
{
xNew = Mathf.Lerp(transform.position.x, xTarget, Time.deltaTime * followSpeed);
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> yNew = transform.position.y;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (!isYLocked)
{
yNew = Mathf.Lerp(transform.position.y, yTarget, Time.deltaTime * followSpeed);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92300/toptal-blog-image-1459427332415-f91fbfd89ae5b1f73b68e0104a20c9f1.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/unity-unity3d/2d-camera-in-unity#" style="border: 0px; box-sizing: border-box; color: #3976cb; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptal" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h2 id="lane-system" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Lane System</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now that the camera only tracks the player horizontally, we are limited to the height of one screen. If the character climbs some ladder or jumps higher than this, we have to follow. The way we are doing this is by using a lane system.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Imagine the following scenario:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92301/toptal-blog-image-1459427342443-78277efb8650b2dee4e73476c684e3a1.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The character is initially on the lower lane. While the character remains within the boundaries of this lane the camera will be moving only horizontally on lane specific height offset we can set.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As soon as the character enters another lane, the camera will transition to that lane and continue to move horizontally from there on until the next lane change occurs.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Care must be taken on lane design in order to prevent fast lane switching during actions like jumps, which can create confusion for the player. A lane should be changed only if the player’s character is going to stay on it for a while.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Lanes’ levels can change throughout the game level based on the designer’s specific needs, or can be interrupted altogether and another camera tracking system can take their place. Therefore, we need some limiters for specifying lane zones.</div>
<h3 id="implementation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Implementation</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A possible implementation is to add lanes as simple objects in the scene. We will use their Y position coordinate paired with Y offset in the tracking script above to implement the system. Therefore, their positioning on the X and Z coordinates does not matter.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Add the LaneSystem class to camera, along with the tracking class, and assign the lane objects to the provided array. Also assign the player character to the Reference field. As the reference is positioned between a lane and another lane, the lower one of the two will be used to position the camera.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92302/toptal-blog-image-1459427377095-9f67be7b84a39e089c8c25aba63f0e30.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And the LaneSystem class takes care of moving the camera between lanes, based on reference position. The followSpeed is used here again for position interpolation, to prevent lane switching from being too abrupt:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
Transform reference;
[SerializeField]
List<Transform> lanes;
[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> followSpeed = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">5</span>f;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> targetYCoord = transform.position.y;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (lanes.Count > <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < lanes.Count - <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>; ++i)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> ((reference.position.y > lanes[i].position.y) &&
(reference.position.y <= lanes[i + <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>].position.y))
{
targetYCoord = lanes[i].position.y;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>;
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (i == lanes.Count - <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>)
targetYCoord = lanes[lanes.Count - <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>].position.y;
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">else</span>
{
targetYCoord = lanes[<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>].position.y;
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> yCoord = Mathf.Lerp(transform.position.y, targetYCoord, Time.deltaTime * followSpeed);
transform.position = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Vector3(transform.position.x, yCoord, transform.position.z);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This implementation is not a WYSIWYG one, and is left as such as an exercise for the reader.</div>
<h2 id="lock-node-system" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Lock Node System</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Having the camera move on lanes is great, but sometimes we need the camera to be locked on to something, a point of interest (POI) in the game scene.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This can be achieved by configuring such POI in the scene and attaching a trigger collider to them. Whenever the character enters that trigger collider, we move the camera and stay on the POI. As the character moves and then leaves the POI’s trigger collider, we get back to another type of tracking, usually the standard follow behavior.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92303/toptal-blog-image-1459427456057-70a9bfff555233310dc18cca78487ccc.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The switching of the camera tracking to a lock node and back can be done either by a simple switch or by a stack system, on which tracking modes are pushed and popped.</div>
<h3 id="implementation-1" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Implementation</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to configure a lock node, just create an object (can be empty or like in the screenshot below, a sprite) and attach a large Circle Collider 2D component to it so it marks the area the player will be in when the camera will focus the node. You can choose any type of collider, I’m choosing Circle as an example here. Also create a tag you can easily check for, like “CameraNode” and assign it to this object.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92304/toptal-blog-image-1459427484471-9ea90187935b909b78a6d8d5418ef2fe.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Add the following property to the tracking script on your camera:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> Transform TrackingTarget
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">get</span>
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> trackingTarget;
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">set</span>
{
trackingTarget = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">value</span>;
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Then attach the following script to the player, that will allow it to temporarily switch the camera’s target to the lock node you’ve set. The script will also remember its previous target so it can get back to it when the player is out of the trigger area. You can go ahead and transform this in a full stack if you need that, but for our purpose since we don’t overlap multiple lock nodes this will do. Also please be aware that you can tweak the position of the Circle Collider 2D, or again add any other kind of collider to trigger the camera lock, this is just a mere example.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> LockBehavior : MonoBehaviour
{
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">region</span> Public Fields</span>
[SerializeField]
Camera camera;
[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> tag;
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">endregion</span></span>
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">region</span> Private</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> Transform previousTarget;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> TrackingBehavior trackingBehavior;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bool</span> isLocked = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">endregion</span></span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Use this for initialization</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Start()
{
trackingBehavior = camera.GetComponent<TrackingBehavior>();
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnTriggerEnter2D(Collider2D other)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (other.tag == tag && !isLocked)
{
isLocked = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>;
PushTarget(other.transform);
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnTriggerExit2D(Collider2D other)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (other.tag == tag && isLocked)
{
isLocked = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
PopTarget();
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">PushTarget</span>(Transform newTarget)
{
previousTarget = trackingBehavior.TrackingTarget;
trackingBehavior.TrackingTarget = newTarget;
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">PopTarget</span>()
{
trackingBehavior.TrackingTarget = previousTarget;
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92305/toptal-blog-image-1459427511605-54f73ec336c059e2dedcacb52755b054.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="camera-zoom" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Camera Zoom</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Camera zoom can be executed either on user input or as an animation when we want to focus on something like a POI or a tighter area within a level.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
2D camera zoom in Unity 3D can be achieved by manipulating the orthographicSize of the camera. Attaching the next script as a component to a camera and using the SetZoom method to change the zoom factor will produce the desired effect. 1.0 means no zoom, 0.5 means zoom in twice, 2 means zoom out twice, and so on.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> zoomFactor = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1.0</span>f;
[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> zoomSpeed = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">5.0</span>f;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> originalSize = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>f;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">private</span> Camera thisCamera;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Use this for initialization</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Start()
{
thisCamera = GetComponent<Camera>();
originalSize = thisCamera.orthographicSize;
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Update is called once per frame</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> targetSize = originalSize * zoomFactor;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (targetSize != thisCamera.orthographicSize)
{
thisCamera.orthographicSize = Mathf.Lerp(thisCamera.orthographicSize,
targetSize, Time.deltaTime * zoomSpeed);
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> SetZoom(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> zoomFactor)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.zoomFactor = zoomFactor;
}
</code></pre>
<h2 id="screen-shake" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Screen Shake</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Whenever we need to show an earthquake, some explosion or any other effect in our game, a camera shake effect comes in handy.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92306/toptal-blog-image-1459427540538-26c28258b49ba767d47023f46ab40610.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
An example implementation of how to do that is available on GitHub: <a href="https://gist.github.com/ftvs/5822103" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">gist.github.com/ftvs/5822103</a>. The implementation is fairly straightforward. Unlike the other effects we have covered so far, it relies on a little randomness.</div>
<h2 id="fade--overlay" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Fade & Overlay</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When our level starts or ends, a fade-in or out-effect is nice. We can implement this by adding a non-interactable UI texture in a panel stretching all over our screen. Initially transparent, we can fill this with any color and opacity, or animate that to achieve the effect we want.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Here is an example of that configuration, please note the UI Panel object being assigned to “Camera Overlay” child of the Main Camera Object. Camera Overlay exposes a script called Overlay that features the following:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">[SerializeField]
Image overlay;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">SetOverlayColor</span>(Color color)
{
overlay.color = color;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/92307/toptal-blog-image-1459427552757-859b2cf2a5f6ee0209d50327ae87278e.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to have a fade-in effect, change your Overlay script by adding an interpolation to a target color you set with SetOverlayColor like in the next script, and set the initial color of our Panel to Black (or White) and the target color to the final color of your overlay. You can change the fadeSpeed to whatever suits your needs, I think 0.8 is a good one for starters. The value of fadeSpeed works as a time modifier. 1.0 means it will happen over multiple frames, but within a 1 second time frame. 0.8 means it will actually take 1/0.8 = 1.25 seconds to complete.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> Overlay : MonoBehaviour
{
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">region</span> Fields</span>
[SerializeField]
Image overlay;
[SerializeField]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> fadeSpeed = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">5</span>f;
[SerializeField]
Color targetColor;
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">endregion</span></span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (overlay.color != targetColor)
{
overlay.color = Color.Lerp(overlay.color, targetColor,
Time.deltaTime * fadeSpeed);
}
}
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">region</span> Public</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">SetOverlayColor</span>(Color color)
{
targetColor = color;
}
<span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">endregion</span></span>
}
</code></pre>
<h2 id="wrap-up" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Wrap Up</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this article I have tried to demonstrate the basic components needed to have a modular 2D camera system in place for your game, and also what the required mind set is for designing it. Naturally, all games have their particular needs, but with the basic tracking and simple effects described here you can get a long way and also have a blueprint for implementing your own effects. Then you can go even further and pack up everything into a reusable Unity 3D package which you can transfer to other projects as well.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Camera systems are very important in conveying the right atmosphere for your players. A good comparison I like to use is when you think of the difference between classical theatre and movies. The cameras and film themselves brought so many possibilities to the scene that it eventually evolved into an art on its own, so if you are not planning to implement another “Pong” game, advanced cameras should be your tool of choice in<a href="https://www.toptal.com/game" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">any game project</a> you’ll undertake from now on.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a href="https://www.toptal.com/resume/mihai-cozma" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Mihai Cozma</a>, a <a href="https://www.toptal.com/unity-unity3d/2d-camera-in-unity">Toptal</a><a href="https://www.toptal.com/technical-writers"> freelance developer</a>.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-2173002080412689822016-08-30T05:30:00.000-07:002016-08-30T05:30:32.163-07:0012 Essential Unity or Unity3D Interview Questions<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90673" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Answer the following questions about threading. Explain your answers:</div>
<ol style="border: 0px; box-sizing: border-box; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; list-style-type: decimal; margin: 0px 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Can threads be used to modify a Texture on runtime?</li>
<li style="border: 0px; box-sizing: border-box; list-style-type: decimal; margin: 0px 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Can threads be used to move a GameObject on the scene?</li>
<li style="border: 0px; box-sizing: border-box; list-style-type: decimal; margin: 0px 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Consider the snippet below:</li>
</ol>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs" style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 13px; line-height: 1.5em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle; width: 916px;">class RandomGenerator : MonoBehaviour
{
public float[] randomList;
void Start()
{
randomList = new float[1000000];
}
void Generate()
{
System.Random rnd = new System.Random();
for(int i=0;i<randomList.Length;i++) randomList[i] = (float)rnd.NextDouble();
}
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Improve this code using threads, so the 1000000 random number generation runs without spoiling performance.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90673" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 308.984px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<ol style="border: 0px; box-sizing: border-box; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">No. Texture and Meshes are examples of elements stored in GPU memory and Unity doesn’t allow other threads, besides the main one, to make modifications on these kinds of data.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">No. Fetching the Transform reference isn’t thread safe in Unity.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">When using threads, we must avoid using native Unity structures like the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Mathf</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Random</code> classes:</li>
</ol>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 893px;">class RandomGenerator : MonoBehaviour
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span>[] randomList;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Start()
{
randomList = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span>[<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1000000</span>];
Thread t = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Thread(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">delegate</span>()
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">while</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>)
{
Generate();
Thread.Sleep(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">16</span>); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// trigger the loop to run roughly every 60th of a second</span>
}
});
t.Start();
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Generate()
{
System.Random rnd = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> System.Random();
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i=<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>;i<randomList.Length;i++) randomList[i] = (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span>)rnd.NextDouble();
}
}</code></pre>
</div>
</div>
<div class="iquestion_answer-footer" style="background: rgb(252, 252, 252); border-top-color: rgb(239, 239, 239); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<div class="clearfix" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90674" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 64.5px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain what a vertex shader is, and what a pixel shader is.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90674" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 100.297px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Vertex shader is a script that runs for each vertex of the mesh, allowing the developer to apply transformation matrixes, and other operations, in order to control where this vertex is in the 3D space, and how it will be projected on the screen.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Pixel shader is a script that runs for each fragment (pixel candidate to be rendered) after three vertexes are processed in a mesh’s triangle. The developer can use information like the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">UV</code> / <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">TextureCoords</code> and sample textures in order to control the final color that will be rendered on screen.</div>
</div>
</div>
<div class="iquestion_answer-footer" style="background: rgb(252, 252, 252); border-top-color: rgb(239, 239, 239); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<div class="clearfix" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90675" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 64.5px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain why deferred lighting optimizes scenes with a lot of lights and elements.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90675" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 119.594px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
During rendering, each pixel is calculated whether it should be illuminated and receive lightning influence, and this is repeated for each light. After approximately eight repeated calculations for different lights in the scene, the overhead becomes significant.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For large scenes, the number of pixels rendered is usually bigger than the number of pixels in the screen itself.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Deferred Lighting makes the scene render all pixels without illumination (which is fast), and with extra information (at a cost of low overhead), it calculates the illumination step only for the pixels of the screen buffer (which is less than all pixels processed for each element). This technique allow much more light instances in the project.</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90676" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 278px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What are the benefits of having a visualization mode for rendering optimization, as shown on the picture bellow?</div>
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91361/toptal-blog-image-1436440710160-c46b314c032ac1ddba5ad073a54adf88.png" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90676" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 77.2969px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The “overdrawn” mode helps the user to profile the number of pixels being rendered in the same “area”. Yellow to white areas are “hot” areas where too many pixels are being rendered.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Developers can use this information to adjust their materials and make better use of the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Z-Test</code> and optimize the rendering.</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90677" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 82px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain why <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">Time.deltaTime</code> should be used to make things that depend on time operate correctly.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90677" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 138.891px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Real time applications, such as games, have a variable FPS. They sometimes run at 60FPS, or when suffering slowdowns, they will run on 40FPS or less.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you want to change a value from <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">A</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">B</code> in 1.0 seconds you can’t simply increase <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">A</code> by <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">B-A</code> between two frames because frames can run fast or slow, so one frame can have different durations.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The way to correct this is to measure the time taken from frame <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">X</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">X+1</code> and increment <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">A</code>, leveraging this change with the frame duration <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">deltaTime</code> by doing <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">A += (B-A) * DeltaTime</code>.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When the accumulated <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">DeltaTime</code> reaches 1.0 second, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">A</code> will have assumed <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">B</code> value.</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90678" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 64.5px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain why vectors should be normalized when used to move an object.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90678" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 69.5px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Normalization makes the vector unit length. It means, for instance, that if you want to move with speed 20.0, multiplying <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">speed * vector</code> will result in a precise 20.0 units per step. If the vector had a random length, the step would be different than 20.0 units.</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90679" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 221px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Consider the following code snippet below:</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 13px; line-height: 1.5em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle; width: 916px;">class Mover : MonoBehaviour
{
Vector3 target;
float speed;
void Update()
{
}
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Finish this code so the <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">GameObject</code> containing this script moves with constant <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">speed</code>towards <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">target</code>, and stop moving once it reaches 1.0, or less, units of distance.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90679" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 201px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 893px;">class Mover : MonoBehaviour
{
Vector3 target;
float speed;
void Update()
{
float distance = Vector3.Distance(target,transform.position);
// will only move while the distance is bigger than 1.0 units
if(distance > 1.0f)
{
Vector3 dir = target - transform.position;
dir.Normalize(); // normalization is obligatory
transform.position += dir * speed * Time.deltaTime; // using deltaTime and speed is obligatory
}
}
}</code></pre>
</div>
</div>
<div class="iquestion_answer-footer" style="background: rgb(252, 252, 252); border-top-color: rgb(239, 239, 239); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<div class="clearfix" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90680" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 84.5px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Can two <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">GameObjects</code>, each with only an <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">SphereCollider</code>, both set as <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">trigger</code> and raise <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">OnTrigger</code> events? Explain your answer.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90680" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-answer_link" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; display: inline; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"><span class="iquestion-answer_icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_hover_1a8c49.png") 0% 0% / 17px 17px no-repeat; border: 0px; box-sizing: border-box; display: inline-block; height: 17px; margin: 0px 8px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; top: 5px; vertical-align: baseline; width: 17px;"></span></a><a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
No. Collision events between two objects can only be raised when one of them has a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">RigidBody</code> attached to it. This is a common error when implementing applications that use “physics.”</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90681" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 156px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Which of the following examples will run faster?</div>
<ol style="border: 0px; box-sizing: border-box; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; list-style-type: decimal; margin: 0px 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1000 <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">GameObjects</code>, each with a <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">MonoBehaviour</code> implementing the <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">Update</code> callback.</li>
<li style="border: 0px; box-sizing: border-box; list-style-type: decimal; margin: 0px 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">One <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">GameObject</code> with one <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">MonoBehaviour</code> with an Array of 1000 classes, each implementing a custom <code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 0.8em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle;">Update()</code> callback.</li>
</ol>
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain your answer.</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90681" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 108.094px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The correct answer is 2.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Update</code> callback is called using a C# Reflection, which is significantly slower than calling a function directly. In our example, 1000 <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GameObjects</code> each with a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MonoBehaviour</code> means 1000 Reflection calls per frame.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Creating one <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MonoBehaviour</code> with one <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Update</code>, and using this single callback to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Update</code> a given number of elements, is a lot faster, due to the direct access to the method.</div>
</div>
</div>
<div class="iquestion_answer-footer" style="background: rgb(252, 252, 252); border-top-color: rgb(239, 239, 239); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<div class="clearfix" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90682" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 94.5px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain, in a few words, what roles the inspector, project and hierarchy panels in the Unity editor have. Which is responsible for referencing the content that will be included in the build process?</div>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90682" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 173.391px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The inspector panel allows users to modify numeric values (such as position, rotation and scale), drag and drop references of scene objects (like Prefabs, Materials and Game Objects), and others. Also it can show a custom-made UI, created by the user, by using Editor scripts.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The project panel contains files from the file system of the assets folder in the project’s root folder. It shows all the available scripts, textures, materials and shaders available for use in the project.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The hierarchy panel shows the current scene structure, with its GameObjects and its children. It also helps users organize them by name and order relative to the GameObject’s siblings. Order dependent features, such as <a href="https://www.toptal.com/designers/ui/portfolios">UI</a>, make use of this categorization.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The panel responsible for referencing content in the build process is the hierarchy panel. The panel contains references to the objects that exist, or will exist, when the application is executed. When building the project, Unity searches for them in the project panel, and adds them to the bundle.</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90683" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 179.5px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Arrange the event functions listed below in the order in which they will be invoked when an application is closed:</div>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 13px; line-height: 1.5em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle; width: 916px;">Update()
OnGUI()
Awake()
OnDisable()
Start()
LateUpdate()
OnEnable()
OnApplicationQuit()
OnDestroy()</code></pre>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90683" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 164.797px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="http://docs.unity3d.com/Manual/ExecutionOrder.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">correct execution order</a> of these event functions when an application closes is as follows:</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 893px;">Awake()
OnEnable()
Start()
Update()
LateUpdate()
OnGUI()
OnApplicationQuit()
OnDisable()
OnDestroy()
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Note: You might be tempted to disagree with the placement of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">OnApplicationQuit()</code> in the above list, but it is correct which can be verified by logging the order in which call occurs when your application closes.</div>
</div>
</div>
</div>
</div>
</div>
<div class="iquestion-wrapper is-active" data-role="content-item watched_by_sticky_panel" data-view="interview_question#content" id="iquestion-90694" style="background-color: #f9f9f9; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 40px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion-inner_border" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-inner" data-role="clicking-area" style="border: 1px solid rgb(41, 73, 120); box-sizing: border-box; color: white; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; transition: all 0.2s; vertical-align: baseline;">
<div class="iquestion-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/question_badge_c0210a.png") 0% 0% / 71px 71px no-repeat; border: 0px; box-sizing: border-box; height: 71px; left: -36px; margin: -46px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 170px; vertical-align: baseline; width: 71px;">
</div>
<div class="iquestion-info" style="background: rgb(59, 103, 167); border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 25px 50px; vertical-align: baseline;">
<div class="iquestion-info_body" style="border: 0px; box-sizing: border-box; font-size: 24px; line-height: 1.25em; margin: 0px 0px 5px; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.4) 1px 1px 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Explain the issue with the code below and provide an alternative implementation that would correct the problem.</div>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(73, 119, 187); border-radius: 3px; border: 1px solid rgb(127, 165, 223); box-sizing: border-box; display: inline-block; font-size: 13px; line-height: 1.5em; margin: 0px 0px 1px; max-width: 100%; min-height: 0px; min-width: 0px; overflow: auto; padding: 1px 5px; text-shadow: none; vertical-align: middle; width: 916px;">using UnityEngine;
using System.Collections;
public class TEST : MonoBehaviour {
void Start () {
transform.position.x = 10;
}
}</code></pre>
</div>
</div>
<div class="iquestion-footer" data-text="Essential Unity or Unity3D Interview Questions" data-title="Toptal Unity or Unity3D Interview Questions" data-url="https://www.toptal.com/unity-unity3d/interview-questions#iquestion-90694" data-view="layout#social_share" style="background: rgb(52, 94, 155); border-top-color: rgb(41, 73, 120); border-top-style: solid; border-width: 1px 0px 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 5px 30px 5px 50px; position: relative; vertical-align: baseline;">
<a class="iquestion-twitter_link" data-pass-click-event="true" data-role="link" data-type="twitter" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/twitter_hover_b1d7bc.png") 0% 0% / 15px 12px no-repeat; border: 0px; box-sizing: border-box; height: 12px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 30px; top: 10px; vertical-align: baseline; width: 15px;" title="share on Twitter"></a><a class="iquestion-facebook_link" data-pass-click-event="true" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="background: url("/assets/front/static/blog/blocks/interview_questions/facebook_hover_d52e39.png") 0% 0% / 7px 13px no-repeat; border: 0px; box-sizing: border-box; height: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; right: 56px; top: 9px; vertical-align: baseline; width: 7px;" title="Share on Facebook"></a></div>
</div>
</div>
<div class="iquestion_answer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; transform: translateZ(0px); vertical-align: baseline;">
<div class="iquestion_answer-wrapper iquestion_answer-animation" data-role="iquestion-answer" style="animation: jelly-answer 1s ease-in both; background: rgb(255, 255, 255); border: 1px solid rgb(239, 239, 239); box-sizing: border-box; margin: 15px 0px 0px 25px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="iquestion_answer-inner" style="border: 0px; box-sizing: border-box; color: #484848; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="iquestion_answer-icon" style="background: url("/assets/front/static/blog/blocks/interview_questions/answer_arrow_da0e94.png") 0% 0% / 63px 63px no-repeat; border: 0px; box-sizing: border-box; height: 63px; left: -32px; margin: -32px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: absolute; top: 196.891px; vertical-align: baseline; width: 63px;">
</div>
<div class="iquestion_answer-body content_body is-small" data-view="content#body" style="border: 0px; box-sizing: border-box; font-size: 13px; margin: 0px; min-height: 0px; min-width: 0px; padding: 35px 30px 35px 50px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The issue is that <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">you can’t modify the position from a transform directly</em>. This is because the position is actually a <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">property</em> (not a field). Therefore, when a getter is called, it invokes a method which returns a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Vector3</code> <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">copy</span> which it places into the stack.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So basically what you are doing in the code above is assigning a member of the struct a value that is in the stack and that is later removed.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Instead, the proper solution is to replace the whole property; e.g.:</div>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 893px;">using UnityEngine;
using System.Collections;
public class TEST : MonoBehaviour {
void Start () {
Vector3 newPos = new Vector3(10, transform.position.y, transform.position.z);
transform.position = newPos;
}
}</code><span style="font-family: "proxima nova" , "arial" , sans-serif; font-size: 1.2em; line-height: 1.5em;">s later removed.</span></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Source: <span id="goog_1082727183"></span><span id="goog_1082727184"></span><a href="https://www.toptal.com/unity-unity3d/interview-questions">Toptal</a></div>
</div>
</div>
</div>
</div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-28788541253347729732016-08-13T09:57:00.000-07:002016-08-13T10:07:46.295-07:00Omnifinity's Infinadeck and OmnideckHey!<br />
<br />
It's been a while since I posted, and as you can see I have someone at <a href="https://www.toptal.com/#trust-only-competent-software-engineers" target="_blank">TopTal</a> posting. It might not be directly related, but still same area and since I'm very busy, I think this is fine to keep the blog alive. Actually, the toptal link is suppose to be a referral link, which would give me money if used.<br />
<br />
As long as their posts are related and useful, I will let them post. Especially since then the blog will be more alive. And so far, I really like their posts. Very well written actually. Again, not necessary directly related to the project, but it's a nice mixup I would say.<br />
<br />
Anyway, I wanted to post because every now and then people email me about the project, and yesterday someone emailed me about these projects:<br />
<br />
<a href="http://infinadeck.com/" target="_blank">Infinadeck</a><br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/7uO8Z34f0xE" width="560"></iframe><br />
<br />
Omnifinity's Omnideck:<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/wPffziOrE6Y" width="560"></iframe> <br />
<br />
This last one is pretty sweet as you can lay down and crawl on it too!<br />
<br />
Both would probably not work so well running on though, but still. Very cool projects, which is why I'm posting about them. :)Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.com3tag:blogger.com,1999:blog-4258209981737157440.post-74966476386339434792016-08-10T08:01:00.001-07:002016-08-10T08:01:47.099-07:00Unity or Unity3D Best Practices and Tips From Game Experts<div class="content_body has-bottom_margin" data-view="content#body" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This resource contains a collection of Unity or Unity3D best practices and tips provided by our Toptal network members, and will be updated regularly with additional information and emerging Unity techniques. This is a community-driven project, so we encourage you to contribute as well, and we are counting on your feedback.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unity is a cross-platform game engine, and here we will embrace Unity and Unity3D best practices that will make you a better game developer.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Check out the Toptal <a href="https://www.toptal.com/resources" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">resource pages</a> for additional information on Unity or Unity3D <a href="https://www.toptal.com/unity-unity3d/interview-questions" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">interview questions</a>.</div>
</div>
<div class="qa-tip" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="content_body has-bottom_margin" data-view="content#body" style="border: 0px; box-sizing: border-box; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h2 style="border: 0px; box-sizing: border-box; color: #3863a0; line-height: 1.3em; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How can I access all Elements of a hierarchy using The “Depth-first search” algorithm?</h2>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sometimes, developers need to find or test the elements that are inside of a complex structure made of intricate transforms relationships. To find or test the desired element, it is necessary to visit <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">all</span> the nodes of the mentioned structure.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Usually, transforms are organized as a complex <a href="https://en.wikipedia.org/wiki/Tree_(data_structure)" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">tree data structure</a>, and one of the most common algorithms for visiting all tree nodes is the <a href="https://en.wikipedia.org/wiki/Depth-first_search" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Depth-first search</a>. This algorithm recursively visits all nodes prioritizing the innermost ones, from left to right.</div>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">using</span> System;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Visits all nodes using the DepthFirstSearch algorithm calling ‘p_callback’ on each visit.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bool</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">TraverseDFS</span>(Transform p_root,Predicate<Transform> p_callback)
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//’Predicate’ is a C# delegate that accepts one parameter and returns a ‘bool’</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//We can use this ‘bool’ it to check if the user wants to keep searching the tree.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(!p_callback(p_root))
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//The desired query was found and we can stop searching.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i=<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>;i<p_root.childCount;i++)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(!TraverseDFS(p_root.GetChild(i),p_callback))
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Stop searching</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Keep searching</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>;
}
</code></pre>
</div>
<div class="tip_category_contributors" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h3 class="tip_category_contributors-title" style="border: 0px; box-sizing: border-box; color: #3863a0; font-size: 20px; line-height: 28px; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Contributors</h3>
<ul class="tip_category_contributors-list" style="border: 0px; box-sizing: border-box; list-style: none; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="tip_category_contributor" style="border: 0px; box-sizing: border-box; font-size: 18px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div class="tip_category_contributor-content" style="border: 0px; box-sizing: border-box; display: flex; flex-wrap: wrap; margin: 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span class="tip_category_contributor-photo_wrapper" style="-webkit-box-flex: 0; align-self: center; border: 0px; box-sizing: border-box; flex: 0 0 65px; height: 65px; margin: 0px 20px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 65px;"><img alt="Small 8e5e962b05ddb596cbcc238c5c1b504e" class="tip_category_contributor-photo" src="https://assets.toptal.io/uploads/user/photo/59610/small_8e5e962b05ddb596cbcc238c5c1b504e.JPG" style="border-radius: 4px; border: 0px; box-sizing: border-box; height: 65px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: auto;" /></span><span class="tip_category_contributor-info" style="-webkit-box-flex: 2; align-self: center; border: 0px; box-sizing: border-box; display: block; flex: 2 0 auto; line-height: 22px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a class="tip_category_contributor-name" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="border: 0px; box-sizing: border-box; color: #3863a0; display: block; font-size: 17px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;">Eduardo Dias da Costa</a><span class="tip_category_contributor-location" style="border: 0px; box-sizing: border-box; color: darkgrey; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Porto Alegre, Brazil</span></span><a class="button is-green_candy is-small tip_category_contributor-hire" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="-webkit-appearance: none; -webkit-box-flex: 0; align-self: center; background-attachment: initial; background-clip: initial; background-image: linear-gradient(rgb(67, 198, 146), rgb(57, 184, 133)); background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-radius: 4px; border: 1px solid rgb(31, 124, 87); box-shadow: rgb(79, 211, 170) 0px 1px inset; box-sizing: border-box; color: white; cursor: pointer; display: block; flex: 0 0 25%; font-size: 16px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden !important; padding: 8px 20px; position: relative; text-align: center; text-decoration: none; text-overflow: ellipsis; text-shadow: rgb(28, 143, 61) 0px 1px 0px; text-transform: uppercase; transition: background 150ms; vertical-align: baseline; white-space: nowrap;">VIEW EDUARDO</a></div>
<div class="tip_category_contributor-footer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="tip_category_contributor-about" style="border: 0px; box-sizing: border-box; color: darkgrey; font-size: 16px; line-height: 28px; margin-top: 15px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Eduardo is a developer with over a decade of experience focused on client and front-end applications. He is always open to learn and take up new challenges that can make him handle new languages and/or technologies. He specializes in computer graphics, image processing, game development, tools development (CLI, desktop ...) and UI/UX/front-end development.</div>
</div>
</li>
</ul>
</div>
</div>
<div class="tip_category_actions" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="tip_category_actions-subscribe" style="border: 0px; box-sizing: border-box; margin: 10px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="border-radius: 6px; border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/unity-unity3d/tips-and-practices#" style="border: 0px; box-sizing: border-box; color: #3863a0; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="background-color: white; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="background-color: white; border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="qa-tip" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="content_body has-bottom_margin" data-view="content#body" style="border: 0px; box-sizing: border-box; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h2 style="border: 0px; box-sizing: border-box; color: #3863a0; line-height: 1.3em; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How to move objects towards the desired position with constant and/or variable rates in a defined time frame?</h2>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Things in games must move. It is just a matter of speed, acceleration, and time.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The most common methods for moving things outside the physics loop of Unity is using <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MoveTowards</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Lerp</code>.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you want to move things with constant speed, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MoveTowards</code> increments your position with a constant rate for each frame.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MoveTowards" src="https://assets.toptal.io/uploads/blog/image/91998/toptal-blog-image-1453718464627-b5840b0fc4f0a39f47b32bf6688f441c.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Constant Speed</span>
Vector3 position;
Vector3 target;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> speed;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
position = Vector3.MoveTowards(position,target,Time.deltaTime * speed);
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To move things with the feel of acceleration one must use <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Lerp</code>. The effect we get is caused because the next position is a percentage of the remaining distance. So, the first steps are bigger than the last ones because the remaining distance keeps getting shorter.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Lerp" src="https://assets.toptal.io/uploads/blog/image/91999/toptal-blog-image-1453718492739-6acea2a636e8515316c5fbeb8a5c183b.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Variable Speed</span>
Vector3 position;
Vector3 target;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> speed;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Update()
{
position = Vector3.Lerp(position,target,Time.deltaTime * speed);
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The interesting part here is that these equations operate in numbers, and considering that quaternions (rotations), colors, rectangles and other Math structures have the same composition, it can be seen that everything can be interpolated using this technique. For instance, fading or sliding screens and rotating objects are other use cases of it.</div>
</div>
<div class="tip_category_contributors" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h3 class="tip_category_contributors-title" style="border: 0px; box-sizing: border-box; color: #3863a0; font-size: 20px; line-height: 28px; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Contributors</h3>
<ul class="tip_category_contributors-list" style="border: 0px; box-sizing: border-box; list-style: none; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="tip_category_contributor" style="border: 0px; box-sizing: border-box; font-size: 18px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div class="tip_category_contributor-content" style="border: 0px; box-sizing: border-box; display: flex; flex-wrap: wrap; margin: 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span class="tip_category_contributor-photo_wrapper" style="-webkit-box-flex: 0; align-self: center; border: 0px; box-sizing: border-box; flex: 0 0 65px; height: 65px; margin: 0px 20px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 65px;"><img alt="Small 8e5e962b05ddb596cbcc238c5c1b504e" class="tip_category_contributor-photo" src="https://assets.toptal.io/uploads/user/photo/59610/small_8e5e962b05ddb596cbcc238c5c1b504e.JPG" style="border-radius: 4px; border: 0px; box-sizing: border-box; height: 65px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: auto;" /></span><span class="tip_category_contributor-info" style="-webkit-box-flex: 2; align-self: center; border: 0px; box-sizing: border-box; display: block; flex: 2 0 auto; line-height: 22px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a class="tip_category_contributor-name" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="border: 0px; box-sizing: border-box; color: #3863a0; display: block; font-size: 17px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;">Eduardo Dias da Costa</a><span class="tip_category_contributor-location" style="border: 0px; box-sizing: border-box; color: darkgrey; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Porto Alegre, Brazil</span></span><a class="button is-green_candy is-small tip_category_contributor-hire" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="-webkit-appearance: none; -webkit-box-flex: 0; align-self: center; background-attachment: initial; background-clip: initial; background-image: linear-gradient(rgb(67, 198, 146), rgb(57, 184, 133)); background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-radius: 4px; border: 1px solid rgb(31, 124, 87); box-shadow: rgb(79, 211, 170) 0px 1px inset; box-sizing: border-box; color: white; cursor: pointer; display: block; flex: 0 0 25%; font-size: 16px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden !important; padding: 8px 20px; position: relative; text-align: center; text-decoration: none; text-overflow: ellipsis; text-shadow: rgb(28, 143, 61) 0px 1px 0px; text-transform: uppercase; transition: background 150ms; vertical-align: baseline; white-space: nowrap;">VIEW EDUARDO</a></div>
<div class="tip_category_contributor-footer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="tip_category_contributor-about" style="border: 0px; box-sizing: border-box; color: darkgrey; font-size: 16px; line-height: 28px; margin-top: 15px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Eduardo is a developer with over a decade of experience focused on client and front-end applications. He is always open to learn and take up new challenges that can make him handle new languages and/or technologies. He specializes in computer graphics, image processing, game development, tools development (CLI, desktop ...) and UI/UX/front-end development.</div>
</div>
</li>
</ul>
</div>
</div>
<div class="tip_category_actions" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="tip_category_actions-subscribe" style="border: 0px; box-sizing: border-box; margin: 10px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="border-radius: 6px; border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/unity-unity3d/tips-and-practices#" style="border: 0px; box-sizing: border-box; color: #3863a0; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="background-color: white; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="background-color: white; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="background-color: white; border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="qa-tip" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="content_body has-bottom_margin" data-view="content#body" style="border: 0px; box-sizing: border-box; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h2 style="border: 0px; box-sizing: border-box; color: #3863a0; line-height: 1.3em; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How to correctly destroy an item from the scene?</h2>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Somewhere in the gameplay, your player eliminated a monster or picked an item. Now your code must remove those instances from the scene.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
New developers usually mistake the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameObject</code>’s components, such as the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Transform</code> and the attached <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MonoBehaviours</code> as the main instance in the scene.</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Reference to the scripts</span>
MonsterScript monster;
ItemScript item;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnPlayerWin()
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Process score.</span>
Destroy(monster); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Will destroy the monster’s script only and the monster will be on scene. </span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnPlayerGetItem()
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Process item.</span>
Destroy(item); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Will destroy the item’s script only and the item will be on scene. </span>
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Every component in the Unity API has a reference to its <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameObject</code>, which is the element containing <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">all</span>scripts and components related to a game element.</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Reference to the scripts</span>
MonsterScript monster;
ItemScript item;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnPlayerWin()
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Process score.</span>
Destroy(monster.gameObject); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Will destroy the monster’s entire instance.</span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnPlayerGetItem()
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Process item.</span>
Destroy(item.gameObject); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Will destroy the item’s entire instance.</span>
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The knowledge to differentiate between a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameObject</code> and its components is crucial to avoid unwanted behaviour in the key parts of your gameplay.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Yet, sometimes, the objective is to actually kill a given script to open a slot for another one. One example is changing between AI behaviours.</div>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">GameObject monster;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnPlayerClose()
{
AIScriptIdle ai = monster.GetComponent<AIScriptIdle>(); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Gets the current AI instance</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(ai) Destroy(ai); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//If it exists, destroy.</span>
monster.AddComponent<AIScriptAttack>(); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Adds the Attack AI Script.</span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnPlayerFar()
{
AIScriptAttack ai = monster.GetComponent<AIScriptAttack >(); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Gets the current AI instance</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(ai) Destroy(ai);<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//If it exists, destroy.</span>
monster.AddComponent<AIScriptIdle>(); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Adds the Idle AI script.</span>
}
</code></pre>
</div>
<div class="tip_category_contributors" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h3 class="tip_category_contributors-title" style="border: 0px; box-sizing: border-box; color: #3863a0; font-size: 20px; line-height: 28px; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Contributors</h3>
<ul class="tip_category_contributors-list" style="border: 0px; box-sizing: border-box; list-style: none; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="tip_category_contributor" style="border: 0px; box-sizing: border-box; font-size: 18px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div class="tip_category_contributor-content" style="border: 0px; box-sizing: border-box; display: flex; flex-wrap: wrap; margin: 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span class="tip_category_contributor-photo_wrapper" style="-webkit-box-flex: 0; align-self: center; border: 0px; box-sizing: border-box; flex: 0 0 65px; height: 65px; margin: 0px 20px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 65px;"><img alt="Small 8e5e962b05ddb596cbcc238c5c1b504e" class="tip_category_contributor-photo" src="https://assets.toptal.io/uploads/user/photo/59610/small_8e5e962b05ddb596cbcc238c5c1b504e.JPG" style="border-radius: 4px; border: 0px; box-sizing: border-box; height: 65px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: auto;" /></span><span class="tip_category_contributor-info" style="-webkit-box-flex: 2; align-self: center; border: 0px; box-sizing: border-box; display: block; flex: 2 0 auto; line-height: 22px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a class="tip_category_contributor-name" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="border: 0px; box-sizing: border-box; color: #3863a0; display: block; font-size: 17px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;">Eduardo Dias da Costa</a><span class="tip_category_contributor-location" style="border: 0px; box-sizing: border-box; color: darkgrey; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Porto Alegre, Brazil</span></span><a class="button is-green_candy is-small tip_category_contributor-hire" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="-webkit-appearance: none; -webkit-box-flex: 0; align-self: center; background-attachment: initial; background-clip: initial; background-image: linear-gradient(rgb(67, 198, 146), rgb(57, 184, 133)); background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-radius: 4px; border: 1px solid rgb(31, 124, 87); box-shadow: rgb(79, 211, 170) 0px 1px inset; box-sizing: border-box; color: white; cursor: pointer; display: block; flex: 0 0 25%; font-size: 16px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden !important; padding: 8px 20px; position: relative; text-align: center; text-decoration: none; text-overflow: ellipsis; text-shadow: rgb(28, 143, 61) 0px 1px 0px; text-transform: uppercase; transition: background 150ms; vertical-align: baseline; white-space: nowrap;">VIEW EDUARDO</a></div>
<div class="tip_category_contributor-footer" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="tip_category_contributor-about" style="border: 0px; box-sizing: border-box; color: darkgrey; font-size: 16px; line-height: 28px; margin-top: 15px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Eduardo is a developer with over a decade of experience focused on client and front-end applications. He is always open to learn and take up new challenges that can make him handle new languages and/or technologies. He specializes in computer graphics, image processing, game development, tools development (CLI, desktop ...) and UI/UX/front-end development.</div>
</div>
</li>
</ul>
</div>
</div>
<div class="tip_category_actions" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="tip_category_actions-subscribe" style="border: 0px; box-sizing: border-box; margin: 10px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="border-radius: 6px; border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/unity-unity3d/tips-and-practices#" style="border: 0px; box-sizing: border-box; color: #3863a0; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="background-color: white; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="background-color: white; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="background-color: white; border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; list-style-type: none !important; margin: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="qa-tip" style="border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="content_body has-bottom_margin" data-view="content#body" style="border: 0px; box-sizing: border-box; margin: 0px 0px 20px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<h2 style="border: 0px; box-sizing: border-box; color: #3863a0; line-height: 1.3em; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How to customize a material on runtime exclusively for its GameObject?</h2>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sometimes you have one material that is configured to render your character with the correct shader and parameters; but your game could have a great number of characters with different textures and parameters for each.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Usually, one would create one material for each. However, if at some point the base material needs its shader, textures or parameters changed, you would need to update all previously created ones.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One way to avoid that is to have one material for all characters and store the parameters and textures in the character script.</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Character.cs</span>
Texture2D skin; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Reference to the character skin texture.</span>
Color tint; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Some tint parameter for the shader.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Start()
{
Material m = GetComponent<Renderer>().sharedMaterial; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Get the renderer material reference.</span>
m.color = tint; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Change the shader color parameter to the character’s.</span>
m.mainTexture = skin; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Change the skin texture to the character’s.</span>
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Pretty easy? However, there is a catch. To simplify the workflow, we had only one material for <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">all</span> characters. So, if someone changes the material attributes, all characters would be affected.</div>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To avoid this, you must duplicate the material instance as soon as the game starts and make it exclusive to that character.</div>
<pre style="border: 0px; box-sizing: border-box; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Character.cs</span>
Texture2D skin; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Reference to the character skin texture.</span>
Color tint; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Some tint parameter for the shader.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Start()
{
Material m = GetComponent<Renderer>().sharedMaterial; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Get the renderer material reference.</span>
m = Instantiate<Material>(m); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Duplicate the original</span>
m.color = tint; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Change the shader color parameter to the character’s.</span>
m.mainTexture = skin; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Change the skin texture to the character’s.</span>
GetComponent<Renderer>().sharedMaterial = m; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//Assign the new material only for this character.</span></code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article is from <a href="https://www.toptal.com/unity-unity3d/tips-and-practices" target="_blank">Toptal</a>.</div>
</div>
</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-8797613361110876512016-08-04T09:57:00.004-07:002016-08-04T09:57:46.334-07:00Taming WebRTC with PeerJS: Making a Simple P2P Web Game<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
WebRTC is a technology that enables real-time communication between web browsers. It is relatively new, and the API definition is still considered to be a draft. Coupled with the fact that WebRTC is <a href="http://caniuse.com/#feat=rtcpeerconnection" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">not supported by all major web browsers</a> yet, (and among the ones that do, some of them <a href="http://iswebrtcreadyyet.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">do not support every feature</a> of this technology), this makes it relatively difficult to use WebRTC for any mission critical applications. Or so you would think!</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Connect Four over WebRTC using PeerJS: Look ma, no server!" src="https://assets.toptal.io/uploads/blog/image/91584/toptal-blog-image-1440144921549-7d3eb3f332b8ac64b20af96c72f820d4.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="background-color: #fafafa; color: #505050; font-size: 1.3em; line-height: 1.5em;">Connect Four over WebRTC using PeerJS: Look ma, no server!</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since it was first introduced by Google in May 2011, WebRTC has been used in many modern web applications. Being a core feature of many modern web browsers, web applications can seamlessly take advantage of this technology to deliver improved user experience in many ways. Video streaming or conferencing applications that don’t require bloated browser plugins, and can take advantage of peer-to-peer (P2P) networks (while not transmitting every bit of data through some server) is only a part of all the amazing things that can be achieved with WebRTC.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this article, we will take a look at how WebRTC can be used to make a <a href="https://github.com/hjr265/arteegee" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">simple P2P web game of Connect Four</a>. To work around the various rough edges and implementation differences of WebRTC, we will use an amazing JavaScript library: <a href="http://peerjs.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">PeerJS</a>.</div>
<h2 id="data-over-webrtc" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Data over WebRTC</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before we start, it is important to understand that WebRTC is not all about transmitting audio and video streams. It also provides support for P2P <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/WebRTC_data_channels" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">data channels</a>. These channels come in two variations: reliable and unreliable. As one may guess, reliable data channels guarantee that messages are delivered and they are delivered in order, while unreliable channels provide no such guarantees.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="WebRTC infrastructure - an ocean of acronyms" src="https://assets.toptal.io/uploads/blog/image/91586/toptal-blog-image-1440147424270-64e534fa12414f7ece037eefe45c1765.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="background-color: #fafafa; color: #505050; font-size: 1.3em; line-height: 1.5em;">WebRTC infrastructure - an ocean of acronyms</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Moreover, WebRTC data channels require no special infrastructure setup, other than what is needed by a typical WebRTC peer connection: a signaling server to coordinate the connection between peers, a STUN server to figure out public identity of the peers, and optionally a TURN server to route messages between peers if a direct connection between peers cannot be established (for example when both peers are behind NATs). If <a href="https://hacks.mozilla.org/2013/07/webrtc-and-the-ocean-of-acronyms/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">these acronyms</a> sound familiar, it is because WebRTC repurposes existing technologies wherever possible.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This opens the door to a lot more use cases of WebRTC, including but not limited to multiplayer games, content delivery, and file sharing. Again, all without the need of any intermediary server and hence with lower latencies.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In our simple web game, we will use a data channel between two web browsers to communicate player moves back-and-forth.</div>
<h2 id="meet-peerjs" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Meet PeerJS</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
PeerJS takes the implementation of WebRTC in your browser and wraps a simple, consistent, and <a href="http://peerjs.com/docs/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">elegant API</a>around it. It <a href="http://peerjs.com/status/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">plugs various holes</a> in WebRTC implementation of earlier browsers. For example, in Chrome 30 or older, only unreliable data channels were available. PeerJS, if configured to use reliable data channels, would use a shim for those older browsers. Although this wouldn’t be as performant as native implementation of reliable channels, it would still work.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With PeerJS, identifying peers is even simpler. Every peer is identified using nothing but an ID. A string that the peer can choose itself, or have a server generate one. Although WebRTC promises peer-to-peer communication, you still need a server anyway to act as a connection broker and handle signaling. PeerJS provides an open source implementation of this connection broker server <a href="https://github.com/peers/peerjs-server" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">PeerJS Server</a> (written in Node.js), in case you do not want to use their <a href="http://peerjs.com/peerserver" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">cloud-hosted version</a> (which is free right now, and comes with some limitations).</div>
<h2 id="connect-four-goes-p2p" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Connect Four Goes P2P</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now that we have a source of confidence for working with WebRTC, i.e PeerJS, let us start by creating a simple Node.js/Express application.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">npm init
npm install express --save
npm install jade --save
npm install peer --save
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We will use this only to host PeerJS Server, and serve a page and front-end assets. We will need to serve only a single page, and this will contain two sections: a plain main menu, and a 7-by-6 Connect Four grid.</div>
<h3 id="peerjs-server" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
PeerJS Server</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Hosting our own PeerJS Server is really easy. The <a href="https://github.com/peers/peerjs-server" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">official repository on GitHub</a> even has a one-click button to deploy an instance of PeerJS Server to Heroku.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In our case, we just want to create an instance of <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ExpressPeerServer</em> in our Node.js application, and serve it at “/peerjs”:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> express = <span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">require</span>(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'express'</span>)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> app = express()
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// … Configure Express, and register necessary route handlers</span>
srv = app.listen(process.env.PORT)
app.use(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/peerjs'</span>, <span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">require</span>(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'peer'</span>).ExpressPeerServer(srv, {
debug: <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>
}))
</code></pre>
<h3 id="peerjs-client" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
PeerJS Client</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With PeerJS Server up and running, we move on to the client side. As discussed earlier, PeerJS identifies peers with unique IDs. These IDs can be generated by PeerServer for every peer automatically, or we can pick one for every peer while instantiating <a href="http://peerjs.com/docs/#peer" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Peer</em></a> objects.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> peer = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Peer(id, options)
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Here, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">id</em> can be omitted altogether if we want the server to generate one for us. In our case, that is what we will want to do. PeerServer will ensure that the IDs it gives out are unique. The second argument, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">options</em>, is usually an object containing <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">key</em> (the API key, if you are using cloud-hosted PeerServer, or <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">host</em>, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">port</em>, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">path</em>, etc in case you are hosting the PeerServer yourself).</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> peer = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Peer({
host: location.hostname,
port: location.port || (location.protocol === <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'https:'</span> ? <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">443</span> : <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">80</span>),
path: <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/peerjs'</span>
})
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to establish a connection between two PeerJS peers, one of the peers must know the ID of the other peer. For the sake of keeping things simple, in our implementation of Connect Four over WebRTC, we will require the player starting the game to share his peer ID with his opponent. With the destination peer ID known, a simple call to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">peer.connect(destId)</em> is all that we will need:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> conn = peer.connect(destId)
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Both the <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Peer</em> object and the <a href="http://peerjs.com/docs/#dataconnection" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">DataConnection</em></a> object returned by <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">peer.connect(destId)</em> emit some really useful events that are worth listening on. For the purposes of this tutorial, we are particularly interested about the ‘data’ event of <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">DataConnection</em> object and ‘error’ events of both objects.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to send data to the other end of the connection, simply invoke <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">conn.send(data)</em>:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">conn.send(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'hello'</span>)
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Although a bit overkill for our needs here, PeerJS transmits data between peers after encoding them in BinaryPack format. This allows peers to communicate strings, numbers, arrays, objects, and even blobs.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To receive incoming data, simply listen for ‘data’ event on <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">conn</em>:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">conn.on(‘data’, <span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(data)</span> {</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// data === 'hello'</span>
})
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And that is pretty much all we need!</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h3 id="game-logic" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Game Logic</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The first player, one who starts a game, is shown his peer ID as generated by PeerJS which they can share with their opponent. Once an opponent joins the game using the first player’s peer ID, the first player is allowed to make a move.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Connect Four, being a game of simple rules and mechanics, has only one type of move: each player, in turn, must pick a column and drop a disc into it. This means that all a peer needs to communicate is the column number in which the current player has chosen to drop his disc in. We will transmit this information as an array with two elements: a string ‘move’, and a number - 0-based index of the column from the left.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Every time a player clicks on a column:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(!turn) {
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// it is not the current player’s turn</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> i
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// i = chosen column index</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(grid[i].length == <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">6</span>) {
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// the column doesn’t have any more space available</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span>
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// track player’s move locally</span>
grid[i].push(peerId)
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// end current player’s turn</span>
turn = <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>
conn.send([<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'move'</span>, i])
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After sending this move data to the opponent, we update the game’s state locally. This includes determining if the current player has won, or if the game has ended in a draw.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
On the receiving end of this move data:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">if(turn) {
// ignore incoming move data when it is the current player's turn
return
}
var i = data[1]
if(grid[i].length == 6) {
// ignore incoming move data when it is invalid
return
}
// track opponent’s move locally
grid[i].push(opponent.peerId)
// activate current player’s turn
turn = true
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And naturally, after this we update the game’s state locally, determine if the opponent has won or if the game has ended in a draw.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Notice how we need to perform sanity checks on incoming data. This is important since with WebRTC-based games, we do not have intermediary server and server-based game logic validating the move data.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To keep the snippets simple, lines of code that update the UI have been omitted. You can find the full source code for the client-side JavaScript <a href="https://github.com/hjr265/arteegee/blob/master/public/assets/js/arteegee.js" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>.</div>
<h3 id="connecting-it-all" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Connecting It All</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To combine it all, we create a simple page with two sections. On page load, the section containing the main menu is shown, the section containing the game grid is kept hidden.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-jade" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">section#menu
div.animated.bounceIn
div
h1 Connect Four
br
div.no-support(style='display: none;')
div.alert.alert-warning
p Unfortunately, your web browser does not <a href="http://iswebrtcreadyyet.com">support WebRTC</a>
div
a.btn.btn-primary.btn-lg(href='#start') Start
| &nbsp;
a.btn.btn-default.btn-lg(href='#join') Join
section#game(style='display: none;')
div
div
h1 Connect Four
br
table.table.grid
tbody
for i in [0, 1, 2, 3, 4, 5]
tr
for j in [0, 1, 2, 3, 4, 5, 6]
td
div.slot
br
div.alert.alert-info
p
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Making these DOM elements look pretty is beyond the scope of this tutorial. Hence we will resort to our trusted companion <a href="http://getbootstrap.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bootstrap</a> and do some light styling over it.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As the first player clicks on the “Start” button, the game grid is revealed along with the player’s peer ID. The player can then share this peer ID with their opponent.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Start a new game, and share your peer ID as generated by PeerJS" src="https://assets.toptal.io/uploads/blog/image/91587/toptal-blog-image-1440148633919-ef730e3a6aa9e889db22e977c1be9998.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The second player can click then click on the “Join” button, enter the first player’s peer ID, and begin the game.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Use your opponent's peer ID to join a game" src="https://assets.toptal.io/uploads/blog/image/91588/toptal-blog-image-1440148642406-b4856113353766addf54b2cfff170178.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h2 id="trying-it-out" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Trying It Out</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You can try out this example application at <a href="https://arteegee.herokuapp.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">https://arteegee.herokuapp.com</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Or, you can clone the repository from GitHub, install NPM dependencies, and try it out locally:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">git clone https://github.com/hjr265/arteegee.git
cd arteegee
npm install
PORT=5000 npm start
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Once the server is running, you can point your web browser to <a href="http://localhost:5000/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">http://localhost:5000</a>, start a game from one tab, and join from another tab (or even a different WebRTC capable web browser) using the peer ID.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You can open your web browser’s console to see some debug information, as in this example application, PeerJS client has been configured to perform verbose logging.</div>
<h3 id="but-it-doesnt-work-for-me" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But It Doesn’t Work for Me!</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are two major reasons why this game may not work on your computer.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is possible that you are using a web browser which doesn’t support the necessary WebRTC APIs yet. If that is the case, you may want to try a different browser - one that supports WebRTC and data channels.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you are using a modern web browser with WebRTC support, then there is the chance that you are behind some network infrastructure which WebRTC cannot penetrate. Ideally this issue can be easily addressed with a TURN server, but since the example application is not using one, it won’t work when both you and your opponent are behind <a href="https://en.wikipedia.org/wiki/Network_address_translation" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">NATs</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a href="https://www.toptal.com/resume/mahmud-ridwan" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Mahmud Ridwan</a>, a <a href="https://www.toptal.com/webrtc/taming-webrtc-with-peerjs" target="_blank">Toptal</a><a href="https://www.toptal.com/python" target="_blank"> Python developer</a>.</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-45407691945503869852016-07-28T20:13:00.000-07:002016-07-28T20:13:30.857-07:00How to Build an Infinite Runner on iOS: Cocos2D, Automation, and More<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Developing iOS games can be an enriching experience in terms of both personal and <a href="http://thegamebakers.com/money-and-the-app-store-a-few-figures-that-might-help-an-indie-developer.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">financial</a> growth. Earlier this year, I deployed a Cocos2D-based game, <a href="https://itunes.apple.com/us/app/bee-race/id546662947?mt=8&ign-mpt=uo%3D4" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bee Race</a>, to the App Store. Its gameplay is simple: an infinite runner in which players (in this case, bees) collect points and avoid obstacles. See <a href="http://www.youtube.com/watch?v=pMc1Xas7oCU&feature=youtu.be" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a> for a demo.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this tutorial, I’ll explain the process behind developing games for iOS, from Cocos2D through to publishing. For reference, here’s a short table-of-contents:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Sprites" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Sprites and physical objects</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Cocos2D" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A brief introduction to Cocos2D</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Storyboards" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Using Cocos2D with storyboards</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#ProjectDescription" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Gameplay and (brief) project description</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Automation" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Automate jobs. Use tools. Be cool.</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Billing" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">In-app billing</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Multiplayer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Multiplayer gameplay with the Game Center</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Improvement" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Room for improvement</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts#Conclusion" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Conclusion</a></li>
</ul>
<h2 id="Sprites" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sprites and physical objects</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before we get into the gritty details, it’ll be helpful to understand the distinction between <a href="https://en.wikipedia.org/wiki/Sprite_(computer_graphics)" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">sprites</a> and physical objects.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For any given entity that appears on the screen of an endless runner game, the graphical representation of that entity is referred to as a <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite</em>, while the polygonal representation of that entity in the physics engine is referred to as a <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">physical object</em>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So the sprite is drawn on the screen, backed by its corresponding physical object, which is then handled by your physics engine. That setup can be visualized here, where sprites are displayed on the screen, with their physical polygonal counterparts outlined in green:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="In iOS infinite runner games, sprites and physical objects coexist." src="https://assets.toptal.io/uploads/blog/image/116/toptal-blog-2_A.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Physical objects aren’t connected to their respective sprites by default, which means that you as the <a href="https://www.toptal.com/ios" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">iOS developer</a> can choose which physics engine to use and how to connect sprites and bodies. The most common way is to subclass the default sprite and add a concrete physical body to it.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With that in mind…</div>
<h2 id="Cocos2D" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A brief tutorial on Cocos2D iOS game development</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="http://www.cocos2d-iphone.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Cocos2D-iphone</a> is an open source framework for iOS that uses OpenGL for hardware graphics acceleration and supports the <a href="http://chipmunk-physics.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Chipmunk</a> and <a href="http://box2d.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Box2D</a> physics engines.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First of all, why do we need such a framework? Well, for starters, frameworks implement the oft-used components of game development. For example, Cocos2D can load sprites (in particular, <a href="http://www.raywenderlich.com/32045/how-to-use-animations-and-sprite-sheets-in-cocos2d-2-x" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">sprite sheets</a>(<a href="http://stackoverflow.com/questions/8050152/why-use-a-sprite-sheet-rather-than-individual-images" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">why?</a>)), launch or stop a physics engine, and handle timing and animation properly. And it does all this with code that’s been reviewed and tested extensively—why devote your own time to re-writing likely-inferior code?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Perhaps most importantly, however—<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Cocos2D game development uses graphics hardware acceleration</span>. Without such acceleration, any iOS infinite runner game with even a moderate number of sprites will run with notably poor performance. If we try to make a more complicated application, then we will probably start to see a “bullet-time” effect on the screen, i.e., multiple copies of each sprite as it attempts to animate.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Finally, Cocos2D optimizes memory usage since it <a href="http://www.cocos2d-x.org/wiki/Texture_Cache#SpriteFrameCache" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">caches sprites</a>. Thus, any duplicated sprites require minimal additional memory, which is obviously useful for games.</div>
<h2 id="Storyboards" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Using Cocos2D with storyboards</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After all of the praise I’ve lapped on Cocos2D, it might seem illogical to <a href="https://www.toptal.com/ios/ios-user-interfaces-storyboards-vs-nibs-vs-custom-code" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">suggest using Storyboards</a>. Why not just manipulate your objects with Cocos2D, etc.? Well, to be honest, for static windows it is often more convenient to use Xcode’s Interface Builder and its Storyboard mechanism.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Firstly, it allows me to drag and position all my graphical elements for my endless runner game with my mouse. Secondly, the Storyboard API is very, very useful. (And yes, I know about <a href="http://cocosbuilder.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Cocos Builder</a>).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Here’s a quick glimpse of my Storyboard:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="To learn how to make an endless running game, start with a good Storyboard." src="https://assets.toptal.io/uploads/blog/image/113/toptal-blog-4_A.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The game’s main view controller just contains a Cocos2D scene with some HUD elements on top:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="The start of our Cocos2D tutorial is at the view controller." src="https://assets.toptal.io/uploads/blog/image/114/toptal-blog-3_A.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Pay attention to the white background: it’s a Cocos2D scene, which will load all of the necessary graphic elements at runtime. Other views (live indicators, dandelions, buttons, etc.) are all standard Cocoa views, added to the screen using Interface Builder.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I won’t dwell on the details—if you’re interested, the code can be found <a href="https://github.com/tinytimgames/CCViewController" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>.</div>
<h2 id="ProjectDescription" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Gameplay and (brief) project description</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(To provide some more motivation, I’d like to describe my endless runner game in slightly more detail. Feel free to skip this section if you want to proceed to the technical discussion.)</em></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
During live gameplay, the bee is motionless, and the field itself is actually rushing along, bringing with it various dangers (spiders and poisonous flowers) and perks (dandelions and their seeds).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Cocos2D has camera object which was designed to follow the character; in practice, it was less complicated to manipulate the CCLayer containing the game world.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The controls are simple: tapping the screen moves the bee up, and another tap moves it down.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The world layer itself actually has two sublayers. When the game starts, the first sublayer is populated from 0 to BUF_LEN and displayed initially. The second sublayer is populated in advance from BUF_LEN to 2*BUF_LEN. When the bee reaches BUF_LEN, the first sublayer is cleaned and instantly repopulated from 2*BUF_LEN to 3*BUF_LEN, and the second sublayer is presented. In this way, we alternate between layers, never retaining obsolete objects, an important part of avoiding memory leaks.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="My infinite runner game is comprised of a multi-layer world." src="https://assets.toptal.io/uploads/blog/image/115/toptal-blog-1_A.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In terms of physics engines, I used Chipmunk for two reasons:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">It’s written in pure Objective-C.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">I’ve worked with Box2D before, so I wanted to compare the two.</li>
</ol>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The physics engine was really only used for collision detection. Sometimes, I’m asked, “Why didn’t you write your own collision detection?”. In reality, there’s not much sense to that. Physics engines were designed for that very purposes: they can detect collisions between bodies of complicated shapes and optimize that process. For example, physics engines often split the world into cells and perform collision checks only for bodies in the same or adjacent cells.</div>
<h2 id="Automation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Automate jobs. Use tools. Be cool.</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A key component of indie infinite runner game development is to avoid stumbling over small issues. Time is a crucial resource when developing an app, and automation can be incredibly time-saving.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But sometimes, automation can also be a compromise between perfectionism and meeting your deadline. In this sense, perfectionism can be an Angry Birds killer.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For example, in another iOS game I am currently developing, I built a framework to create layouts using a special tool (available on <a href="https://github.com/Nepherhotep/terevaka/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">GitHub</a>). This framework has its limitations (for example, it doesn’t have nice transitions between scenes), but using it allows me to make my scenes in a tenth of the time.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So while you can’t build your own superframework with special supertools, you still can and should automate as many of these small tasks as possible.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="background-color: #fafafa; color: #505050; font-size: 1.3em; line-height: 1.5em;">Perfectionism can be an Angry Birds killer. Time is a crucial resource </span>in<span style="background-color: #fafafa; color: #505050; font-size: 1.3em; line-height: 1.5em;"> iOS game development.</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In building this infinite runner, automation was key once again. For example, my artist would send me high resolution graphics through a special Dropbox folder. To save time, I wrote some scripts to automatically build file sets for the various target resolutions required by the App Store, adding -hd or @2x as well (said scripts are based on <a href="http://www.imagemagick.org/script/index.php" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">ImageMagick</a>).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In terms of additional tools, I found <a href="http://www.codeandweb.com/texturepacker" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">TexturePacker</a> to be very useful—it can pack sprites into sprite sheets so that your app will consume less memory and load faster, as all of your sprites will be read from a single file. It can also export textures in almost all possible frameworks formats. (Note that TexturePacker is not a free tool, but I think it’s worth the price. You can also check out free alternatives like <a href="http://renderhjs.net/shoebox/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">ShoeBox</a>.)</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The main difficulty associated with game physics is to create suitable polygons for each sprite. In other words, creating a polygonal representation of some obscurely-shaped bee or flower. Don’t even try to do this by hand—always use special applications, of which there are many. Some are even quite… exotic—like creating vector masks with Inkspace and then importing them into to game.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For my own endless runner game development, I created a tool to automate this process (see <a href="http://www.andengine.org/forums/features/vertex-helper-t1370.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a> for proper usage), which I call <a href="https://github.com/Nepherhotep/andengine-vertex-helper" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Andengine Vertex Helper</a>. As the name suggests, it was initially designed for the<a href="http://www.andengine.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Andengine framework</a>, although it will work appropriately with a number of formats these days.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In our case, we need to use the plist pattern:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><real>%.5f</real><real>%.5f</real>
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Next, we create a plist file with object descriptions:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>jet_ant</key>
<dict>
<key>vertices</key>
<array>
<real>-0.18262</real><real>0.08277</real>
<real>-0.14786</real><real>-0.22326</real>
<real>0.20242</real><real>-0.55282</real>
<real>0.47047</real><real>0.41234</real>
<real>0.03823</real><real>0.41234</real>
</array>
</dict>
</dict>
</plist>
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And an object loader:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">- (void)createBodyAtLocation:(CGPoint)location{
float mass = 1.0;
body = cpBodyNew(mass, cpMomentForBox(mass, self.sprite.contentSize.width*self.sprite.scale, self.sprite.contentSize.height*self.sprite.scale));
body->p = location;
cpSpaceAddBody(space, body);
NSString *path =[[NSBundle mainBundle] pathForResource:@"obj _descriptions" ofType:@"plist"];
// <- load plist
NSDictionary *objConfigs = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease]; NSArray *vertices = [[objConfigs objectForKey:namePrefix] objectForKey:@"vertices"];
shape = [ChipmunkUtil polyShapeWithVertArray:vertices
withBody:body
width:self.sprite.contentSize.width
height:self.sprite.contentSize.height];
shape->e = 0.7;
shape->u = 1.0;
shape->collision_type = OBJ_COLLISION_TYPE;
cpSpaceAddShape(space, shape);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To test out how sprites correspond to their physical bodies, see <a href="https://github.com/nubbel/CPDebugLayer" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Much better, right?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In summary, always automate when possible. Even simple scripts can save you tons of time. And importantly, that time can be used for programming instead of mouse clicking. (For additional motivation, here’s a <a href="http://xkcd.com/1205/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">token XKCD</a>.)</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-email_form is-current" style="border: 0px; box-sizing: border-box; display: flex; flex-wrap: wrap; height: auto; margin: 0px; min-height: 0px; min-width: 0px; overflow: visible; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-privacy" style="border: 0px; box-sizing: border-box; margin: 0px 20px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="embeddable_form-privacy" style="-webkit-box-align: center; align-items: center; border: 0px; box-sizing: border-box; color: #9a9a9a; display: flex; font-size: 12px; line-height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-privacy_icon" style="background: url("/assets/front/static/public/primitives/icon/lock_ed584f.png") 0% 0% / 9.5px 11.5px no-repeat; border: 0px; box-sizing: border-box; display: inline-block; flex-shrink: 0; height: 11.5px; margin: 0px 15px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; top: -2px; vertical-align: baseline; width: 9.5px;">
</div>
</div>
</div>
</div>
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><br /><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h2 id="Billing" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In-app billing</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Collected blowballs in the game act as an in-app currency, allowing users to purchase new skins for their bee. However, this currency can also be purchased with real money. An important point to note with respect to in-app billing is whether or not you need to perform server-side checks for purchase validity. Since all of the purchasable goods are essentially equal in terms of gameplay (just altering the bee’s appearance), there is no need to perform a server check for purchase validity. However, in many cases, you’ll definitely need to do so.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For more, Ray Wenderlich has the perfect <a href="http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">in-app billing tutorial</a>.</div>
<h2 id="Multiplayer" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Multiplayer gameplay with the Game Center</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In mobile gaming, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">socializing</em> is more than just adding a Facebook ‘Like’ button or setting up leaderboards. To make the game more exciting, I implemented a multiplayer version.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How does it work? First, two players are connected using the iOS Game Center’s real-time match-making. As the players are really playing the same infinite runner game, there needs to be just a single set of game objects. That means that one player’s instance needs to be generating the objects, and the other play’s will read them off. In other words, if both players’ devices were generating game objects, it’d be tough to synchronize the experience.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With that in mind, after the connection is established, both players send each other a random number. The player with the higher number acts as the “server”, creating game objects.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Do you remember the discussion of portioned world generation? Where we had two sublayers, one from 0 to BUF_LEN and the other from BUF_LEN to 2*BUF_LEN? This architecture wasn’t used by accident—it was necessary to provide smooth graphics over delayed networks. When a portion of objects is generated, it gets packed into a plist and sent to the other player. The buffer is big enough to let the second player play even with a network delay. Both players send each other their current position with a period of half a second, also sending their up-down movements immediately. To smooth out the experience, position and velocity are corrected every 0.5 second with a smooth animation, so in practice it looks like the other player is moving or accelerating gradually.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are certainly more considerations to be made with regards to multiplayer endless running gameplay, but hopefully this gives you a sense for the types of challenges involved.</div>
<h2 id="Improvement" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Room for improvement</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Games are never finished. Admittedly, there are several areas where I’d like to improve my own, namely:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Control issues: tapping is often an unintuitive gesture for players who prefer to slide.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The world layer is moved using the CCMoveBy action. This was fine when the world layer’s velocity was constant, since CCMoveBy action was cycled with CCRepeatForever:</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 834px;">-(void) infiniteMove{
id actionBy = [CCMoveBy actionWithDuration: BUFFER_DURATION position: ccp(-BUFFER_LENGTH, 0)]; id actionCallFunc = [CCCallFunc actionWithTarget:self selector:@selector(requestFillingNextBuffer)];
id actionSequence = [CCSequence actions: actionBy, actionCallFunc, nil];
id repeateForever = [CCRepeatForever actionWithAction:actionSequence];
[self.bufferContainer runAction:repeateForever];
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But later, I added a world velocity increase to make the game harder as it goes on:</div>
<pre style="border: 0px; box-sizing: border-box; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 834px;">-(void) infiniteMoveWithAccel {
float duration = BUFFER_DURATION-BUFFER_ACCEL*self.lastBufferNumber;
duration = max(duration, MIN_BUFFER_DURATION);
id actionBy = [CCMoveBy actionWithDuration: duration position: ccp(-BUFFER_LENGTH, 0)];
id restartMove = [CCCallFunc actionWithTarget:self selector:@selector(infiniteMoveWithAccel)]; id fillBuffer = [CCCallFunc actionWithTarget:self selector:@selector(requestFillingNextBuffer)];
id actionSequence = [CCSequence actions: actionBy, restartMove, fillBuffer, nil]; [self.bufferContainer runAction:actionSequence];
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This change caused the animation to tatter on each action restart. I tried to fix the issue, to no avail. However, my beta testers didn’t notice the behavior, so I postponed the fix.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">On the one hand, there’s been no need to write my own authorization for multiplayer when using Game Center or running my own game server. On the other hand, it’s made it impossible to create bots, which is something I might like to change.</li>
</ol>
<h2 id="Conclusion" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Conclusion</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Creating your own indie infinite runner game can be a great experience. And once you get to the publishing step of the process, it can be a wonderful feeling as you release your own creation out into the wild.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The review process can range from several days to several weeks. For more, there’s a helpful site <a href="http://reviewtimes.shinydevelopment.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a> that uses crowd-sourced data to estimate current review times.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Additionally, I recommend using <a href="http://appannie.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">AppAnnie</a> to examine various information about all the applications in the App Store, and registering with some analytics services like <a href="http://www.flurry.com/flurry-analytics.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Flurry Analytics</a> can be helpful too.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And if this game has intrigued you, be sure to check out <a href="https://itunes.apple.com/us/app/bee-race/id546662947?mt=8&ign-mpt=uo%3D4" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bee Race</a> in the store.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a href="https://www.toptal.com/resume/alexey-zankevich" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Alexey Zankevich</a>, a<a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts" target="_blank"> Toptal </a><a href="https://www.toptal.com/xml" target="_blank">XML developer</a>.</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-87962103221116000192016-07-21T16:12:00.002-07:002016-07-21T16:12:30.256-07:00Ultimate Guide to Processing Part II: Building a Simple Game<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
This is the second part of the ultimate guide to Processing. In the first part, I tried to give a basic walkthrough to the Processing language. If you haven’t read the first part, you can find it <a href="https://www.toptal.com/game/ultimate-guide-to-processing-the-fundamentals" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">here</a>.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
In this article, we will implement our own game step-by-step. Each step will be explained in detail. Then, we will port the game to the web.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Building a Simple Game with Processing" src="https://assets.toptal.io/uploads/blog/image/91874/toptal-blog-image-1450355133671-5a81e639a3b2553907867a0721ae592d.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;" /></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Before we begin, <a href="https://gist.github.com/oguzgelal/a3b8fba696cc4e662158" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a> is the code of the DVD logo exercise from the previous part. If you have any questions, be sure to leave a comment.</div>
<h2 id="a-simple-game" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
A Simple Game</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<a href="http://codepen.io/anon/pen/BjyzoP/left" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">The game</a> we will build in this article is sort of a combination of Flappy Bird, Pong and Brick Breaker. The reason I picked a game like this is that it has most of the concepts that beginners struggle with when learning game development. This is based on my experience from when I was a teaching assistant, helping new learners with Processing. These concepts include gravity, collisions, keeping scores, handling different screens and keyboard/mouse interactions. Flappy Pong has all of them in it.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Read the full article in <a href="https://www.toptal.com/game/ultimate-guide-to-processing-simple-game" target="_blank">Toptal Engineering blog</a>. </div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-41667270140640751952016-07-12T03:38:00.000-07:002016-07-12T03:38:42.167-07:00Video Game Physics Tutorial - Part III: Constrained Rigid Body Simulation<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Video Game Physics tutorial - Constrained Rigid Body Simulation" src="https://assets.toptal.io/uploads/blog/image/91124/toptal-blog-image-1431660451592-55d803aebe4ef61ce7f29e08f6200595.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In Part I of this series, we saw how the free motion of rigid bodies can be simulated. In Part II, we saw how to make bodies aware of each other through collision and proximity tests. Up to this point, however, we still have not seen how to make objects truly interact with each other. For example, even though we know how to detect collisions and determine lots of useful information about them, we still don’t know what to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">do</em> with this information.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In other words, we have only described <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">unconstrained simulations</span>. The final step to simulating realistic, solid objects, is to apply <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">constraints</span>, defining restrictions on the motion of rigid bodies. Some examples of constraints are <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">joints</span> (such as ball joints and hinge joints), and <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">non-penetration constraints</span>. This last type is what is used to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">solve collisions</em>, by enforcing behavior that prevents bodies from interpenetrating, and instead causes them to rebound off of each other in a realistic way.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Joints" src="https://assets.toptal.io/uploads/blog/image/91125/toptal-blog-image-1431660570359-e56c2976eb61acbc041e298d54b129c3.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this article, we’ll discuss equality constraints and inequality constraints within video game physics. We’ll describe them first in terms of a force-based approach, where corrective forces are computed, and then in terms of an impulse-based approach, where corrective velocities are computed instead. Finally, we’ll go over some clever tricks to eliminate unnecessary work and speed up computation.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This installment will involve more heavy-duty math than either Part I or Part II, so be warned. If you need to brush up on your calculus, go <a href="https://www.khanacademy.org/math/differential-calculus" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here on Khan Academy</a>. For a review of the fundamentals of linear algebra, you can refer to the <a href="https://www.toptal.com/game/video-game-physics-part-i-an-introduction-to-rigid-body-dynamics#appendix" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">appendix in Part I</a>, and for the more complex linear algebra, such as matrix multiplication, Khan Academy <a href="https://www.khanacademy.org/math/linear-algebra" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">again delivers</a>. Wikipedia also has great articles on <a href="https://en.wikipedia.org/wiki/Differential_equation" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">calculus</a> and <a href="https://en.wikipedia.org/wiki/Vector_space" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">linear algebra</a>.</div>
<h2 id="what-are-constraints" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What are Constraints?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Constraints are essentially rules that must be satisfied during the simulation, such as <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">“the distance between these two particles should not be greater than 2”</em> or <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">“these two points on this pair of rigid bodies should coincide at all times”</em>. In other words, a constraint removes <a href="https://en.wikipedia.org/wiki/Degrees_of_freedom_(physics_and_chemistry)" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">degrees of freedom</span></a> from a rigid body. On each step of the simulation, we can compute corrective forces or impulses that, when applied on the bodies, will pull them together or push them apart, so their movement will be restricted and the rules imposed by the constraints will remain satisfied.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In practice, a constraint is defined in terms of a <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">behavior function</span> or <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">constraint function</span> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>, which takes the state of a pair of bodies as parameters (e.g. position and orientation) and outputs a scalar number. When the value of this function is in the acceptable range, the constraint is satisfied. Thus, in each step of the simulation, we must apply forces or impulses on the rigid bodies to attempt to keep the value of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> in the allowed range.</div>
<h2 id="an-example-equality-constraints" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
An Example: Equality Constraints</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A common class of constraint is known as an <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">equality constraint</span>. An equality constraint is one in which the only acceptable value of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> is zero. Thus, during each step of the simulation, we want to keep <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> as close to zero as possible. In other words, we want to <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">minimize</em></span> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>. Equality constraints are used when the position of some particle or point must always exactly match some predefined condition. A good example is a ball joint, where two rigid bodies must always be connected at the location of the joint.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s look at a simple example. Consider a particle in two dimensions, with position <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em>) = (<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p<span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">x</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em>), <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p<span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">y</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em>))</span>, which is a function of time that gives the particle’s position at a time <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em></span>. We’ll use dot notation to express time derivatives, thus, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ṗ</span></em></span> is the first time derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em></span> with respect to time, which is the particle’s velocity <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em>)</span>, and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p̈</span></em></span>is its second time derivative, or it’s acceleration.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Particle" src="https://assets.toptal.io/uploads/blog/image/91126/toptal-blog-image-1431660591530-6523314effc978dc1d93d57066db43ab.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s define a constraint. Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> be the following behavior function:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ParticleDistanceConstraint" src="https://assets.toptal.io/uploads/blog/image/91127/toptal-blog-image-1431660608914-3eed26a7bf4966d088a88d946d78d10a.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This function takes the particle position as parameter, and outputs its distance from the origin minus <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">l</em></span>. It will be zero whenever the distance between the particle and the origin is <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">l</em></span>. Thus the effect of this constraint is to keep the particle at a fixed distance <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">l</em></span> from the origin, like a pendulum attached to the origin. The values of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p </span></em></span>that satisfy <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em>) = 0</span> are the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">legal positions</span> of the particle.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Pendulum" src="https://assets.toptal.io/uploads/blog/image/91128/toptal-blog-image-1431660619704-45e0f08fc3feb25e0d46caad053b935d.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this example, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> is a function of only two variables that outputs a scalar, so we can easily plot it and examine some of its properties. If we set the constraint distance as 2 (that is, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">l</em> = 2</span>), then the graph of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> looks like this:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintPlot" src="https://assets.toptal.io/uploads/blog/image/91129/toptal-blog-image-1431660631811-5a5df932a56ee9b3b3917306a59206b8.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s an upside down cone. The blue ring contains the points where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em> = 0</span>, which are the roots of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>. This set of points is known as the <a href="http://mathworld.wolfram.com/Hypersurface.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">constraint</span></a> <a href="https://en.wikipedia.org/wiki/Hypersurface" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">hypersurface</span></a>, and it contains all of the legal positions of our particle. The constraint hypersurface is an <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">s</span>-dimensional surface, where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">s</span> is the number of variables of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The green arrows show <a href="https://en.wikipedia.org/wiki/Gradient" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">gradients</a> of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>, evaluated around the hypersurface, and indicates the directions to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">illegal positions</em> of our particle, where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em> ≠ 0</span>. If the particle moves in along these lines in any way, either in the positive direction (away from the origin) or the negative direction (towards the origin), it will break the constraint. Thus, the forces we generate to push the particle into legal positions will be parallel to these lines.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
While this simple example has only two variables, most constraint functions have more, and that makes it hard to picture what they look like. But the principle remains the same. At each step, we must generate constraint forces that are parallel to the gradient of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> at the hypersurface.</div>
<h3 id="computing-constraint-forces" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Computing Constraint Forces</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It would be nice to simply set <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em></span> such that <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> is always exactly zero. In practice, this will result in unrealistic behavior, as our particle will jump and jitter around the hypersurface. To keep <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> as close as possible to zero while maintaining a realistic behavior, an intuitive approach is to use <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">force-based dynamics</span>, and compute the necessary force to apply to the particle so that it will satisfy the constraints without breaking Newton’s laws of motion.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To compute the constraint force, we will need to have a grasp of the allowable accelerations and velocities of the particle. To this end, we must obtain the derivatives of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> with respect to time.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We want to ensure that the value of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> will stay equal to zero, and remain unchanged throughout the simulation. This means that the first time derivative, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ċ</em></span>, must be zero as well.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Likewise, in order for <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ċ</em></span> to remain fixed at zero, the second derivative, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C̈</em></span>, must also be zero.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We do not have to constrain any further derivatives of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>, because the second derivative is where our constraint forces will be applied.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s determine these derivatives. Our current definition of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> has a square root in it, and that makes differentiation a bit difficult. We can rewrite <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> though, using squared distances:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ParticleDistanceConstraintSimple" src="https://assets.toptal.io/uploads/blog/image/91130/toptal-blog-image-1431660650594-06b7c340b396aaa3748ca2de93b97e76.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This doesn’t change the property that <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> will be zero when the distance between the particle and the origin is<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">l</em></span>. From this, we can get the first derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> with respect to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em></span>:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ParticleDistanceConstraintVelocity" src="https://assets.toptal.io/uploads/blog/image/91131/toptal-blog-image-1431660661719-14f01ff0631dd14549bb179090dca00a.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Given a legal position of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em></span>, all velocities <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ṗ</span></em></span> that satisfy <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ċ</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em>) = 0</span> are legal velocities. In this example, these should be only those velocities that are tangential to the hypersurface in the above image.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The second derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> with respect to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em></span> is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ParticleDistanceConstraintAcceleration" src="https://assets.toptal.io/uploads/blog/image/91132/toptal-blog-image-1431660677030-4e6efdcc50adc6ec22db08c7c30e01b6.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Equivalently, given a legal position and velocity, all accelerations <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p̈</span></em></span> that satisfy <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C̈</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em>) = 0</span> are legal accelerations. In this example, these should be only those accelerations that are directly towards or away from the origin.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Using Newton’s Second Law of motion we can express the acceleration in terms of force. We can consider that there are two forces acting on the particle: a combination of all external forces <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ext</em></span></span>, such as gravity, wind, and forces applied by the user, and the constraint force <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span>. The latter is the one we want to determine. Assuming the particle has mass <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em></span>, its acceleration is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ParticleAcceleration" src="https://assets.toptal.io/uploads/blog/image/91188/toptal-blog-image-1431662107002-f2c725b2f27bccd4b95bf0fcdb467a68.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Substituting this into <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C̈</em> = 0</span> we get:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintForceEquation" src="https://assets.toptal.io/uploads/blog/image/91189/toptal-blog-image-1431662206772-7ad35f6d1e07cacd2a87697198e85ac8.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Which can be rearranged to:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintForceEquationIsolated" src="https://assets.toptal.io/uploads/blog/image/91190/toptal-blog-image-1431662337076-1861810c55c16a9b5180a2680419a997.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We have a single equation and two unknowns (the two coordinates of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span>), thus it cannot be solved. We need to introduce one additional condition.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Intuitively, we know that the constraint force must be applied to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">oppose</em> to the direction we want to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">prevent </em>the particle from moving in. In this example, the constraint forces will always point to a direction that is perpendicular to the circle of radius <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">l</em></span>, because the particle is not allowed to move outside this circle. These perpendicular forces will push the particle back into the circular path whenever it tries to leave it, and this causes the velocity component that points in these directions to be zero. Thus, the constraint forces be always perpendicular to the velocity of the particle.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Therefore:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ForceVelocityOrthogonal" src="https://assets.toptal.io/uploads/blog/image/91136/toptal-blog-image-1431660719501-9c5200f8d61ecc3aa13a33813b9d1bac.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The equation for the first derivative of our constraint says that <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em> · <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ṗ</span></em> = 0</span>. Since <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span> · <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ṗ</span></em> = 0</span>, we have that both <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span>and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em></span> are orthogonal to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ṗ</span></em></span>, and so <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em></span> are parallel. Thus, we can write one as a multiple of the other</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintForceLambda" src="https://assets.toptal.io/uploads/blog/image/91137/toptal-blog-image-1431660729449-f856f1bb0c66d82ba0e1c2b8eb89f013.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We are nearly there! The scalar <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> represents the <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">magnitude of the constraint force that should be applied</em> to bring the system to a valid state. The further our system moves away from the valid states, the bigger <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> will be in order to push it back to a valid state. At this point <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> is our only unknown. Substituting the above into our previous equation we obtain:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Lambda" src="https://assets.toptal.io/uploads/blog/image/91191/toptal-blog-image-1431662395593-f8c15aee5b8c5c7c5679f592431666b8.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now we can compute <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> directly and obtain <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span> by multiplying it with <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em></span>. Then we simply apply <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span> to the particle, and let the simulation described in Part I do the rest!</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> is also known as a <a href="https://en.wikipedia.org/wiki/Lagrange_multiplier" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Lagrange multiplier</span></a>. For any constraint, the calculation involves determining the direction of the force vector, and it’s magnitude, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span>.</div>
<h3 id="when-to-apply-constraint-forces" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When to Apply Constraint Forces</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
From this example, we can see that computing the constraint forces requires that all other forces <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ext</em></span></span> are already known. And of course, we must apply the constraint forces before simulating the resulting motion. Thus, a generalized sequence for each simulation step look like this:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Compute all external forces <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ext</em></span></span>.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Compute the constraint forces <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">C</span></span>.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Apply all the forces and simulate the motion, as described in Part I.</li>
</ol>
<h2 id="systems-of-constraints" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Systems of Constraints</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
That was a relatively simple example of a pretty basic constraint involving one single entity. We actually want to be able to have many constraints and many objects in our simulation. Constraints cannot be handled in isolation because the forces applied by one constraint might influence the forces that are applied by another constraint. That is clearly visible in the example of a chain of rigid bodies connected by revolute joints. For that reason, constraints must be solved as a whole, in a system of equations.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Chain" src="https://assets.toptal.io/uploads/blog/image/91139/toptal-blog-image-1431660755532-2e981d99a3b35fd8afc842482990bac6.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h3 id="setting-up" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Setting Up</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We’ll now work with vectors and matrices that contain the state of all entities in our simulation, and use them to develop our global equations in a similar manner to what we did for the single particle example. Let’s develop these equations for rigid bodies in two dimensions.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">State Vector</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Say we have <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em></span> rigid bodies we are simulating. Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q</span></em></span> be a <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">state vector</span> that has all the rigid bodies’ positions and angles:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="StateVector" src="https://assets.toptal.io/uploads/blog/image/91140/toptal-blog-image-1431660767075-37033d7be3f01276c2158b3fa492fdc3.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span> is a two-dimensional vector representing the position of the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span>-th rigid body, and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">α</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span> is its angle, which is a scalar. Thus, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q</span></em></span> has <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3<span style="border: 0px; box-sizing: border-box; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></span> elements.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Dynamics: Newton’s Second Law</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">M</span></span> be the following <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3<span style="border: 0px; box-sizing: border-box; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></span> by <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3<span style="border: 0px; box-sizing: border-box; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></span> diagonal matrix:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MassMatrix" src="https://assets.toptal.io/uploads/blog/image/91141/toptal-blog-image-1431660870513-c282342c762a563c9dc49c6d4fc0c7ce.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span> is the mass of the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span>-th rigid body, and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">I</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span> is its moment of inertia.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</span></em></span> be a global force vector that contains the forces and torques acting on each body. It’s the sum of external and constraint forces:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalForce" src="https://assets.toptal.io/uploads/blog/image/91142/toptal-blog-image-1431660969522-d6ffa0508d75753b7a7ad56c61d17276.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
and:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalForceVector" src="https://assets.toptal.io/uploads/blog/image/91143/toptal-blog-image-1431660979478-4485b5b89870c3b1ddd07789675ca7bb.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</span></em></span> also has <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3n</em></span> elements, since each <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span> is a vector of two dimensions.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now we can write Newton’s Second Law of motion for the whole set of bodies with one expression:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalEquationOfMotion" src="https://assets.toptal.io/uploads/blog/image/91192/toptal-blog-image-1431662490424-6a3a106de209112f8ecaa18e95ac8736.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Constraints</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Finally, let’s set up our behavior functions. Say there are <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em></span> constraints, each representing a link in the chain of rigid bodies. We are going to group all our behavior functions into a single function <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q</span></em>)</span>:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalBehaviorFunction" src="https://assets.toptal.io/uploads/blog/image/91145/toptal-blog-image-1431661010890-0cb9cfc312cf8d4146f678458b4b1752.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q</span></em>)</span> takes the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3<span style="border: 0px; box-sizing: border-box; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></span>-dimensional vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q</span></em></span> as input, and outputs an <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em></span>-dimensional vector. We want to keep this output as close to the zero vector as possible, using a similar process to what we did above.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We aren’t going to get into defining each behavior function here, as it won’t be necessary, but the web has great tutorials on <a href="http://www.iforce2d.net/b2dtut/joints-revolute" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">revolute joint constraints</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Derivatives of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> Over Time</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As before, we also want the first and second time derivatives of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span> to be zero vectors. Let’s develop these equations.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span> with respect to time can be given as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalBehaviorFunctionFirstDerivative" src="https://assets.toptal.io/uploads/blog/image/91146/toptal-blog-image-1431661036315-8632d9ed20bb260729e41ff3ab25e211.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Note the use of the chain rule. We can develop this equation further, by defining <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span></span> as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="JacobianOfC" src="https://assets.toptal.io/uploads/blog/image/91147/toptal-blog-image-1431661049621-7e1493279e07181884554f0bfb958082.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is the <a href="https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Jacobian Matrix</span></a>, or the <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Jacobian of</em> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span>. The Jacobian is a generalization of the gradient, which is itself a generalization of the slope. It’s also interesting to note that each row is the gradient of each behavior function. The Jacobian tells us how every behavior function reacts to changes with respect to every state variable.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="JacobianMatrix" src="https://assets.toptal.io/uploads/blog/image/91148/toptal-blog-image-1431661063254-859940ca297520b07b635bbcfac98e54.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the case of our chain, it will be a sparse matrix, because each constraint only involves the two rigid bodies linked by that constraint. The state of all other bodies will have no direct effect on that link.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We can now express the time derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span> as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Cdot" src="https://assets.toptal.io/uploads/blog/image/91149/toptal-blog-image-1431661116189-1631929bdfbbbb6209052df4b19c517e.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Beautiful.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The second derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span> will be:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalBehaviorFunctionSecondDerivative" src="https://assets.toptal.io/uploads/blog/image/91150/toptal-blog-image-1431661128675-6064e52aa03cb1d4490bcf6c264e660d.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="JacobianDerivative" src="https://assets.toptal.io/uploads/blog/image/91151/toptal-blog-image-1431661142736-f94b50ad6b2fe4c3db6eeb8b56750c72.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Substituting our expression of Newton’s Second Law we have:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalBehaviorFunctionSecondDerivativeForce" src="https://assets.toptal.io/uploads/blog/image/91193/toptal-blog-image-1431662582134-5c7e58d985a4f004d982937bda3bd38b.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Computing the Constraint Force Vector</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We want the second derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span> to be zero, so let’s set it to zero and rearrange:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalConstraintForceEquationIsolated" src="https://assets.toptal.io/uploads/blog/image/91194/toptal-blog-image-1431662649509-33402e61d8a74e947be1d6875e53a543.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This equation is analogous to the one we developed before for a single constraint:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintForceEquationIsolated" src="https://assets.toptal.io/uploads/blog/image/91195/toptal-blog-image-1431662686520-1861810c55c16a9b5180a2680419a997.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Again, the number of unknowns is greater than the number of equations, and again, we can use the fact that constraint forces are orthogonal to the velocities to find a solution:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintForcesDoNoWork" src="https://assets.toptal.io/uploads/blog/image/91155/toptal-blog-image-1431661214830-cc5df7850a6bceb004efb02c4ab7e50e.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We also want the first derivative of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</span></em></span> to be zero. From <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ċ</span></em> = 0</span> we have that:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="VelocityConstraintZero" src="https://assets.toptal.io/uploads/blog/image/91156/toptal-blog-image-1431661230532-6a6e7a8bd95167ca574cd09961fff4dd.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
and therefore we can write the constraint force vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span></span> as a multiple of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span></span>:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalForceJacobian" src="https://assets.toptal.io/uploads/blog/image/91157/toptal-blog-image-1431661248248-326f6033f8abe05e21bba340ffadcb79.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> has <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em></span> scalar components, and in this matrix-vector multiplication, each component <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span> multiplies a row of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span></span> (which is the gradient of the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span>-th constraint function) and sums them together. That is</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="JacobianLinearCombination" src="https://assets.toptal.io/uploads/blog/image/91158/toptal-blog-image-1431661307870-8c96c1efebb205e186a0c8ce3a4c2374.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span></span> is thus a <a href="https://en.wikipedia.org/wiki/Linear_combination" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">linear combination</span></a> of the rows of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span></span>, which are the gradients of the constraint functions. Although this system is too complex to be able to easily visualize the hypersurface, as we did for the particle example, it behaves just the same as that example: the gradients are orthogonal to the constraints’ hypersurfaces, and are the directions in which the system is not allowed to move. Hence, this is a linear combination of vectors that point in the prohibited directions, meaning that the constraint forces will be restricted to these directions and they will push the bodies towards the valid states imposed by the constraints.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The only thing remaining to solve for is the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> vector, which will determine the magnitudes of the constraint forces. Let’s get back to our main equation and substitute the last expression in there:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GlobalConstraintLinearSystem" src="https://assets.toptal.io/uploads/blog/image/91196/toptal-blog-image-1431662767726-d5db17a15791ed222d42490427e5ae03.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is a <a href="https://en.wikipedia.org/wiki/System_of_linear_equations" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">system of linear equations</span></a> where only <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> is not known. There are plenty of well known <a href="https://en.wikipedia.org/wiki/System_of_linear_equations#Solving_a_linear_system" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">methods</a> to solve a linear system like this efficiently. Once it’s solved and we have <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span>, we can compute <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span></span>, apply the results to the rigid bodies, and simulate the resulting motion as shown in Part I.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For a detailed derivation of these equations check out Andrew Witkin’s <a href="http://www.cs.cmu.edu/~baraff/sigcourse/notesf.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Constrained Dynamics</em></a>, part of the<a href="http://www.cs.cmu.edu/~baraff/sigcourse/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Physically Based Modeling: Principles and Practice</em></a> course at Carnegie Mellon University.</div>
<h2 id="inequality-constraints" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Inequality Constraints</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Up to now, we have assumed that our behavior functions must be equal to zero at all times for the constraints to be satisfied. There are, however, types of constraints that require some flexibility, where corrective forces won’t be applied for a wider range of values of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> than just zero. An example of one such constraint is the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">non-penetration constraint</span>, which is often the most important type of constraint in rigid body simulations, because it is responsible for <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">collision resolution</span>, ensuring two bodies never interpenetrate unrealistically, and giving them a natural solid behavior.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As we described in Part II, after a collision is detected by the <a href="https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects#computing_distance" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">GJK algorithm</a>, we’ll have the contact points on both bodies as well as the a surface normal at the contact point. Remember that GJK is both a collision test and a proximity test, and that two bodies may be considered “colliding” even if they are not actually touching, but the distance between them is very small. In this case, the contact points on the two bodies are considered to be the points where they are closest to each other.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The non-penetration constraint will strive to keep the bodies separated by applying corrective forces that push the bodies apart, but <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">only if the bodies are colliding</em>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Consider a pair of 2-dimensional bodies <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span> that are colliding. At the moment of contact, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span> has position<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span></span> and angle <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">α</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span></span>, and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span> has position <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span></span> and angle <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">α</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span></span>. Let’s call <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span></span> a vector that goes from the center of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span> to the contact point on <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span>, and let’s also define <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span></span> similarly. Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></em></span> be the contact normal that points from <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span> to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="RigidBodyContactElements" src="https://assets.toptal.io/uploads/blog/image/91160/toptal-blog-image-1431661352038-c97be6634fac730df68e6b8e48bad65e.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s take a standard 2D rotation matrix <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">R</span>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">θ</em>)</span> that rotates vectors by a given angle <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">θ</em></span>:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="RotationMatrixFunction" src="https://assets.toptal.io/uploads/blog/image/91161/toptal-blog-image-1431661363330-7f63f9a9c89082fa2de95254cf3f3139.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We can use it to rotate the vectors <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span></span> by the angles <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">α</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">α</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span></span>, respectively. This allows us to define a behavior function, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span>, as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="NonPenetrationConstraintFunction" src="https://assets.toptal.io/uploads/blog/image/91162/toptal-blog-image-1431661375643-a81f8f0b8a8bfa65e294e6e81f985bb4.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This behavior function looks daunting, but it’s action is simple. It takes a vector between the contact point on<span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</em></span> and the contact point on <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span>, projects it onto the normal vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></em></span>, and outputs the length of this projection vector. In other words, it determines the penetration depth in the direction of the normal. If <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> is greater than or equal to zero, no force should be applied, because the bodies are not penetrating. Thus, we need to enforce the <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">inequality</em> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em> ≥ 0</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If we analyze the equations, we’ll find we need only to restrict the value of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> for each constraint. In the equality constraints of the previous examples, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> can take any value, meaning the constraint forces could be in either a positive or negative direction along the behavior gradients). In an inequality constraint such as the non-penetration constraint, however, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> must be greater than or equal to zero, which represents constraint forces that can only push <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">away</em> the colliding bodies <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">away</em> from each other.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This change transforms the system of linear equations we have into something quite different (and more complicated) called a <a href="http://chrishecker.com/The_Mixed_Linear_Complementarity_Problem" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Mixed Linear Complementarity Problem</span></a>, or MLCP. There are a few nice algorithms that can solve this problem directly, such as <a href="https://en.wikipedia.org/wiki/Lemke%27s_algorithm" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Lemke’s Algorithm</a>. However, we’ll skip the details here, and discuss another approach to constraints that is very popular in game physics.</div>
<h2 id="impulse-based-dynamics" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Impulse-Based Dynamics</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So far, we have examined the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">force-based</span> approach to enforcing constraints. We calculate the constraint forces, apply these forces on the bodies together with the external forces, and integrate them using the methods we described in Part I to simulate the resulting motions. There is, however, another technique that is very popular among game physics engines, which takes an <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">impulse-based</span> approach, operating on the velocity of the bodies and not on the force or acceleration. This means the constraint solver calculates and applies a direct change in the linear and angular velocities of the bodies, instead of calculating and applying corrective forces and relying on integration to then change the velocities.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With impulse-based dynamics, the goal is to find the impulses that result in velocities that solve the constraints. This is somewhat analogous to the force-based goal of finding the forces that will result in accelerations that solve the constraints. However, we are working at a lower order of magnitude, and as a result, the math is less complex.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The impulse-based approach was popularized by Brian Mirtich in <a href="http://www.kuffner.org/james/software/dynamics/mirtich/index.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">his PhD thesis from 1996</a>, which is still one of the most important references on the topic. Jan Bender <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">et. al.</em> have also published a series of <a href="http://www.impulse-based.de/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">important papers on the subject</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The general sequence of a simulation step using impulse-based dynamics is somewhat different from that of force-based engines:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Compute all external forces.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Apply the forces and determine the resulting velocities, using the techniques from Part I.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Calculate the constraint velocities based on the behavior functions.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Apply the constraint velocities and simulate the resulting motion.</li>
</ol>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Perhaps the biggest advantage of impulse-based dynamics over the force-based approach and others is the relative simplicity of the algorithms. It is also easier to understand intuitively. In most cases, it is also more computationally efficient, which makes it more appealing for games, where real-time performance is often a priority. There are drawbacks to take into account, however, including difficulty realistically handling stable contacts (like in a resting stack of boxes), and added complexity when modeling contact friction. Nevertheless, we can work around these issues in a couple of ways, as we’ll see further down.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In physics parlance, an <a href="https://en.wikipedia.org/wiki/Impulse_(physics)" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">impulse</span></a> is the integral of a force with respect to time. That is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Impulse" src="https://assets.toptal.io/uploads/blog/image/91163/toptal-blog-image-1431661401616-2126299cea185953e86c0c86ce0bfcf9.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is equal to the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">change in <a href="https://en.wikipedia.org/wiki/Momentum" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">momentum</a></span> during that time.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If a constant force <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</em></span> is applied for an amount of time <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">h</em></span>, then the impulse is simply:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstantImpulse" src="https://assets.toptal.io/uploads/blog/image/91164/toptal-blog-image-1431661418577-5fc978dd59b21ec07584c2031a8f92a3.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When two rigid objects collide, they stay in contact for a very short amount of time, during which they deform and apply equal and opposite forces on each other. After this brief interaction, their velocities may have changed drastically, and therefore so might their momentums. If the objects are perfectly rigid bodies, the amount of time they stay in contact is infinitesimally close to zero, and their velocities change immediately after a collision. Perfectly rigid bodies do not exist in real life, but the simplification can be used to realistically simulate the behavior of objects that are very rigid.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h3 id="sequential-impulses" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sequential Impulses</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Our goal is to find the impulses that solve the constraints for the current time step of the simulation.<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Sequential impulses</span> is a technique we can use to find these impulses. It was popularized by Erin Catto, the author of the <a href="http://box2d.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Box2D</em> physics engine</a>. It is an iterative algorithm, where the idea is to hone in on the constraint velocity by applying impulses on the rigid bodies on each iteration, and repeat until resulting velocity error is very small, or in other words, until <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ċ</span></em></span> is very close to zero.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SequentialImpulses" src="https://assets.toptal.io/uploads/blog/image/91165/toptal-blog-image-1431661430040-88309dc4f6fa78b9479f33f3d57d1b0d.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In sequential impulses, we don’t create one monolithic system of equations and inequalities like we did before. We actually model and solve each constraint individually, pretty much like we did in the first example for one particle. The algorithm boils down to these three steps:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Integrate applied forces using semi-implicit Euler as in Part I, yielding tentative velocities. These velocities may violate the constraints and need to be corrected before being applied.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Apply impulses sequentially for all constraints, to correct the velocity errors. Repeat for several iterations, until impulses become small or after a maximum number of iterations is reached.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Use the new velocities to simulate motion, updating positions, again using semi-implicit Euler.</div>
</li>
</ol>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Note that these steps correspond to steps 2 through 4 of the general sequence of impulse-based time steps described above.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Computing the Velocities</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s examine the equations. Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span> = <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em>-1</span>)</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span> = <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span>)</span>. That is, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span> are the velocity in the previous time step and the velocity for the current time step (which we want to determine), respectively. Using the semi-implicit Euler integration scheme, the tentative, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">unconstrained</em> velocity for the current step (indicated by an asterisk) is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91166/toptal-blog-image-1431661485199-d1b2b255d94389fcc32289bd4baa8167.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This velocity may violate the constraints, in which case it must be corrected with an impulse.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">P</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span></span> be the constraint impulse. Dividing it by mass we get the change in velocity, and apply it to the tentative velocity to get the desired velocity that satisfies the constraints:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ApplyImpulse" src="https://assets.toptal.io/uploads/blog/image/91167/toptal-blog-image-1431661495445-8ca620bb9f0bd481eae9f757436a03d1.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So how do we determine <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">P</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span></span>? If we recognize that the impulse will be applied in the same direction as an instantaneous force that produces it, we can again use the fact that the constraint forces must be parallel to the gradient of the behavior function, just like we did with the force-based constraints. Thus, we can write:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintImpulse" src="https://assets.toptal.io/uploads/blog/image/91169/toptal-blog-image-1431661522251-37298455da53e8862ec2c5162069866b.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> is again a vector of magnitudes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The impulse-based approach represents a shortcut that bypasses Newton’s Second Law. By skipping the computation of forces and their resulting accelerations, it can generate noticeable, instantaneous velocity changes that can make a simulation jitter undesirably. To mitigate these effects, it’s common to add a <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bias</span>factor to the velocity constraints, to soften the effects:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConstraintBias" src="https://assets.toptal.io/uploads/blog/image/91170/toptal-blog-image-1431661530920-10698aa12f59571623e649ab0b7c5cf0.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Observe that <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span> + <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</em> = 0</span>, since <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span> must be a valid velocity. Then, substituting and rearranging the valid velocity equation, we obtain</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ImpulseLambda" src="https://assets.toptal.io/uploads/blog/image/91171/toptal-blog-image-1431661543643-eb8a0fd42f91d959a42265ae861d69c1.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After solving this equation for <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> we can compute the constraint impulse using <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">P</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> = <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: super;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">T</em></span><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span>, and finally update the velocity.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We have to solve every constraint individually and apply the impulses, updating the bodies’ velocities, and then repeat this step multiple times until convergence is achieved or a maximum number of iterations is met. That means we <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">accumulate</em> the impulses as we iterate. To finish the time step, we just have to update the positions using the final velocities:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="PositionUpdateSolved" src="https://assets.toptal.io/uploads/blog/image/91172/toptal-blog-image-1431661560654-b366ed52c80f3316dbdceb99d985b37f.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Inequality Constraints</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For inequality constraints, we have to bound the impulses and keep them in the allowable values as we accumulate them, so that the constraints won’t apply impulses in undesired directions or strengths. This bounding procedure is not as simple as just applying a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">min</code>/<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">max</code> function, because we only want to bound the final accumulated impulse, but <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">not</em> the intermediate impulses generated during the accumulation. Check out <a href="http://twvideo01.ubm-us.net/o1/vault/gdc09/slides/04-GDC09_Catto_Erin_Solver.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Erin Catto’s GDC 2009</a> presentation for details.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Warm Starting</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One little technique that improves the accuracy of the algorithm greatly is called <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">warm starting</span>. The algorithm starts with an initial guess for <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span>, and works its way up from there. Given that a physics simulation has a lot of temporal and spatial coherence, it’s natural to think about using the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> found in the previous step as a starting point, and that is what warm starting is about. The bodies often don’t move much from step to step, so it’s very likely that the impulses we computed in the previous step will be almost the same in the current step. Starting our algorithm from there makes it converge to a more accurate solution faster. This improves the stability of the simulation, especially for constraints such as joints and persistent contact between bodies.</div>
<h3 id="projected-gauss-seidel" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Projected Gauss-Seidel</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Another technique for solving impulse-based constraints comes from the fact that it can also be modeled as an MLCP. <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Projected Gauss-Seidel</span> (PGS) is an iterative algorithm for solving MLCPs that works well for impulse-based dynamics. It essentially solves a linear system <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em> = <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span>, with bounds on <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em></span>. PGS is an extension of the<a href="https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Gauss-Seidel method</a>, where we bound the value of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em></span> on each iteration to keep it in the desired range.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since we’re working on the velocity, we can eliminate the acceleration by writing an approximation of it as the ratio between the velocity change and the delta time for the current time step. Let <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span> = <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em>-1</span>)</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span> = <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span>)</span>, then:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="AccelerationApproximation" src="https://assets.toptal.io/uploads/blog/image/91173/toptal-blog-image-1431661577405-0a53aa118a70053833bc01f629893b50.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where, again, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> is the velocity calculated in the previous step, and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span> is the velocity we want to find for the current step. From Newton’s Second Law we have:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91174/toptal-blog-image-1431661615596-9d58124072b2aab25f761692a1080833.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Substituting our approximation and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em></span> = <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: super;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">T</em></span><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span>, we get:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91175/toptal-blog-image-1431661649931-9eb9ba332a540fac054caa4f3c3d5b29.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ċ</span></em> = 0</span>, we have that <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span> = <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span></span>, because <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span> will be a legal velocity after this is solved. Rearranging and multiplying by <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">J</span></span> on both sides, we get:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ImpulseBasedSystem" src="https://assets.toptal.io/uploads/blog/image/91197/toptal-blog-image-1431662881142-c2141970afee3033876a339832a40737.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This MLCP is slightly different from what we have for the force-based approach, because it uses an approximate acceleration. Once we solve it using PGS, we’ll have <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span>, and then <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">q̇</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span> can be computed using the previous equation:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="VelocityUpdate" src="https://assets.toptal.io/uploads/blog/image/91198/toptal-blog-image-1431662931118-49b9c1c46a592b3c964df26da46eda97.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The updated positions and orientations follow easily from the semi-implicit Euler scheme:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="PositionUpdate" src="https://assets.toptal.io/uploads/blog/image/91178/toptal-blog-image-1431661683297-b366ed52c80f3316dbdceb99d985b37f.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Interestingly, close investigation reveals that PGS is equivalent to sequential impulses! We’re doing essentially the same thing here. Warm starting can again be used, taking <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</span></em></span> computed in the previous step as a starting point. The difference is that the sequential impulses formulation is more intuitive, but the PGS formulation is more general and allows for more flexible code. For instance, we can experiment using other tools to solve the MLCP.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For more details about using PGS in an impulse-based simulation, take a look at <a href="https://code.google.com/p/box2d/downloads/detail?name=GDC2005_ErinCatto.zip&can=2&q=" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Erin Catto’s 2005 GDC presentation and paper</a>.</div>
<h3 id="simulating-friction-using-impulses" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Simulating Friction Using Impulses</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Friction" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Coulomb friction model</a> is simple and works nicely. It defines two different cases when two solid surfaces are in contact with each other:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Static friction</span>: Resistance to tangential motion when the surfaces are not moving relative to each other, because there is not enough force to overcome friction. The friction force points in the opposite direction of the net tangent force, and is equal to it in magnitude.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Kinetic friction</span>: Resistance to tangential motion when the surfaces are sliding. The friction force points in the opposite direction of motion, and is less than the net tangent forces in magnitude.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The friction force is proportional to the normal force, which is the net force component in the direction of the contact surface’s normal vector. In other words, the force of friction is proportional to the force pushing the two objects towards into each other. It can be expressed by:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CoulombFriction" src="https://assets.toptal.io/uploads/blog/image/91179/toptal-blog-image-1431661697558-8805278f1c9eaa1aba6a6f209833c694.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</em></span></span> is the friction force, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em></span></span> is the normal force and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">μ</em></span> is the <a href="https://en.wikipedia.org/wiki/Friction#Coefficient_of_friction" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">coefficient of friction</span></a> (which can be different for static and kinetic friction).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SurfaceFriction" src="https://assets.toptal.io/uploads/blog/image/91180/toptal-blog-image-1431661708306-f3f177deb797062e5db3621ae5f4512c.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To simulate friction using a constraint model, we have to write a velocity constraint directly:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="FrictionVelocityConstraint" src="https://assets.toptal.io/uploads/blog/image/91181/toptal-blog-image-1431661732345-1b3eb40f81fb45037ebd0cbf2e1b54f1.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</em></span></span> is the relative velocity vector at the contact point <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</em></span>, and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</span></em></span> is a unit vector tangent to the surfaces. We want to bring the tangential velocity to zero.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Per the friction equation, we have to limit the value of the friction impulse to the normal impulse times the coefficient of friction. This means we have to keep our <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em></span> between <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">-<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">μ</em> <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">n</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">μ</em> <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">n</span></span>, where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">λ</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">n</span></span> is the magnitude of the normal impulse.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="FrictionBounds" src="https://assets.toptal.io/uploads/blog/image/91182/toptal-blog-image-1431661741126-4541bd6ef8909c33095c3b5e071d57aa.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Thus, friction is another example of an inequality constraint.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In three dimensions, things get a tad more complicated. In his <a href="https://code.google.com/p/box2d/downloads/detail?name=GDC2005_ErinCatto.zip&can=2&q=" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">2005 GDC presentation</a>, Erin Catto presents an approach that uses two tangent vectors and a pair of constraints. However, limiting the friction impulse by a multiple of the normal impulse in this case couples the two constraints, and makes things hard to solve. He works around that by instead limiting it it by a constant value proportional to the mass of the body and the gravity acceleration.</div>
<h2 id="optimizations" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Optimizations</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We’ve described several methods for determining either the forces or the impulses to apply to our rigid bodies in order to enforce our constraints. In each case, the calculations involve a good amount of legwork. Let’s now look at some clever optimization strategies to cut out some of this work when it isn’t necessary.</div>
<h3 id="islands" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Islands</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In a constrained physics simulation, one can observe that some objects influence the motion of others, while some don’t.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Islands" src="https://assets.toptal.io/uploads/blog/image/91183/toptal-blog-image-1431661753947-56ff783d1d1fa2a69d1c6863edd2cdb9.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 500px;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the above image, the box <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span> is a static object that doesn’t move. It’s the floor. The objects on the left are stacked, in contact with each other. If any of them move at all, the others will potentially move as well, because there are contact constraints between them. Any force or impulse that is applied to any of these bodies might propagate throughout the other bodies. However, the triangle in the middle is just sitting alone on the fixed box <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</em></span>. Forces applied on the stacked objects on the left will never affect the motion of the triangle, because there’s no connection between any of the stacked objects and the triangle. The same can be said about the chain of boxes on the right. They’re all connected by revolute joints, and so the motion of any of them can generate a reaction along the constraints, influencing the motion of all other boxes that are part of the chain. But they will never influence the state of the triangle, nor the stacked objects on the left, unless a new constraint is created between any of these, such as a contact/non-penetration constraint due to their motion causing them to collide with the other objects.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Based on this simple observation, we can group these objects into what we call <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">islands</span>, which are self contained groups of bodies that can influence the motion of each other in the group through constraint forces/impulses, but will not influence the movement of objects belonging to any other island.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IslandsIdentified" src="https://assets.toptal.io/uploads/blog/image/91184/toptal-blog-image-1431661768683-accffc45b8ea208005e61ef6c01d00bb.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 500px;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This separation allows us to solve smaller groups of constraints, creating smaller systems instead of one single big system for the whole physics world. This eliminates a potentially huge amount of useless work that the computer must perform.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If we look at the world as a graph, where bodies are nodes and constraints are edges, we can build the islands using a <a href="https://en.wikipedia.org/wiki/Depth-first_search" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">depth-first search</span></a> on this graph. In graph theory, our islands are known as <a href="https://en.wikipedia.org/wiki/Connected_component_%28graph_theory%29" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">connected components</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Graph" src="https://assets.toptal.io/uploads/blog/image/91185/toptal-blog-image-1431661783741-0420fb0c60957a13ff1561ec08ee9d00.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 500px;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Box2D</em> does this in its <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Dynamics/b2World.cpp#385" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2World::Solve</code></a> method, which is responsible for solving all the constraints in each<a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Dynamics/b2World.cpp#897" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">step</a>. It builds the islands and then calls <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Dynamics/b2Island.cpp#183" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2Island::Solve</code></a> on each of them. This method solves the constraints in that island using sequential impulses.</div>
<h3 id="sleeping" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Sleeping</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When a body comes to rest during the simulation, its position will naturally remain unchanged for all subsequent steps of the simulation, until some external force causes it to move again. This calls our attention to another possible optimization: we can stop simulating a given island when the linear and angular velocities of all its bodies stay below a given tolerance for a small amount of time. This condition is called <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sleeping</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Sleeping" src="https://assets.toptal.io/uploads/blog/image/91186/toptal-blog-image-1431661795697-a12c76d2ccd7043a1d9336ba369e8883.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 500px;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After an island is put to sleep, its bodies are excluded from all steps of the simulation except collision detection. If a body outside the island collides with any body of this island, the island “wakes up,” and gets back into the simulation again. If any other external force or impulse is applied on any of its bodies, it also wakes up.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is a rather simple technique that can greatly improve the performance of simulations containing many objects.</div>
<h2 id="conclusion---video-game-physics-and-constrained-rigid-body-simulation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Conclusion - Video Game Physics and Constrained Rigid Body Simulation</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This concludes our three-part series on <a href="https://www.toptal.com/game" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">video game</a> physics. We have seen how physics can be simulated in games, focusing on rigid body simulation, which is a foundational subset of physics simulation that is often enough to make games dynamic and fun. We saw how the motion of rigid bodies can be simulated, how collisions between them can be detected and solved, and also how other interactions among them can be modeled.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The techniques we’ve seen are used in popular game physics engines such as <a href="http://box2d.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Box2D</em></a>, <a href="https://chipmunk-physics.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Chipmunk Physics</em></a> and<a href="http://www.bulletphysics.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Bullet Physics</em></a>. These methods can be used to make games with realistic, dynamic behavior, with objects moving around and colliding, and also allows objects to be connected to one another in a variety of ways through joints of many types. It may be of interest to note that these same methods even find applications in other realms beyond gaming, such as robotics.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As usual, things may be beautiful in theory, but in practice turn out to be another story. Many clever simplifications are necessary to obtain a stable and efficient implementation, especially regarding constrained dynamics. Many great developments have been made over the last few years regarding collision detection, time of impact computation, MLCP resolution, and so on, and yet there are still many things that can be improved. The <a href="http://bulletphysics.org/Bullet/phpBB3/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bullet Physics Forum</a> is a good place to keep up to date on what is going on in the game and rigid body physics simulation world, particularly the <a href="http://bulletphysics.org/Bullet/phpBB3/viewforum.php?f=4" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Research and development discussion about Collision Detection and Physics Simulation</em></a> section, where members discuss modern physics simulation techniques of all sorts.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Bridge" src="https://assets.toptal.io/uploads/blog/image/91187/toptal-blog-image-1431661808580-f65a67c6d9653e8ec46d82bf9b25b3af.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a href="https://www.toptal.com/resume/nilson-souto" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Nilson Souto</a>, a <a href="https://www.toptal.com/game/video-game-physics-part-iii-constrained-rigid-body-simulation">Toptal</a><a href="https://www.toptal.com/ios"> iOS developer</a>.</div>
Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-4258209981737157440.post-5273199975312390002016-06-27T22:48:00.000-07:002016-06-27T22:48:03.584-07:00Video Game Physics Tutorial - Part II: Collision Detection for Solid Objects<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">This is Part II of our three-part series on video game physics. For the rest of this series, see:</span></em></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; font-style: italic; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px 0px 0px 50px; vertical-align: baseline;">
<a href="https://www.toptal.com/game/video-game-physics-part-i-an-introduction-to-rigid-body-dynamics" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Part I: An Introduction to Rigid Body Dynamics</a></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In Part I of this series, we explored rigid bodies and their motions. In that discussion, however, objects did not interact with each other. Without some additional work, the simulated rigid bodies can go right through each other, or “interpenetrate”, which is undesirable in the majority of cases.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to more realistically simulate the behavior of solid objects, we have to check if they collide with each other every time they move, and if they do, we have to do something about it, such as applying forces that change their velocities, so that they will move in the opposite direction. This is where understanding collision physics is particularly important for <a href="https://www.toptal.com/game" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">game developers</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="video game physics and collision detection" src="https://assets.toptal.io/uploads/blog/image/924/toptal-blog-image-1425298886178.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In Part II, we will cover the collision detection step, which consists of finding pairs of bodies that are colliding among a possibly large number of bodies scattered around a 2D or 3D world. In the next, and final, installment, we’ll talk more about “solving” these collisions to eliminate interpenetrations.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For a review of the linear algebra concepts referred to in this article, you can refer to the <a href="https://www.toptal.com/game/video-game-physics-part-i-an-introduction-to-rigid-body-dynamics#appendix" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">linear algebra crash course in Part I</a>.</div>
<h2 id="collision-physics-in-video-games" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Collision Physics in Video Games</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the context of rigid body simulations, a collision happens when the shapes of two rigid bodies are intersecting, or when the distance between these shapes falls below a small tolerance.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If we have <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em></span> bodies in our simulation, the computational complexity of detecting collisions with pairwise tests is <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">O</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: super;">2</span>)</span>, a number that makes computer scientists cringe. The number of pairwise tests increases quadratically with the number of bodies, and determining if two shapes, in arbitrary positions and orientations, are colliding is already not cheap. In order to optimize the collision detection process, we generally split it in two phases: <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">broad phase</span> and <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">narrow phase</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The broad phase is responsible for finding pairs of rigid bodies that are <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">potentially</em> colliding, and excluding pairs that are certainly not colliding, from amongst the whole set of bodies that are in the simulation. This step must be able to scale really well with the number of rigid bodies to make sure we stay well under the <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">O</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: super;">2</span>)</span>time complexity. To achieve that, this phase generally uses <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">space partitioning</em> coupled with <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bounding volumes</em>that establish an upper bound for collision.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="BroadPhase" src="https://assets.toptal.io/uploads/blog/image/889/toptal-blog-image-1425291521137.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 500px;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The narrow phase operates on the pairs of rigid bodies found by the broad phase that might be colliding. It is a refinement step where we determine if the collisions are actually happening, and for each collision that is found, we compute the contact points that will be used to solve the collisions later.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="NarrowPhase" src="https://assets.toptal.io/uploads/blog/image/890/toptal-blog-image-1425291555824.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the next sections we’ll talk about some algorithms that can be used in the broad phase and narrow phase.</div>
<h2 id="broad-phase" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Broad Phase</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the broad phase of collision physics for video games we need to identify which pairs of rigid bodies <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">might</em>be colliding. These bodies might have complex shapes like polygons and polyhedrons, and what we can do to accelerate this is to use a simpler shape to encompass the object. If these <a href="https://en.wikipedia.org/wiki/Bounding_volume" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bounding volumes</span></a> do not intersect, then the actual shapes also do not intersect. If they intersect, then the actual shapes <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">might</em> intersect.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Some popular types of bounding volumes are oriented bounding boxes (OBB), circles in 2D, and spheres in 3D. Let’s look at one of the simplest bounding volumes: <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">axis-aligned bounding boxes (AABB)</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="BoundingVolumes" src="https://assets.toptal.io/uploads/blog/image/891/toptal-blog-image-1425291565424.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
AABBs get a lot of love from physics programmers because they are simple and offer good tradeoffs. A 2-dimensional AABB may be represented by a struct like this in the C language:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-c hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> x;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> y;
} Vector2;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
Vector2 min;
Vector2 max;
} AABB;
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">min</code> field represents the location of the lower left corner of the box and the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">max</code> field represents the top right corner.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="AABB" src="https://assets.toptal.io/uploads/blog/image/892/toptal-blog-image-1425291576115.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To test if two AABBs intersect, we only have to find out if their projections intersect on all of the coordinate axes:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-c hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">BOOL TestAABBOverlap(AABB* a, AABB* b)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> d1x = b->min.x - a->max.x;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> d1y = b->min.y - a->max.y;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> d2x = a->min.x - b->max.x;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> d2y = a->min.y - b->max.y;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (d1x > <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.0f</span> || d1y > <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.0f</span>)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> FALSE;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (d2x > <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.0f</span> || d2y > <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.0f</span>)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> FALSE;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> TRUE;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This code has the same logic of the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2TestOverlap</code> function from the <a href="http://box2d.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Box2D</a> engine (version 2.3.0). It calculates the difference between the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">min</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">max</code> of both AABBs, in both axes, in both orders. If any of these values is greater than zero, the AABBs don’t intersect.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="AABBOverlap" src="https://assets.toptal.io/uploads/blog/image/893/toptal-blog-image-1425291587817.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 500px;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Even though an AABB overlap test is cheap, it won’t help much if we still do pairwise tests for every possible pair since we still have the undesirable <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">O</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: super;">2</span>)</span> time complexity. To minimize the number of AABB overlap tests we can use some kind of <a href="https://en.wikipedia.org/wiki/Space_partitioning" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">space partitioning</span></a>, which which works on the same principles as <a href="https://en.wikipedia.org/wiki/Database_index" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">database indices</a>that speed up queries. (Geographical databases, such as <a href="http://postgis.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">PostGIS</a>, actually use similar data structures and algorithms for their spatial indexes.) In this case, though, the AABBs will be moving around constantly, so generally, we must recreate indices after every step of the simulation.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are plenty of space partitioning algorithms and data structures that can be used for this, such as<a href="https://en.wikipedia.org/wiki/Regular_grid" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">uniform grids</a>, <a href="https://en.wikipedia.org/wiki/Quadtree" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">quadtrees</a> in 2D, <a href="https://en.wikipedia.org/wiki/Octree" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">octrees</a> in 3D, and <a href="http://matthias-mueller-fischer.ch/publications/tetraederCollision.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">spatial hashing</a>. Let us take a closer look at two popular spatial partitioning algorithms: sort and sweep, and bounding volume hierarchies (BVH).</div>
<h3 id="the-sort-and-sweep-algorithm" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Sort and Sweep Algorithm</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sort and sweep</span> method (alternatively known as <a href="https://en.wikipedia.org/wiki/Sweep_and_prune" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sweep and prune</span></a>) is one of the favorite choices among physics programmers for use in rigid body simulation. The <a href="http://bulletphysics.org/wordpress/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bullet Physics</a> engine, for example, has an implementation of this method in the <a href="http://bulletphysics.org/Bullet/BulletFull/classbtAxisSweep3.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">btAxisSweep3</code></a> class.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The projection of one AABB onto a single coordinate axis is essentially an interval <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">[<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</em>, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">e</em>]</span> (that is, beginning and end). In our simulation, we’ll have many rigid bodies, and thus, many AABBs, and that means many intervals. We want to find out which intervals are intersecting.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SortAndSweep" src="https://assets.toptal.io/uploads/blog/image/894/toptal-blog-image-1425291599861.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the sort and sweep algorithm, we insert all <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</em></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">e</em></span> values in a single list and sort it ascending by their scalar values. Then we <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sweep</em> or traverse the list. Whenever a <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</em></span> value is encountered, its corresponding interval is stored in a separate list of <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">active intervals</em>, and whenever an <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">e</em></span> value is encountered, its corresponding interval is removed from the list of active intervals. At any moment, all the active intervals are intersecting. (Check out<a href="http://www.cs.cmu.edu/~baraff/papers/thesis-part1.ps.Z" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">David Baraff’s Ph. D Thesis</a>, p. 52 for details. I suggest using <a href="http://view.samurajdata.se/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">this online tool</a> to view the postscript file.) The list of intervals can be reused on each step of the simulation, where we can efficiently re-sort this list using<a href="https://en.wikipedia.org/wiki/Insertion_sort" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">insertion sort</a>, which is good at sorting nearly-sorted lists.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In two and three dimensions, running the sort and sweep, as described above, over a single coordinate axis will reduce the number of direct AABB intersection tests that must be performed, but the payoff may be better over one coordinate axis than another. Therefore, more sophisticated variations of the sort and sweep algorithm are implemented. In his book <a href="http://realtimecollisiondetection.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Real-Time Collision Detection</em></a> (page 336), Christer Ericson presents an efficient variation where he stores all AABBs in a single array, and for each run of the sort and sweep, one coordinate axis is chosen and the array is sorted by the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">min</code> value of the AABBs in the chosen axis, using<a href="https://en.wikipedia.org/wiki/Quicksort" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">quicksort</a>. Then, the array is traversed and AABB overlap tests are performed. To determine the next axis that should be used for sorting, the <a href="https://en.wikipedia.org/wiki/Variance" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">variance</a> of the center of the AABBs is computed, and the axis with greater variance is chosen for the next step.</div>
<h3 id="dynamic-bounding-volume-trees" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Dynamic Bounding Volume Trees</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Another useful spatial partitioning method is the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">dynamic bounding volume tree</span>, also known as <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Dbvt</span>. This is a type of <a href="https://en.wikipedia.org/wiki/Bounding_volume_hierarchy" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bounding volume hierarchy</span></a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Dbvt is a binary tree in which each node has an AABB that bounds all the AABBs of its children. The AABBs of the rigid bodies themselves are located in the leaf nodes. Typically, a Dbvt is “queried” by giving the AABB for which we would like to detect intersections. This operation is efficient because the children of nodes that do not intersect the queried AABB do not need to be tested for overlap. As such, an AABB collision query starts from the root, and continues recursively through the tree only for AABB nodes that intersect with the queried AABB. The tree can be balanced through <a href="https://en.wikipedia.org/wiki/Tree_rotation" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">tree rotations</a>, as in an <a href="https://en.wikipedia.org/wiki/AVL_tree" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">AVL tree</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Dbvt" src="https://assets.toptal.io/uploads/blog/image/895/toptal-blog-image-1425291611336.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Box2D has a sophisticated implementation of Dbvt in the <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2DynamicTree.h" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2DynamicTree</code></a> <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2DynamicTree.cpp" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">class</a>. The <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2BroadPhase.h" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2BroadPhase</code></a> <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2BroadPhase.cpp" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">class</a> is responsible for performing the broad phase, and it uses an instance of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2DynamicTree</code> to perform AABB queries.</div>
<h2 id="narrow-phase" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Narrow Phase</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After the broad phase of video game collision physics, we have a set of pairs of rigid bodies that are<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">potentially</em> colliding. Thus, for each pair, given the shape, position and orientation of both bodies, we need to find out if they are, in fact, colliding; if they are intersecting or if their distance falls under a small tolerance value. We also need to know what points of contact are between the colliding bodies, since this is needed to resolve the collisions later.</div>
<h3 id="convex-and-concave-shapes" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Convex and Concave Shapes</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As a video game physics general rule, it is not trivial to determine if two arbitrary shapes are intersecting, or to compute the distance between them. However, one property that is of critical importance in determining just how hard it is, is the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">convexity</span> of the shape. Shapes can be either <a href="https://en.wikipedia.org/wiki/Convex_set" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">convex</span></a> or <a href="https://en.wikipedia.org/wiki/Convex_set#Non-convex_set" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">concave</span></a> and concave shapes are harder to work with, so we need some strategies to deal with them.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In a convex shape, a line segment between any two points within the shape always falls completely inside the shape. However for a concave (or “non-convex”) shape, the same is not true for all possible line segments connecting points in the shape. If you can find at least one line segment that falls outside of the shape at all, then the shape is concave.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConvexConcave" src="https://assets.toptal.io/uploads/blog/image/923/toptal-blog-image-1425292601966.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Computationally, it is desirable that all shapes are convex in a simulation, since we have a lot of powerful distance and intersection test algorithms that work with convex shapes. Not all objects will be convex though, and usually we work around them in two ways: convex hull and convex decomposition.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Convex_hull" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">convex hull</span></a> of a shape is the smallest convex shape that fully contains it. For a concave polygon in two dimensions, it would be like hammering a nail on each vertex and wrapping a rubber band around all nails. To calculate the convex hull for a polygon or polyhedron, or more generally, for a set of points, a good algorithm to use is the <a href="https://en.wikipedia.org/wiki/QuickHull" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">quickhull</span></a> algorithm, which has an average time complexity of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">O</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em> log <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em>)</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConvexHull" src="https://assets.toptal.io/uploads/blog/image/922/toptal-blog-image-1425292592226.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Obviously, if we use a convex hull to represent a concave object, it will lose its concave properties. Undesirable behavior, such as “ghost” collisions may become apparent, since the object will still have a concave graphical representation. For example, a car usually has a concave shape, and if we use a convex hull to represent it physically and then put a box on it, the box might appear to be floating in the space above.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CarConvexHull" src="https://assets.toptal.io/uploads/blog/image/921/toptal-blog-image-1425292583611.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In general, convex hulls are often good enough to represent concave objects, either because the unrealistic collisions are not very noticeable, or their concave properties are not essential for whatever is being simulated. In some cases, though, we might want to have the concave object behave like a concave shape physically. For example, if we use a convex hull to represent a bowl physically, we won’t be able to put anything inside of it. Objects will just float on top of it. In this case, we can use a <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">convex decomposition</span> of the concave shape.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Convex decomposition algorithms receive a concave shape and return a set of convex shapes whose union is identical to the original concave shape. Some concave shapes can only be represented by a large number of convex shapes, and these might become prohibitively costly to compute and use. However, an approximation is often good enough, and so, algorithms such as <a href="https://code.google.com/p/v-hacd/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">V-HACD</span></a> produce a small set of convex polyhedrons out of a concave polyhedron.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In many collisons physics cases, though, the convex decomposition can be made by hand, by an artist. This eliminates the need to tax performance with decomposition algorithms. Since performance is one of the most important aspects in real-time simulations, it’s generally a good idea to create very simple physical representations for complex graphic objects. The image below shows one possible convex decomposition of a 2D car using nine convex shapes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConvexDecomposition" src="https://assets.toptal.io/uploads/blog/image/920/toptal-blog-image-1425292575659.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><br /><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h3 id="testing-for-intersections---the-separating-axis-theorem" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Testing for Intersections - The Separating Axis Theorem</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Hyperplane_separation_theorem" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">separating axis theorem</span></a> (SAT) states that two convex shapes are not intersecting if and only if there exists at least one axis where the orthogonal projections of the shapes on this axis do not intersect.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SeparatingAxis" src="https://assets.toptal.io/uploads/blog/image/919/toptal-blog-image-1425292560762.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SeparatingAxisIntersecting" src="https://assets.toptal.io/uploads/blog/image/918/toptal-blog-image-1425292552444.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s usually more visually intuitive to find a line in 2D or a plane in 3D that separates the two shapes, though, which is effectively the same principle. A vector orthogonal to the line in 2D, or the normal vector of the plane in 3D, can be used as the “separating axis”.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SeparatingLines" src="https://assets.toptal.io/uploads/blog/image/917/toptal-blog-image-1425292544196.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Game physics engines have a number of different classes of shapes, such as circles (spheres in 3D), edges (a single line segment), and convex polygons (polyhedrons in 3D). For each pair of shape type, they have a specific collision detection algorithm. The simplest of them is probably the circle-circle algorithm:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-c hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> centerX;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> centerY;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> radius;
} Circle;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">bool</span> CollideCircles(Circle *cA, Circle *cB) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> x = cA->centerX - cB->centerX;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> y = cA->centerY - cB->centerY;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> centerDistanceSq = x * x + y * y; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// squared distance</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> radius = cA->radius + cB->radius;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> radiusSq = radius * radius;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> centerDistanceSq <= radiusSq;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Even though the SAT applies to circles, it’s much simpler to just check if the distance between their centers is smaller than the sum of their radii. For that reason, the SAT is used in the collision detection algorithm for specific pairs of shape classes, such as convex polygon against convex polygon (or polyhedrons in 3D).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For any pair of shapes, there are an infinite number of axes we can test for separation. Thus, determining which axis to test first is crucial for an efficient SAT implementation. Fortunately, when testing if a pair of convex polygons collide, we can use the edge normals as potential separating axes. The normal vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</em></span></span> of an edge is perpendicular to the edge vector, and points outside the polygon. For each edge of each polygon, we just need to find out if all the vertices of the other polygon are <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">in front</em> of the edge.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ConvexPolygonSAT" src="https://assets.toptal.io/uploads/blog/image/916/toptal-blog-image-1425292534225.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If any test passes – that is, if, for any edge, all vertices of the other polygon are <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">in front</em> of it – then the polygons do not intersect. Linear algebra provides an easy formula for this test: given an edge on the first shape with vertices <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span> and a vertex <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em></span> on the other shape, if <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em> - <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em>) · <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">n</span></em></span> is greater than zero, then the vertex is in front of the edge.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For polyhedrons, we can use the face normals and also the cross product of all edge combinations from each shape. That sounds like a lot of things to test; however, to speed things up, we can cache the last separating axis we used and try using it again in the next steps of the simulation. If the cached separating axis does not separate the shapes anymore, we can search for a new axis starting from faces or edges that are adjacent to the previous face or edge. That works because the bodies often don’t move or rotate much between steps.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Box2D uses SAT to test if two convex polygons are intersecting in its polygon-polygon collision detection algorithm in <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2CollidePolygon.cpp?r=313" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">b2CollidePolygon.cpp</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="https://www.blogger.com/null" name="computing_distance" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"></a></div>
<h3 id="computing-distance---the-gilbert-johnson-keerthi-algorithm" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Computing Distance - The Gilbert-Johnson-Keerthi Algorithm</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In many collisions physics cases, we want to consider objects to be colliding not only if they are actually intersecting, but also if they are very close to each other, which requires us to know the distance between them. The <a href="https://en.wikipedia.org/wiki/Gilbert%E2%80%93Johnson%E2%80%93Keerthi_distance_algorithm" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Gilbert-Johnson-Keerthi</span></a> (GJK) algorithm computes the distance between two convex shapes and also their closest points. It is an elegant algorithm that works with an implicit representation of convex shapes through support functions, Minkowski sums, and simplexes, as explained below.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Support Functions</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A <a href="https://en.wikipedia.org/wiki/Support_(mathematics)" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">support function</span></a> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">s</em><span style="border: 0px; box-sizing: border-box; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">A</span>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em>)</span> returns a point on the boundary of the shape <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> that has the highest projection on the vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span>. Mathematically, it has the highest dot product with <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span>. This is called a <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">support point</span>, and this operation is also known as <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">support mapping</span>. Geometrically, this point is the farthest point on the shape in the direction of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SupportMapping" src="https://assets.toptal.io/uploads/blog/image/915/toptal-blog-image-1425292204269.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Finding a support point on a polygon is relatively easy. For a support point for vector <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span>, you just have to loop through its vertices and find the one which has the highest dot product with <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span>, like this:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-c hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">Vector2 GetSupport(Vector2 *vertices, <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> count, Vector2 d) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> highest = -FLT_MAX;
Vector2 support = (Vector2){<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>};
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < count; ++i) {
Vector2 v = vertices[i];
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> dot = v.x * d.x + v.y * d.y;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span> (dot > highest) {
highest = dot;
support = v;
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> support;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, the real power of a support function is that makes it easy to work with shapes such as cones, cylinders, and ellipses, among others. It is rather difficult to compute the distance between such shapes directly, and without an algorithm like GJK you would usually have to discretize them into a polygon or polyhedron to make things simpler. However, that might lead to further problems because the surface of a polyhedron is not as smooth as the surface of, say, a sphere, unless the polyhedron is very detailed, which can lead to poor performance during collision detection. Other undesirable side effects might show up as well; for example, a “polyhedral” sphere might not roll smoothly.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To get a support point for a sphere centered on the origin, we just have to normalize <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span> (that is, compute <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em> / ||<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em>||</span>, which is a vector with length 1 (unit length) that still points in the same direction of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">d</span></em></span>) and then we multiply it by the sphere radius.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SphereSupportPoint" src="https://assets.toptal.io/uploads/blog/image/914/toptal-blog-image-1425292006044.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Check <a href="http://www.dtecta.com/papers/jgt98convex.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Gino van den Bergen’s paper</a> to find more examples of support functions for cylinders, and cones, among other shapes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Our objects will, of course, be displaced and rotated from the origin in the simulation space, so we need to be able to compute support points for a transformed shape. We use an <a href="https://en.wikipedia.org/wiki/Affine_transformation" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">affine transformation</span></a> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">T</em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em>) = <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">R</span><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em> + <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">c</span></em></span> to displace and rotate our objects, where <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">c</span></em></span> is the displacement vector and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">R</span></span> is the <a href="https://en.wikipedia.org/wiki/Rotation_matrix" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rotation matrix</span></a>. This transformation first rotates the object about the origin, and then translates it. The support function for a transformed shape <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="TransformedSupportMapping" src="https://assets.toptal.io/uploads/blog/image/913/toptal-blog-image-1425291823757.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Minkowski Sums</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Minkowski_sum" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Minkowski sum</span></a> of two shapes <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span> is defined as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinkowskiSum" src="https://assets.toptal.io/uploads/blog/image/912/toptal-blog-image-1425291808625.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
That means we compute the sum for all points contained in <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span>. The result is like <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">inflating</em> <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> with <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinkowskiSumExample.png" src="https://assets.toptal.io/uploads/blog/image/911/toptal-blog-image-1425291800413.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Similarly, we define the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Minkowski difference</span> as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinkowskiDifference" src="https://assets.toptal.io/uploads/blog/image/910/toptal-blog-image-1425291791138.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
which we can also write as the Minkowski sum of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> with <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">-B</span>:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinkowskiDifferenceSum" src="https://assets.toptal.io/uploads/blog/image/909/toptal-blog-image-1425291770651.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinkowskiDifferenceExample" src="https://assets.toptal.io/uploads/blog/image/908/toptal-blog-image-1425291758424.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For convex <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span>, <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊕B</span> is also convex.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One useful property of the Minkowski difference is that if it contains the origin of the space, the shapes intersect, as can be seen in the previous image. Why is that? Because if two shapes intersect, they have at least one point in common, which lie in the same location in space, and their difference is the zero vector, which is actually the origin.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Another nice feature of the Minkowski difference is that if it doesn’t contain the origin, the minimum distance between the origin and the Minkowski difference is the distance between the shapes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The distance between two shapes is defined as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Distance" src="https://assets.toptal.io/uploads/blog/image/907/toptal-blog-image-1425291750628.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In other words, the distance between <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span> is the length of the shortest vector that goes from <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span>. This vector is contained in <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊖B</span> and it is the one with the smallest length, which consequently is the one closest to the origin.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is generally not simple to explicitly build the Minkowski sum of two shapes. Fortunately, we can use support mapping here as well, since:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinkowskiDifferenceSupport" src="https://assets.toptal.io/uploads/blog/image/906/toptal-blog-image-1425291741891.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Simplexes</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The GJK algorithm iteratively searches for the point on the Minkowski difference closest to the origin. It does so by building a series of <a href="https://en.wikipedia.org/wiki/Simplex" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">simplexes</span></a> that are closer to the origin in each iteration. A simplex – or more specifically, a <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">k-simplex</span> for an integer <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">k</span> – is the convex hull of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">k + 1</span> <a href="https://en.wikipedia.org/wiki/Affine_space#Affine_combinations_and_affine_dependence" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">affinely independent</span></a> points in a k-dimensional space. That is, if for two points, they must not coincide, for three points they additionally must not lie on the same line, and if we have four points they also must not lie on the same plane. Hence, the 0-simplex is a point, the 1-simplex is a line segment, the 2-simplex is a triangle and the 3-simplex is a tetrahedron. If we remove a point from a simplex we decrement its dimensionality by one, and if we add a point to a simplex we increment its dimensionality by one.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Simplices" src="https://assets.toptal.io/uploads/blog/image/905/toptal-blog-image-1425291730573.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">GJK in Action</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s put this all together to see how GJK works. To determine the distance between two shapes <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span>, we start by taking their Minkowski difference <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊖B</span>. We are searching for the closest point to the origin on the resulting shape, since the distance to this point is the distance between the original two shapes. We choose some point <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em></span> in <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊖B</span>, which will be our distance approximation. We also define an empty point set <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">W</span>, which will contain the points in the current test simplex.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Then we enter a loop. We start by getting the support point <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">w</span></em> = s<span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">A⊖B</span>(-<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em>)</span>, the point on <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊖B</span> whose projection onto <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em></span> is closest to the origin.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">||<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">w</span></em>||</span> is not much different than <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">||<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em>||</span> and the angle between them didn’t change much (according to some predefined tolerances), it means the algorithm has converged and we can return <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">||<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em>||</span> as the distance.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Otherwise, we add <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">w</span></em></span> to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">W</span>. If the convex hull of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">W</span> (that is, the simplex) contains the origin, the shapes intersect, and this also means we are done. Otherwise, we find the point in the simplex that is closest to the origin and then we reset <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em></span> to be this new closest approximation. Finally, we remove whatever points in <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">W</span> that do not contribute to the closest point computation. (For example, if we have a triangle, and the closest point to the origin lies in one of its edges, we can remove the point from <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">W</span> that is not a vertex of this edge.) Then we repeat these same steps until the algorithm converges.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The next image shows an example of four iterations of the GJK algorithm. The blue object represents the Minkowski difference <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊖B</span> and the green vector is <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em></span>. You can see here how <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em></span> hones in on the closest point to the origin.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="GJK" src="https://assets.toptal.io/uploads/blog/image/904/toptal-blog-image-1425291719088.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For a detailed and in-depth explanation of the GJK algorithm, check out the paper <a href="http://www.dtecta.com/papers/jgt98convex.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A Fast and Robust GJK Implementation for Collision Detection of Convex Objects</em></a>, by Gino van den Bergen. The blog for the <a href="http://www.dyn4j.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">dyn4j</a>physics engine also has a <a href="http://www.dyn4j.org/2010/04/gjk-gilbert-johnson-keerthi/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">great post on GJK</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Box2D has an implementation of the GJK algorithm in <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2Distance.cpp" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">b2Distance.cpp</a>, in the <a href="https://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Collision/b2Distance.cpp#444" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">b2Distance</code></a> function. It only uses GJK during time of impact computation in its algorithm for continuous collision detection (a topic we will discuss further down).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Chimpunk physics engine uses GJK for all collision detection, and its implementation is in <a href="https://github.com/slembcke/Chipmunk2D/blob/master/src/cpCollision.c" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">cpCollision.c</a>, in the <a href="https://github.com/slembcke/Chipmunk2D/blob/master/src/cpCollision.c#L420" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GJK</code></a> function. If the GJK algorithm reports intersection, it still needs to know what the contact points are, along with the penetration depth. To do that, it uses the Expanding Polytope Algorithm, which we shall explore next.</div>
<h3 id="determining-penetration-depth---the-expanding-polytope-algorithm" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Determining Penetration Depth - The Expanding Polytope Algorithm</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As stated above, if the shapes <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span> are intersecting, GJK will generate a simplex <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">W</span> that contains the origin, inside the Minkowski difference <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A⊖B</span>. At this stage, we only know that the shapes intersect, but in the design of many collision detection systems, it is desirable to be able to compute how much intersection we have, and what points we can use as the points of contact, so that we handle the collision in a realistic way. The <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Expanding Polytope Algorithm</span> (EPA) allows us to obtain that information, starting where GJK left off: with a simplex that contains the origin.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">penetration depth</span> is the length of the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">minimum translation vector</span> (MTV), which is the smallest vector along which we can translate an intersecting shape to separate it from the other shape.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="MinimumTranslatioVector" src="https://assets.toptal.io/uploads/blog/image/903/toptal-blog-image-1425291708892.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When two shapes are intersecting, their Minkowski difference contains the origin, and the point on the boundary of the Minkowski difference that is closest to the origin is the MTV. The EPA algorithm finds that point by expanding the simplex that GJK gave us into a polygon; successively subdividing it’s edges with new vertices.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First, we find the edge of the simplex closest to the origin, and compute the support point in the Minkowski difference in a direction that is normal to the edge (i.e. perpendicular to it and pointing outside the polygon). Then we split this edge by adding this support point to it. We repeat these steps until the length and direction of the vector doesn’t change much. Once the algorithm converges, we have the MTV and the penetration depth.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="EPA" src="https://assets.toptal.io/uploads/blog/image/902/toptal-blog-image-1425291700012.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Using GJK in combination with EPA, we get a detailed description of the collision, no matter if the objects are already intersecting, or just close enough to be considered a collision.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The EPA algorithm is described in the paper <a href="http://www.dtecta.com/papers/gdc2001depth.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Proximity Queries and Penetration Depth Computation on 3D Game Objects</em></a>, also written by Gino van den Bergen. The dyn4j blog also has a <a href="http://www.dyn4j.org/2010/05/epa-expanding-polytope-algorithm/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">post about EPA</a>.</div>
<h2 id="continuous-collision-detection" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Continuous Collision Detection</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The video game physics techniques presented so far perform collision detection for a static snapshot of the simulation. This is called <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">discrete collision detection</span>, and it ignores what happens between the previous and current steps. For this reason, some collisions might not be detected, especially for fast moving objects. This issue is known as <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tunneling</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Tunneling" src="https://assets.toptal.io/uploads/blog/image/901/toptal-blog-image-1425291689009.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Continuous collision detection techniques attempt to find <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">when</em> two bodies collided between the previous and the current step of the simulation. They compute the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">time of impact</span>, so we can then go back in time and process the collision at that point.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The time of impact (or time of contact) <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">c</em></span></span> is the instant of time when the distance between two bodies is zero. If we can write a function for the distance between two bodies along time, what we want to find is the smallest<a href="https://en.wikipedia.org/wiki/Zero_of_a_function" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">root</a> of this function. Thus, the time of impact computation is a <a href="https://en.wikipedia.org/wiki/Root-finding_algorithm" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">root-finding problem</span></a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For the time of impact computation, we consider the state (position and orientation) of the body in the previous step at time <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em>-1</span></span>, and in the current step at time <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span>. To make things simpler, we assume linear motion between the steps.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="TimeOfContact" src="https://assets.toptal.io/uploads/blog/image/900/toptal-blog-image-1425291677172.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s simplify the problem by assuming the shapes are circles. For two circles <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span>, with radius <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span>, where their center of mass <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span> coincide with their centroid (i.e., they naturally rotate about their center of mass), we can write the distance function as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CircleDistance" src="https://assets.toptal.io/uploads/blog/image/899/toptal-blog-image-1425291666810.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Considering linear motion between steps, we can write the following function for the position of <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">C</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> from <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em>-1</span></span>to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CirclePositionInterval" src="https://assets.toptal.io/uploads/blog/image/898/toptal-blog-image-1425291657301.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is a linear interpolation from <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em>-1</span>)</span> to <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</em></span>)</span>. The same can be done for <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">2</span></span>. For this interval we can write another distance function:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CircleDistanceInterval" src="https://assets.toptal.io/uploads/blog/image/897/toptal-blog-image-1425291643863.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Set this expression equal to zero and you get a <a href="https://en.wikipedia.org/wiki/Quadratic_equation" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">quadratic equation</a> on <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em></span>. The roots can be found directly using the <a href="https://en.wikipedia.org/wiki/Quadratic_formula" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">quadratic formula</a>. If the circles don’t intersect, the quadratic formula will not have a solution. If they do, it might result in one or two roots. If it has only one root, that value is the time of impact. If it has two roots, the smallest one is the time of impact and the other is the time when the circles separate. Note that the time of impact here is a number from 0 to 1. It is not a time in seconds; it is just a number we can use to interpolate the state of the bodies to the precise location where the collision happened.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CirclesTimeOfContact" src="https://assets.toptal.io/uploads/blog/image/896/toptal-blog-image-1425291633731.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Continuous Collision Detection for Non-Circles</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Writing a distance function for other kinds of shapes is difficult, primarily because their distance depends on their orientations. For this reason, we generally use iterative algorithms that move the objects closer and closer on each iteration until they are <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">close enough</em> to be considered colliding.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">conservative advancement</span> algorithm moves the bodies forward (and rotates them) iteratively. In each iteration it computes an upper bound for displacement. The original algorithm is presented in <a href="http://www.kuffner.org/james/software/dynamics/mirtich/index.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Brian Mirtich’s PhD Thesis</a> (section 2.3.2), which considers the ballistic motion of bodies. <a href="http://gamedevs.org/uploads/continuous-collision-detection-and-physics.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">This paper</a> by Erwin Coumans (the author of the Bullet Physics Engine) presents a simpler version that uses constant linear and angular velocities.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The algorithm computes the closest points between shapes <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A</span> and <span style="border: 0px; box-sizing: border-box; font-family: TimesNewRoman; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">B</span>, draws a vector from one point to the other, and projects the velocity on this vector to compute an upper bound for motion. It guarantees that no points on the body will move beyond this projection. Then it advances the bodies forward by this amount and repeats until the distance falls under a small tolerance value.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It may take too many iterations to converge in some cases, for example, when the angular velocity of one of the bodies is too high. Erin Catto (the author of the Box2D Engine) presents another algorithm based on conservative advancement in his <a href="https://box2d.googlecode.com/files/ErinCatto_GDC2013.zip" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">2013 GDC talk</a>.</div>
<h2 id="resolving-collisions" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Resolving Collisions</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Once a collision has been detected, it is necessary to change the motions of the colliding objects in a realistic way, such as causing them to bounce off each other. In the next and final installment in this theories, we’ll discuss some popular methods for resolving collisions in video games.</div>
<h2 id="references" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
References</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you are interested in obtaining a deeper understanding about collision physics such as collision detection algorithms and techniques, the book <a href="http://realtimecollisiondetection.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Real-Time Collision Detection</em></a>, by Christer Ericson, is a must-have.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since collision detection relies heavily on geometry, Toptal’s article <a href="https://www.toptal.com/python/computational-geometry-in-python-from-theory-to-implementation" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Computational Geometry in Python: From Theory to Application</em></a> is an excellent introduction to the topic.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a href="https://www.toptal.com/resume/nilson-souto" style="background-color: #436ba8; border: 0px; box-sizing: border-box; color: white; font-size: 19px; font-weight: 600; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; text-decoration: none; vertical-align: baseline;">Nilson Souto</a>, a <a href="https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects">Toptal</a><a href="https://www.toptal.com/ios"> iOS developer</a>.</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-4693252559592512922016-06-22T02:18:00.000-07:002016-06-22T02:18:35.495-07:00Video Game Physics Tutorial - Part I: An Introduction to Rigid Body Dynamics<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">This is Part I of our three-part series on video game physics.</span></em></div>
<hr style="background: rgb(228, 228, 228); border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; height: 1px; line-height: 20px; margin: 3em 0px;" />
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Physics simulation is a field within computer science that aims to reproduce physical phenomena using a computer. In general, these simulations apply numerical methods to existing theories to obtain results that are as close as possible to what we observe in the real world. This allows us, as <a href="https://www.toptal.com/game" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">advanced game developers</a>, to predict and carefully analyze how something would behave before actually building it, which is almost always simpler and cheaper to do.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Video game physics is all about simulating the physics of the real world." src="https://assets.toptal.io/uploads/blog/image/764/toptal-blog-image-1421916899496.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The range of applications of physics simulations is enormous. The earliest computers were already being used to perform physics simulations – for example, to predict the ballistic motion of projectiles in the military. It is also an essential tool in civil and automotive engineering, illuminating how certain structures would behave in events like an earthquake or a car crash. And it doesn’t stop there. We can simulate things like astrophysics, relativity, and lots of other insane stuff we are able to observe in among the wonders of nature.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Simulating physics in video games is very common, since most games are <a href="https://www.toptal.com/ios/building-an-infinite-runner-on-ios-cocos2d-automation-scripts" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">inspired by things we have in the real world</a>. Many games rely entirely on the physics simulation to be fun. That means these games require a stable simulation that will not break or slow down, and this is usually not trivial to achieve.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In any game, only certain physical effects are of interest. Rigid body dynamics – the movement and interaction of solid, inflexible objects – is by far the most popular kind of effect simulated in games. That’s because most of the objects we interact with in real life are fairly rigid, and simulating rigid bodies is relatively simple (although as we will see, that doesn’t mean it’s a cakewalk). A few other games require the simulation of more complicated entities though, such as deformable bodies, fluids, magnetic objects, etc.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this video game physics tutorial series, rigid body simulation will be explored, starting with simple rigid body motion in this article, and then covering interactions among bodies through collisions and constraints in the following installments. The most common equations used in modern game physics engines such as<a href="http://box2d.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Box2D</a>, <a href="http://bulletphysics.org/wordpress/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bullet Physics</a> and <a href="https://chipmunk-physics.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Chipmunk Physics</a> will be presented and explained.</div>
<h2 id="rigid-body-dynamics" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rigid Body Dynamics</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In video game physics, we want to animate objects on screen and give them realistic physical behavior. This is achieved with physics-based procedural animation, which is animation produced by numerical computations applied to the theoretical laws of physics.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Animations are produced by displaying a sequence of images in succession, with objects moving slightly from one image to the next. When the images are displayed in quick succession, the effect is an apparent smooth and continuous movement of the objects. Thus, to animate the objects in a physics simulation, we need to update the physical state of the objects (e.g. position and orientation), according to the laws of physics multiple times per second, and redraw the screen after each update.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Physics_engine" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">physics engine</span></a> is the software component that performs the physics simulation. It receives a specification of the bodies that are going to be simulated, plus some configuration parameters, and then the simulation can be <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stepped</span>. Each step moves the simulation forward by a few fractions of a second, and the results can be displayed on screen afterwards. Note that physics engines only perform the numerical simulation. What is done with the results may depend on the requirements of the game. It is not always the case that the results of every step wants to be drawn to the screen.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The motion of rigid bodies can be modeled using <a href="https://en.wikipedia.org/wiki/Classical_mechanics" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">newtonian mechanics</span></a>, which is founded upon Isaac Newton’s famous <a href="https://en.wikipedia.org/wiki/Newton%27s_laws_of_motion" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Three Laws of Motion</span></a>:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Inertia</span>: If no force is applied on an object, its velocity (speed and direction of motion) shall not change.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Force, Mass, and Acceleration</span>: The force acting on an object is equal to the mass of the object multiplied by its acceleration (rate of change of velocity). This is given by the formula <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">F</em> = <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ma</em></span></span>.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Action and Reaction</span>: “For every action there is an equal and opposite reaction.” In other words, whenever one body exerts a force on another, the second body exerts a force of the same magnitude and opposite direction on the first.</div>
</li>
</ol>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Based on these three laws, we can make a physics engine that is able to reproduce the dynamic behavior we’re so familiar with, and thus create an immersive experience for the player.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The following diagram shows a high level overview of the general procedure of a physics engine:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="A well-functioning physics engine is key in video game physics and programming." src="https://assets.toptal.io/uploads/blog/image/765/toptal-blog-image-1421917038776.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h3 id="vectors" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Vectors</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to understand how physics simulations work, it is crucial to have a basic understanding of vectors and their operations. If you are already familiar with vector math, read on. But if you are not, or you want to brush up, take a minute to review the <a href="https://www.toptal.com/game/video-game-physics-part-i-an-introduction-to-rigid-body-dynamics#appendix" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">appendix</a> at the end of this article.</div>
<h3 id="particle-simulation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Particle Simulation</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A good stepping stone to understanding rigid body simulation is to start with particles. Simulating particles is simpler than simulating rigid bodies, and we can simulate the latter using the same principles, but adding volume and shape to the particles.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A particle is just a point in space that has a position vector, a velocity vector and a mass. According to Newton’s First Law, its velocity will only change when a force is applied on it. When its velocity vector has a non-zero length, its position will change over time.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To simulate a particle system, we need to first create an array of particles with an initial state. Each particle must have a fixed mass, an initial position in space and an initial velocity. Then we have to start the main loop of the simulation where, for each particle, we have to compute the force that is currently acting on it, update its velocity from the acceleration produced by the force, and then update its position based on the velocity we just computed.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The force may come from different sources depending on the kind of simulation. It can be gravity, wind, or magnetism, among others – or it can be a combination of these. It can be a global force, such as constant gravity, or it can be a force between particles, such as attraction or repulsion.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To make the simulation run at a realistic pace, the time step we “simulate” should be the same as the real amount of time that passed since the last simulation step. However, this time step can be scaled up to make the simulation run faster, or scaled down to make it run in slow motion.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Suppose we have one particle with mass <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em></span>, position <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i</span>)</span> and velocity <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i</span>)</span> at an instant of time <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i</span></span>. A force <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i</span>)</span>is applied on that particle at that time. The position and velocity of this particle at a future time <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i + 1</span></span>, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i + 1</span>)</span>and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em>(<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i + 1</span>)</span> respectively, can be computed with:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Semi-implicit Euler" src="https://assets.toptal.io/uploads/blog/image/766/toptal-blog-image-1421917076647.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In technical terms, what we’re doing here is numerically integrating an ordinary differential equation of motion of a particle using the semi-implicit Euler method, which is the method most game physics engines use due to its simplicity and acceptable accuracy for small values of the time span, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">dt</em></span>. The <a href="http://www.cs.cmu.edu/~baraff/sigcourse/notesb.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Differential Equation Basics</a>lecture notes from the amazing <a href="http://www.cs.cmu.edu/~baraff/sigcourse/index.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Physically Based Modeling: Principles and Practice</a> course, by Drs. Andy Witkin and David Baraff, is a nice article to get a deeper look into the numerical methodology of this method.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The following is an example of a particle simulation in the C language.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-c hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#define NUM_PARTICLES 1</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Two dimensional vector.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> x;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> y;
} Vector2;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Two dimensional particle.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
Vector2 position;
Vector2 velocity;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> mass;
} Particle;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Global array of particles.</span>
Particle particles[NUM_PARTICLES];
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Prints all particles' position to the output. We could instead draw them on screen</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// in a more interesting application.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> PrintParticles() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < NUM_PARTICLES; ++i) {
Particle *particle = &particles[i];
<span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">printf</span>(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"particle[%i] (%.2f, %.2f)\n"</span>, i, particle->position.x, particle->position.y);
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Initializes all particles with random positions, zero velocities and 1kg mass.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> InitializeParticles() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < NUM_PARTICLES; ++i) {
particles[i].position = (Vector2){arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">50</span>), arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">50</span>)};
particles[i].velocity = (Vector2){<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>};
particles[i].mass = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>;
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Just applies Earth's gravity force (mass times gravity acceleration 9.81 m/s^2) to each particle.</span>
Vector2 ComputeForce(Particle *particle) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> (Vector2){<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, particle->mass * -<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">9.81</span>};
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> RunSimulation() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> totalSimulationTime = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// The simulation will run for 10 seconds.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> currentTime = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// This accumulates the time that has passed.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> dt = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Each step will take one second.</span>
InitializeParticles();
PrintParticles();
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">while</span> (currentTime < totalSimulationTime) {
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// We're sleeping here to keep things simple. In real applications you'd use some</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// timing API to get the current time in milliseconds and compute dt in the beginning </span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// of every iteration like this:</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// currentTime = GetTime()</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// dt = currentTime - previousTime</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// previousTime = currentTime</span>
sleep(dt);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < NUM_PARTICLES; ++i) {
Particle *particle = &particles[i];
Vector2 force = ComputeForce(particle);
Vector2 acceleration = (Vector2){force.x / particle->mass, force.y / particle->mass};
particle->velocity.x += acceleration.x * dt;
particle->velocity.y += acceleration.y * dt;
particle->position.x += particle->velocity.x * dt;
particle->position.y += particle->velocity.y * dt;
}
PrintParticles();
currentTime += dt;
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you call the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">RunSimulation</code> function (for a single particle) it will print something like:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">particle[0] (-8.00, 57.00)
particle[0] (-8.00, 47.19)
particle[0] (-8.00, 27.57)
particle[0] (-8.00, -1.86)
particle[0] (-8.00, -41.10)
particle[0] (-8.00, -90.15)
particle[0] (-8.00, -149.01)
particle[0] (-8.00, -217.68)
particle[0] (-8.00, -296.16)
particle[0] (-8.00, -384.45)
particle[0] (-8.00, -482.55)
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As you can see, the particle started at the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">(-8, 57)</code> position and then its <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">y</code> coordinate started to drop faster and faster, because it was accelerating downwards under the force of gravity.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The following animation gives a visual representation of a sequence of three steps of a single particle being simulated:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Particle animation" src="https://assets.toptal.io/uploads/blog/image/767/toptal-blog-image-1421917166837.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Initially, at <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em> = 0</span>, the particle is at <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">p</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">0</span></span>. After a step it moves in the direction its velocity vector <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">v</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">0</span></span> was pointing. In the next step a force <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">1</span></span> is applied to it, and the velocity vector starts to change as if it was being pulled in the direction of the force vector. In the next two steps, the force vector changes direction but continues pulling the particle upwards.</div>
<h3 id="rigid-body-simulation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rigid Body Simulation</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A <a href="https://en.wikipedia.org/wiki/Rigid_body" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rigid body</span></a> is a solid that cannot deform. Such solids do not exist in the real world – even the hardest materials deform at least a very small amount when some force is applied to them – but the rigid body is a useful model of physics for game developers that simplifies the study of the dynamics of solids where we can neglect deformations.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A rigid body is like an extension of a particle because it also has mass, position and velocity. Additionally, it has volume and shape, and so it can rotate. That adds more complexity than it sounds, especially in three dimensions.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A rigid body naturally rotates around its <a href="https://en.wikipedia.org/wiki/Center_of_mass" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">center of mass</span></a>, and the position of a rigid body is considered to be the position of its center of mass. We define the initial state of the rigid body with its center of mass at the origin and a rotation angle of zero. Its position and rotation at any instant of time <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">t</em></span> is going to be an offset of the initial state.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Understanding video game physics is essential in creating a game with fewer bugs and more fans." src="https://assets.toptal.io/uploads/blog/image/768/toptal-blog-image-1421917187878.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The center of mass is the mid-point of the mass distribution of a body. If you imagine that a rigid body with mass <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">M</em></span> is made up of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">N</em></span> tiny particles, each with mass <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i</span></span> and location <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: sub;">i</span></span> inside the body, the center of mass can be computed as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Center of mass" src="https://assets.toptal.io/uploads/blog/image/769/toptal-blog-image-1421917210009.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This formula shows that the center of mass is the average of the particle positions weighted by their mass. If the density of the body is uniform throughout, the center of mass is the same as the geometric center of the body shape, also known as the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">centroid</span>. Game physics engines usually only support uniform density, so the geometric center can be used as the center of mass.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rigid bodies are not made up of a finite number of discrete particles though, they’re <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">continuous</em>. For that reason, we should calculate it using an <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">integral</em> instead of a finite sum, like this:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Center of mass integral" src="https://assets.toptal.io/uploads/blog/image/770/toptal-blog-image-1421917221187.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span> is the position vector of each point, and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">𝜌</span> (rho) is a function that gives the density at each point within the body. Essentially, this integral does the same thing as the finite sum, however it does so in a continuous volume <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">V</em></span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since a rigid body can rotate, we have to introduce its <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">angular</span> properties, which are analogous to a particle’s linear properties. In two dimensions, a rigid body can only rotate about the axis that points out of the screen, hence we only need one scalar to represent its orientation. We usually use <a href="https://en.wikipedia.org/wiki/Radian" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">radians</span></a> (which go from 0 to 2<span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">π</span> for a full circle) as a unit here instead of angles (that go from 0 to 360 for a full circle), as this simplifies calculations.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In order to rotate, a rigid body needs some <a href="https://en.wikipedia.org/wiki/Angular_velocity" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">angular velocity</span></a>, which is a scalar with unit <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">radians per second</span>and which is commonly represented by the greek letter <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ω</em></span> (omega). However, to gain angular velocity the body needs to receive some rotational force, which we call <a href="https://en.wikipedia.org/wiki/Torque" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">torque</span></a>, represented by the greek letter <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">τ</em></span> (tau). Thus, Newton’s Second Law applied to rotation is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="2nd law for rotations" src="https://assets.toptal.io/uploads/blog/image/771/toptal-blog-image-1421917241277.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">α</em></span> (alpha) is the angular acceleration and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">I</em></span> is the <a href="https://en.wikipedia.org/wiki/Moment_of_inertia" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">moment of inertia</span></a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For rotations, the moment of inertia is analogous to mass for linear motion. It defines how hard it is to change the angular velocity of a rigid body. In two dimensions it is a scalar and is defined as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Moment of inertia" src="https://assets.toptal.io/uploads/blog/image/772/toptal-blog-image-1421917288466.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">V</em></span> means that this integral should be performed for all points throughout body volume, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span> is the position vector of each point relative to the axis of rotation, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em><span style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: super;">2</span></span> is actually the dot product of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span> with itself, and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">𝜌</span> is a function that gives the density at each point within the body.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For example, the moment of inertia of a 2-dimensional box with mass <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">m</em></span>, width <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">w</em></span> and height <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">h</em></span> about its centroid is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Box moment of inertia" src="https://assets.toptal.io/uploads/blog/image/774/toptal-blog-image-1421917331379.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="https://en.wikipedia.org/wiki/List_of_moments_of_inertia" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Here</a> you can find a list of formulas to compute the moment of inertia for a bunch of shapes about different axes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When a force is applied to a point on a rigid body it, it may produce torque. In two dimensions, the torque is a scalar, and the torque <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">τ</em></span> generated by a force <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em></span> applied at a point on the body which has an offset vector <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span> from the center of mass is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Torque 2D" src="https://assets.toptal.io/uploads/blog/image/773/toptal-blog-image-1421917305538.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">θ</em></span> (theta) is the smallest angle between <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="The diagram may help you understand the content of this video game physics tutorial." src="https://assets.toptal.io/uploads/blog/image/775/toptal-blog-image-1421917393511.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The previous formula is exactly the formula for the length of the cross product between <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em></span>. Thus, in three dimensions we can do this:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Torque" src="https://assets.toptal.io/uploads/blog/image/776/toptal-blog-image-1421917408382.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="A keen understanding of physics for game developers makes the difference between a good and bad user experience in the final product." src="https://assets.toptal.io/uploads/blog/image/777/toptal-blog-image-1421917420294.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A two-dimensional simulation can be seen as a three-dimensional simulation where all rigid bodies are thin and flat, and it all happens on the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">xy</em></span>-plane, meaning there’s no movement in the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">z</em></span>-axis. This means that <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">f</span></em></span> and<span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">r</span></em></span> are always in the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">xy</em></span> plane and so <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">τ</span></em></span> will always have zero <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</em></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">y</em></span> components because the cross product will always be perpendicular to the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">xy</em></span>-plane. This in turn means it will always be parallel to the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">z</em></span>-axis. Thus, only the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">z</em></span> component of the cross product matters. What this leads to is that the calculation of torque in two dimensions can be simplified to:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Torque 2D" src="https://assets.toptal.io/uploads/blog/image/778/toptal-blog-image-1421917434687.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Video game physics can be complicated. Using diagrams and standard physics equations can clarify it." src="https://assets.toptal.io/uploads/blog/image/779/toptal-blog-image-1421917446129.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s incredible how adding only one more dimension to the simulation makes things considerably more complicated. In three dimensions, the orientation of a rigid body has to be represented with a <a href="https://en.wikipedia.org/wiki/Quaternion" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">quaternion</span></a>, which is a kind of four-element vector. The moment of inertia is represented by a 3x3 matrix, called the <a href="https://en.wikipedia.org/wiki/Moment_of_inertia#The_inertia_tensor" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">inertia tensor</span></a>, which is not constant since it depends on the rigid body orientation, and thus varies over time as the body rotates. To learn all the details about 3D rigid body simulation, you can check out the excellent <a href="http://www.cs.cmu.edu/~baraff/sigcourse/notesd1.pdf" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Rigid Body Simulation I — Unconstrained Rigid Body Dynamics</a>, which is also part of Witkin and Baraff’s <a href="http://www.cs.cmu.edu/~baraff/sigcourse/index.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Physically Based Modeling: Principles and Practice</a> course.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The simulation algorithm is very similar to that of particle simulation. We only have to add the shape and rotational properties of the rigid bodies:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-c hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-preprocessor" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">#define NUM_RIGID_BODIES 1</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// 2D box shape. Physics engines usually have a couple different classes of shapes</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// such as circles, spheres (3D), cylinders, capsules, polygons, polyhedrons (3D)...</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> width;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> height;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> mass;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> momentOfInertia;
} BoxShape;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Calculates the inertia of a box shape and stores it in the momentOfInertia variable.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> CalculateBoxInertia(BoxShape *boxShape) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> m = boxShape->mass;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> w = boxShape->width;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> h = boxShape->height;
boxShape->momentOfInertia = m * (w * w + h * h) / <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">12</span>;
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Two dimensional rigid body</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">typedef</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">struct</span> {
Vector2 position;
Vector2 linearVelocity;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> angle;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> angularVelocity;
Vector2 force;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> torque;
BoxShape shape;
} RigidBody;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Global array of rigid bodies.</span>
RigidBody rigidBodies[NUM_RIGID_BODIES];
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Prints the position and angle of each body on the output.</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// We could instead draw them on screen.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> PrintRigidBodies() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < NUM_RIGID_BODIES; ++i) {
RigidBody *rigidBody = &rigidBodies[i];
<span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">printf</span>(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"body[%i] p = (%.2f, %.2f), a = %.2f\n"</span>, i, rigidBody->position.x, rigidBody->position.y, rigidBody->angle);
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Initializes rigid bodies with random positions and angles and zero linear and angular velocities.</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// They're all initialized with a box shape of random dimensions.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> InitializeRigidBodies() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < NUM_RIGID_BODIES; ++i) {
RigidBody *rigidBody = &rigidBodies[i];
rigidBody->position = (Vector2){arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">50</span>), arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">50</span>)};
rigidBody->angle = arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">360</span>)/<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">360.f</span> * M_PI * <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span>;
rigidBody->linearVelocity = (Vector2){<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>};
rigidBody->angularVelocity = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>;
BoxShape shape;
shape.mass = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span>;
shape.width = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span> + arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span>);
shape.height = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span> + arc4random_uniform(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span>);
CalculateBoxInertia(&shape);
rigidBody->shape = shape;
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Applies a force at a point in the body, inducing some torque.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> ComputeForceAndTorque(RigidBody *rigidBody) {
Vector2 f = (Vector2){<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">100</span>};
rigidBody->force = f;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// r is the 'arm vector' that goes from the center of mass to the point of force application</span>
Vector2 r = (Vector2){rigidBody->shape.width / <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span>, rigidBody->shape.height / <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span>};
rigidBody->torque = r.x * f.y - r.y * f.x;
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> RunRigidBodySimulation() {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> totalSimulationTime = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// The simulation will run for 10 seconds.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> currentTime = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// This accumulates the time that has passed.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> dt = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Each step will take one second.</span>
InitializeRigidBodies();
PrintRigidBodies();
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">while</span> (currentTime < totalSimulationTime) {
sleep(dt);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span> (<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < NUM_RIGID_BODIES; ++i) {
RigidBody *rigidBody = &rigidBodies[i];
ComputeForceAndTorque(rigidBody);
Vector2 linearAcceleration = (Vector2){rigidBody->force.x / rigidBody->shape.mass, rigidBody->force.y / rigidBody->shape.mass};
rigidBody->linearVelocity.x += linearAcceleration.x * dt;
rigidBody->linearVelocity.y += linearAcceleration.y * dt;
rigidBody->position.x += rigidBody->linearVelocity.x * dt;
rigidBody->position.y += rigidBody->linearVelocity.y * dt;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> angularAcceleration = rigidBody->torque / rigidBody->shape.momentOfInertia;
rigidBody->angularVelocity += angularAcceleration * dt;
rigidBody->angle += rigidBody->angularVelocity * dt;
}
PrintRigidBodies();
currentTime += dt;
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Calling <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">RunRigidBodySimulation</code> for a single rigid body outputs its position and angle, like this:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">body[0] p = (36.00, 12.00), a = 0.28
body[0] p = (36.00, 22.00), a = 15.28
body[0] p = (36.00, 42.00), a = 45.28
body[0] p = (36.00, 72.00), a = 90.28
body[0] p = (36.00, 112.00), a = 150.28
body[0] p = (36.00, 162.00), a = 225.28
body[0] p = (36.00, 222.00), a = 315.28
body[0] p = (36.00, 292.00), a = 420.28
body[0] p = (36.00, 372.00), a = 540.28
body[0] p = (36.00, 462.00), a = 675.28
body[0] p = (36.00, 562.00), a = 825.28
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since an upward force of 100 Newtons is being applied, only the <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">y</span> coordinate changes. The force is not being applied directly on the center of mass, and thus it induces torque, causing the rotational angle to increase (counter clockwise rotation).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The graphical result is similar to the particles animation but now we have shapes moving and rotating.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Rigid body animation" src="https://assets.toptal.io/uploads/blog/image/780/toptal-blog-image-1421917469884.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is an <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">unconstrained</span> simulation, because the bodies can move freely and they do not interact with each other – they don’t collide. Simulations without collisions are pretty boring and not very useful. In the next installment of this series we’re gonna talk about collision detection, and how to solve a collision once it’s been detected.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="https://www.blogger.com/null" name="appendix" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"></a></div>
<h2 id="appendix-vectors" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Appendix: Vectors</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A <a href="https://en.wikipedia.org/wiki/Euclidean_vector" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">vector</span></a> is an entity that has a <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">length</em> (or, more formally, a <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">magnitude</em>) and a <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">direction</em>. It can be intuitively represented in the <a href="https://en.wikipedia.org/wiki/Cartesian_coordinate_system" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Cartesian coordinate system</span></a>, where we decompose it into two components, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">y</span></span>, in a 2-dimensional space, or three components, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">x</span></span>, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">y</span></span>, and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; font-style: italic; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">z</span></span>, in 3-dimensional space.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Game programming tutorials don’t often include physics diagrams within them, despite the level of clarity they provide for developers." src="https://assets.toptal.io/uploads/blog/image/781/toptal-blog-image-1421917486683.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Understanding video game physics makes a developers job more complex, but the final product much more successful." src="https://assets.toptal.io/uploads/blog/image/782/toptal-blog-image-1421917499528.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We represent a vector with a bold lowercase character, and its components by a regular identical character with the component subscript. For example:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Vec2D" src="https://assets.toptal.io/uploads/blog/image/784/toptal-blog-image-1421917603856.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
represents a 2-dimensional vector. Each component is the distance from the origin in the corresponding coordinate axis.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Physics engines usually have their own light weight, highly-optimized math libraries. The <a href="http://bulletphysics.org/wordpress/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Bullet Physics</a>engine, for instance, has a decoupled math library called <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Linear Math</em> that can be used on its own without any of Bullet’s physics simulation features. It has classes that represents entities such as vectors and matrices, and it leverages <a href="https://en.wikipedia.org/wiki/SIMD" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">SIMD</a> instructions if available.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Some of the fundamental algebraic operations that operate on vectors are reviewed below.</div>
<h4 id="length" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Length</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The length, or magnitude, operator is represented by <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">|| ||</span>. The length of a vector can be computed from its components using the famous <a href="https://en.wikipedia.org/wiki/Pythagorean_theorem" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Pythagorean theorem</span></a> for right triangles. For example, in two dimesions:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Vec2DLength" src="https://assets.toptal.io/uploads/blog/image/783/toptal-blog-image-1421917515237.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/developers/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/developers/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h4 id="negation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Negation</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When a vector is negated, the length remains the same, but the direction changes to the exact opposite. For example, given:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Vec2D" src="https://assets.toptal.io/uploads/blog/image/784/toptal-blog-image-1421917603856.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
the negation is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="negation" src="https://assets.toptal.io/uploads/blog/image/786/toptal-blog-image-1421917671785.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Physics for game development is a simpler way of simulating what would happen to rigid bodies if movement were to happen in the real world." src="https://assets.toptal.io/uploads/blog/image/787/toptal-blog-image-1421917686471.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h4 id="addition-and-subtraction" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Addition and Subtraction</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Vectors can be added to, or subtracted from, one another. Subtracting two vectors is the same as adding one to the negation of the other. In these operations, we simply add or subtract each component:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="AddSubtract" src="https://assets.toptal.io/uploads/blog/image/788/toptal-blog-image-1421917700625.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The resulting vector can be visualized as pointing to the same point that the two original vectors would if they were connected end-to-end:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="This video game physics tutorial provides instruction and diagrams to improve the skills of game developers." src="https://assets.toptal.io/uploads/blog/image/789/toptal-blog-image-1421917713199.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h4 id="scalar-multiplication" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Scalar Multiplication</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When a vector is multiplied by a scalar (for the purposes of this tutorial, a scalar is simply any real number), the vector’s length changes by that amount. If the scalar is negative, it also makes the vector point in the opposite direction.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="ScalarVec2D" src="https://assets.toptal.io/uploads/blog/image/790/toptal-blog-image-1421917726111.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Scalar multiplication" src="https://assets.toptal.io/uploads/blog/image/791/toptal-blog-image-1421917737475.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h4 id="dot-product" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Dot Product</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Dot_product" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">dot product</span></a> operator takes two vectors and outputs a scalar number. It is defined as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="DotProduct" src="https://assets.toptal.io/uploads/blog/image/792/toptal-blog-image-1421917751035.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ø</span> is the angle between the two vectors. Computationally, it is much simpler to compute it using the components of the vectors, i.e.:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="DotProductComponents" src="https://assets.toptal.io/uploads/blog/image/793/toptal-blog-image-1421917764080.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The value of the dot product is equivalent to the length of the <a href="https://en.wikipedia.org/wiki/Vector_projection" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">projection</span></a> of the vector <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> onto the vector <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span>, multiplied by the length of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span>. This action can also be flipped, taking the length of the projection of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span> onto <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span>, and multiplying by the length of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span>, producing the same result. This means that the dot product is <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">commutative</em>– the dot product of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</em></span></span> with <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</em></span></span> is the same as the dot product of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</em></span></span> with <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</em></span></span>. One useful property of the dot product is that its value is zero if the vectors are orthogonal (the angle between them is 90 degrees), because <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">cos 90 = 0</span>.</div>
<h4 id="cross-product" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Cross Product</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In three dimensions, we can also multiply two vectors to output another vector using the <a href="https://en.wikipedia.org/wiki/Cross_product" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">cross product</span></a>operator. It is defined as:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CrossProduct" src="https://assets.toptal.io/uploads/blog/image/794/toptal-blog-image-1421917781113.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
and the length of the cross product is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CrossLength" src="https://assets.toptal.io/uploads/blog/image/795/toptal-blog-image-1421917794011.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
where <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ø</span> is the smallest angle between <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span>. The result is a vector <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">c</span></em></span> that is orthogonal (perpendicular) to both <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span>. If <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> and <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span> are parallel, that is, the angle between them is zero or 180 degrees, <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">c</span></em></span> is going to be the zero vector, because <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sin 0 = sin 180 = 0</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unlike the dot product, the cross product is not commutative. The order of the elements in the cross product is important, because:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="CrossCommute" src="https://assets.toptal.io/uploads/blog/image/796/toptal-blog-image-1421917817019.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The direction of the result can be determined by the <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">right hand rule</em>. Open your right hand and point your index finger in the same direction of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> and orient your hand in a way that when making a fist your fingers move straight towards <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span> through the smallest angle between these vectors. Now your thumb is pointing in the direction of <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span></em></span> × <span style="border: 0px; box-sizing: border-box; font-family: "timesnewroman"; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">b</span></em></span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="https://assets.toptal.io/uploads/blog/image/797/toptal-blog-image-1421917884658.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="The right hand rule applies to video game physics as well as traditional physics." border="0" src="https://assets.toptal.io/uploads/blog/image/797/toptal-blog-image-1421917884658.jpg" style="border: 0px; box-sizing: border-box; display: block; margin-top: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 640px;" /></a></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <a class="link is-blue" href="https://www.toptal.com/resume/nilson-souto" style="border: 0px; box-sizing: border-box; color: #103d77; display: inline; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: 600; letter-spacing: 0.13px; line-height: 19px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; text-transform: uppercase; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;" target="_blank">NILSON SOUTO</a>, <span style="font-size: 19.2px; line-height: 28.8px;">a <a href="https://www.toptal.com/game/video-game-physics-part-i-an-introduction-to-rigid-body-dynamics">Toptal</a><a href="https://www.toptal.com/ios"> iOS developer</a>.</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-77479695804234228012016-06-14T02:58:00.001-07:002016-06-14T02:58:32.934-07:00Introducing Battlescripts: Bots, Ships, Mayhem!<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Programming doesn’t need to be all about building applications, meeting goals, and satisfying project specifications. It can also be about having fun, about enjoying the process of <a href="https://www.toptal.com/web/making-html5-canvas-based-game-with-angularjs-and-createjs" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">creating something</a>. Many people do treat programming and development of this skill as a form of recreation. At Toptal, we wanted to try out something interesting within our community. We decided to build <a href="http://battlescripts.toptal.net/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">a bot-vs-bot game platform around Battleship</a>, that is now <a href="https://github.com/hjr265/battlescripts" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">open-source</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a class="button is-green_candy is-default is-full_width" href="http://battlescripts.toptal.net/" rel="noopener noreferrer" style="-webkit-appearance: none; background: linear-gradient(rgb(67, 198, 146), rgb(57, 184, 133)); border-radius: 4px; border: 1px solid rgb(31, 124, 87); box-shadow: rgb(79, 211, 170) 0px 1px inset; box-sizing: border-box; color: white; cursor: pointer; display: inline-block; font-size: 14px; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 15px 20px; position: relative; text-align: center; text-decoration: none; text-shadow: rgb(28, 143, 61) 0px 1px 0px; transition: background 150ms; vertical-align: baseline; width: 864px;" target="_blank">Play Game Now!</a></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Introducing Battlescripts: Bots, Ships, Mayhem!" src="https://assets.toptal.io/uploads/blog/image/91309/toptal-blog-image-1435062036872-f28accb9aca647f7f823c50b9f9b854c.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since its initial launch internally, the platform has grabbed the attention of some amazing bot makers within our community. We were really impressed to see that one of the community members, <a href="https://www.toptal.com/resume/le-anh-quan" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Toptal engineer Quân Lê</a>, even built a <a href="http://quanla.github.io/battleship-tester/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">tool to debug Battlescripts Bots easily</a>. The announcement also sparked an interest among a few to create their own bot-vs-bot engines, supporting different games types and different rules. Amazing ideas started to stream in from the moment Battlescripts was unveiled. Today, we are happy to make Battlescripts open-source. This gives our community and everyone else an opportunity to explore the code, make contributions, and/or fork it to make something else entirely of it.</div>
<h2 id="anatomy-of-battlescripts" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Anatomy of Battlescripts</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Battlescripts is built using some very simple components. It runs on Node.js and uses some of the most popular and well implemented packages, such as <a href="http://expressjs.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Express</a>, <a href="http://mongoosejs.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Mongoose</a>, etc. The back-end is in pure JavaScript, as well as the front-end scripts. The only two external dependencies of this application are<a href="https://www.mongodb.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">MongoDB</a> and <a href="http://redis.io/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Redis</a>. User submitted code for bots are run using the <a href="https://nodejs.org/api/vm.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">“vm” module</a> that comes with Node.js. In production, <a href="http://docker.io/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Docker</a> is used for added safety, but is not a hard dependency of Battlescripts.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="battlescripts" src="https://assets.toptal.io/uploads/blog/image/91310/toptal-blog-image-1435062049131-71818290fcb1997a105ac1a8bf627992.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The code for Battlescripts is <a href="https://github.com/hjr265/battlescripts" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">available on GitHub</a> under the BSD 3-clause license. The included <a href="https://github.com/hjr265/battlescripts/blob/master/README.md" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">README.md</a>file has detailed instructions on how to clone the repository and launch the application locally.</div>
<h3 id="web-server" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Web Server</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
You will notice that the application has a structure similar to that of simple Express.js web applications. The app.js file bootstraps the server by establishing a connection to the database, registering some common middlewares, and defining some social authentication strategies. Furthermore, all the models and routes are defined within the “lib/” directory. The entirely application requires only a few models: Battle, Bot, Challenge, Contest, Party, and User. Battles between bots are simulated outside of the web server nodes, and is done using Node.js package Kue. This enables us to isolate the engine from the rest of the web application, making it less likely for the battle simulation engine to interfere with the web servers, keeping the web application itself more responsive and stable.</div>
<h2 id="bots--engine" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Bots & Engine</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since the bots are expected to be implemented in JavaScript, and that is exactly what we have on our back-end with Node.js, it was easier to build the engine. When it comes to executing user submitted code, one of the biggest challenges is to make sure that the code doesn’t do something malicious on the server, or that any code that is buggy doesn’t interfere with the stability of the overall system. Node.js’s standard library comes with this amazing module that makes part of the this task a very easy. The “vm” module was introduced in order to make it easier for <a href="https://www.toptal.com/nodejs" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Node.js developers</a> to run untrusted code in a separate context. Although according to the official documentation, it is important to run untrusted code in a separate process - but that is something we do on the production servers. During local development, the “vm” module and the features that it offers work alright.</div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 864px;">
Make bots fight each other, while it's still legal!</div>
<div class="tweet_this" style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: -10px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; vertical-align: baseline;">
<iframe allowtransparency="true" class="twitter-share-button twitter-share-button-rendered twitter-tweet-button" data-url="https://www.toptal.com/nodejs/introducing-battlescripts-bots-ships-mayhem" frameborder="0" id="twitter-widget-0" scrolling="no" src="https://platform.twitter.com/widgets/tweet_button.6e778523ecf0a9c9f1c446083d86ede1.en.html#dnt=false&id=twitter-widget-0&lang=en&original_referer=https%3A%2F%2Fwww.toptal.com%2Fnodejs%2Fintroducing-battlescripts-bots-ships-mayhem&size=m&text=Make%20bots%20fight%20each%20other%2C%20while%20it%27s%20still%20legal!&time=1465898128278&type=share&url=https%3A%2F%2Fwww.toptal.com%2Fnodejs%2Fintroducing-battlescripts-bots-ships-mayhem&via=toptalllc" style="border-style: initial; border-width: 0px; box-sizing: border-box; height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: static; vertical-align: baseline; visibility: visible; width: 60px;" title="Twitter Tweet Button"></iframe></div>
<h4 id="executing-javascript" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Executing JavaScript</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you want to run some arbitrary JavaScript code in Node.js under a separate context, you can use the “vm” module as follows:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> vm = <span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">require</span>(‘vm’)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> ctxObj = {
result: ‘’
}
vm.runInNewContext(‘ result = “<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0xBEEF</span>” ’, ctxObj )
console.log(ctxObj); <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// { result: “0xBEEF” }</span>
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Within this “new context”, the code that you run do not even get access to “console.log”, because in that context such a function does not exist. You could, however, expose the “context.log” function of the original context into the new context by passing it as an attribute of “ctxObj”.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In Battlescripts, nodes that simulate battles run each bot under separate Node.js “vm” contexts. The engine takes on the responsibility of syncing the state of the contexts for both bots according to rules of the game.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91311/toptal-blog-image-1435062066713-af75a70324ebb5b2cdc6362d32610b5d.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Running JavaScript code in isolated context is not all that this module does. The “runInNewContext” function accepts an object as the third parameter which can control three additional aspects of this code execution:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Filename to be used in generated stack traces relevant to this execution.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Whether or not to print errors to stderr.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Number of milliseconds to allow the execution to continue before timing it out.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One of the pitfalls of this “vm” module is that it doesn’t provide any means of limiting memory usage. This, along with a few other limitations of the module is worked-around on the server through the use of Docker, and the way the engine nodes are run. The “vm” module, when used very frequently slowly starts to leak memory that is hard to track down and free. Even if the context objects are reused, the memory usage keeps growing. We solved this problem by following a simple strategy. Every time a battle is simulated in a worker node, the node exits. The supervisor program on the production server then restarts the worker node which then becomes ready to handle the next battle simulation in a fraction of a second.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><br /><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://draft.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://draft.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://draft.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h4 id="extensibility" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Extensibility</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Battlescripts was originally designed around the standard rules of Battleship. The engine within was not very extensible. However, after Battlescripts was launched, one of the most common requests was to introduce newer game types, as users of the application quickly realized that some games are easier to conquer with bots than others. For example, if you compare TicTacToe with Chess, the former has a much smaller state space, making it very easy for bots to come up with a solution that will either win or end a game in draw.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Battlescripts engine has been recently modified a little to make it easier to introduce newer game types. This can be done by simply following a construct with a handful of hook-like functions. An additional game type, TicTacToe, was added to the codebase since it is easier to follow. Everything relevant to this game type can be found inside the “lib/games/tictactoe.js” file.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, in this article, we will take a look at the implementation of Battleship game type. Exploration of TicTacToe game code can be left as an exercise for later.</div>
<h4 id="battleship" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Battleship</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before taking a look at how the game is implemented, let us take a peek at what a standard bot for Battlescript looks like:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Bot</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>}
Bot.prototype.play = <span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(turn)</span> {</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
That is pretty much it. Every bot is defined as a constructor function with one method “play”. The method is invoked for every turn with one argument. For any game, the argument is an object with one method that allows the bot to make its move for the turn, and can come with some additional attributes representing the game state.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As mentioned earlier, the engine has been modified a little recently. All Battleship specific logic has been pulled out of the actual engine code. As the engine still does the heavy lifting, the code that defines the Battleship game is very simple, and lightweight.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Battleships</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(bot1, bot2)</span> {</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span> Engine(bot1, bot2, {
hooks: {
init: <span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
},
play: <span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
},
turn: <span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// ...</span>
}
}
})
}
module.exports = exports = Battleships
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Notice how we are merely defining three hook-like functions here: init, play, and turn. Each function is invoked with the engine as its context. The “init” function right as the engine object is instantiated, from within the constructor function. Typically this is where you should prepare all the state attributes of the engine. One such attribute that must be prepared for every game is “grids” and (optionally) “pieces”. This should always be an array with two elements, one for each player, representing the state of the game board.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.bots.length; ++i) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> grid = []
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> y = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; y < consts.gridSize.height; ++y) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> row = []
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> x = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; x < consts.gridSize.width; ++x) {
row.push({
attacked: <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>
})
}
grid.push(row)
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.grids.push(grid)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.pieces.push([])
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The second hook, “play”, is invoked right before the game begins. This is useful, as this gives us the opportunity to do things like place game pieces on the board on behalf of the bots.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> botNo = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; botNo < <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.bots.length; ++botNo) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < consts.pieces.length; ++i) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> piece = consts.pieces[i]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> j = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; j < piece.many; ++j) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> pieceNo = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.pieces[botNo].length
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> squares = []
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> y = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; y < consts.gridSize.height; ++y) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> x = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; x < consts.gridSize.width; ++x) {
squares.push({
x: x,
y: y,
direction: <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'h'</span>
})
squares.push({
x: x,
y: y,
direction: <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'v'</span>
})
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> square = _.sample(squares.filter(<span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(square)</span> {</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> f = {
<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'h'</span>: [<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>],
<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'v'</span>: [<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>]
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> xn = square.x, yn = square.y, i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; i < piece.size; xn += f[square.direction][<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>], yn += f[square.direction][<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>], ++i) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> d = [[<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, -<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>], [<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>], [-<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>], [<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>], [-<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, -<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>], [-<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>], [<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, -<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>], [<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>, <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>]]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> j = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>; j < d.length; ++j) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> xp = xn+d[j][<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> yp = yn+d[j][<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(xp >= <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span> && xp < <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span> && yp >= <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span> && yp < <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span> && <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.grids[botNo][yp][xp].pieceNo >= <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(xn >= consts.gridSize.width || yn >= consts.gridSize.height || <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.grids[botNo][yn][xn].pieceNo >= <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>
}
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>;
}.bind(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>)))
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">switch</span>(<span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> square.direction === <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'h'</span>:
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> k = square.x; k < square.x+piece.size; ++k) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.grids[botNo][square.y][k].pieceNo = pieceNo
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> square.direction === <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'v'</span>:
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">for</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> k = square.y; k < square.y+piece.size; ++k) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.grids[botNo][k][square.x].pieceNo = pieceNo
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>.pieces[botNo].push({
kind: piece.kind,
size: piece.size,
x: square.x,
y: square.y,
direction: square.direction,
hits: <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>,
dead: <span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>
})
}
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This may look a bit overwhelming at first, but the goal that this piece of code achieves is simple. It generates arrays of pieces, one for each bot, and places them on the corresponding grids in a uniform fashion. For every piece, the grid is scanned and every valid position is stored in a temporary array. A valid position is where two pieces do not overlap or share adjacent cells.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Finally, the third and the last hook “turn”. Unlike the other two hooks, this one is a little different. The purpose of this hook is to return an object, which the engine uses as the first argument in invoking the bot’s play method.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">return {
attack: _.once(function(x, y) {
this.turn.called = true
var botNo = this.turn.botNo
var otherNo = (botNo+1)%2
var baam = false
var square = this.grids[otherNo][y][x]
square.attacked = true
if(square.pieceNo >= 0) {
baam = true
this.turn.nextNo = botNo
var pieceNo = square.pieceNo
var pieces = this.pieces[otherNo]
var piece = pieces[pieceNo]
piece.hits += 1
if(piece.hits === piece.size) {
piece.dead = true
baam = {
no: pieceNo,
kind: piece.kind,
size: piece.size,
x: piece.x,
y: piece.y,
direction: piece.direction
}
}
var undead = false
for(var i = 0; i < pieces.length; ++i) {
if(!pieces[i].dead) {
undead = true
}
}
if(!undead) {
this.end(botNo)
}
}
this.track(botNo, true, {
x: x,
y: y,
baam: !!baam
})
return baam
}.bind(this))
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Within this method, we begin by informing the engine that the bot has successfully made a move. A bot that fails to make an attacking move for any game in any turn automatically forfeits the game. Next, in case the move has successfully hit the ship, we determine if the ship has been destroyed completely. In case it was, we return details of the ship that was destroyed, otherwise we return “true” to indicate a successful hit without any additional information.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Throughout these codes, we have encountered some attributes and method names that are available at “this”. These are provided by the Engine object and each have some simple behavioral characteristics:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
this.turn.called: This begins as false before every turn, and must be set to true to inform the engine that the bot has acted for the turn.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
this.turn.botNo: This will either be 0 or 1, depending on which bot has played this turn.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
this.end(botNo): Calling this with a bot number ends the game, and marks the bot as victorious. Calling it with -1 ends the game in a draw.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
this.track(botNo, isOkay, data, failReason): This is a convenience method that lets you record the move details for the bot, or reason for a failed move. Eventually, these recorded data are used to visualize the simulation on the front-end.</div>
</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Essentially, this is all that needs to be done on the back-end to implement a game on this platform.</div>
<h4 id="replaying-games" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Replaying Games</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As soon as a battle simulation ends, the front-end redirects itself to the game replay page. This is where the simulation and results are visualized, and other game related data is displayed.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91312/toptal-blog-image-1435062134465.1-db0d729de1949c964ce49b4ee64d5407.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This view is rendered by the back-end using the “battle-view-battleships.jade” in “views/” with all battle details in context. Re-play animation of the game is done through front-end JavaScript. All the data recorded through the “trace()” method of the engine is available in the context of this template.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-js hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">play</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-play'</span>).hide()
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-stop'</span>).show()
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(i === moves.length) {
i = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>
stop()
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.ul-moves h4'</span>).fadeIn()
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span>
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(i === <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>) {
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.ul-moves h4'</span>).hide()
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'table td'</span>).removeClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'warning danger'</span>)
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.count span'</span>).text(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>)
}
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.ul-moves li'</span>).slice(<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>, $(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.ul-moves li'</span>).length-i).hide()
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.ul-moves li'</span>).slice($(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.ul-moves li'</span>).length-i-<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>).show()
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> move = moves[i]
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> $td = $(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'table'</span>).eq((move.botNo+<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>)%<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span>).find(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'tr'</span>).eq(move.data.y+<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>).find(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'td'</span>).eq(move.data.x+<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(<span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">parseInt</span>($td.text()) >= <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>) {
$td.addClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'danger'</span>)
} <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">else</span> {
$td.addClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'warning'</span>)
}
++i
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.count span'</span>).eq(move.botNo).text(<span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">parseInt</span>($(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.count span'</span>).eq(move.botNo).text())+<span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span>)
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span> delay = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">switch</span>(<span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>) {
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> $(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-fast'</span>).hasClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'active'</span>):
delay = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> $(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-slow'</span>).hasClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'active'</span>):
delay = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">100</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> $(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-slower'</span>).hasClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'active'</span>):
delay = <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">500</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> $(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-step'</span>).hasClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'active'</span>):
stop()
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span>
}
playTimer = setTimeout(<span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
play()
}, delay)
}
<span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">stop</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-stop'</span>).hide()
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-play'</span>).text(i === <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span> ? <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Re-play'</span> : ($(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-step'</span>).hasClass(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'active'</span>) ? <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Next'</span> : <span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Resume'</span>)).show()
clearTimeout(playTimer)
}
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-play'</span>).click(<span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
play()
})
$(<span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'.btn-stop'</span>).click(<span class="hljs-function" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span>
stop()
})
</code></pre>
<h2 id="what-next" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: "Proxima Nova", Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What Next?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now that Battlescripts is open source, contributions are welcome. The platform at its current stage is mature, but has a lot of room for improvements. Be it a new feature, a security patch, or even bug fixes, feel free create an issue in the repository requesting it to be addressed, or fork the repository and submit a pull request. And if this inspires you to build something entirely new, be sure to let us know and leave a link to it in the comments section below!</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: "Proxima Nova", Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by Mahmud Ridwan, a <a href="https://www.toptal.com/nodejs/introducing-battlescripts-bots-ships-mayhem">Toptal</a><a href="https://www.toptal.com/python"> Python developer</a>.</div>
Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-4258209981737157440.post-10685341950707045392016-06-08T05:42:00.000-07:002016-06-08T05:42:00.167-07:00Unity with MVC: How to Level Up Your Game Development<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First time programmers usually start learning the trade with the classic <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Hello World</code> program. From there, bigger and bigger assignments are bound to follow. Each new challenge drives home an important lesson:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The bigger the project, the bigger the spaghetti.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IMAGE: SPAGHETTI CODE" src="https://assets.toptal.io/uploads/blog/image/91480/toptal-blog-image-1438268040078-fe38ebf823bdc7c5b70ac85e46a91f4e.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Soon, it is easy to see that in large or small teams, one cannot recklessly do as one pleases. Code must be maintained and may last for a long time. Companies you’ve worked for can’t just look up your contact information and ask you every time they want to fix or improve the codebase (and you don’t want them to either).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is why <a href="https://www.toptal.com/agile/ultimate-introduction-to-agile-project-management" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">software design patterns</a> exist; they impose simple rules to dictate the overall structure of a software project. They help one or more programmers separate core pieces of a large project and organize them in a standardized way, eliminating confusion when some unfamiliar part of the codebase is encountered.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IMAGE: BAD PROGRAMMER GANDALF" src="https://assets.toptal.io/uploads/blog/image/91492/toptal-blog-image-1438269765600-d44c13af1df68d9b8a98110068348234.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
These rules, when followed by everyone, allow legacy code to be better maintained and navigated, and new code to be added more swiftly. Less time is spent planning the methodology of development. Since problems don’t come in one flavor, there isn’t a silver bullet design pattern. One must carefully consider the strong and weak points of each pattern, and find the best fit for the challenge at hand.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this tutorial I’ll relate my experience with the popular <a href="http://unity3d.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Unity game development platform</a> and the Model-View-Controller (MVC) pattern for game development. In my seven years of development, having wrestled with my fair share of game dev spaghetti, I’ve been achieving great code structure and development speed using this design pattern.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I’ll start by explaining a bit of Unity’s base architecture, the Entity-Component pattern. Then I’ll move on to explain how MVC fits on top of it, and use a little mock project as example.</div>
<h2 id="motivation" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Motivation</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the literature of software we will find a great number of design patterns. Even though they have a set of rules, developers will usually do a little rule-bending in order to better adapt the pattern to their specific problem.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This “freedom of programming” is proof that we haven’t yet found a single, definitive method for designing software. Thus, this article isn’t meant to be the ultimate solution for your problem, but rather, to show the benefits and possibilities of two well known patterns: Entity-Component and Model-View-Controller.</div>
<h2 id="the-entity-component-pattern" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Entity-Component Pattern</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Entity-Component (EC) is a design pattern where we first define the hierarchy of elements that make up the application (Entities), and later, we define the features and data each will contain (Components). In more “programmer” terms, an Entity can be an object with an array of 0 or more Components. Let’s depict an Entity like this:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">some-entity [component0, component1, ...]
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Here’s a simple example of an EC tree.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">- app [Application]
- game [Game]
- player [KeyboardInput, Renderer]
- enemies
- spider [SpiderAI, Renderer]
- ogre [OgreAI, Renderer]
- ui [UI]
- hud [HUD, MouseInput, Renderer]
- pause-menu [PauseMenu, MouseInput, Renderer]
- victory-modal [VictoryModal, MouseInput, Renderer]
- defeat-modal [DefeatModal, MouseInput, Renderer]
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
EC is a good pattern for alleviating the problems of multiple inheritance, where a complex class structure can introduce problems like the <a href="https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">diamond problem</a> where a class D, inheriting two classes, B and C, with the same base class A, can introduce conflicts because how B and C modify A’s features differently.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IMAGE: DIAMOND PROBLEM" src="https://assets.toptal.io/uploads/blog/image/91482/toptal-blog-image-1438268683860-d3025ae9dd53822d1a460760d8f07623.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
These kinds of problems can be common in game development where inheritance is often used extensively.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
By breaking down the features and data handlers into smaller Components, they can be attached and reused in different Entities without relying on multiple inheritance (which, by the way, isn’t even a feature of C# or Javascript, the main languages used by Unity).</div>
<h4 id="where-entity-component-falls-short" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Where Entity-Component Falls Short</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Being one level above OOP, EC helps to defragment and better organize your code architecture. However, in large projects we are still “too free” and we can find ourselves in a “feature ocean”, having a hard time finding the right Entities and Components, or figuring out how they should interact. There are infinite ways to assemble Entities and Components for a given task.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IMAGE: EC FEATURE OCEAN" src="https://assets.toptal.io/uploads/blog/image/91483/toptal-blog-image-1438268717006-70650d968fc4debe6232c0626e9ed890.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
One way to avoid a mess is to impose some additional guidelines on top of Entity-Component. For example, one way I like to think about software is to divide it up into three different categories:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Some handle the raw data, allowing it to be created, read, updated, deleted or searched (i.e., the <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">CRUD</a>concept).</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Others implement the interface for other elements to interact with, detecting events related to their scope and triggering notifications when they occur.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Finally, some elements are responsible for receiving these notifications, making business logic decisions, and deciding how the data should be manipulated.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Fortunately, we already have a pattern that behaves in this exact way.</div>
<h2 id="the-model-view-controller-mvc-pattern" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Model-View-Controller (MVC) Pattern</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Model-View-Controller pattern</a> (MVC) splits the software into three major components: Models (Data CRUD), Views (Interface/Detection) and Controllers (Decision/Action). MVC is flexible enough to be implemented even on top of ECS or OOP.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Game and UI development have the usual workflow of waiting for a user’s input, or other triggering condition, sending notification of those events somewhere appropriate, deciding what to do in response, and updating the data accordingly. These actions clearly show the compatibility of these applications with MVC.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This methodology introduces another abstraction layer that will help with the software planning, and also allow new programmers to navigate even in a bigger codebase. By splitting the thinking process into data, interface, and decisions, developers can reduce the number of source files that must be searched in order to add or fix functionality.</div>
<h2 id="unity-and-ec" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unity and EC</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s first take a closer look at what Unity gives us up front.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unity is an EC-based development platform, where all Entities are instances of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GameObject</code> and the features that makes them be “visible,” “moveable,” “interactable,” and so on, are provided by classes extending <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Component</code>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Unity editor’s <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Hierarchy Panel</span> and <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Inspector Panel</span> provide a powerful way to assemble your application, attach Components, configure their initial state and bootstrap your game with a lot less source code than it would normally.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SCREENSHOT: HIERARCHY PANEL" src="https://assets.toptal.io/uploads/blog/image/91484/toptal-blog-image-1438268864417.2-add1572af1b50ac961e0369119f3b2ca.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="border: 0px; box-sizing: border-box; display: block; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Hierarchy Panel with four GameObjects on the right</em></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SCREENSHOT: INSPECTOR PANEL" src="https://assets.toptal.io/uploads/blog/image/91485/toptal-blog-image-1438268935606-f2f272daf9d4b36ad2f007e3cb0f24b7.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="border: 0px; box-sizing: border-box; display: block; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Inspector Panel with a GameObject’s components</em></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Still, as we’ve discussed, we can hit the “too many features” problem and find ourselves in a gigantic hierarchy, with features scattered everywhere, making the life of a developer a lot harder.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Thinking in the MVC way, we can, instead, start by dividing things according to their function, structuring our application like the example below:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SCREENSHOT: UNITY MVC EXAMPLE STRUCTURE" src="https://assets.toptal.io/uploads/blog/image/91486/toptal-blog-image-1438268968391.2-56f489174107c172be051385f7d274e8.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h4 id="adapting-mvc-to-a-game-development-environment" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Adapting MVC to a Game Development Environment</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now, I would like to introduce two small modifications to the generic MVC pattern, which help adapt it to unique situations I’ve come across building Unity projects with MVC:</div>
<ol style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">The MVC class references easily get scattered throughout the code.<ul style="border: 0px; box-sizing: border-box; font-size: 1em; list-style: none; margin: 1em 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Within Unity, developers typically must drag and drop instances around to make them accessible, or else reach them through cumbersome find statements like <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GetComponent( ... )</code>.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Lost-reference hell will ensue if Unity crashes or some bug makes all the dragged references disappear.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0px 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">This makes it necessary to have a single root reference object, through which all instances in the<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Application</span> can be reached and recovered.</li>
</ul>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Some elements encapsulate general functionality that should be highly reusable, and which does not naturally fall into one of the three main categories of Model, View, or Controller. These I like to call simply<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Components</span>. They are also “Components” in the Entity-Component sense, but merely act as helpers in the MVC framework.<ul style="border: 0px; box-sizing: border-box; font-size: 1em; list-style: none; margin: 1em 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0px 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">For example, a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Rotator</code> Component, which only rotates things by a given angular velocity and doesn’t notify, store, or decide anything.</li>
</ul>
</li>
</ol>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To help alleviate these two issues, I came up with a modified pattern I call <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">AMVCC</span>, or Application-Model-View-Controller-Component.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IMAGE: AMVCC DIAGRAM" src="https://assets.toptal.io/uploads/blog/image/91487/toptal-blog-image-1438268986192-dc455bb88c34cd8c689ae9edb33f5eba.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Application</span> - Single entry point to your application and container of all critical instances and application-related data.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">MVC</span> - You should know this by now. :)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Component</span> - Small, well-contained script that can be reused.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
These two modifications have satisfied my needs for all projects I’ve used them in.</div>
<h2 id="example-10-bounces" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Example: <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10 Bounces</em></h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As a simple example, let’s look at a small game called <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10 Bounces</em>, where I’ll make use of the core elements of the AMVCC pattern.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The game setup is simple: A <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Ball</code> with a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">SphereCollider</code> and a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Rigidbody</code> (which will start to fall after “Play”), a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Cube</code> as ground and 5 scripts to make up the AMVCC.</div>
<h4 id="hierarchy" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Hierarchy</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before scripting, I usually start at the hierarchy and create an outline of my class and assets. Always following this new AMVCC style.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SCREENSHOT: BUILDING THE HIERARCHY" src="https://assets.toptal.io/uploads/blog/image/91488/toptal-blog-image-1438269027508.2_10.42.25_AM-adaef24b99d08995ac47299b6960bde1.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As we can see, the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">view</code> GameObject contains all visual elements and also ones with other <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">View</code> scripts. The<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">model</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">controller</code> GameObjects, for small projects, usually contain only their respective scripts. For bigger projects, they will contain GameObjects with more specific scripts.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When someone navigating your project wants to access:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Data:</span> Go to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">application > model > ...</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Logic/Workflow:</span> Go to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">application > controller > ...</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Rendering/Interface/Detection:</span> Go to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">application > view > ...</code></li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If all teams follow these simple rules, legacy projects shouldn’t become a problem.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Note that there is no <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Component</code> container because, as we’ve discussed, they are more flexible and can be attached to different elements at the developer’s leisure.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h4 id="scripting" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Scripting</h4>
<blockquote style="background-color: white; border-left-color: rgb(240, 240, 240); border-left-style: solid; border-width: 0px 0px 0px 10px; box-sizing: border-box; color: #505050; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px 0px 0px 15px; quotes: none; vertical-align: baseline;">
<div style="border: 0px; box-sizing: border-box; font-size: 1.2em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Note:</span> The scripts shown below are abstract versions of real-world implementations. A detailed implementation wouldn’t benefit the reader much. However, if you would like to explore more, <a href="https://bitbucket.org/eduardo_costa/thelab-unity-mvc/overview" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here’s the link</a> to my personal MVC framework for Unity, <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Unity MVC</em>. You will find core classes that implement the AMVCC structural framework needed for most applications.</div>
</blockquote>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s take a look at the structure of the scripts for <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10 Bounces</em>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before starting, for those not familiar with Unity’s workflow, let’s clarify briefly how scripts and GameObjects work together. In Unity, “Components,” in the Entity-Component sense, are represented by the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MonoBehaviour</code>class. For one to exist during runtime, the developer should either drag and drop its source file into a GameObject (which is the “Entity” of the Entity-Component pattern) or use the command <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">AddComponent<YourMonobehaviour>()</code>. After this, the script will be instantiated and ready to use during execution.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To begin, we define the Application class (the “A” in AMVCC), which will be the main class containing references to all instantiated game elements. We’ll also create a helper base class called <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Element</code>, which gives us access to the instance of the Application and its children’s MVC instances.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With this in mind, let’s define the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Application</code> class (the “A” in AMVCC), which will have a unique instance. Inside it, three variables, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">model</code>, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">view</code>, and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">controller</code>, will give us access points for all MVC instances during runtime. These variables should be <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MonoBehaviour</code>s with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">public</code> references to the desired scripts.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Then, we’ll also create a helper base class called <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Element</code>, which gives us access to the instance of the Application. This access will allow every MVC class to reach every other.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Note that both classes extend <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">MonoBehaviour</code>. They are “Components” that will be attached to GameObject “Entities”.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceApplication.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Base class for all elements in this application.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BounceElement : MonoBehaviour
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Gives access to the application and all instances.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> BounceApplication app { <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">get</span> { <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span> GameObject.FindObjectOfType<BounceApplication>(); }}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// 10 Bounces Entry Point.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BounceApplication : MonoBehaviour
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Reference to the root instances of the MVC.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> BounceModel model;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> BounceView view;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> BounceController controller;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Init things here</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> Start() { }
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
From <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceElement</code> we can create the MVC core classes. The <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceModel</code>, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceView</code>, and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceController</code> scripts usually act as containers for more specialized instances, but since this is a simple example only the View will have a nested structure. The Model and Controller can be done in one script for each:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceModel.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Contains all data related to the app.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BounceModel : BounceElement
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Data</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> bounces;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> winCondition;
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceView .cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Contains all views related to the app.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BounceView : BounceElement
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Reference to the ball</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> BallView ball;
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BallView.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Describes the Ball view and its features.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BallView : BounceElement
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Only this is necessary. Physics is doing the rest of work.</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Callback called upon collision.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnCollisionEnter() { app.controller.OnBallGroundHit(); }
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceController.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Controls the app workflow.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BounceController : BounceElement
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Handles the ball hit event</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">OnBallGroundHit</span>()
{
app.model.bounces++;
Debug.Log(“Bounce ”+app.model.bounce);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(app.model.bounces >= app.model.winCondition)
{
app.view.ball.enabled = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
app.view.ball.GetComponent<RigidBody>().isKinematic=<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// stops the ball</span>
OnGameComplete();
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Handles the win condition</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">OnGameComplete</span>() { Debug.Log(“Victory!!”); }
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With all scripts created, we can proceed to attaching and configuring them.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The hierarchy layout should be like this:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;">- application [BounceApplication]
- model [BounceModel]
- controller [BounceController]
- view [BounceView]
- ...
- ball [BallView]
- ...
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Using the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceModel</code> as an example, we can see how it looks in Unity’s editor:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SCREENSHOT: BounceModel IN INSPECTOR" src="https://assets.toptal.io/uploads/blog/image/91491/toptal-blog-image-1438269533580.2-56f489174107c172be051385f7d274e8.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="border: 0px; box-sizing: border-box; display: block; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceModel</code> with the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">bounces</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">winCondition</code> fields.</em></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With all scripts set and the game running, we should get this output in the <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Console Panel</span>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="SCREENSHOT: CONSOLE OUTPUT" src="https://assets.toptal.io/uploads/blog/image/91489/toptal-blog-image-1438269069944-03037d0a37cd8efd0e105123411ff0ce.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<h4 id="notifications" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Notifications</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As shown in the example above, when the ball hits the ground its view executes <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app.controller.OnBallGroundHit()</code> which is a method. It isn’t, by any means, “wrong” to do that for all notifications in the application. However, in my experience, I’ve achieved better results using a simple notification system implemented in the AMVCC Application class.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To implement that, let’s update the layout of the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceApplication</code> to be:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceApplication.cs</span>
class BounceApplication
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Iterates all Controllers and delegates the notification data</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// This method can easily be found because every class is “BounceElement” and has an “app” </span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// instance.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Notify</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> p_event_path, Object p_target, <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">params</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">object</span>[] p_data)
{
BounceController[] controller_list = GetAllControllers();
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">foreach</span>(BounceController c <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">in</span> controller_list)
{
c.OnNotification(p_event_path,p_target,p_data);
}
}
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Fetches all scene Controllers.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> BounceController[] <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">GetAllControllers</span>() { <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">/* ... */</span> }
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Next, we need a new script where all developers will add the notification event’s names, which can be dispatched during execution.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceNotifications.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// This class will give static access to the events strings.</span>
class BounceNotification
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">static</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> BallHitGround = “ball.hit.ground”;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">static</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> GameComplete = “game.complete”;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">/* ... */</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">static</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> GameStart = “game.start”;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">static</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> SceneLoad = “scene.load”;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">/* ... */</span>
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is easy to see that, this way, the code legibility is improved because developers don’t need to search all over the source code for <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">controller.OnSomethingComplexName</code> methods in order understand what kind of actions can happen during execution. By only checking one file, it is possible to understand the overall behaviour of the application.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now, we only need to adapt the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BallView</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">BounceController</code> to handle this new system.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BallView.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Describes the Ball view and its features.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BallView : BounceElement
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Only this is necessary. Physics is doing the rest of work.</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Callback called upon collision.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> OnCollisionEnter() { app.Notify(BounceNotification.BallHitGround,<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>); }
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// BounceController.cs</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Controls the app workflow.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span> BounceController : BounceElement
{
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Handles the ball hit event</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">void</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">OnNotification</span>(<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">string</span> p_event_path,Object p_target,<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">params</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">object</span>[] p_data)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">switch</span>(p_event_path)
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> BounceNotification.BallHitGround:
app.model.bounces++;
Debug.Log(“Bounce ”+app.model.bounce);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span>(app.model.bounces >= app.model.winCondition)
{
app.view.ball.enabled = <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span>;
app.view.ball.GetComponent<RigidBody>().isKinematic=<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span>; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// stops the ball</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Notify itself and other controllers possibly interested in the event</span>
app.Notify(BounceNotification.GameComplete,<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span>);
}
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">case</span> BounceNotification.GameComplete:
Debug.Log(“Victory!!”);
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">break</span>;
}
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Bigger projects will have a lot of notifications. So, to avoid getting a big switch-case structure, it is advisable to create different controllers and make them handle different notification scopes.</div>
<h2 id="amvcc-in-the-real-world" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
AMVCC in the Real World</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This example has shown a simple use case for the AMVCC pattern. Adjusting your way of thinking in terms of the three elements of MVC, and learning to visualize the entities as an ordered hierarchy, are the skills that ought to be polished.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In bigger projects, developers will be faced with more complex scenarios and doubts about whether something should be a View or a Controller, or if a given class should be more thoroughly separated in smaller ones.</div>
<h3 id="rules-of-thumb-by-eduardo" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rules of Thumb (by Eduardo)</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There isn’t any “Universal Guide for MVC sorting” anywhere. But there are some simple rules that I typically follow to help me determine whether to define something as a Model, View, or Controller, and also when to split a given class in smaller pieces.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Usually this happens organically while I think about the software architecture or during scripting.</div>
<h4 id="class-sorting" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Class Sorting</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Models</span></div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Hold the application’s core data and state, such as player <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">health</code> or gun <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ammo</code>.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Serialize, deserialize, and/or convert between types.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Load/save data (locally or on the web).</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Notify Controllers of the progress of operations.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Store the Game State for the Game’s <a href="http://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Finite State Machine</a>.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Never access Views.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Views</span></div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Can get data from Models in order to represent up-to-date game state to the user. For example, a View method <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">player.Run()</code> can internally use <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">model.speed</code> to manifest the player abilities.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Should never mutate Models.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Strictly implements the functionalities of its class. For example:<ul style="border: 0px; box-sizing: border-box; font-size: 1em; list-style: none; margin: 1em 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">PlayerView</code> should not implement input detection or modify the Game State.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">A View should act as a black box that has an interface, and notifies of important events.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0px 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Does not store core data (like speed, health, lives,…).</li>
</ul>
</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Controllers</span></div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Do not store core data.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Can sometimes filter notifications from undesired Views.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Update and use the Model’s data.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Manages Unity’s scene workflow.</li>
</ul>
<h4 id="class-hierarchy" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Class Hierarchy</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this case, there aren’t a lot of steps I follow. Usually, I perceive that some class needs to be split when variables start to show too many “prefixes,” or too many variants of the same element start to appear (like <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Player</code> classes in an MMO or <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Gun</code> types in an FPS).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
For example, a single <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Model</code> containing the Player data would have a lot of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">playerDataA, playerDataB,...</code> or a<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Controller</code> handling Player notifications would have <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">OnPlayerDidA,OnPlayerDidB,...</code>. We want to reduce the script size and get rid of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">player</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">OnPlayer</code> prefixes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let me demonstrate using a <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Model</code> class because it is more simple to understand using data only.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
During programming, I usually start with a single <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Model</code> class holding all data for the game.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Model.cs</span>
class Model
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> playerHealth;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> playerLives;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> GameObject playerGunPrefabA;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> playerGunAmmoA;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> GameObject playerGunPrefabB;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> playerGunAmmoB;
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Ops Gun[C D E ...] will appear...</span>
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">/* ... */</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> gameSpeed;
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> gameLevel;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It is easy to see that the more complex the game, the more numerous variables will get. With enough complexity we could end up with a giant class containing <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">model.playerABCDFoo</code> variables. Nesting elements will simplify the code completion and also give room to switch between variations of data.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Model.cs</span>
class Model
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> PlayerModel player; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Container of the Player data.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> GameModel game; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Container of the Game data.</span>
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// GameModel.cs</span>
class GameModel
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> speed; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Game running speed (influencing the difficulty)</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> level; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Current game level/stage loaded</span>
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// PlayerModel.cs</span>
class PlayerModel
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span> health; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Player health from 0.0 to 1.0.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> lives; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Player “retry” count after he dies.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> GunModel[] guns; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Now a Player can have an array of guns to switch ingame.</span>
}
</code></pre>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-cs hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// GunModel.cs</span>
class GunModel
{
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> GunType type; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Enumeration of Gun types.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> GameObject prefab; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Template of the 3D Asset of the weapon.</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> ammo; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Current number of bullets</span>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">public</span> <span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">int</span> clips; <span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Number of reloads possible</span>
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
With this configuration of classes, developers can intuitively navigate in the source code one concept at a time. Let’s assume a first-person shooter game, where weapons and their configurations can get really numerous. The fact that <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GunModel</code> is contained in a class allows the creation of a list of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Prefabs</code>(preconfigured GameObjects to be quickly duplicated and reused in-game) for each category and stored for later use.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In contrast, if the gun information was all stored together in the single <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GunModel</code> class, in variables like <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gun0Ammo</code>, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gun1Ammo</code>, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gun0Clips</code>, and so on, then the user, when faced with the need to store <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Gun</code> data, would need to store the entire <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Model</code> including the unwanted <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">Player</code> data. In this case, it would be obvious that a new <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">GunModel</code> class would be better.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="IMAGE: CLASS HIERARCHY" src="https://assets.toptal.io/uploads/blog/image/91490/toptal-blog-image-1438269131871-fb7c3ac197fa95c295996b4b819b4fef.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /><span style="border: 0px; box-sizing: border-box; display: block; font-size: 0.8em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-align: center; vertical-align: baseline;"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Improving the class hierarchy.</em></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As with everything, there are two sides of the coin. Sometimes one can unnecessarily over-compartmentalize and increase the code complexity. Only experience can hone your skills enough to find the best MVC sorting for your project.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="background-color: #fafafa; color: #505050; font-size: 1.3em; line-height: 1.5em;">New game dev Special Ability unlocked: Unity games with the MVC pattern.</span></div>
<h2 id="conclusion" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Conclusion</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are tons of software patterns out there. In this post I tried to show the one that helped me most in past projects. <a href="https://www.toptal.com/freelance" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Developers</a> should always absorb new knowledge, but always question it, too. I hope this tutorial helps you to learn something new, and at the same time, serves as a stepping stone as you develop your own style.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Also, I really encourage you to research other patterns and find the one that suits you best. One good starting point is <a href="https://en.wikipedia.org/wiki/Software_design_pattern" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">this Wikipedia article</a>, with its excellent list of patterns and their characteristics.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you like the AMVCC pattern and would like to test it out, don’t forget to try out my library, <a href="https://bitbucket.org/eduardo_costa/thelab-unity-mvc/overview" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank"><em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Unity MVC</em></a>, which contains all the core classes necessary to start an AMVCC application.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <span style="border: 0px; box-sizing: border-box; color: #3976cb; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: 600; letter-spacing: 0.13px; line-height: 19px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-transform: uppercase; vertical-align: baseline;"><a class="link is-blue" href="https://www.toptal.com/resume/eduardo-dias-da-costa" style="border: 0px; box-sizing: border-box; color: #103d77; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;" target="_blank">EDUARDO DIAS DA COSTA</a></span><span style="font-size: 1.2em; line-height: 1.5em;">, a <a href="https://www.toptal.com/unity-unity3d/unity-with-mvc-how-to-level-up-your-game-development">Toptal</a><a href="https://www.toptal.com/html5"> HTML developer</a>.</span></div>
Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-4258209981737157440.post-84665794692351977642016-06-02T06:09:00.002-07:002016-06-02T06:09:59.879-07:00Making an HTML5 Canvas Based Game: A Tutorial Using AngularJS and CreateJS<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Game development is one of the more interesting, advanced programming techniques that constantly challenges the software development industry.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
There are many programming platforms used to develop games, and there are a plethora of devices to play them on, but when it comes to playing games in a web browser, Flash-based development still leads the way.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Rewriting Flash-based games to <a href="https://www.toptal.com/html5/job-description" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">HTML5</a> Canvas technology would let us play them on mobile browsers as well. And, with Apache Cordova, <a href="https://www.toptal.com/web" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">skilled web developers</a> could easily wrap them into cross platform mobile game apps.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Folks at <a href="http://www.createjs.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">CreateJS</a> set out to do that and more.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">EaselJS</span>, part of CreateJS’s suite, makes drawing on HTML5 Canvas simple. Imagine building custom data visualization with high performance and thousands of elements. Scalable Vector Graphic (SVG) is not the right choice, because it uses DOM elements. Browsers become overwhelmed when, at around 600 DOM elements, initial renderings, re-draws, and animation become expensive operations. With HTML5 Canvas, we can easily get around these problems; Canvas drawings are like ink on paper, no DOM elements and their associated costs.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
This means that Canvas based development needs more attention when it comes to separating elements, and attaching events and behaviors to them. EaselJS comes to the rescue; we can code as if we are dealing with individual elements, letting EaselJS library handle your mouse-overs, clicks, and collisions.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
SVG-based coding has one big advantage: SVG has an old specification, and there are a lot of design tools that export SVG assets for use in development, so that cooperation between designers and developers works well. Popular libraries, such as <a href="http://d3js.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">D3.JS</a>, and newer, more powerful libraries like <a href="http://www.snapsvg.io/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">SnapSVG</a>, bring much to the table.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If designer-to-developer workflow is the only reason you would use SVGs, consider <a href="http://drawscri.pt/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">drawscript</a>. This is an extension for <a href="https://www.toptal.com/designers/illustrator" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Adobe Illustrator</a> (AI) and generates code from shapes created in AI. In our context, this extension generates EaselJS code or ProcessingJS code, both of which are HTML5 Canvas-based libraries</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Bottom line, if you are starting a new project, there is no reason to use SVGs anymore!</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">SoundJS</span> is part of the CreateJS suite; it provides a simple API for HTML5 Audio specification.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">PreloadJS</span> is used to preload assets such as bitmaps, sound files, and the like. It works well in combination with other CreateJS libraries.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
EaselJS, SoundJS, and PreloadJS make game development super easy for any JavaScript ninja. Its API methods are familiar to anyone who used Flash-based game development.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">“This is all great. But, what if we have a team of developers converting a bunch of games from Flash to HTML5? Is it possible to do that with this suite?”</em></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">The answer:</span> “Yes, but only if all of your developers are at Jedi level!”.</em></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If you have a team of varying skill set developers, which is often the case, it can be a little scary to use CreateJS and expect a scalable and modular code. What if we bring together CreateJS suite with <a href="https://angularjs.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">AngularJS</a>? Can we mitigate against this risk by bringing in the best and most adopted front-end JS framework?</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Yes</span>, and this HTML5 Canvas game tutorial will teach you how to create a basic game with CreateJS and AngularJS!</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="HTML5 Canvas game tutorial with CreateJS and AngularJS" src="https://assets.toptal.io/uploads/blog/image/801/toptal-blog-image-1422289110561.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;" /></div>
<h2 id="planting-the-seed" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Planting The Seed</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
To give you an idea of what are we going to make in this tutorial, I made a small <a href="http://www.techxplorers.net/showcase.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">demo</a>. Check it, and warm up to make your HTML5 Canvas based game.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
I started with default AngularJS seed app, created by my <a href="https://www.jetbrains.com/webstorm/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">WebStorm</a> IDE. Then, I downloaded the source code of EaselJS Spritesheets example from <a href="http://www.createjs.com/#!/Demos/EaselJS/Spritesheets" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">createjs.com</a>, and separated the code into AngularJS directive, service, and factories. I also added some music to the game, and a little more control of the character movement. Plus, I added a score and life count for the character, which are necessary for the game.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
AngularJS significantly reduces complexity by enabling your development team with the following:</div>
<ol style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Adding code modularity, so that team members can focus on different aspects of the game.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Breaking the code into separate testable and maintainable pieces.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Enabling code re-use, so that one factory class can be instantiated multiple times, and re-used to load different but similar assets and behaviors.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Speeding up the development because multiple team members can work in parallel, without stepping on each other’s toes.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Protecting developers from using bad patterns (Javascript carries notoriously bad parts with it and JSLint can only help us so much).</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: decimal; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Adding a solid testing framework.</li>
</ol>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If, like me, you are a “tinkerer” or a tactile learner, you should get the code from <a href="https://github.com/angular/angular-seed" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">GitHub</a> and start learning. My suggestion is to look through my check-ins and understand the steps I took to gain benefits of adding AngularJS goodness to CreateJS code.</div>
<h2 id="running-your-angularjs-seed-project" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Running Your AngularJS Seed Project</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If you haven’t already done so, you need to install <a href="http://www.nodejs.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">nodeJS</a> before you can run this demo.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
After creating an AngularJS seed project, or downloading it from <a href="https://github.com/angular/angular-seed" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">GitHub</a>, run <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">npm install</code> to download all dependencies to your app folder.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
To run your application, execute <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">npm start</code> from same folder and navigate to <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">http://localhost:8000/app/#/view1</code> in your browser. Your page should look like the image below.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="page example" src="https://assets.toptal.io/uploads/blog/image/802/toptal-blog-image-1422290065053.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;" /></div>
<h2 id="easeljs-meets-angularjs" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
EaselJS Meets AngularJS</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Add CreateJS library reference to your AngularJS seed project. Make sure that CreateJS script is included after AngularJS.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;"><script src="http://code.createjs.com/createjs-2014.12.12.min.js"></script></code></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Next, clean up the application:</div>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Delete view2 folder from your app folder</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Remove menu and AngularJS version info from index.html, by deleting the code shown below:</li>
</ul>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"><</span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ul</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">=</span><span class="hljs-value" style="border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"menu"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">></span></div>
<code class="language-html hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">li</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">href</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"#/view1"</span>></span><span style="font-size: 0.9em;">view1</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">li</span>></span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">li</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">href</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"#/view2"</span>></span><span style="font-size: 0.9em;">view2</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">li</span>></span></div>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"></</span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ul</span><span style="font-size: 0.9em;">></span></div>
</span><div style="text-align: justify;">
<span style="font-size: 0.9em;">…</span></div>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">div</span>></span><span style="font-size: 0.9em;">Angular seed app: v</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">span</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">app-version</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">span</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">div</span>></span></div>
</span><div style="text-align: justify;">
<span style="font-size: 0.9em;">…</span></div>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"view2/view2.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span></div>
</span></code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Remove <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">view2</code> module from <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app.js</code>, by deleting the following line</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">myApp.view2,</code></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If you haven’t used AngularJS before, and are not familiar with AngularJS directives, <a href="https://egghead.io/articles/an-introduction-to-the-angularjs-directive-part-1" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">check this tutorial</a>. Directives in AngularJS are a way to teach HTML some new tricks. They are the most well thought out feature in the framework, and make AngularJS powerful and extensible.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Whenever you need a specialized DOM functionality or a component, search for it online; there is a good chance it is already available in places like <a href="http://ngmodules.org/popular" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Angular modules</a>.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
The next thing we need to do is create a new AngularJS directive that will implement the example from EaselJS. Create a new directive called spriteSheetRunner in a new file located in <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">/app/view1/directives/spriteSheetRunner.js</code>.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.directives'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [])</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">.directive(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'spriteSheetRunner'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> "use strict"</span><span style="font-size: 0.9em;">;</span></div>
</span><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> restrict : </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'EAC'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> replace : </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope :{</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">plate: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"<canvas width='960' height='400'></canvas>"</span><span style="font-size: 0.9em;">,</span></div>
te
m
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> link: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(scope, element, attribute)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> w, h, loader, manifest, sky, grant, ground, hill, hill2;</span></div>
drawGame();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">drawGame</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//drawing the game canvas from scratch here</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//In future we can pass stages as param and load indexes from arrays of background elements etc</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.stage) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.autoClear = </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.removeAllChildren();
</span></div>
scope.stage.update();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">else</span><span style="font-size: 0.9em;"> {</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Stage(element[</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">]);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> w = scope.stage.canvas.width;</span></div>
h = scope.stage.canvas.height;
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span></div>
manifest = [
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"spritesheet_grant.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"grant"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill1.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2"</span><span style="font-size: 0.9em;">}</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ];</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.LoadQueue(</span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">false</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"complete"</span><span style="font-size: 0.9em;">, handleComplete);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader.loadManifest(manifest, </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"/app/assets/"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleComplete</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Shape();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky.graphics.beginBitmapFill(loader.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky"</span><span style="font-size: 0.9em;">)).drawRect(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, w, h);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> groundImg = loader.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Shape();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.graphics.beginBitmapFill(groundImg).drawRect(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, w groundImg.width, groundImg.height);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.tileW = groundImg.width;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.y = h - groundImg.height;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Bitmap(loader.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill"</span><span style="font-size: 0.9em;">));</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.setTransform(</span><span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Math</span><span style="font-size: 0.9em;">.random() * w, h - hill.image.height * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;"> - groundImg.height, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.alpha = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.5</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2 = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Bitmap(loader.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2"</span><span style="font-size: 0.9em;">));</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.setTransform(</span><span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Math</span><span style="font-size: 0.9em;">.random() * w, h - hill2.image.height * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;"> - groundImg.height, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> spriteSheet = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.SpriteSheet({</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> framerate: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"images"</span><span style="font-size: 0.9em;">: [loader.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"grant"</span><span style="font-size: 0.9em;">)],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"frames"</span><span style="font-size: 0.9em;">: {</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"regX"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">82</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"height"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">292</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"count"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">64</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"regY"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"width"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">165</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// define two animations, run (loops, 1.5x speed) and jump (returns to run):</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"animations"</span><span style="font-size: 0.9em;">: {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">: [</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">25</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1.5</span><span style="font-size: 0.9em;">],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">: [</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">26</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">63</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">]</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
});
<div style="text-align: justify;">
<span style="font-size: 0.9em;">t = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Sprite(spriteSheet, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">);</span></div>
gra
n
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.y = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">35</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.addChild(sky, hill, hill2, ground, grant);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"stagemousedown"</span><span style="font-size: 0.9em;">, handleJumpStart);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.timingMode = createjs.Ticker.RAF;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleJumpStart</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.gotoAndPlay(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tick</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(event)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> deltaS = event.delta / </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1000</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> position = grant.x </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;"> * deltaS;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> grantW = grant.getBounds().width * grant.scaleX;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.x = (position >= w grantW) ? -grantW : position;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.x = (ground.x - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;">) % ground.tileW;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.x = (hill.x - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill.x hill.image.width * hill.scaleX <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.x = w;</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ll2.x = (hill2.x - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">45</span><span style="font-size: 0.9em;">);</span></div>
h
i
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill2.x hill2.image.width * hill2.scaleX <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.x = w;
</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">pe.stage.update(event);
}
</span></div>
sc
o }
}
<div style="text-align: justify;">
</div>
});
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Once your directive is created, add a dependency to the app by updating <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">/app/app.js</code> as below:</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'use strict'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">;</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="color: #93a1a1; font-size: 0.9em;">// Declare app level module which depends on views, and components</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp'</span><span style="font-size: 0.9em;">,[</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'ngRoute'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.view1'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.version'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.services'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.uiClasses'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.directives'</span><span style="font-size: 0.9em;">])</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> .config([</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$routeProvider'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($routeProvider)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $routeProvider.otherwise({redirectTo: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/view1'</span><span style="font-size: 0.9em;">});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }]);</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Include the directive code in <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">index.html</code> by adding a reference to <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">spriteSheetRunner.js</code>.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><code class="language-html hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"view1/directives/spriteSheetRunner.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
We are almost ready! Copy the game assets to your app folder. I’ve prepared the images, so feel free to download them and save in your app/assets folder.</div>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://raw.githubusercontent.com/avikaza/game-for-blog/f19f439c3cd7d5a9ccbc982474a34b1c31f2715a/app/assets/spritesheet_grant.png" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/spritesheet_grant.png</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://raw.githubusercontent.com/avikaza/game-for-blog/f19f439c3cd7d5a9ccbc982474a34b1c31f2715a/app/assets/ground.png" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/ground.png</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://raw.githubusercontent.com/avikaza/game-for-blog/f19f439c3cd7d5a9ccbc982474a34b1c31f2715a/app/assets/hill1.png" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/hill1.png</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://raw.githubusercontent.com/avikaza/game-for-blog/f19f439c3cd7d5a9ccbc982474a34b1c31f2715a/app/assets/hill2.png" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/hill2.png</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://raw.githubusercontent.com/avikaza/game-for-blog/f19f439c3cd7d5a9ccbc982474a34b1c31f2715a/app/assets/sky.png" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/sky.png</a></li>
</ul>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
As a final step, add our newly created directive to the page. To do so change your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/view/view1.html</code> file, and make it a one-liner:</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><code class="language-html hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite-sheet-runner</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite-sheet-runner</span>></span>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Start your application and you will get your runner in motion :)</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="runner in motion" src="https://assets.toptal.io/uploads/blog/image/803/toptal-blog-image-1422291398104.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline; width: 1258px;" /></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If this is your first AngularJS or first CreateJS application, celebrate, you just made something really cool!</div>
<h2 id="preloading-assets-in-a-service" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Preloading Assets In A Service</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Services in AngularJS are singletons used primarily to share the code and the data. We will use a service to share the ‘game assets’ across the application. To learn more about AngularJS services check the <a href="https://docs.angularjs.org/guide/services" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">AngularJS documentation</a>.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
AngularJS services provide an effective mechanism for loading and managing all assets in one place. Asset changes are propagated to each individual instance of a service, making our code much easier to maintain.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Create new JS file named <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">loaderSvc.js</code> in your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">/app/view1/services</code> folder.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #93a1a1; font-size: 0.9em;">//app/view1/services/loaderSvc.js</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">myServices.service(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> manifest = [ </span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"spritesheet_grant.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"grant"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill1.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2"</span><span style="font-size: 0.9em;">}</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.LoadQueue(</span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.getResult = </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(asset)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> loader.getResult(asset);</span></div>
};
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.getLoader = </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> loader;</span></div>
};
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.loadAssets = </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader.loadManifest(manifest, </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"/app/assets/"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> };
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> });</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
AngularJS requires us to register any service we are using. To do so, update your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app.js</code> file to include reference to <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">myApp.services</code>.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'use strict'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">;</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// Declare app level module which depends on views, and components</span><span style="font-size: 0.9em;">
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp'</span><span style="font-size: 0.9em;">,[</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'ngRoute'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.view1'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.version'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.services'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.directives'</span><span style="font-size: 0.9em;">])</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> .config([</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$routeProvider'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($routeProvider)</span> {</span><span style="font-size: 0.9em;"> </span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $routeProvider.otherwise({redirectTo: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/view1'</span><span style="font-size: 0.9em;">});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }]);</span></div>
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> myServices = angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.services'</span><span style="font-size: 0.9em;">, []);</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Update your directive code, in <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/view1/directives/spriteSheetRunner.js</code> file, to remove the preloading code and use the service instead.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.directives'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [])</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">.directive(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'spriteSheetRunner'</span><span style="font-size: 0.9em;">, [</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc)</span> {</span></div>
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> "use strict"</span><span style="font-size: 0.9em;">;</span></div>
</span><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> restrict : </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'EAC'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> replace : </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope :{</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">plate: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"<canvas width='960' height='400'></canvas>"</span><span style="font-size: 0.9em;">,</span></div>
te
m
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> link: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(scope, element, attribute)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> w, h, manifest, sky, grant, ground, hill, hill2;</span></div>
drawGame();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">drawGame</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//drawing the game canvas from scratch here</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//In future we can pass stages as param and load indexes from arrays of background elements etc</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.stage) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.autoClear = </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.removeAllChildren();
</span></div>
scope.stage.update();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">else</span><span style="font-size: 0.9em;"> {</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Stage(element[</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">]);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> w = scope.stage.canvas.width;</span></div>
h = scope.stage.canvas.height;
<div style="text-align: justify;">
<span style="font-size: 0.9em;">istener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"complete"</span><span style="font-size: 0.9em;">, handleComplete);</span></div>
loaderSvc.getLoader().addEvent
L
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loaderSvc.loadAssets();
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleComplete</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Shape();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky.graphics.beginBitmapFill(loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky"</span><span style="font-size: 0.9em;">)).drawRect(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, w, h);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> groundImg = loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Shape();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.graphics.beginBitmapFill(groundImg).drawRect(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, w + groundImg.width, groundImg.height);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.tileW = groundImg.width;
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.y = h - groundImg.height;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Bitmap(loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill"</span><span style="font-size: 0.9em;">));</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.setTransform(</span><span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Math</span><span style="font-size: 0.9em;">.random() * w, h - hill.image.height * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;"> - groundImg.height, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.alpha = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.5</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2 = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Bitmap(loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2"</span><span style="font-size: 0.9em;">));</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.setTransform(</span><span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Math</span><span style="font-size: 0.9em;">.random() * w, h - hill2.image.height * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;"> - groundImg.height, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> spriteSheet = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.SpriteSheet({</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> framerate: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"images"</span><span style="font-size: 0.9em;">: [loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"grant"</span><span style="font-size: 0.9em;">)],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"frames"</span><span style="font-size: 0.9em;">: {</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"regX"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">82</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"height"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">292</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"count"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">64</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"regY"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"width"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">165</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// define two animations, run (loops, 1.5x speed) and jump (returns to run):</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"animations"</span><span style="font-size: 0.9em;">: {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">: [</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">25</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1.5</span><span style="font-size: 0.9em;">],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">: [</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">26</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">63</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">]</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
});
<div style="text-align: justify;">
<span style="font-size: 0.9em;">t = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Sprite(spriteSheet, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">);</span></div>
gra
n
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.y = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">35</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.addChild(sky, hill, hill2, ground, grant);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"stagemousedown"</span><span style="font-size: 0.9em;">, handleJumpStart);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.timingMode = createjs.Ticker.RAF;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleJumpStart</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.gotoAndPlay(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tick</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(event)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> deltaS = event.delta / </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1000</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> position = grant.x + </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;"> * deltaS;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> grantW = grant.getBounds().width * grant.scaleX;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.x = (position >= w + grantW) ? -grantW : position;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.x = (ground.x - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;">) % ground.tileW;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.x = (hill.x - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill.x + hill.image.width * hill.scaleX <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.x = w;</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ll2.x = (hill2.x - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">45</span><span style="font-size: 0.9em;">);</span></div>
h
i
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill2.x + hill2.image.width * hill2.scaleX <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.x = w;
</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">pe.stage.update(event);
}
</span></div>
sc
o }
}
<div style="text-align: justify;">
</div>
}]);
</code></pre>
<h2 id="creating-ui-elements-factory" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Creating UI elements factory</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Re-using and repeating sprites in game development is very important. In order to enable instantiation of UI classes (which are sprites in our case) we will use AngularJS Factories.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Factory is registered in the application just like any other AngularJS module. To create uiClasses factory, modify your app.js file to look like this:</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'use strict'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">;</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="color: #93a1a1; font-size: 0.9em;">// Declare app level module which depends on views, and components</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp'</span><span style="font-size: 0.9em;">,[</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'ngRoute'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.view1'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.version'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.services'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.uiClasses'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.directives'</span><span style="font-size: 0.9em;">])</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> .config([</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$routeProvider'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($routeProvider)</span> {</span><span style="font-size: 0.9em;"> </span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $routeProvider.otherwise({redirectTo: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/view1'</span><span style="font-size: 0.9em;">});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }]);</span></div>
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> uiClasses = angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.uiClasses'</span><span style="font-size: 0.9em;">, []);</span></div>
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="color: #657b83; font-size: 0.9em;"> myServices = angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.services'</span><span style="color: #657b83; font-size: 0.9em;">, []);</span></div>
</span></code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Let’s use the new factory to create sky, hill, ground, and our runner. To do so, create JavaScript files as listed below.</div>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">app/view1/uiClasses/sky.js</li>
</ul>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">uiClasses.factory(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"Sky"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Sky</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(obj)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.sky = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Shape();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.sky.graphics.beginBitmapFill(loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky"</span><span style="font-size: 0.9em;">)).drawRect(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, obj.width, obj.height);</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">otype = {
ad</span></div>
Sky.pro
<div style="text-align: justify;">
<span style="font-size: 0.9em;">tdToStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.addChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.sky);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> removeFromStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.removeChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.sky);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
};
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> (Sky);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">]);
</span></div>
}
</code></pre>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">app/view1/uiClasses/hill.js</li>
</ul>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">uiClasses.factory(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"Hill"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Hill</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(obj)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Bitmap(loaderSvc.getResult(obj.assetName));</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.setTransform(</span><span class="hljs-built_in" style="border: 0px; box-sizing: border-box; color: #dc322f; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Math</span><span style="font-size: 0.9em;">.random() * obj.width, obj.height - </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.image.height * obj.scaleFactor - obj.groundHeight,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> obj.scaleFactor, obj.scaleFactor);</span></div>
}
Hill.prototype = {
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span><span style="font-size: 0.9em;"> {</span></div>
addToStage:
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.addChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> removeFromStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.removeChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> setAlpha: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(val)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.alpha = val;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ImageWidth: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
ge
t
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.image.width;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">caleX: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
get
S
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.scaleX;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
get
X
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.x;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> getY: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.y;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> setX: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(val)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.x = val;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">e: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(x, y)</span> {</span></div>
mo
v
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.x = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.x + x;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.y = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.hill.y + y;
</span></div>
}
<div style="text-align: justify;">
</div>
};
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> (Hill);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">}]);</span></div>
</code></pre>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">app/view1/ground.js</li>
</ul>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">uiClasses.factory(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"Ground"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ground</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(obj)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> groundImg = loaderSvc.getResult(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Shape();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.graphics.beginBitmapFill(groundImg).drawRect(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, obj.width + groundImg.width, groundImg.height);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.tileW = groundImg.width;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.y = obj.height - groundImg.height;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.height = groundImg.height;</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ound.prototype = {
</span></div>
G
<div style="text-align: justify;">
<span style="font-size: 0.9em;">r addToStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.addChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground);</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">oveFromStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
re
m
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.removeChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> getHeight: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.height;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> getX: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.x;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">X: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(val)</span> {</span></div>
se
t
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.x = val;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ileWidth: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
get
T
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.tileW;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(x, y)</span> {</span></div>
mov
e
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.x = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.x + x;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.y = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.ground.y + y;</span></div>
}
<div style="text-align: justify;">
</div>
};
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> (Ground);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">}]);</span></div>
</code></pre>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">app/view1/uiClasses/character.js</li>
</ul>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">uiClasses.factory(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"Character"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Character</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(obj)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> spriteSheet = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.SpriteSheet({</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> framerate: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"images"</span><span style="font-size: 0.9em;">: [loaderSvc.getResult(obj.characterAssetName)],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"frames"</span><span style="font-size: 0.9em;">: {</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"regX"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">82</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"height"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">292</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"count"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">64</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"regY"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"width"</span><span style="font-size: 0.9em;">: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">165</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// define two animations, run (loops, 1.5x speed) and jump (returns to run):</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"animations"</span><span style="font-size: 0.9em;">: {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">: [</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">25</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1.5</span><span style="font-size: 0.9em;">],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">: [</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">26</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">63</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">]</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
});
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Sprite(spriteSheet, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"run"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant.y = obj.y;</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">acter.prototype = {
</span></div>
Cha
<div style="text-align: justify;">
<span style="font-size: 0.9em;">r addToStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.addChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> removeFromStage: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(stage)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> stage.removeChild(</span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> getWidth: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant.getBounds().width * </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant.scaleX;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">X: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
ge
t
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant.x;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> },
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> setX: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(val)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant.x = val;</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">yAnimation: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(animation)</span> {</span></div>
pl
a
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.grant.gotoAndPlay(animation);</span></div>
}
};
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> (Character);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">]);
</span></div>
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Do not forget to add all these new JS files in your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">index.html</code>.</span></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Now, we need to update the game directive.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">myDirectives.directive(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'spriteSheetRunner'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">,</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Sky'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, </span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Ground'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, </span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Hill'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, </span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Character'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, </span><span class="hljs-function" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc, Sky, Ground, Hill, Character)</span> {</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> "use strict"</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> restrict : </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'EAC'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> replace : </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope :{</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">plate: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"<canvas width='960' height='400'></canvas>"</span><span style="font-size: 0.9em;">,</span></div>
te
m
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> link: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(scope, element, attribute)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> w, h, sky, grant, ground, hill, hill2;</span></div>
drawGame();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">drawGame</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//drawing the game canvas from scratch here</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.stage) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.autoClear = </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.removeAllChildren();
</span></div>
scope.stage.update();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">else</span><span style="font-size: 0.9em;"> {</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Stage(element[</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">]);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> w = scope.stage.canvas.width;</span></div>
h = scope.stage.canvas.height;
<div style="text-align: justify;">
<span style="font-size: 0.9em;">istener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"complete"</span><span style="font-size: 0.9em;">, handleComplete);</span></div>
loaderSvc.getLoader().addEvent
L
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loaderSvc.loadAssets();
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleComplete</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Sky({width:w, height:h});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky.addToStage(scope.stage);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Ground({width:w, height:h});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Hill({width:w, height:h, scaleFactor: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;">, assetName: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'hill'</span><span style="font-size: 0.9em;">, groundHeight: ground.getHeight()});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.setAlpha(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.5</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2 = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Hill({width:w, height:h, scaleFactor: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">, assetName: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'hill2'</span><span style="font-size: 0.9em;">, groundHeight: ground.getHeight()});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Character({characterAssetName: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'grant'</span><span style="font-size: 0.9em;">, y: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">34</span><span style="font-size: 0.9em;">})</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"stagemousedown"</span><span style="font-size: 0.9em;">, handleJumpStart);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.timingMode = createjs.Ticker.RAF;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleJumpStart</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.playAnimation(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tick</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(event)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> deltaS = event.delta / </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1000</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> position = grant.getX() + </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;"> * deltaS;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.setX((position >= w + grant.getWidth()) ? -grant.getWidth() : position);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.setX((ground.getX() - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;">) % ground.getTileWidth());</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.move(deltaS * -</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill.getX() + hill.getImageWidth() * hill.getScaleX() <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.setX(w);</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ll2.move(deltaS * -</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">45</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">);</span></div>
h
i
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill2.getX() + hill2.getImageWidth() * hill2.getScaleX() <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.setX(w);
</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">pe.stage.update(event);
}
</span></div>
sc
o }
}
<div style="text-align: justify;">
</div>
}]);
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Note that moving <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">uiClasses</code> out of the directive reduced the directive size by 20%, from 91 to 65 lines.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
In addition, we can independently write tests for each factory class to simplify its maintenance.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Note: Testing is a topic that is not covered in this post but <a href="https://docs.angularjs.org/guide/unit-testing" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a> is a good place to start.</span></div>
<h2 id="arrow-keys-interaction" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Arrow Keys Interaction</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
At this point in our HTML5 Canvas game tutorial, mouse click or tap on a mobile will make our guy jump, and we cannot stop him. Let’s add arrow key controls:</div>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Left arrow (pause the game)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Up arrow (jump)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">Right arrow (start running)</li>
</ul>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
To do that, create the <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">keyDown</code> function and add an event listener as last line of <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">handleComplete()</code> function.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">keydown</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(event)</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> {</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (event.keyCode === </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">38</span><span style="font-size: 0.9em;">) {</span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//if keyCode is "Up"</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> handleJumpStart();</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (event.keyCode === </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">39</span><span style="font-size: 0.9em;">) {</span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//if keyCode is "Right"</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.status === </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"paused"</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.status = </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"running"</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (event.keyCode === </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">37</span><span style="font-size: 0.9em;">) {</span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//if keyCode is "Left"</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.removeEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.status = </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"paused"</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">dow.onkeydown = keydown;
</span></div>
wi
n
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Try running your game again and check the keyboard controls.</div>
<h2 id="let-the-music-play" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Let The Music Play</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Games are not fun without music, so let’s play some music.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
We will first need to add MP3 files to our app/assets folder. You can download them from the URLs provided below.</div>
<ul style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://raw.githubusercontent.com/avikaza/game-for-blog/0386dbd058c0e0ae73b550e4eb77c171cf3042b6/app/assets/jump.mp3" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/jump.mp3</a></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><a href="https://github.com/avikaza/game-for-blog/blob/master/app/assets/runningTrack.mp3" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">app/assets/runningTrack.mp3</a></li>
</ul>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Now, we need to preload these sound files using our loader service. We will use <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">loadQueue</code> of <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">PreloaderJS</code>library. Update your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/view1/services/loaderSvc.js</code> to preload these files.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">myServices.service(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, </span><span class="hljs-function" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> manifest = [</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"spritesheet_grant.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"grant"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"sky"</span><span style="font-size: 0.9em;">},
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"ground"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill1.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2.png"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"hill2"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"runningTrack.mp3"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"runningSound"</span><span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> {src: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump.mp3"</span><span style="font-size: 0.9em;">, id: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jumpingSound"</span><span style="font-size: 0.9em;">}</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ],</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.LoadQueue(</span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// need this so it doesn't default to Web Audio</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]);
</span></div>
loader.installPlugin(createjs.Sound);
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.getResult = </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(asset)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> loader.getResult(asset);</span></div>
};
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.getLoader = </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> loader;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> };
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">this</span><span style="font-size: 0.9em;">.loadAssets = </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loader.loadManifest(manifest, </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"/app/assets/"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> };</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">});</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Modify your game directive to play sounds on game events.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">myDirectives.directive(</span><span class="hljs-string" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'spriteSheetRunner'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">, [</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'loaderSvc'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Sky'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Ground'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Hill'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'Character'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(loaderSvc, Sky, Ground, Hill, Character)</span> {</span></div>
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> "use strict"</span><span style="font-size: 0.9em;">;</span></div>
</span><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">return</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> restrict : </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'EAC'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> replace : </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope :{</span></div>
},
<div style="text-align: justify;">
<span style="font-size: 0.9em;">plate: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"<canvas width='960' height='400'></canvas>"</span><span style="font-size: 0.9em;">,</span></div>
te
m
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> link: </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(scope, element, attribute)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> w, h, sky, grant, ground, hill, hill2, runningSoundInstance, status; drawGame();</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">drawGame</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//drawing the game canvas from scratch here</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.stage) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.autoClear = </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.removeAllChildren();
</span></div>
scope.stage.update();
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">else</span><span style="font-size: 0.9em;"> {</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> createjs.Stage(element[</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">]);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> w = scope.stage.canvas.width;</span></div>
h = scope.stage.canvas.height;
<div style="text-align: justify;">
<span style="font-size: 0.9em;">istener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"complete"</span><span style="font-size: 0.9em;">, handleComplete);</span></div>
loaderSvc.getLoader().addEvent
L
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> loaderSvc.loadAssets();
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleComplete</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Sky({width:w, height:h});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> sky.addToStage(scope.stage);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Ground({width:w, height:h});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Hill({width:w, height:h, scaleFactor: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">4</span><span style="font-size: 0.9em;">, assetName: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'hill'</span><span style="font-size: 0.9em;">, groundHeight: ground.getHeight()});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.setAlpha(</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0.5</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2 = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Hill({width:w, height:h, scaleFactor: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">, assetName: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'hill2'</span><span style="font-size: 0.9em;">, groundHeight: ground.getHeight()});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant = </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">new</span><span style="font-size: 0.9em;"> Character({characterAssetName: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'grant'</span><span style="font-size: 0.9em;">, y: </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">34</span><span style="font-size: 0.9em;">}); grant.addToStage(scope.stage);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.stage.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"stagemousedown"</span><span style="font-size: 0.9em;">, handleJumpStart);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.timingMode = createjs.Ticker.RAF;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">// start playing the running sound looping indefinitely</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> runningSoundInstance = createjs.Sound.play(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"runningSound"</span><span style="font-size: 0.9em;">, {loop: -</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span><span style="font-size: 0.9em;">});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.status = </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"running"</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> window.onkeydown = keydown;</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">keydown</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(event)</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (event.keyCode === </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">38</span><span style="font-size: 0.9em;">) {</span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//if keyCode is "Up"</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> handleJumpStart();
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (event.keyCode === </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">39</span><span style="font-size: 0.9em;">) {</span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//if keyCode is "Right"</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.status === </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"paused"</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.addEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> runningSoundInstance = createjs.Sound.play(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"runningSound"</span><span style="font-size: 0.9em;">, {loop: -</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1</span><span style="font-size: 0.9em;">});</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.status = </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"running"</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (event.keyCode === </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">37</span><span style="font-size: 0.9em;">) {</span><span class="hljs-comment" style="border: 0px; box-sizing: border-box; color: #93a1a1; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">//if keyCode is "Left"</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Ticker.removeEventListener(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"tick"</span><span style="font-size: 0.9em;">, tick);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Sound.stop();
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> scope.status = </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"paused"</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">handleJumpStart</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (scope.status === </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"running"</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> createjs.Sound.play(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jumpingSound"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.playAnimation(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"jump"</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> }
</span></div>
}
<div style="text-align: justify;">
<span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span style="font-size: 0.9em;"> </span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tick</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(event)</span><span style="font-size: 0.9em;"> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> deltaS = event.delta / </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">1000</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">var</span><span style="font-size: 0.9em;"> position = grant.getX() + </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;"> * deltaS;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> grant.setX((position >= w + grant.getWidth()) ? -grant.getWidth() : position);
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> ground.setX((ground.getX() - deltaS * </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">150</span><span style="font-size: 0.9em;">) % ground.getTileWidth());</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.move(deltaS * -</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">);</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill.getX() + hill.getImageWidth() * hill.getScaleX() <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill.setX(w);</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">ll2.move(deltaS * -</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">45</span><span style="font-size: 0.9em;">, </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">);</span></div>
h
i
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">if</span><span style="font-size: 0.9em;"> (hill2.getX() + hill2.getImageWidth() * hill2.getScaleX() <= </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">) {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> hill2.setX(w);
</span></div>
}
<div style="text-align: justify;">
<span style="font-size: 0.9em;">e.stage.update(event);
}
</span></div>
sco
p }
}
<div style="text-align: justify;">
</div>
}]);
</code></pre>
<div class="pop_out_box is-full_width is-big" style="background-color: #fafafa; border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; text-align: justify; vertical-align: baseline; width: 864px;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Related: </span><a href="https://www.toptal.com/angular-js/top-18-most-common-angularjs-developer-mistakes" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">AngularJS Best Practices and Tips by Toptal Developers</a></div>
<h2 id="adding-score-and-life-indicators" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Adding Score and Life Indicators</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Let’s add the game score and life (heart) indicators to the HTML5 Canvas game. The score will be shown as a number in the upper left corner, and heart symbols, at the top right corner, will indicate life count.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
We will use an external font library to render hearts, so add the following line to your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">index.html</code> file header.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;"><code class="language-html hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">link</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">href</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">rel</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"stylesheet"</span>></span>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Standard AngularJS binding will provide real-time updates. Add the following code to your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/view1/view1.html</code> file:</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite-sheet-runner</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">score</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"score"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">lifes-count</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount"</span>></span><span class="hljs-tag" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite-sheet-runner</span>></span></div>
<code class="language-html hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">span</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"top-left"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">h2</span>></span><span style="font-size: 0.9em;">Score: {{score}}</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">h2</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">span</span>></span></div>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">span</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"top-right"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">h2</span>></span><span style="font-size: 0.9em;">Life:</span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ng-if</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount > 0"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"fa fa-heart"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span>></span><span style="font-size: 0.9em;"> </span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ng-if</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount < 1"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"fa fa-heart-o"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span>></span><span style="font-size: 0.9em;"> </span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ng-if</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount > 1"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"fa fa-heart"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span>></span><span style="font-size: 0.9em;"> </span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ng-if</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount < 2"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"fa fa-heart-o"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span>></span><span style="font-size: 0.9em;"> </span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ng-if</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount > 2"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"fa fa-heart"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span>></span><span style="font-size: 0.9em;"> </span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">ng-if</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount < 3"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">class</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"fa fa-heart-o"</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">i</span>></span><span style="font-size: 0.9em;"> </span></div>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">h2</span>></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">span</span>></span></div>
</span></code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
To properly position our indicators, we need to add CSS classes for top-left and top-right in <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/app.css</code> file.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-class" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">.top-left</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-rules" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">{</span></div>
<code class="language-css hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">position</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> absolute</span></span><span style="font-size: 0.9em;">;</span></div>
<span class="hljs-rules" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">left</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">30</span>px</span></span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">top</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span>px</span></span><span style="font-size: 0.9em;">;</span></div>
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">}</span></div>
</span></span><span class="hljs-class" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-class" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">.top-right</span><span style="font-size: 0.9em;"> </span><span class="hljs-rules" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">{</span></div>
</span><span class="hljs-rules" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">position</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> absolute</span></span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">right</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">100</span>px</span></span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">top</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span>px</span></span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> </span><span class="hljs-rule" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">float</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> right</span></span><span style="font-size: 0.9em;">;</span></div>
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">}</span></div>
</span></span></code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Initialize the score and <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">lifesCount</code> variables in <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/view1/view1.js</code> controller.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'use strict'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">;</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.view1'</span><span style="font-size: 0.9em;">, [</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'ngRoute'</span><span style="font-size: 0.9em;">])</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">.config([</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$routeProvider'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($routeProvider)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $routeProvider.when(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/view1'</span><span style="font-size: 0.9em;">, {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> templateUrl: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'view1/view1.html'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> controller: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'View1Ctrl'</span><span style="font-size: 0.9em;"> });</span></div>
}])
<div style="text-align: justify;">
<span style="font-size: 0.9em;">troller(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'View1Ctrl'</span><span style="font-size: 0.9em;">, [</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$scope'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($scope)</span> {</span></div>
.co
n
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $scope.score = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $scope.lifesCount = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">]);
</span></div>
}
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
To make sure that indicators are properly updated, modify your main game directive to use the scope variables.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">...</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">replace : </span><span class="hljs-literal" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">true</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">scope :{</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> score: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'=score'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> lifesCount: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'=lifesCount'</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">template:</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">...</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
To test the scope binding, add these three lines at the end of <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">handleComplete()</code> method.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">scope.score = </span><span class="hljs-number" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">10</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">;</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">scope.lifesCount = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">2</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">scope.$apply();</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
When you run the application you should see the score and life indicators.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="score and life indicators" src="https://assets.toptal.io/uploads/blog/image/804/toptal-blog-image-1422291491829.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline; width: 1259px;" /></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Additional white space, on the right of the page, will continue to be present because we are still hardcoding the game’s width and height at this point in our HTML5 game programming tutorial.</div>
<h2 id="adapting-the-game-width" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Adapting the Game Width</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
AngularJS is packed with useful methods and services. One of them is $window, which provides an innerWidth property that we will use to calculate the position of our elements.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Modify your <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">app/view1/view1.js</code> to inject <code style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">$window</code> service.</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span class="hljs-pi" style="background-color: #fffffc; border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'use strict'</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">;</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">angular.module(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'myApp.view1'</span><span style="font-size: 0.9em;">, [</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'ngRoute'</span><span style="font-size: 0.9em;">])</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">.config([</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$routeProvider'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($routeProvider)</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $routeProvider.when(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'/view1'</span><span style="font-size: 0.9em;">, {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> templateUrl: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'view1/view1.html'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> controller: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'View1Ctrl'</span><span style="font-size: 0.9em;">
});</span></div>
}])
<div style="text-align: justify;">
<span style="font-size: 0.9em;">troller(</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'View1Ctrl'</span><span style="font-size: 0.9em;">, [</span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$scope'</span><span style="font-size: 0.9em;">, </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'$window'</span><span style="font-size: 0.9em;">, </span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">($scope, $window)</span> {</span></div>
.co
n
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $scope.windowWidth = $window.innerWidth;
</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $scope.gameHeight = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">400</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $scope.score = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> $scope.lifesCount = </span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">3</span><span style="font-size: 0.9em;">;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">}]);</span></div>
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Extend the main game directive with width and height properties and that’s it!</div>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"><</span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite-sheet-runner</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">width</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">=</span><span class="hljs-value" style="border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"windowWidth"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">height</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">=</span><span class="hljs-value" style="border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"gameHeight"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">score</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">=</span><span class="hljs-value" style="border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"score"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;"> </span><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">lifes-count</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">=</span><span class="hljs-value" style="border: 0px; box-sizing: border-box; color: #657b83; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"lifesCount"</span><span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">></span></div>
<code class="language-html hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;"></</span><span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">sprite-sheet-runner</span><span style="font-size: 0.9em;">></span></div>
</code></pre>
<pre style="border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="text-align: justify;">
<span style="background-color: #fffffc; color: #657b83; font-size: 0.9em;">...</span></div>
<code class="language-javascript hljs" style="background-color: #fffffc; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 864px;"><div style="text-align: justify;">
<span style="font-size: 0.9em;">scope :{</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> width: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'=width'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> height: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'=height'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> score: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'=score'</span><span style="font-size: 0.9em;">,</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;"> lifesCount: </span><span class="hljs-string" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">'=lifesCount'</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">},</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">..
</span></div>
.
<div style="text-align: justify;">
<span style="font-size: 0.9em;">awGame();
e</span></div>
d
<div style="text-align: justify;">
<span style="font-size: 0.9em;">rlement[</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">].width = scope.width;</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">element[</span><span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span><span style="font-size: 0.9em;">].height = scope.height;</span></div>
w = scope.width;
<div style="text-align: justify;">
<span style="font-size: 0.9em;">
</span></div>
h = scope.height
<div style="text-align: justify;">
<span style="font-size: 0.9em;">;</span><span class="hljs-function" style="border: 0px; box-sizing: border-box; font-size: 0.9em; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-keyword" style="border: 0px; box-sizing: border-box; color: #859900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">drawGame</span><span class="hljs-params" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">()</span> {</span></div>
<div style="text-align: justify;">
<span style="font-size: 0.9em;">..
</span></div>
.
</code></pre>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Now you have the game adjusting itself to width of the browser window.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
If you want to port this into a mobile app, I suggest reading my other mobile app development tutorial about <a href="https://www.toptal.com/front-end/building-multi-platform-real-time-mobile-applications-using-ionic-framework-and-firebase" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">using Ionic framework to create mobile apps</a>. You should be able to create an ionic seed app, copy all the code from this project, and start playing the game on your mobile device in less than an hour.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
The only thing I am not covering here is collision detection. To learn more about it, I read <a href="http://www.createjs.com/tutorials/HitTest/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">this article</a>.</div>
<h2 id="wrap-up" style="border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
Wrap Up</h2>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
I believe that through the course of this game development tutorial you realized that <a href="https://www.toptal.com/angular-js/job-description" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">AngularJS</a> and CreateJS are a winning duo for HTML5 based game development. You’ve got all the basics and I’m sure you recognized the benefits of combining these two platforms.</div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span></div>
<div style="border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; text-align: justify; vertical-align: baseline;">
You can download the code for this article from <a href="https://github.com/avikaza/game-for-blog" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">GitHub</a>, feel free to use, share, and make it your own.</div>
<i><div style="text-align: justify;">
<i>This post originally appeared in <a href="https://www.toptal.com/web/making-html5-canvas-based-game-with-angularjs-and-createjs">Toptal Engineering blog</a>. Written by <a href="https://www.toptal.com/resume/avinash-kaza">Avinash Kaza</a></i></div>
</i>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-71225880546261359722016-05-26T20:37:00.000-07:002016-05-26T20:37:22.815-07:00Ultimate Guide to Processing: Building a Simple Game<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-size: 1.2em; line-height: 1.5em;">In this article, we will implement our own game step-by-step. Each step will be explained in detail. Then, we will port the game to the web.</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Building a Simple Game with Processing" src="https://assets.toptal.io/uploads/blog/image/91874/toptal-blog-image-1450355133671-5a81e639a3b2553907867a0721ae592d.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Before we begin, <a href="https://gist.github.com/oguzgelal/a3b8fba696cc4e662158" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a> is the code of the DVD logo exercise from the previous part. If you have any questions, be sure to leave a comment.</div>
<h2 id="a-simple-game" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A Simple Game</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="http://codepen.io/anon/pen/BjyzoP/left" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">The game</a> we will build in this article is sort of a combination of Flappy Bird, Pong and Brick Breaker. The reason I picked a game like this is that it has most of the concepts that beginners struggle with when learning game development. This is based on my experience from when I was a teaching assistant, helping new learners with Processing. These concepts include gravity, collisions, keeping scores, handling different screens and keyboard/mouse interactions. Flappy Pong has all of them in it.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-size: 1.2em; line-height: 1.5em;">Without using object-oriented programming (OOP) concepts, it is not easy to build complex games, such as platform games with multiple levels, players, entities etc. As we move along, you’ll see how the code gets complicated really fast. I did my best to keep it organised and simple.</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I advise you to follow the article, grab the full code, play with them on your own, start thinking about your own game as quickly as possible, and start implementing it.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So let’s begin.</div>
<h2 id="building-flappy-pong" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Building Flappy Pong</h2>
<h3 id="step-1-initialize--handle-different-screens" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Step #1: Initialize & Handle Different Screens</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The first step is to initialize our project. For starters, we will write our setup and draw blocks as usual, nothing fancy or new. Then, we will handle different screens (initial screen, game screen, game over screen etc.). So the question arises, how do we make Processing show the correct page at the correct time?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Accomplishing this task is fairly simple. We will have a global variable that stores the information of the currently active screen. We then draw the contents of the correct screen depending on the variable. In the draw block, we will have an if statement that checks the variable and displays the contents of the screen accordingly. Whenever we want to change the screen, we will change that variable to the identifier of screen we want it to display. With that said, here is what our skeleton code looks like:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">/********* VARIABLES *********/
// We control which screen is active by settings / updating
// gameScreen variable. We display the correct screen according
// to the value of this variable.
//
// 0: Initial Screen
// 1: Game Screen
// 2: Game-over Screen
int gameScreen = 0;
/********* SETUP BLOCK *********/
void setup() {
size(500, 500);
}
/********* DRAW BLOCK *********/
void draw() {
// Display the contents of the current screen
if (gameScreen == 0) {
initScreen();
} else if (gameScreen == 1) {
gameScreen();
} else if (gameScreen == 2) {
gameOverScreen();
}
}
/********* SCREEN CONTENTS *********/
void initScreen() {
// codes of initial screen
}
void gameScreen() {
// codes of game screen
}
void gameOverScreen() {
// codes for game over screen
}
/********* INPUTS *********/
public void mousePressed() {
// if we are on the initial screen when clicked, start the game
if (gameScreen==0) {
startGame();
}
}
/********* OTHER FUNCTIONS *********/
// This method sets the necessery variables to start the game
void startGame() {
gameScreen=1;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This may look scary at first, but all we did is build the basic structure and separate different parts with comment blocks.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As you can see, we define a different method for each screen to display. In our draw block, we simply check the value of our <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameScreen</code> variable, and call the corresponding method.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">void mousePressed(){...}</code> part, we are listening to mouse clicks and if the active screen is 0, the initial screen, we call the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">startGame()</code> method which starts the game as you’d expect. The first line of this method changes <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameScreen</code> variable to 1, the game screen.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If this is understood, the next step is to implement our initial screen. To do that, we will be editing the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">initScreen()</code> method. Here it goes:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">void initScreen() {
background(0);
textAlign(CENTER);
text("Click to start", height/2, width/2);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now our initial screen has a black background and a simple text, “Click to start”, located in the middle and aligned to the center. But when we click, nothing happens. We haven’t yet specified any content for our game screen. The method <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameScreen()</code> doesn’t have anything in it, so we aren’t covering the previous contents drawn from the last screen (the text) by having <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">background()</code> as the first line of draw. That’s why the text is still there, even though the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">text()</code> line is not being called anymore <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(just like the moving ball example from the last part which was leaving a trace behind)</em>. The background is still black for the same reason. So let’s go ahead and begin implementing the game screen.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">void gameScreen() {
background(255);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
After this change, you will notice that the background turns white & the text disappears.</div>
<h3 id="step-2-creating-the-ball--implementing-gravity" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Step #2: Creating the Ball & Implementing Gravity</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now, we will start working on the game screen. We will first create our ball. We should define variables for its coordinates, color and size because we might want to change those values later on. For instance, if we want to increase the size of the ball as the player scores higher so that the game will be harder. We will need to change its size, so it should be a variable. We will define speed of the ball as well, after we implement gravity.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First, let’s add the following:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
int ballX, ballY;
int ballSize = 20;
int ballColor = color(0);
...
void setup() {
...
ballX=width/4;
ballY=height/5;
}
...
void gameScreen() {
...
drawBall();
}
...
void drawBall() {
fill(ballColor);
ellipse(ballX, ballY, ballSize, ballSize);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We defined the coordinates as global variables, created a method that draw the ball, called from<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">gameScreen</em> method. Only thing to pay attention to here is that we <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">initialized</span> coordinates, but we defined them in <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">setup()</code>. The reason we did that is we wanted the ball to start at one fourth from left and one fifth from top. There is no particular reason we want that, but that is a good point for the ball to start. So we needed to get the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">width</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">height</code> of the sketch dynamically. The sketch size is defined in <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">setup()</code>, after the first line. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">width</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">height</code> are not set before <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">setup()</code> runs, that’s why we couldn’t achieve this if we defined the variables on top.</div>
<h4 id="gravity" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Gravity</h4>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now implementing gravity is actually the easy part. There are only a few tricks. Here is the implementation first:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
float gravity = 1;
float ballSpeedVert = 0;
...
void gameScreen() {
...
applyGravity();
keepInScreen();
}
...
void applyGravity() {
ballSpeedVert += gravity;
ballY += ballSpeedVert;
}
void makeBounceBottom(float surface) {
ballY = surface-(ballSize/2);
ballSpeedVert*=-1;
}
void makeBounceTop(float surface) {
ballY = surface+(ballSize/2);
ballSpeedVert*=-1;
}
// keep ball in the screen
void keepInScreen() {
// ball hits floor
if (ballY+(ballSize/2) > height) {
makeBounceBottom(height);
}
// ball hits ceiling
if (ballY-(ballSize/2) < 0) {
makeBounceTop(0);
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And the result is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91875/toptal-blog-image-1450355303665-0843cb22cd3a2a69ad2c98d48bf70410.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Hold your horses, physicist. I know that’s not how gravity works in real life. The variable we defined as <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gravity</code> is just a numeric value that we add to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code> on every loop. And <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code> is the vertical speed of the ball, which is added to the Y coordinate of the ball (<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballY</code>) on each loop. We watch the coordinates of the ball and make sure it stays in the screen. If we didn’t, the ball would fall to infinity. For now, our ball only moves vertically. So we watch the floor and ceiling boundries of the screen. With <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">keepInScreen()</code> method, we check if <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballY</code> (<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">+</span> the radius) is less than <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">height</code>, and similarly <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballY</code> (<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">-</span> the radius) is more than <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">0</code>. If the conditions don’t meet, we make the ball bounce (from the bottom or the top) with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceBottom()</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceTop()</code> methods. To make the ball bounce, we simply move the ball to the exact location where it had to bounce and multiply the vertical speed (<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code>) with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">-1</code>(multiplying with -1 changes the sign). When the speed value has a minus sign, adding Y coordinate the speed becomes <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballY + (-ballSpeedVert)</code>, which is <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballY - ballSpeedVert</code>. So the ball immediately changes its direction with the same speed. Then, as we add <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gravity</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code> has a negative value, it starts to get close to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">0</code>, eventually becomes <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">0</code>, and starts increasing again. That makes the ball rise, rise slower, stop and start falling.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91876/toptal-blog-image-1450355332910-a32bcdd5ffc0964a36c7c714afe0f5b6.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is a problem though - the ball keeps bouncing. If this was a real world scenario, the ball would have faced air resistance and friction every time it touches a surface. That’s the behaviour we want for our game, so implementing this is easy. We add the following:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
float airfriction = 0.0001;
float friction = 0.1;
...
void applyGravity() {
...
ballSpeedVert -= (ballSpeedVert * airfriction);
}
void makeBounceBottom(int surface) {
...
ballSpeedVert -= (ballSpeedVert * friction);
}
void makeBounceTop(int surface) {
...
ballSpeedVert -= (ballSpeedVert * friction);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And what we get is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91877/toptal-blog-image-1450355396964-29b18c2ef066bc40704f01529017db35.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As the name suggests, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">friction</code> is the surface friction and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">airfriction</code> is the friction of air. So obviously, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">friction</code> has to apply each time the ball touches any surface. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">airfriction</code> however has to apply constantly. So that’s what we did. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">applyGravity()</code> method runs on each loop, so we take away <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">0.0001</code>percent of its current value from <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code> on every loop. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceBottom()</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceTop()</code>methods run when the ball touches any surface. So in those methods, we did the same thing, only this time with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">friction</code>.</div>
<h3 id="step-3-creating-the-racket" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Step #3: Creating the Racket</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now we need a racket for the ball to bounce on. We should be controlling the racket. Let’s make it controllable with the mouse. Here is the code:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
color racketColor = color(0);
float racketWidth = 100;
float racketHeight = 10;
...
void gameScreen() {
...
drawRacket();
...
}
...
void drawRacket(){
fill(racketColor);
rectMode(CENTER);
rect(mouseX, mouseY, racketWidth, racketHeight);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We defined the color, width and height of the racket as a global variable, we might want them to change during gameplay. We implemented a method <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">drawRacket()</code> which does what its name suggests. We set the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">rectMode</code> to center, so our racket is aligned to the center of our cursor.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now that we created the racket, we have to make the ball bounce on it.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
int racketBounceRate = 20;
...
void gameScreen() {
...
watchRacketBounce();
...
}
...
void watchRacketBounce() {
float overhead = mouseY - pmouseY;
if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) {
if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) {
makeBounceBottom(mouseY);
// racket moving up
if (overhead<0) {
ballY+=overhead;
ballSpeedVert+=overhead;
}
}
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And here is the result:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91878/toptal-blog-image-1450355448539-5b69a293af98cf41a012eef9d2d778a9.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So what <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">watchRacketBounce()</code> does is it makes sure that the racket and the ball collides. There are two things to check here, which is if the ball and racket lined up both vertically and horizontally. The first if statement checks if the X coordinate of the right side of the ball is greater than the X coordinate of the left side of the racket (and the other way around). If it is, second statement checks if the distance between the ball and the racket is smaller than or equal to the radius of the ball <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(which means they are colliding)</em>. So if these conditions meet, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceBottom()</code> method gets called and the ball bounces on our racket (at <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">mouseY</code>, where the racket is).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Have you noticed the variable <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">overhead</code> which is calculated by <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">mouseY - pmouseY</code>? <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">pmouseX</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">pmouseY</code>variables store the coordinates of the mouse at the previous frame. As the mouse can move very fast, there is a good chance we might not detect the distance between the ball and the racket correctly in between frames if the mouse is moving towards the ball fast enough. So, we take the difference of the mouse coordinates in between frames and take that into account while detecting distance. The the faster mouse is moving, the greater distance is acceptable.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We also use <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">overhead</code> for another reason. We detect which way the mouse is moving by checking the sign of <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">overhead</code>. If overhead is negative, the mouse was somewhere below in the previous frame so our mouse (racket) is moving up. In that case, we want to add an extra speed to the ball and move it a little further than regular bounce to simulate the effect of hitting the ball with the racket. If <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">overhead</code> is less than<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">0</code>, we add it to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballY</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedVert</code> to make the ball go higher and faster. So the faster the racket hits the ball, the higher and faster it will move up.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 835px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h3 id="step-4-horizontal-movement--controlling-the-ball" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Step #4: Horizontal Movement & Controlling the Ball</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this section, we will add horizontal movement to the ball. Then, we will make it possible to control the ball horizontally with our racket. Here we go:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
// we will start with 0, but for we give 10 just for testing
float ballSpeedHorizon = 10;
...
void gameScreen() {
...
applyHorizontalSpeed();
...
}
...
void applyHorizontalSpeed(){
ballX += ballSpeedHorizon;
ballSpeedHorizon -= (ballSpeedHorizon * airfriction);
}
void makeBounceLeft(float surface){
ballX = surface+(ballSize/2);
ballSpeedHorizon*=-1;
ballSpeedHorizon -= (ballSpeedHorizon * friction);
}
void makeBounceRight(float surface){
ballX = surface-(ballSize/2);
ballSpeedHorizon*=-1;
ballSpeedHorizon -= (ballSpeedHorizon * friction);
}
...
void keepInScreen() {
...
if (ballX-(ballSize/2) < 0){
makeBounceLeft(0);
}
if (ballX+(ballSize/2) > width){
makeBounceRight(width);
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And the result is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91879/toptal-blog-image-1450355477910-fec185e051d8fee6ef281d4cf69e46d1.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The idea here is the same as what we did for vertical movement. We created a horizontal speed variable, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballSpeedHorizon</code>. We created a method to apply horizontal speed to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballX</code> and take away the air friction. We added two more if statements to the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">keepInScreen()</code> method which will watch the ball for hitting the left and right edges of the screen. Finally we created <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceLeft()</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">makeBounceRight()</code> methods to handle the bounces from left and right.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now that we added horizontal speed to the game, we want to control the ball with the racket. As in the famous Atari game <a href="https://www.youtube.com/watch?v=MTnhlAlzb6Y" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Breakout</a> and in all other brick breaking games, the ball should go left or right according to the point on the racket it hits. The edges of the racket should give the ball more horizontal speed whereas the middle shouldn’t have any effect. Code first:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">void watchRacketBounce() {
...
if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) {
if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) {
...
ballSpeedHorizon = (ballX - mouseX)/5;
...
}
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Result is:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91880/toptal-blog-image-1450355529745-435e9c6a5727ab9a6625b8ca9d28452c.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Adding that simple line to the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">watchRacketBounce()</code> did the job. What we did is we determined the distance of the point that the ball hits from the center of the racket with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ballX - mouseX</code>. Then, we make it the horizontal speed. The actual difference was too much, so I gave it a few tries and figured that one-tenth of the value feels the most natural.</div>
<h3 id="step-5-creating-the-walls" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Step #5: Creating the Walls</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Our sketch is starting to look more like a game with each step. In this step, we will add walls moving towards the left, just like in Flappy Bird:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
int wallSpeed = 5;
int wallInterval = 1000;
float lastAddTime = 0;
int minGapHeight = 200;
int maxGapHeight = 300;
int wallWidth = 80;
color wallColors = color(0);
// This arraylist stores data of the gaps between the walls. Actuals walls are drawn accordingly.
// [gapWallX, gapWallY, gapWallWidth, gapWallHeight]
ArrayList<int[]> walls = new ArrayList<int[]>();
...
void gameScreen() {
...
wallAdder();
wallHandler();
}
...
void wallAdder() {
if (millis()-lastAddTime > wallInterval) {
int randHeight = round(random(minGapHeight, maxGapHeight));
int randY = round(random(0, height-randHeight));
// {gapWallX, gapWallY, gapWallWidth, gapWallHeight}
int[] randWall = {width, randY, wallWidth, randHeight};
walls.add(randWall);
lastAddTime = millis();
}
}
void wallHandler() {
for (int i = 0; i < walls.size(); i++) {
wallRemover(i);
wallMover(i);
wallDrawer(i);
}
}
void wallDrawer(int index) {
int[] wall = walls.get(index);
// get gap wall settings
int gapWallX = wall[0];
int gapWallY = wall[1];
int gapWallWidth = wall[2];
int gapWallHeight = wall[3];
// draw actual walls
rectMode(CORNER);
fill(wallColors);
rect(gapWallX, 0, gapWallWidth, gapWallY);
rect(gapWallX, gapWallY+gapWallHeight, gapWallWidth, height-(gapWallY+gapWallHeight));
}
void wallMover(int index) {
int[] wall = walls.get(index);
wall[0] -= wallSpeed;
}
void wallRemover(int index) {
int[] wall = walls.get(index);
if (wall[0]+wall[2] <= 0) {
walls.remove(index);
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And this resulted in:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91881/toptal-blog-image-1450355573501-68d95e7e1b2a0d7e3da2d980062ba7a0.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Even though the code looks long and intimidating, I promise there is nothing hard to understand. First thing to notice is <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ArrayList</code>. For those of you who don’t know what an <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ArrayList</code> is, it is just an implementation of list that acts like an Array, but it has some advantages over it. It is resizeable, it has useful methods like <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">list.add(index)</code>, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">list.get(index)</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">list.remove(index)</code>. We keep the wall data as integer arrays within the arraylist. The data we keep in the arrays are for the gap between two walls. The arrays contain the following values:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">[gap wall X, gap wall Y, gap wall width, gap wall height]
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The actual walls are drawn based on the gap wall values. Note that all these could be handled better and cleaner using classes, but since the use of Object Oriented Programming (OOP) is not in the scope of this article, this is how we’ll handle it. We have two base methods to manage the walls, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallAdder()</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallHandler</code>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallAdder()</code> method simply adds new walls in every <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallInterval</code> millisecond to the arraylist. We have a global variable <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">lastAddTime</code> which stores the time when the last wall was added <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">(in milliseconds)</em>. If the current millisecond <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">millis()</code> minus the last added millisecond <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">lastAddTime</code> is larger than our interval value <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallInterval</code>, it means it is now time to add a new wall. Random gap variables are then generated based on the global variables defined at the very top. Then a new wall (integer array that stores the gap wall data) is added into the arraylist and the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">lastAddTime</code> is set to the current millisecond <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">millis()</code>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallHandler()</code> loops through the current walls that is in the arraylist. And for each item at each loop, it calls <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallRemover(i)</code>, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallMover(i)</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallDrawer(i)</code> by the index value of the arraylist. These methods do what their name suggests. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallDrawer()</code> draws the actual walls based on the gap wall data. It grabs the wall data array from the arraylist, and calls <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">rect()</code> method to draw the walls to where they should actually be. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallMover()</code> method grabs the element from the arraylist, changes its X location based on the<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallSpeed</code> global variable. Finally, <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">wallRemover()</code> removes the walls from the arraylist which are out of the screen. If we didn’t do that, Processing would have treated them as they are still in the screen. And that would have been a huge loss in performance. So when a wall is removed from the arraylist, it doesn’t get drawn on subsequent loops.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The final challenging thing left to do is to detect collisions between the ball and the walls.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">void wallHandler() {
for (int i = 0; i < walls.size(); i++) {
...
watchWallCollision(i);
}
}
...
void watchWallCollision(int index) {
int[] wall = walls.get(index);
// get gap wall settings
int gapWallX = wall[0];
int gapWallY = wall[1];
int gapWallWidth = wall[2];
int gapWallHeight = wall[3];
int wallTopX = gapWallX;
int wallTopY = 0;
int wallTopWidth = gapWallWidth;
int wallTopHeight = gapWallY;
int wallBottomX = gapWallX;
int wallBottomY = gapWallY+gapWallHeight;
int wallBottomWidth = gapWallWidth;
int wallBottomHeight = height-(gapWallY+gapWallHeight);
if (
(ballX+(ballSize/2)>wallTopX) &&
(ballX-(ballSize/2)<wallTopX+wallTopWidth) &&
(ballY+(ballSize/2)>wallTopY) &&
(ballY-(ballSize/2)<wallTopY+wallTopHeight)
) {
// collides with upper wall
}
if (
(ballX+(ballSize/2)>wallBottomX) &&
(ballX-(ballSize/2)<wallBottomX+wallBottomWidth) &&
(ballY+(ballSize/2)>wallBottomY) &&
(ballY-(ballSize/2)<wallBottomY+wallBottomHeight)
) {
// collides with lower wall
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">watchWallCollision()</code> method gets called for each wall on each loop. We grab the coordinates of the gap wall, calculate the coordinates of the actual walls (top and bottom) and we check if the coordinates of the ball collides with the walls.</div>
<h3 id="step-6-health-and-score" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Step #6: Health and Score</h3>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Now that we can detect the collisions of the ball and the walls, we can decide on the game mechanics. After some tuning to the game, I managed to make the game somewhat playable. But still, it was very hard. My first thought on the game was to make it like Flappy Bird, when the ball touches the walls, game ends. But then I realised it would be impossible to play. So here is what I thought:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There should be a health bar on top of the ball. The ball should lose health while it is touching the walls. With this logic, it doesn’t make sense to make the ball bounce back from the walls. So when the health is 0, the game should end and we should switch to the game over screen. So here we go:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">int maxHealth = 100;
float health = 100;
float healthDecrease = 1;
int healthBarWidth = 60;
...
void gameScreen() {
...
drawHealthBar();
...
}
...
void drawHealthBar() {
noStroke();
fill(236, 240, 241);
rectMode(CORNER);
rect(ballX-(healthBarWidth/2), ballY - 30, healthBarWidth, 5);
if (health > 60) {
fill(46, 204, 113);
} else if (health > 30) {
fill(230, 126, 34);
} else {
fill(231, 76, 60);
}
rectMode(CORNER);
rect(ballX-(healthBarWidth/2), ballY - 30, healthBarWidth*(health/maxHealth), 5);
}
void decreaseHealth(){
health -= healthDecrease;
if (health <= 0){
gameOver();
}
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
And here is a simple run:</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91882/toptal-blog-image-1450355859616-53c855102fc0ff45751e4963c69d801d.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We created a global variable <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">health</code> to keep the health of the ball. And then created a method <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">drawHealthBar()</code> which draws two rectangles on top of the ball. First one is the base health bar, other is the active one that shows the current health. The width of the second one is dynamic, and is calculated with <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">healthBarWidth*(health/maxHealth)</code>, the ratio of our current health with respect to the width of the health bar. Finally, the fill colors are set according to the value of health. Last but not the least, <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">scores</span>:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
void gameOverScreen() {
background(0);
textAlign(CENTER);
fill(255);
textSize(30);
text("Game Over", height/2, width/2 - 20);
textSize(15);
text("Click to Restart", height/2, width/2 + 10);
}
...
void wallAdder() {
if (millis()-lastAddTime > wallInterval) {
...
// added another value at the end of the array
int[] randWall = {width, randY, wallWidth, randHeight, 0};
...
}
}
void watchWallCollision(int index) {
...
int wallScored = wall[4];
...
if (ballX > gapWallX+(gapWallWidth/2) && wallScored==0) {
wallScored=1;
wall[4]=1;
score();
}
}
void score() {
score++;
}
void printScore(){
textAlign(CENTER);
fill(0);
textSize(30);
text(score, height/2, 50);
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We needed to score when the ball passes a wall. But we need to add maximum 1 score per wall. Meaning, if the ball passes a wall than goes back and passes it again, another score shouldn’t be added. To achieve this, we added another variable to the gap wall array within the arraylist. The new variable stores <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">0</code> if the ball didn’t yet pass that wall and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">1</code> if it did. Then, we modified the <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">watchWallCollision()</code> method. We added a condition that fires <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">score()</code> method and marks the wall as passed when the ball passes a wall which it has not passed before.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We are now very close to the end. The last thing to do is implement <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">click to restart</code> on the game over screen. We need to set all the variables we used to their initial value, and restart the game. Here it is:</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-processing" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;">...
public void mousePressed() {
...
if (gameScreen==2){
restart();
}
}
...
void restart() {
score = 0;
health = maxHealth;
ballX=width/4;
ballY=height/5;
lastAddTime = 0;
walls.clear();
gameScreen = 0;
}
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s add some more colors.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/91883/toptal-blog-image-1450356035018-d2df7ff9bca1b2b243f5075d98a77681.gif" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Voila! We have Flappy Pong!</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Full code for the game can be found <a href="https://gist.github.com/oguzgelal/a2a8db8b2da0e864d1d0#file-flappy_pong-pde" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>.</div>
<h2 id="porting-processing-code-to-the-web-using-p5js" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Porting Processing Code to the Web Using p5.js</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="http://p5js.org/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">p5.js</a> is a JavaScript interpreter for Processing. It is not a simple library that is capable of running Processing code, instead, p5.js takes in pure JavaScript codes. Our task is to convert Processing code into JavaScript following p5.js format. The library has a set of functions and a syntax similar to Processing, and we have to do certain changes to our code to make them work in JavaScript. Even if you are not a<a href="https://www.toptal.com/javascript" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">JavaScript developer</a>, the changes are very trivial and you should be able to follow along just fine.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First of all, we need to create a simple <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">index.html</code> and add <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">p5.min.js</code> to our header. We also need to create another file called <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">flappy_pong.js</code> which will house our converted code.</div>
<pre style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-size: 15px; line-height: 20px; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code class="language-html hljs" style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; color: #657b83; display: inline-block; font-size: 0.9em; line-height: 1.5em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; overflow-x: auto; padding: 2px 5px; vertical-align: text-bottom; width: 835px;"><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">html</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">title</span>></span>Flappy Pong<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">title</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tyle</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"text/javascript"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.19/p5.min.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">tyle</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"text/javascript"</span> <span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">"flappy_pong.js"</span>></span><span class="javascript" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">style</span>></span><span class="css" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">canvas</span> <span class="hljs-rules" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">{
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="border: 0px; box-sizing: border-box; color: #b58900; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">box-shadow</span>:<span class="hljs-value" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">0</span> <span class="hljs-number" style="border: 0px; box-sizing: border-box; color: #2aa198; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">20</span>px lightgray</span></span>;
<span class="hljs-rule" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">}</span></span>
</span><span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">style</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"></<span class="hljs-title" style="border: 0px; box-sizing: border-box; color: #268bd2; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">html</span>></span>
</code></pre>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Our strategy while converting the code should be copying and pasting all our code into <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">flappy_pong.js</code>and then making all the changes. And that’s what I did. And here are the steps I took to update the code:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Javascript is an untyped languages (there are no type declarations like <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">int</code> and <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">float</code>). So we need to change all the type declarations to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">var</code>.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is no <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">void</code> in Javascript. We should change all to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">function</code>.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We need to remove the type declarations of arguments from function signatures. (ie. <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">void wallMover(var index) {</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">function wallMover(index) {</code> )</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is no <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ArrayList</code> in JavaScript. But we can achieve the same thing using JavaScript arrays. We make the following changes:</div>
<ul style="border: 0px; box-sizing: border-box; font-size: 1em; list-style: none; margin: 1em 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">ArrayList<int[]> walls = new ArrayList<int[]>();</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">var walls = [];</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.clear();</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls = [];</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.add(randWall);</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.push(randWall);</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.remove(index);</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.splice(index,1);</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.get(index);</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls[index]</code></li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: circle; margin: 0px 0px 0px 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.size()</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">walls.length</code></li>
</ul>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Change the declaration of the array <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">var randWall = {width, randY, wallWidth, randHeight, 0};</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">var randWall = [width, randY, wallWidth, randHeight, 0];</code></div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Remove all <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">public</code> keywords.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Move all <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">color(0)</code> declarations into <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">function setup()</code> because <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">color()</code> will not be defined before <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">setup()</code> call.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Change <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">size(500, 500);</code> to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">createCanvas(500, 500);</code></div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rename <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">function gameScreen(){</code> to something else like <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">function gamePlayScreen(){</code> because we already have a global variable named <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">gameScreen</code>. When we were working with Processing, one was a function and the other was an <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">int</code> variable. But JavaScript confuses these since they are untyped.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Same thing goes for <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">score()</code>. I renamed it to <code style="background: rgb(255, 255, 252); border-radius: 3px; border: 1px solid rgb(238, 238, 238); box-sizing: border-box; display: inline-block; font-size: 0.8em; line-height: 1em; margin: 0px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 2px 5px; vertical-align: text-bottom;">addScore()</code>.</div>
</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Full Javascript code can be found <a href="https://gist.github.com/oguzgelal/a2a8db8b2da0e864d1d0#file-flappy_pong-js" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">here</a>.</div>
<h2 id="conclusion" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Conclusion</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In this article, I tried to explain how to build a very simple game with Processing. However what we did in this article is just the tip of the iceberg. With Processing, just about anything can be achieved. In my opinion, it’s the best tool to program what you’re imagining. My actual intention with this article is rather than teaching Processing and building a game, to prove that programming isn’t that hard. Building your own game isn’t just a dream. I wanted to show you that with a little effort and enthusiasm, you can do it. I really hope these two articles inspire everyone to give programming a shot.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-size: 19.2px; line-height: 28.8px;">This is the second part of the ultimate guide to Processing. In the first part, I tried to give a basic walkthrough to the Processing language. If you haven’t read the first part, you can find it </span><a href="https://www.toptal.com/game/ultimate-guide-to-processing-the-fundamentals" style="border: 0px; box-sizing: border-box; color: #3976cb; font-size: 19.2px; line-height: 28.8px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">here</a><span style="font-size: 19.2px; line-height: 28.8px;">.</span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="font-size: 19.2px; line-height: 28.8px;">This article was written by </span><a class="link is-blue" href="https://www.toptal.com/resume/oguz-gelal" style="border: 0px; box-sizing: border-box; color: #103d77; display: inline; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: 600; letter-spacing: 0.13px; line-height: 19px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; text-transform: uppercase; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;" target="_blank"><span style="color: #103d77; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="border-color: initial; border-style: initial; box-sizing: border-box; font-size: 13px; font-weight: 600; letter-spacing: 0.13px; line-height: 19px; text-transform: uppercase; transition: color 150ms, transform, text-shadow, -webkit-transform;">OGUZ </span></span>GELAL</a>, a <a href="https://www.toptal.com/game/ultimate-guide-to-processing-simple-game">Toptal</a><a href="https://www.toptal.com/javascript"> JavaScript developer</a>.</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-20080223966139140472016-05-20T10:15:00.000-07:002016-08-13T10:17:37.844-07:00CycliHey!<br />
<br />
As you might have noticed, there are posts by TopTal. They contacted my about making posts, and the articles seemed pretty well written, so as long as they provide value and they write about related things, I will let them write here on the blog. Especially since I'm busy myself I thought it was a good idea. Note that the posts aren't my opinions.<br />
<br />
And, here is yet another interesting "excergaming" project:<br />
<br />
<br />
<iframe frameborder="0" height="360" scrolling="no" src="https://www.kickstarter.com/projects/cycli/cycli-the-worlds-first-bluetooth-enabled-social-cy/widget/video.html" width="640"> </iframe>Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-22141739417032597132016-05-18T00:11:00.001-07:002016-05-18T00:11:29.417-07:00Google Cardboard Overview: VR On The Cheap<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Imagine if you will, standing on the surface of the moon, overlooking a crater from your lunar rover, listening to mission control chatter. Or don’t. Instead of imagining it, just order a cheap Google Cardboard VR set instead, stick your phone in it, and start exploring the solar system, museums, tourist spots, coral reefs and much more. Let the Imagination Technologies GPU in your phone live up to its name and do your imagining for you.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Cardboard is hardly a new concept. It was unleashed on the unsuspecting geekosphere at Google I/O 2014, roughly 18 months ago. Since then, Google has tweaked the Cardboard reference design, but the concept hasn’t changed; Google Cardboard was envisioned as the cheapest Virtual Reality (VR) solution on the planet, and at this point, nothing else comes close in terms of pricing.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Google Cardboard is significantly cheaper than competing VR platforms, so why is adoption so slow?" src="https://assets.toptal.io/uploads/blog/image/91989/toptal-blog-image-1453451371221-ee23fa3dfe00b92e831e2b265767920d.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 828px;">
Google Cardboard is significantly cheaper than competing VR platforms, so why is adoption so slow?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you keep track of tech news, you are probably aware that Oculus Rift started shipping a few days ago. The news even made it to mainstream media, and CNN interviewed a few Oculus execs, who discussed the future of Oculus and VR in general. Demand for the Rift appears to be high because the pre-order website crashed hours into the launch, which coincided with the Consumer Electronics Show (CES) in Vegas. The Oculus Rift is priced at $599, and you also need a $1,000-plus computer to use it properly, but the high price obviously didn’t faze the loads of consumers who pre-ordered one.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I could try to explain what makes Oculus different and why it costs so much, but that’s beside the point. It’s a product for enthusiasts and connoisseurs, people who don’t mind spending a lot of money for a great gaming user experience or for some niche professional applications. Compared to Google’s VR platform, Oculus Rift is a technological tour de force, but for the price of a single Oculus headset, you can get more than 50 prefabricated Google Cardboard headsets. Mind you, I am not talking about cardboard DIY sets, but proper headsets made out of plastic, with soft padding and a few straps to keep the contraption on your head.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Considering that you can get a Google Cardboard compatible set for $10 to $20, you’d expect that loads of people are buying them, but that’s not the case. Let’s take a closer look at Google’s platform and try to figure out what’s going on.</div>
<h2 id="the-year-of-vr-not-really" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
2016: The Year Of VR? Not Really</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
71,000.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In addition to being the ZIP code for Sarajevo, that’s the number of users that have rated the official<a href="https://play.google.com/store/apps/details?id=com.google.samples.apps.cardboarddemo&hl=en" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Google Cardboard app</a> so far. The number of downloads is in the one to five million range. That’s low by anyone’s standards, and for a Google product 18 months after launch, it’s a shockingly poor result. Granted, there are VR apps with more downloads, but even they are stuck in the 100,000 to 500,000 range.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Does this mean we should dismiss Cardboard as a hyped up geek fad? Does the user experience suck? What the hell is wrong with it?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This may sound a bit harsh and opinionated, but I believe <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Google simply can’t do hardware</em>. Regardless of how good they are, Google sucks at marketing its own hardware solutions. In the interest of full disclosure, I am a Nexus veteran and I tend to like Google hardware, but most consumers don’t (many don’t even know it exists). The fact that people aren’t buying a dirt cheap product like Cardboard, and that more companies aren’t using it to build their own products and services, despite the fact that it’s free, might vindicate my position on Google hardware.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is just one problem: <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Google Cardboard is a good idea and it works</em>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="While Google may not excel at hardware, Cardboard VR is a sound concept and it works." src="https://assets.toptal.io/uploads/blog/image/91994/toptal-blog-image-1453456766973-5a2b1c6cfa980e002cb36fc75afe88c6.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 828px;">
While Google may not excel at hardware, Cardboard VR is a sound concept and it works.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Rather than dismiss Cardboard outright, I decided to try it out. I quickly realised the concept is sound and there’s nothing terribly wrong with the <a href="https://www.toptal.com/designers/ux/portfolios" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">user experience</a>, but once again, Google failed to market it properly and make it appeal to non-geeks. As a result, adoption is pathetic, at least for now.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What about VR adoption and popularity in general? Weren’t we told that 2015 was going to be “The Year of VR?” Or was it supposed to be 2016? I am sure CNN said it was going to be this year.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It all depends on whose marketing pitches you were listening to, but in reality, 2016 will <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">not go down in tech history as the year of VR</em>. Sure, it sounds good and investors like the idea, but it’s not going to happen. This is not my personal opinion. A few industry sources believe things will start moving in 2017, but it will take a while.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
When I say “industry sources,” I am talking about GPU industry execs, people who know this stuff better than anyone. They’re pointing to 2017 and beyond, but they’re doing so off the record. This applies to cheap VR solutions like Google Cardboard and expensive sets like Oculus Rift: <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">VR won’t get a lot of traction this year, don’t fall for the hype!</em></div>
<h2 id="google-cardboard-vr-for-the-masses" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Cardboard: VR For The Masses</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How does Google Cardboard work? What makes it different?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The really fascinating thing about Google Cardboard is its simplicity and low price. The concept relies on off-the-shelf hardware, you just need to stick a smartphone into a Cardboard headset and you’re ready to go, more or less.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As the low price suggests, Google Cardboard doesn’t contain any magic or expensive components. All you need is a couple of lenses, a plastic or cardboard body, and a couple of magnets which double as a physical button. When you push the button, the phone’s magnetic sensor, or e-compass, detects the changes in the magnetic field and that’s all there is to it.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="The recipe for Google’s Cardboard VR special sauce: simple, widely available, cheap, open-source, based on prolific hardware." src="https://assets.toptal.io/uploads/blog/image/91990/toptal-blog-image-1453451433772-647f4286572cc53f454776b678261af4.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 828px;">
The recipe for Google’s Cardboard VR special sauce: simple, widely available, cheap, open-source, based on prolific hardware.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are a few caveats: Google Cardboard won’t work on <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">any</em> phone because it relies on sensor input that might not be available on many devices (gyroscopic sensors aren’t very common on cheap phones). The phone also needs to have a high resolution display, but thanks to the pixel density marketing craze, this shouldn’t be much of a problem moving forward. Having a bigger display with more pixels simply makes everything look better. While 1080p on a 5-inch phone sounds like a lot, once you start using Cardboard, you’ll see individual pixels. I didn’t try it on a 720p display, but I am convinced it wouldn’t be enough. There are a few other problems, such as battery consumption and overheating, and let’s not forget that you could get a call or message while you’re in the middle of your VR experience.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In spite of these foibles, Google Cardboard has a lot going for it. For starters, it does not require consumers to spend a small fortune just to get a taste of VR. It relies on one of the most prolific software/hardware platforms on the market, so it’s within easy reach for hundreds of millions of smartphone users and developers alike.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unfortunately, this vast potential has not translated into market success. With a few dozen thousand users in the wild, I could hardly blame anyone for dismissing Cardboard as a geeky curiosity, but I’d stop short of calling it a flop.</div>
<h2 id="what-went-wrong" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What Went Wrong?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nothing, apart from the fact that <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Google can’t do hardware</em>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To be fair, Google Cardboard wasn’t envisioned as a product with mass market appeal and I personally view it as a tech testbed rather than a proper product. It’s not the only VR concept to rely on a phone for display and processing: Samsung’s Gear VR is similar.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, this seems to be part of the problem, because it does not appear Google is taking Cardboard very seriously. Although Google Cardboard was released 18 months ago, a lot of building blocks weren’t ready for launch. Google is still dragging its feet, but there’s some progress: As of May 2015, Cardboard can be used on iOS devices, it has better OpenGL and WebGL support, and Google launched a few new VR initiatives, including Jump and Expeditions. YouTube also got a dedicated VR/360 degree video channel, and it could become the go to place for people searching for VR video.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Cardboard’s biggest problem is not technological.</em></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The platform is too small to attract a lot of third-party development, and who could blame app makers for refusing to waste man-hours on projects that don’t guarantee a return. That’s one of the reasons I decided to try it out; I kept looking at Google Play stats, the terrible reviews and I started wondering whether or not Google Cardboard has a bright future, or any future for that matter.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I don’t intend to turn this post into a Google Cardboard review, but I think it’s important to review a few things, just to give you a clear idea of what to expect (in case you haven’t tried it, yet).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s start with Cardboard requirements. I should note that these are <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">not</em> official Google Cardboard requirements:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Android 4.1 or iOS 8 device required</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Gyro sensor</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">NFC or magnetic sensor</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">High definition display (1080p is sufficient, the more the better)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">High capacity battery can’t hurt</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Loads of storage</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Fast network/broadband access</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The good news is that there aren’t any software hoops to jump through. Since Google Cardboard relies on standard smartphones, designers and developers are unlikely to encounter many hardware-related issues. The biggest hardware compatibility issue is on the sensor side. A lot of inexpensive Android phones don’t feature some of the sensors that may be employed by Cardboard apps (namely gyro and magnetic sensors).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Cardboard can accommodate a range of different phone sizes, so it should work on standard 5-inch phones, as well as oversized 5.5- or 6-inch phablets. Display density isn’t much of a problem on 1080p, although it could be better. Resolution will eventually go up, as hardware-makers shift to 1600p and 4K/UHD displays on plus-size phones. Sony already has a flagship Android phone with a 4K display.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I’ve already discussed the more or less pointless trend of moving to higher definition phone displays in one of my <a href="https://www.toptal.com/virtual-reality/www.toptal.com/designers/ui/the-industry-could-do-without-pixel-density-and-ppi-marketing" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Toptal blog posts</a>, but VR is an exception. There’s no way you’ll see individual pixels on modern, high-definition phone displays, unless you use them in a Cardboard headset.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, higher resolution displays don’t mean a thing unless you’ve got high-res content for them. Unfortunately, there’s not a lot of 1080p VR content out there, let alone 4K/UHD content.</div>
<h2 id="vr-video-resolution-conundrum" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
VR Video Resolution Conundrum</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Bear in mind that increasing the resolution comes with trade-offs. This brings us to the next problem: Even if we had loads of 4K VR videos, how would we get them on our devices? The problem I encountered was simple: I quickly started running out of bandwidth and storage, in some cases even on 1080p. Sure, you can stream 1080p video on even a slow internet connection, but you’ll often need to slow down and give your device time to buffer, which is always annoying, but it’s <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">really annoying</em> when you have a VR headset strapped to your cranium.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Some of you may be thinking that I live in a part of the world with terrible Internet infrastructure, and I’ll be the first to admit that Bosnia isn’t exactly Silicon Valley, but bear with me; my broadband is still faster than the average speed in the US, UK, Sweden, Japan, and a bunch of other highly developed economies. In other words, a lot of users in California and Tokyo still rely on even slower Internet access. Recent surveys indicate that just one fifth of US homes have enough bandwidth to stream 4K content.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I know. I’ll just download the videos and enjoy them off local storage, but it’s not an ideal solution. First of all, a lot of content isn’t available for download at all, it’s just streamed. Worse, you’ll need <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a lot of storage</em>to pull it off. For the past couple of years, mobile services have been shifting to streaming in lieu of local content, allowing people to make good use of fast mobile broadband. Why keep gigabytes of music and video on your phone when you can enjoy Netflix or Spotify on the go? Resorting to local storage for high definition VR feels like a step back, but if you’ve got good 4G coverage or fast broadband in your home, it won’t be much of a problem.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Limited bandwidth and resolution are the biggest problems facing virtual reality video at the moment." src="https://assets.toptal.io/uploads/blog/image/91992/toptal-blog-image-1453451541084-31b186cde3802234c9bb7badc64f0485.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 828px;">
Limited bandwidth and resolution are the biggest problems facing virtual reality video at the moment.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In addition to requiring more bandwidth, high resolution content also requires more processing power. At 1080p, this isn’t a problem because this industry-standard resolution has been around for ages and even cheap hardware handles it with ease. However, at 4K you simply need more bandwidth and CPU/GPU muscle to handle the data and decode the stream. This means more milliamps, more heat, more charging. Smartphones aren’t designed with this application in mind, they’re simply not supposed to be used for this stuff. With cranked-up screen brightness, high CPU and GPU loads, and a lot of data streaming in to ensure smooth playback, a standard phone will run out of steam in a couple of hours or less. On top of that, it will heat up in minutes. Bear in mind that there’s no airflow inside the headset, so the device will have a hard time dissipating the heat.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I tried it out on a Snapdragon 808 device. For those who don’t pay close attention to the silicon space, this is a one of the latest Qualcomm smartphone chips. It’s a 20nm planar part with a couple of ARM Cortex-A57 CPU cores and powerful Qualcomm Adreno 418 graphics. The same chip is used in Google’s new Nexus 5X. It’s fast enough, but it heats up in no time despite the fact that it’s one of few mobile chips to be produced in a node superior to 28nm.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, video is not the only type of VR content out there. Let’s take a look at some alternatives.</div>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 828px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h2 id="different-types-of-google-cardboard-content" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Different Types Of Google Cardboard Content</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I focused on video in the first section of the article because I feel it will be the most attractive form of VR content, at least at this early stage. However, I think people who choose to use their VR headsets solely for video will be missing out.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
VR video is usually limited in terms of terms of field of view, and what you see is what you get: You can’t walk around a VR video scene, you’re just stuck in a single virtual location, either a front row seat at a Paul McCartney gig, or a cockpit of a Swiss Air Force F-5 jet performing an acrobatic routine. My problem with video and photos is that the user can truly enjoy this sort of content only once, and there’s not a whole lot of it out there.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Don’t get me wrong, these experiences can be good, but what about getting my glorious behind off the sofa and navigating <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">a real</em> VR world? What about generating a different environment every single time, and interacting with it?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The only way of doing this is on Google Cardboard by rendering the content locally and putting the user smack in the middle of a digital environment. We’ve been doing this since the early nineties, when games like Wolfenstein took the world by storm (and games like Descent made a lot of geeks experience motion sickness without moving, just by staring at their screen).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="It’s possible to render 3D VR content locally on most smartphones, but quality is limited due to a range of technical challenges." src="https://assets.toptal.io/uploads/blog/image/91995/toptal-blog-image-1453458379206-36442d9addb96a9961ad98c1a6de7d89.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 828px;">
It’s possible to render 3D VR content locally on most smartphones, but quality is limited due to a range of technical challenges.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is what makes Oculus Rift fundamentally different: It relies on desktop hardware to render 3D content and display it on the VR headset. This is obviously a huge difference, and the official Oculus Rift requirements look like a gamer’s shopping wishlist: a powerful Haswell generation Core i5 processor backed by 8GB of RAM. More importantly, the list includes Nvidia GeForce GTX 970 and AMD Radeon R9 290 discrete graphics cards, based on Maxwell and Hawaii GPU architectures respectively. High-end PC processors, like the one listed by Oculus, usually have about 1.5 billion transistors. Big GPUs, like Maxwell and Hawaii designs used in the GTX 970 and R9 290, have five to seven billion, and they’re getting bigger. The combined power draw of a PC with such specs is a few hundred Watts, roughly 100 times more than the power consumption of an average smartphone chip. In other words, even if you still believe in Moore’s Law, it’s obvious that we won’t get the same level of performance on mobile devices for years.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Most smartphones have enough GPU muscle to render good looking 3D scenes in 1080p, although they don’t come close to the sort of overkill graphics you get on a high-end PC. You can forget about fancy shaders, advanced antialiasing techniques and many post processing features, but let’s not forget that phones have come a long way and that this sort of technology would have been next to impossible just five years ago.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is not the only bit of good news; Google has two SDKs for Cardboard developers: an Android SDK using Java and a Unity SDK, using C#. Both rely on OpenGL, and Unity support was added to the iOS SDK earlier this year. Once you are no longer bound to video, VR starts to make a lot more sense. Done right, artificial environment can immerse users into a dynamic and interactive 3D environment, so even simple demos look and feel good.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Even if you plan to rely on video content or photos, you’ll still need a <a href="https://www.toptal.com/designers/ui/portfolios" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">UI that works</a>, and chances are it will use some form of 3D, or at least 2D objects placed in a 3D environment, per Google Cardboard guidelines. Most apps that focus on digitally generated imagery instead rely on Unity. There’s nothing wrong with that, Unity is a popular engine and it’s quite capable.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As I’ve already pointed out, Google Cardboard relies on standard hardware, hence there aren’t that many technical challenges to overcome. Make sure you follow <a href="https://developers.google.com/cardboard/overview" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Google’s Cardboard guidelines</a> and best practices, and you should be in the clear.</div>
<h2 id="d-is-the-way-to-go-sort-of" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
3D Is The Way To Go, Sort Of</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So what’s the problem with using Unity and 3D graphics in general? It sounds straightforward and offers people a chance to experience a true VR experience on a budget.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s not get ahead of ourselves. Here are a few issues that come to mind:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Battery life</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Heat dissipation</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Limited GPU power</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Need for high resolution assets (mainly textures for 3D models)</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Different level of detail (LOD) approach</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Motion sickness</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Limited ability to control movement and interact with environment</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I’ve already addressed the problem of heat and power consumption. Placing a smartphone in a small environment with no airflow and maxing out the GPU is more or less the worst thing you can do in terms of thermals and efficiency. This issue cannot and will not be resolved. Phones simply aren’t designed to be used this way.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This brings us to the next problem: GPU performance. While smartphone application processors have evolved at a staggering pace, they are not developed for sustained performance. A discrete graphics card or integrated GPU on your desktop can run at high loads for hours, even days, but your mobile GPU cannot. Once the device starts overheating, it will throttle the processor to stay within the thermal envelope, protecting the hardware and saving battery power. Sure, you can get good graphics out of smartphone chips, but running a VR app with a virtual UI in 3D, along with loads of core 3D content, will drain the battery and overheat any phone.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Mobile game developers already know a thing or two about optimising their creations for this sort of hardware. Unity has been around for years, so generating good looking 3D content should not be a problem, right? It depends on the type of environment being designed. If it’s supposed to be a photorealistic 3D environment with advanced lighting and post processing, designing for VR could prove a bit more challenging. This is the problem: Although we’re still using the same resolution, the field of view is much bigger. As a result, the VR experience on a 5-inch 1080p display looks a bit pixelated, and you certainly get to see a lot more details than you usually would. While these devices boast high pixel density displays, the <a href="https://www.toptal.com/designers/ui/the-industry-could-do-without-pixel-density-and-ppi-marketing" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">real metric to have in mind is PPD rather than PPI</a>.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This basically means the user gets to <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">see more</em> than you’d expect given the resolution, which means 3D models and textures need to be optimised for a wider field of view. For example, a few low resolution textures won’t ruin the appearance of 3D model on a 5-inch phone. It can still look good because of the small size of the display, but once you put the same phone in a VR headset, you’ll get to see all sorts of compression artefacts and other nasty stuff. If an object looks good on a phone with even with a low LOD, that doesn’t necessarily mean it will look good in VR; it might need more complex geometry and textures. It’s not <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">solely the resolution</em>, please keep that in mind.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Lastly, motion sickness and nausea remain a concern. One of main causes is lag. It takes a tiny amount of time for the phone’s gyro sensor to figure out the user is moving, and then it takes a bit more time for the phone to crunch the numbers and render the subsequent frame while taking the motion into account. If, for any reason, something goes wrong and you drop a few frames or experience stuttering, the VR illusion will break down right before your eyes. This process should be fast and automated to such an extent that the user has no idea what’s going on behind the scenes.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, this is easier said than done in complex, heavily subdivided 3D scenes with huge textures. A standard phone will struggle with photorealistic graphics even when it’s not overheating, so trying to get a phone to render smooth, photorealistic 3D graphics is not a viable option at this time. In addition, a number of effects and features that could help improve the visual experience are not available. Sure, motion blur, depth of field effects, high-quality antialiasing and other techniques would help, but they’re still not an option on mobile devices.</div>
<h2 id="google-cardboard-for-developers-opportunity-or-waste-of-time" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Cardboard For Developers: Opportunity Or Waste Of Time?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So, Google Cardboard is not perfect, it suffers from a few teething problems, lack of content, lack of users, and lack of developer interest. By now, a lot of you must be wondering why I am convinced Google Cardboard has potential. After all, I listed a number of real and potential problems hampering mass adoption.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Why bother with Google Cardboard?</em></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s a legitimate question, and considering the size of the user base, coming up with a good answer is not simple. This is still a very tight niche, and even if you manage to come up with a great idea and execute it flawlessly, you won’t make much of a difference (or much money, for that matter). The limited number of people interested in VR is a huge problem.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This lack of interest becomes obvious as soon as you start browsing the Play Store for VR content. There aren’t that many Google Cardboard apps around, and I can confidently report that most of them suck. If you don’t believe me, just check out the user reviews. In fact, many of these apps aren’t <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">real</em> apps; they’re tech demos.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Did <a href="https://www.toptal.com/android" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Android developers</a> drop the ball? Not really. A lot of these subpar apps are clearly a work in progress, or they are pet projects that allowed individual developers to play around with VR. Very few apps come from big publishers and this is understandable; with such a small user base, nobody can afford to burn thousands of man-hours to create an app that won’t turn a profit. Oddly enough, this could be good news. If you are confident you can do a better job, go for it. There’s not a lot of competition, and if you create something good, your product will definitely stand out.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Not all Google Cardboard apps are bad, so you could try out a few quality designs to get a sense of what makes them tick. I usually don’t list products and services in my blog posts, but I will go ahead with a few examples of promising Google Cardboard apps:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://play.google.com/store/apps/details?id=com.jauntvr.android.player.cardboard" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Jaunt VR</a></span> is a highly acclaimed VR platform with one of the best user review scores of any VR app on the Play Store. Jaunt is a relatively big player in the small VR ecosystem and has a number of good products. I’d direct your attention to the UI layout and the quality of the content itself.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">YouTube and Google Maps</span> are an obvious choice, and happen to be the only Google core apps with Cardboard functionality. They will give you a chance to check out how Google does stuff, although I was not too impressed. Don’t underestimate the power of YouTube. If a lot of VR content is uploaded, it could tip the scales in Google’s favour.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://play.google.com/store/apps/details?id=in.fulldive.shell" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Fulldive</a></span> is an ambitious app with loads of features. You can use it to view panoramic photos, watch local and YouTube videos, take VR photos and more. There are a number of similar apps out there, but I feel the Fulldive team did a better job in the UI department. The UI is clean, fast and intuitive.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://play.google.com/store/apps/details?id=air.com.ercangigi.sitesin3d" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Sites in VR</a></span> is a different sort of app and I think it’s a good showcase of what might be achieved by an individual developer. The app allows users to experience a number of different VR sites, ranging from the lunar surface to the Eiffel Tower, plus some good-looking examples of Islamic architecture. I appreciated the ability to tweak settings that aren’t available in most VR apps.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">VR Roller Coaster</span> is a good example of 3D VR, and the name is self-explanatory; roller coasters are a popular theme in VR apps. In addition, the same concept is used to create a VR tour of the Solar System. <a href="https://play.google.com/store/apps/details?id=com.drashvr.titansofspacecb&hl=en_GB" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Titans Of Space</a> and <a href="https://play.google.com/store/apps/details?id=com.Cosmic.rollercoaster&hl=en" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">VR Cosmic Roller Coaster</a> are good examples of this approach.</div>
</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><div style="border: 0px; box-sizing: border-box; font-size: 1em; line-height: 1.5em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://play.google.com/store/apps/details?id=com.nexus.VRscene" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Shadowgun VR</a></span> and <span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><a href="https://play.google.com/store/apps/details?id=com.otherworld.Sisters" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Sisters</a></span> are nice examples of VR games; the latter is spooky, if you’re into that sort of thing.</div>
</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
We intend to publish more content dealing with the finer points of VR design and development, so if you are interested in this emerging field, be sure to tune in from time to time.</div>
<h2 id="the-elephant-in-the-living-room" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The Elephant In The Living Room</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s bad for SEO, talking about it is bad for tech publications in general, and it might not go down well with some of our team members or redears, but I have to get it out of the way. So what is <em style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">it</em>?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Pornography.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="The adult entertainment industry played a pivotal role in the adoption of legacy video standards. Can it boost VR adoption as well?" src="https://assets.toptal.io/uploads/blog/image/91991/toptal-blog-image-1453451498356-f0190fcd4b7c6d004c87ade997288f4f.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div class="pop_out_box is-full_width is-big" style="background: rgb(250, 250, 250); border: 0px; box-sizing: border-box; color: #505050; float: none; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.3em; line-height: 1.5em; margin: 0px 30px 15px 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 1em 1.5em; vertical-align: baseline; width: 828px;">
The adult entertainment industry played a pivotal role in the adoption of legacy video standards. Can it boost VR adoption as well?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There, I said it. And no, I wasn’t joking.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The adult entertainment industry was instrumental in the adoption of multiple video standards, from VHS over Beta, to Blu-Ray over HD DVD. Granted, these were physical storage standards, but they were around when physical storage mattered a lot more than today. Nowadays, content distribution is digital, on-demand and fast. Best of all, the same content can be distributed across multiple platforms with relative ease.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The adult industry played a pivotal role in the mass adoption of major content standards for decades. It can do it again, albeit not through physical standards. It can obviously make a big difference by generating demand for all sorts of VR devices. Google Cardboard looks like an obvious candidate for VR content distribution on the cheap, and it will undoubtedly be the first glimpse of VR for millions of users.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Does anyone doubt the adult entertainment industry will attract millions upon millions more? For many people, that first glimpse of VR could be described as NSFW.</div>
<h2 id="virtual-world-of-potential" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Virtual World Of Potential</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Cardboard is a good step toward mass adoption of VR. It’s not without its problems, but we can’t expect miracles this early on, especially not from the cheapest VR platform on the market.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But that’s sort of the beauty of it: It’s cheap and disposable, yet it’s upgradeable. You can get a better headset if you feel like you need one, and the occasional phone upgrade should take care of the actual hardware behind it. One could potentially repurpose old phones as well, provided they sport the necessary sensors and hardware.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Despite my optimism, Google Cardboard isn’t a very popular platform and I don’t think anyone expects it to become one in the immediate future. However, in the long run, I am confident it will attract a lot more users, and not just geeks. As always, mainstream users are the Holy Grail, and I can report that non-geeks are even more impressed by the Google Cardboard experience than tech savvy people.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It all boils down to content. There’s not enough VR content out there, use-cases are limited, and there’s not a lot of urgency to get involved. However, moving forward we are bound to see a lot more VR video, along with other types of content. As soon as we see more VR content being churned out, we will see more adoption. I suspect many people will choose to try out VR over the next couple of years, and once VR starts gaining mainstream traction, price will become even more relevant.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In a mass adoption context, the fact that people can enjoy Cardboard VR for the price of a decent lunch could make Google’s “no frills” VR concept a lot more attractive in no time.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The article was written by<span style="color: #929292; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; letter-spacing: 0.13px; line-height: 19px; text-transform: uppercase;"> </span><span style="border: 0px; box-sizing: border-box; color: #3976cb; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: 600; letter-spacing: 0.13px; line-height: 19px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-transform: uppercase; vertical-align: baseline;"><a class="link is-blue" href="https://www.toptal.com/blog" style="border: 0px; box-sizing: border-box; color: #3863a0; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;" target="_blank">NERMIN HAJDARBEGOVIC</a>, </span><span style="font-size: 19.2px; line-height: 28.8px;">a <a href="https://www.toptal.com/virtual-reality/google-cardboard-vr">Toptal</a> </span><a href="https://www.toptal.com/developers/all" style="font-size: 19.2px; line-height: 28.8px;">developer</a><span style="font-size: 19.2px; line-height: 28.8px;">.</span></div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-34277142491609974632016-05-11T07:46:00.000-07:002016-05-11T07:46:25.254-07:00Nvidia Shield - A Different Take On Android Gaming Consoles<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia surprised many industry observers with the launch of the Shield Android gaming console at the Game Developers Conference in San Francisco, but describing it as a mere Android console might not be the right thing to do.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="http://shield.nvidia.com/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Shield</a> is a powerful piece of hardware, with Nvidia’s custom 64-bit Denver CPU cores and 256 GPU cores, based on the company’s latest Maxwell infrastructure. While Nvidia describes the Tegra X1 System-on-Chip (SoC) as a “mobile superchip with the soul of a console,” it still can’t go up against the latest consoles from Sony and Microsoft. However, the Tegra X1 is roughly on a par with previous generation PlayStation and Xbox hardware.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Nvidia Shield and Android gaming" src="https://assets.toptal.io/uploads/blog/image/939/toptal-blog-image-1425990659379.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So, will this give <a href="https://www.toptal.com/android" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Android game developers</a> more headroom to develop better looking games and bring them to the living room in 4K/UHD resolutions? Yes, that is one possibility, but Shield is not about bringing expensive AAA titles to Android.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In fact, Nvidia’s first few Shield products were all about <a href="http://shield.nvidia.com/grid-game-streaming" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">streaming PC games onto Android</a> devices. They can be viewed as test beds at this point, with streaming capabilities as a differentiator in the oversaturated Android hardware market.</div>
<h2 id="android-gaming-consoles-dead-on-arrival" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Android Gaming Consoles Dead On Arrival</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
First we need to take a look at the history of Android’s gaming console successes and failures, then examine the cost of developing Android games that could benefit from more powerful hardware. Nvidia Shield could end up boosting, or killing, some aspects of Android game development, and chances are it will do both.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Speaking of kickstarting, a few years ago a group of entrepreneurs launched a Kickstarter project to create the OUYA Android gaming console, which was, coincidentally, based on Nvidia hardware. A lot of people like the idea of a $99 Android console, investments poured in, but the end result was a flop. Last year <a href="http://www.forbes.com/sites/erikkain/2014/03/07/hit-kickstarter-video-game-console-ouya-is-basically-dead/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Forbes</a>proclaimed the OUYA dead – the console never had a big enough user base, so developers didn’t bother with it. There was no money to be made.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia Shield gaming tablet costs twice as much ($199 MSRP), but as an Nvidia product, it should be more appealing to Android developers. So this should help, right?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Wrong.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Very few Android developers focus on graphically intensive titles. They require a lot more resources, they don’t look as good as proper console or PC games, they’re not great for touch input, and, with a lot of eye candy, they can drain a smartphone or tablet battery in no time. The biggest games on Android and, indeed, all mobile platforms, are casual games, not so-called “AAA” titles. Rovio and King did not make a fortune developing elaborate games with photorealistic graphics, they focused on casual games that could be played on practically any smartphone. These games didn’t put much strain on the SoC and the battery, so you could kill some time without killing your mobile phone.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Throttling is another problem. Mobile phones and tablets don’t dissipate heat well, so while they can deliver great performance on paper, if they’re forced to run under a load for extended periods of time, the SoC will throttle back and operate on lower clocks to stay within its thermal envelope, thus degrading performance.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Android gaming and throttling" src="https://assets.toptal.io/uploads/blog/image/940/toptal-blog-image-1425990697610.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Android gaming consoles and set-top boxes don’t suffer from these shortcomings since they don’t rely on battery power and can be designed to dissipate a lot more heat due to their bigger form.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, that does not mean Android developers will flock to create games for them; the user base is so small that developers could not make their money back since developing good-looking shooters and action games requires more resources than creating casual games like Flappy Bird. On the other hand, recent research indicates that more than 200 Android games are published each day. Most of these titles never gain any significant traction, as the market is overcrowded. With that in mind, trying to move into Android TV or Android consoles could make sense for some developers.</div>
<h2 id="so-whats-nvidias-endgame" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So What’s Nvidia’s Endgame?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia is fully aware of this problem, as are other hardware makers. That is why we don’t have a lot of Android gaming consoles and why most big brands have steered clear of them. The business model does not make much sense, either. Sony and Microsoft don’t make a lot of money on hardware, in fact at launch they tend to sell new consoles below cost, since they control the ecosystem and make money on games rather than consoles. This obviously does not, and cannot, apply to Android.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, Nvidia thinks it has cracked this problem. Why bother developing AAA games for Android when you can use PC titles instead? Why render the content locally on the device if you can stream it? Why try to make money on hardware if you can make it on services? It may sounds like a bit of a moon-shot, but Nvidia is confident that it will work and likens GRID Game Streaming to Netflix for games.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What does this mean for Nvidia Shield’s gaming tablet, Android developers and consumers?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia Shield could allow the company to mimic Sony’s and Microsoft’s approach, by making money on games rather than hardware, but with a twist: by offering Gaming as a Service (GaaS).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s see how this approach helps the company:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Ecosystem</span> — Nvidia would be able to control the ecosystem by supporting select games, creating a walled garden.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Hardware</span> — The games would be rendered solely on Nvidia GRID servers, so the company could eventually become its own biggest hardware customer.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Longevity</span> — As long as the consumer has hardware capable of streaming GRID content, there will be no need to upgrade it – Nvidia would do it on the server side, using more of its own hardware.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Efficiency</span> — Instead of marketing expensive graphics cards, Nvidia could sell processing power and utilize installed hardware more efficiently than individual consumers.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Piracy</span> — There is no risk of piracy, which should appeal to publishers.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Consumers also stand to benefit from GRID streaming, but there are some drawbacks as well:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Convenience</span> — Consumers would no longer have to bother with upgrades, patches, updates and drivers.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Value</span> — instead of buying an expensive gaming PC and upgrading it on a regular basis, consumers would be able to pay as they go.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Choice</span> — Lack of choice might be a problem, as Nvidia will only stream select titles, so consumers interested in niche games and genres probably would not be catered to, at least, not initially.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Geography</span> — GRID services would not be available globally, and servers need to be in close proximity to the client in order to keep latency down.</li>
</ul>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
As for Android developers, Nvidia Shield is a mixed bag to say the least. There are some potential benefits, but it’s not all good news:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Power</span> — If the concept takes off, Android developers would finally have some more powerful hardware to play with, on a bigger install base.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">TV</span> — Shield is all about bringing Android to the living room in 4K, so developers could also create applications specifically designed for this purpose (just in time for next generation smart TVs).</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Exposure</span> — Focusing on console and TV could give developers more exposure than the oversaturated mobile Android segment.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">AAA</span> — If successful, Nvidia’s initiative could make high-budget Android games even less viable, and they’re already not profitable for most publishers.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; box-sizing: border-box; font-weight: 600; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Enterprise</span> — Nvidia has already partnered with <a href="http://www.nvidia.com/object/vmware-vgpu-direct-access.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">VMware</a>, so in the long run Android could be employed for enterprise as well, but this is a hypothetical scenario and would take some time to become viable.</li>
</ul>
<div class="embeddable_form-wrapper for-post" data-role="blog_subscribe" data-view="blog_subscribe#form" style="background-color: white; border-radius: 6px; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 15px; line-height: 20px; margin: 0px; min-height: 0px; min-width: 0px; padding: 30px 0px; vertical-align: baseline;">
<form action="https://www.toptal.com/blog/subscription" class="embeddable_form" data-entity="blog_subscription" data-remote="" data-view="form#form" method="post" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-step is-email_form is-current" style="border: 0px; box-sizing: border-box; display: flex; flex-wrap: wrap; height: auto; margin: 0px; min-height: 0px; min-width: 0px; overflow: visible; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Like what you're reading?</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Get the latest updates first.</div>
</div>
<div class="embeddable_form-row form-field is-email_field" style="border: 0px; box-sizing: border-box; flex-basis: 100%; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<input autocomplete="off" class="input is-medium" data-role="email" name="blog_subscription[email]" placeholder="Enter your email address..." style="-webkit-appearance: none; background: rgb(250, 250, 250); border-radius: 4px; border: 1px solid rgb(238, 238, 238); color: #3c3c3c; font-family: proxima-nova, Arial, sans-serif; font-size: 14px; margin-bottom: 0px; margin-top: 0px; padding: 15px 12px; transition: all 0.2s; width: 864px;" type="text" /></div>
<div class="embeddable_form-row is-submit" style="-webkit-box-flex: 1; -webkit-box-ordinal-group: 4; border: 0px; box-sizing: border-box; flex-grow: 1; margin: 0px; min-height: 0px; min-width: 0px; order: 3; padding: 0px; position: relative; vertical-align: baseline;">
<input class="button is-green_candy is-default is-full_width" data-loader-text="Subscribing..." data-role="submit" style="-webkit-appearance: none; background-attachment: initial; background-clip: initial; background-image: linear-gradient(rgb(67, 198, 146), rgb(57, 184, 133)); background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-radius: 4px; border: 1px solid rgb(31, 124, 87); box-shadow: rgb(79, 211, 170) 0px 1px inset; color: white; cursor: pointer; font-size: 14px; font-weight: 600; padding: 15px 20px; position: relative; text-shadow: rgb(28, 143, 61) 0px 1px 0px; transition: background 150ms; width: 552.672px;" type="submit" value="Get Exclusive Updates" /></div>
<div class="embeddable_form-row is-privacy" style="border: 0px; box-sizing: border-box; margin: 0px 20px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline;">
<div class="embeddable_form-privacy" style="-webkit-box-align: center; align-items: center; border: 0px; box-sizing: border-box; color: #9a9a9a; display: flex; font-size: 12px; line-height: 50px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-privacy_icon" style="background: url("data:image/png; border: 0px; box-sizing: border-box; display: inline-block; flex-shrink: 0; height: 11.5px; margin: 0px 15px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; top: -2px; vertical-align: baseline; width: 9.5px;">
</div>
<div class="embeddable_form-privacy_text" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
No spam. Just great engineering and design posts.</div>
</div>
</div>
</div>
<div class="embeddable_form-step is-confirmation" data-place="@blog_subscribe" data-role="confirmation" style="border: 0px; box-sizing: border-box; height: 0px; margin: 0px; min-height: 0px; min-width: 0px; overflow: hidden; padding: 0px; vertical-align: baseline;">
<div class="embeddable_form-row is-label is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label_title" style="border: 0px; box-sizing: border-box; color: #2557a1; display: inline-block; font-size: 17px; font-weight: 700; line-height: 23px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px 0px 10px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<div class="embeddable_form-label is-header" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
</div>
<div class="embeddable_form-label" style="border: 0px; box-sizing: border-box; color: #313131; display: inline-block; font-size: 17px; font-style: italic; line-height: 19px; margin: 0px 10px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a data-role="preferences_link" href="https://www.toptal.com/android/nvidia-shield-a-different-take-on-android-gaming#" style="border: 0px; box-sizing: border-box; color: #3976cb; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;"></a></div>
</div>
<div class="embeddable_form-row is-success" style="border: 0px; box-sizing: border-box; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; vertical-align: baseline; width: 864px;">
<ul class="social_share is-horizontal is-loaded" data-rss-url="https://www.toptal.com/blog.rss" data-twitter-username="@toptalllc" data-url="https://www.toptal.com/blog" data-view="layout#social_share" data-youtube-channel-url="https://www.youtube.com/channel/UCNqm_euTHZz3o5OnKhUS-oA" style="-webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: start; border: 0px; box-sizing: border-box; display: flex; flex-direction: row; font-size: 1.2em; justify-content: flex-start; list-style: none; margin: 0px; max-width: 300px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li class="social_share-item is-counter" style="background-color: #3863a0; border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-radius: 4px 0px 0px 4px; border-right-color: rgb(56, 99, 160) !important; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; color: white; flex-shrink: 0; height: 50px; line-height: 15px; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 10px 0px; position: relative; text-align: center; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;" title="Total number of shares"><span class="social_share-item_num" data-role="counter_num" style="border: 0px; box-sizing: border-box; display: block; font-size: 14px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; transition: opacity 0.3s; vertical-align: baseline;"></span><span class="social_share-item_text" data-role="counter_text" style="border: 0px; box-sizing: border-box; display: block; font-size: 9px; margin: 0px; min-height: 0px; min-width: 0px; opacity: 1; padding: 0px; text-transform: uppercase; transition: opacity 0.3s; vertical-align: baseline;"></span></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="facebook" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Facebook"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/facebook_dc66c9.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-bottom-color: rgb(236, 236, 236); border-bottom-style: solid; border-left-color: rgb(236, 236, 236); border-left-style: solid; border-top-color: rgb(236, 236, 236); border-top-style: solid; border-width: 1px 0px 1px 1px; box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0.75em; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="google_plus" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Share on Google Plus"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/google_plus_355fb0.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
<li class="social_share-item" style="border-radius: 0px 4px 4px 0px; border: 1px solid rgb(236, 236, 236); box-sizing: border-box; flex-shrink: 0; height: 50px; line-height: 1.5em; list-style-type: disc; margin-bottom: 0px; margin-left: 30px; margin-right: 0px !important; margin-top: 0px !important; min-height: 0px; min-width: 0px; padding: 0px; text-shadow: rgba(0, 0, 0, 0.498039) 0px 1px 2px; transition: box-shadow 0.2s; vertical-align: baseline; width: 50px;"><a class="social_share-item_link" data-role="link" data-type="twitter_follow" href="https://www.blogger.com/null" style="border: 0px; box-sizing: border-box; color: #3976cb; cursor: pointer; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" title="Follow Toptal on Twitter"><img class="social_share-item_image" height="50" src="https://assets.toptal.io/assets/front/static/public/primitives/social/share_bar/twitter_83c6d4.png" style="border: 0px; box-sizing: border-box; display: block; height: 50px; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline; width: 50px;" width="50" /></a></li>
</ul>
</div>
</div>
</form>
</div>
<h2 id="how-nvidia-shield-works" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
How Nvidia Shield Works</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
I won’t waste much time explaining the finer points of Nvidia’s GRID technology, but in case you are not familiar with the concept, a brief summary should come in handy. If you are interested in the finer point of GRID and GRID SDKs, Nvidia’s official documentation is extensive and available online.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="" src="https://assets.toptal.io/uploads/blog/image/941/toptal-blog-image-1425990739411.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A GRID server essentially operates like a remote vGPU, or a virtual gaming machine. The client side provides the input via graphic commands, which are then handled by the host interface and rendered on low-latency hardware. The frame buffer is then encoded on a low latency hardware decoder and sent back to the client in the form of a compressed video stream.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The original spec called for H.264 video, but the latest iteration of Nvidia’s SoCs, the <a href="https://developer.nvidia.com/content/tegra-x1" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Tegra X1</a>, supports 4K H.265 (HEVC) at 60fps. This means the stream can be stutter-free and allow fluent framerates.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What about latency?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is, perhaps, the biggest problem facing Nvidia GRID, and cloud gaming in general. Streaming video from the cloud is one thing, but rendering original audio and video content, based on user input, is something else. High latencies are not something gamers can live with; online multiplayer gaming has been around for years and Nvidia put a lot of time and effort into resolving the problem.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="How Nvidia Shield Works" src="https://assets.toptal.io/uploads/blog/image/943/toptal-blog-image-1425991896199.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia estimates server-side latency at 30ms, network latency at 30ms and client-side latency at less than 16ms. The client decode API is designed for low latency of about 1 frame. Nvidia’s plan is to deploy dedicated GRID servers in telecom data centres and “flood the map” with servers to cut down latency. The company also designed partner middleware solutions on Amazon Web Services (AWS).</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia has done a lot to create an infrastructure, but it may be a while before all corners of the globe gain access to low-latency GRID services.</div>
<h2 id="where-does-nvidia-shield-leave-android-developers" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Where Does Nvidia Shield Leave Android Developers?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia’s gaming tablet approach offers a few opportunities, and downsides, for Android developers. Big developers focused on creating the Android equivalent of big-budget AAA games could face more competitive pressure from Nvidia GRID, which can offer vastly superior quality at a premium.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, small or independent developers focused on casual games and other apps have nothing to worry about. To the contrary, Nvidia is opening another door, in this case the door to the living room and big high-def screens. Coupled with H.265 and VP9 capabilities, Shield offers a range of opportunities, but ultimately it is up to developers to create a new generation of killer apps for 4K TVs, be it on Shield or Android TV.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="Nvidia GRID" src="https://assets.toptal.io/uploads/blog/image/942/toptal-blog-image-1425990777409.jpg" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Coincidentally, Taiwan-based chipmaker, MediaTek, will <a href="http://www.mediatek.com/en/news-events/mediatek-news/mediatek-enables-the-worlds-first-ultra-hd-tv-powered-by-android-tv-software-in-collaboration-with-google/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">provide SoCs for the first generation of Android TVs</a>, and the first chip was announced at CES 2015, just like the Tegra X1. MediaTek’s MT5595 SoC is based on 32-bit Cortex-A17 and Cortex-A7 cores, but its GPU can still handle HEVC and VP9 and 60fps, just like the Tegra X1. Android TV is a different topic, and I do not wish to discuss it in depth, but there is clearly a lot of overlap as far as developers are concerned.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Developing Android applications for big 4K/UHD displays is the next big thing, while Android Wear is, literally, the next small thing.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
While it may sound like another challenge and another hardware platform to master, don’t forget to consider the benefits of developing apps designed specifically for the living room, for Android TV and devices like Nvidia’s Shield:</div>
<ul style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 20px; list-style: none; margin: 0px 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Fewer software and hardware platforms to take into account.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">More powerful hardware available.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Power efficiency is a non-issue.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">You only have to deal with one aspect ratio.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Apps will be designed to run in just two resolutions (UHD and FHD).</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">UI layout will be more or less standardised.</li>
<li style="border: 0px; box-sizing: border-box; line-height: 1.5em; list-style-type: disc; margin: 0px 0px 0.75em 30px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">User experience should be nearly identical across a number of different products.</li>
</ul>
<h2 id="alternative-applications" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Alternative Applications</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So far, I have talked about Nvidia’s foray into the living room, but what about other potential applications? With so much processing power available on demand via GRID, surely there has to be a way to use it for something other than games?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This is a tricky one and I can only speculate, but a few things are already clear. Gaming is just one aspect of Nvidia’s parallel computing efforts – enterprise virtualisation is another, although it does not have much to do with Android, or the living room.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Devices like Nvidia Shield, or upcoming Android TV sets, could serve as a hub for many other devices, expanding the abilities of our smartphones to double as smart remote controls, transforming cheap tablets with fast wireless into “second screens”, offering new ways to distribute and consume content.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Shield stands out by virtue of its streaming capabilities and impressive processing power, including powerful and programmable CUDA cores that can be put to use for things other than graphics. Nvidia has already demonstrated that even its mobile GPUs, used in the latest Tegra chips, can be utilized to create 3D maps of surroundings, do rudimentary motion tracking and more. This means that in the future, Android devices could offer Kinect-like capabilities, seamlessly integrated with other Android devices. How about interactive fitness routines in the living room, backed by motion tracking and fitness wearables? Or games designed solely for big screen TVs, smart home control hubs, or new Virtual Reality (VR) capabilities?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
VR and Augmented Reality (AR) might also benefit from such devices, and especially from Nvidia’s GRID technology. Google is also said to be working on Android VR, which will join Android Wear, Android TV and Android Auto in the future, but details are still sketchy. (I discussed the potential applications of <a href="https://www.toptal.com/virtual-reality/microsoft-hololens-bridging-the-gap-between-ar-and-vr" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">streaming on VR and AR headsets in a previous post</a>.) In the meantime, a number of companies have announced new or updated VR products and technologies, and all this happened in a matter of weeks at the Mobile World Congress in Barcelona and the Game Developers Conference in San Francisco. Valve, Samsung, and AMD are just some of the big names worth mentioning.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But if Nvidia Shield could use streaming on home consoles, either via GRID or locally, why not use it on mobile devices as well? It sounds like a match made in heaven, with most of the computing being done in the cloud, offloading mobile devices for other tasks and improving battery life in the process.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Unfortunately this is not practical at this point. Few people would need access to such processing power on their mobile devices, which are already good enough for casual gaming, and even for some titles with truly staggering graphics. Bandwidth and latency would be another problem, as 4G/LTE is still not widely available across the world and in some scenarios it would not be fast enough. In addition, modern integrated modems are relatively complex; they often take up more room on the SoC than the GPU, or all CPU cores combined. Besides, running the modem at full blast, and crunching all the numbers to decode and display high resolution content, is not good from an efficiency perspective and would inevitably take a big toll on battery life.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In theory, it would be possible to use the same approach for some enterprise applications built around the same infrastructure, or for niche devices that could be used in some industries; but all this is a long way off, and such proprietary technologies should not concern the average Android developer, anyway.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So what should Android developers interested in Nvidia Shield gaming tablets, streaming, and Android TV, focus on? It is hard to say at this point, but the potential market for a new generation living room apps is huge and should not be overlooked. Who knows, maybe our posts will motivate some of our readers to look into this emerging market and come up with the next killer app, in which case I just want you to know one thing: a bottle of Blue Label would be nice.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<br /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The original article is from <a href="https://www.toptal.com/android/nvidia-shield-a-different-take-on-android-gaming">Toptal</a>. Find more gaming resources <a href="https://www.toptal.com/game">here</a>.</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-68510567622167244032016-05-02T23:59:00.000-07:002016-05-02T23:59:11.338-07:00Microsoft HoloLens Review - Bridging The Gap Between AR And VR<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft has a long tradition of spicing up relatively dull product announcements with compelling tech demos, and the Windows 10 announcement was no exception. The software giant used the opportunity to create a fair amount of buzz about the HoloLens, a futuristic headset that offers a glimpse into the future of Augmented Reality (AR). However, Microsoft also has a tradition of spectacular hardware flops, which peaked under the Ballmer regime. Remember the Kin phone? Neither do I.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The introduction of <a href="http://www.microsoft.com/microsoft-hololens/en-us" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">HoloLens</a> probably won’t be such a flop for a number of reasons. First of all, the HoloLens still has a long way to go before it becomes a commercially viable device - it could be about a few quarters, or a couple of years. Secondly, the concept behind it is sound, and builds on a few promising emerging industry trends, such as wearable tech and Virtual Reality (VR) headsets. The HoloLens is trying to be somewhat different by bundling a lot of functionality into a single device, but in this Microsoft HoloLens review we will take a look at what’s already out there and what is in the works.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<img alt="microsoft hololens and VR" src="https://assets.toptal.io/uploads/blog/image/809/toptal-blog-image-1422624228687.png" style="border: 0px; box-sizing: border-box; display: block; margin: 0px auto 7px; max-width: 100%; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" /></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Since this is an engineering blog designed for <a href="https://www.toptal.com/virtual-reality" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">VR professionals</a> and other engineers, I won’t spend much time answering the question “What is HoloLens?” and explaining the difference between AR and VR. Augmented reality technology has a range of potential applications in various industries, but limited applications in entertainment. Virtual reality is more geared towards entertainment, although it has some professional applications as well.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Both technologies still have a lot of limitations, and numerous technical challenges have to be overcome in order to gain mass market appeal. This is a gradual process that will take years rather than months. The technology needed to create such products without breaking the bank is simply not ready, but it’s slowly getting there.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Let’s take a look at what’s out there and what’s missing.</div>
<h2 id="hardware-limitations---google-glass-vs-oculus-rift-vs-microsoft-hololens" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Hardware Limitations - Google Glass vs. Oculus Rift vs. Microsoft HoloLens</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Glass was announced in early 2012 and started shipping a year later at a cost of $1,500. The high price tag meant it was reserved for a very small niche – early adopters described as “explorers” by Google’s PR and marketing machine. The device offered limited AR functionality, and contained a small prism projector with a resolution of 640x360 pixels, powered by an outdated processor.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
While it managed to captivate the public for a while, Google Glass can hardly be described as a success. App developers who were keen to jump on the bandwagon started losing interest, along with “explorers” who appeared to get over the fad in a matter of months. The latest rumours point to a new version of Google Glass with Intel silicon inside, so it might be a bit too early for an obituary. Either way, Google Glass was not a big success no matter how you look at it.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Oculus Rift is perhaps the most talked about VR system at the moment, but unlike Google Glass, it has yet to launch. Oculus VR has been working on the device for years, and in the process the company went through two generations of development kits. The consumer version is expected to launch sometime in 2015, with a revised spec. In March 2014, Oculus VR was bought by Facebook for more than $2bn in cash and Facebook stock.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<a href="http://www.samsung.com/global/microsite/gearvr/gearvr_specs.html" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Samsung’s Gear VR</a> offers a different approach, as it utilises the Galaxy Note 4 phablet in lieu of a built-in screen, but it relies on some technology developed by Oculus. I find the modular concept interesting, as a similar approach could be employed with a range of mobile devices from different vendors that would allow users to effectively upgrade hardware every time they got a new phone. Qualcomm’s <a href="https://www.qualcomm.com/products/vuforia" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Vuforia</a> platform boasts some promising features for mobile devices and potential AR/VR applications.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So, what’s missing? The simple answer might be processing power, but it’s a bit more complicated than that.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The problem with both concepts is that they are still ahead of their time, and the technology still needs to catch up. Microsoft’s HoloLens is bound to suffer from the same teething problems, but Microsoft’s concept is somewhat different, and therefore stands a chance of overcoming at least some of these issues.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Google Glass was designed as a lightweight wearable, which resulted in a number of compromises. The device featured a single display on a thick prism in front of the user’s right eye. The resolution was very limited given the field of view (FOV). For example, smartwatch displays tend to feature similar vertical resolutions for a device that takes up just a couple of degrees of the user’s field of view. Google Glass was based on an antiquated System on Chip (SoC) and had limited battery life.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Designing mobile devices is not easy, and always involves a number of trade-offs. Higher resolution displays require more GPU power, necessitating the use of bigger SoCs with more powerful GPUs working at a higher load, which then requires a larger battery and so on. It’s a fine balancing act, and an AR headset is simply too small to accommodate a large battery like those used in high-resolution tablets.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
At first glance, Oculus Rift does not appear to suffer from similar shortcomings on the hardware front, since it does not have compromises for the sake of battery life and portability. It does not rely on an integrated SoC, and a 1080p display sounds desirable; but, in reality it’s not nearly enough for photorealism. The device has a very large FOV, and pixel density is still insufficient.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
To overcome this problem, VR devices would have to use higher resolution 4K/UHD displays, or even 8K displays at some point in the future. The technology is almost there, but it does not come cheap, and is anything but portable.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If you want to run the latest AAA games on a 4K display with the highest possible detail settings, you need two high-end discrete graphics cards. For example, Nvidia and AMD cards based on flagship Maxwell and Hawaii generation GPUs. To eliminate frame tearing (using technologies similar to Nvidia’s G-Sync or AMD’s FreeSync) you need a bit more power, and to do proper 3D for both eyes you need even more GPU power.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The bottom line is: to power a 4K VR device using currently available technology, you would need at least two GPUs with a total of 12-14bn transistors in 28nm, consuming 350W to 500W of power, not counting the CPU and rest of the system. This is a conservative estimate, based on currently available GPU and CPUs - and let’s not even discuss the idea of powering two 4K screens, one per eye.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Nvidia’s latest mobile SoC, the Tegra K1 64-bit used in the Google Nexus 9, features 192 CUDA cores based on Kepler architecture, not the more efficient Maxwell. The company’s current flagship discrete graphics cards sport 2048 Maxwell CUDA cores running at higher clocks than Kepler cores in mobile Tegra SoCs.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Portable VR devices with photorealistic graphics are clearly unavailable for years to come, and even wired devices like Oculus Rift have a long way to go. The overall platform cost is another concern. Gaming PCs capable of pumping out playable frame rates at 1080p are relatively cheap, since mainstream GPUs are fast enough to do the job. But at 2160p you need four times the GPU muscle, backed by more memory and a faster CPU.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is another way of tackling this problem, and I will go over it later.</div>
<h2 id="so-what-did-microsoft-get-right" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
So What Did Microsoft Get Right?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Remember <a href="https://www.toptal.com/oculus-rift/toptal-and-facebook-creating-a-global-virtual-office" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">Facebook’s Oculus Rift</a> deal I mentioned earlier? Just a few days after it was announced, it emerged that Microsoft bought intellectual property (IP) assets related to augmented reality and wearable computers from the <a href="http://techcrunch.com/2014/03/27/microsoft-paid-up-to-150m-to-buy-wearable-computing-ip-from-the-osterhout-design-group/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Osterhout Design Group</a> (ODG). Some of the patents covered “see-through near-eye display glasses” with a partially transmitting optical element.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
In other words, Microsoft bought the IP needed to create HoloLens; and the deal reportedly covered dozens of ODG patents, including a few dozen more patent applications in progress. Meanwhile, Oculus VR is said to have just a single patent, which vaguely describes “a virtual reality headset”.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft appears to be trying to get the best of both worlds – a wide FOV usually associated with VR devices, and a transparent display surface suitable for AR applications. The approach should allow HoloLens to utilize a lot less processing power than VR devices, while at the same time offering more functionality thanks to the wide FOV. Instead of trying to render photorealistic content, HoloLens could get away with a slightly lower resolution and image quality due to the limited opacity of displayed content. There is no need to create an illusion of reality, so there is a lot less hardware overhead involved. A lot of off-the-shelf technology could allow the HoloLens to reduce or eliminate aliasing and generate good looking composites, since the backdrop is already there.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This fact limits HoloLens’ appeal in the entertainment niche, as opposed to true VR headsets; but, it opens up a number of possibilities in other industries, ranging from engineering and healthcare to architecture and defense. HoloLens could be used to assist healthcare professionals, engineers, operators of industrial machinery, soldiers, and law enforcement.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, HoloLens still has applications in the consumer space. Microsoft’s Phil Spencer said HoloLens needs to be a successful standalone product, adding that the company is already looking into ways of using it in unison with PCs and Xbox One consoles. The device could serve as a heads up display (HUD) for gamers, or even for fitness buffs in gyms.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
<span style="color: #3863a0; line-height: 1.3em;"><b><span style="font-size: large;">HoloLens Hardware Conundrum</span></b></span></div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft has not revealed the exact hardware specifications, so we still don’t quite know what to expect. There is no word about display resolution, GPU GFLOPs, connectivity, or battery life. This leaves a lot of room for speculation, which the tech press is happy to fill with column inches and clickbait, but nothing is official yet.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Like I said, HoloLens should not require nearly as much GPU power as the Oculus Rift and similar VR products. However, this does not mean that Microsoft can get away with a cheap SoC, like the ones commonly used in mobile products. Microsoft currently uses a range of chips from different vendors – Qualcomm Snapdragon SoCs with integrated 4G/LTE for mobile phones, Intel chips for Surface Pro tablets (along with Nvidia SoCs on defunct Surface RT products), along with custom AMD APUs in the Xbox One.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Due to power considerations, the most obvious choice would be a Snapdragon SoC, similar to those used in Lumia phones. This does not mean that HoloLens would be as underpowered as Google Glass. HoloLens is a much larger device, with room for a bigger battery; and, the latest Snapdragon SoCs are vastly more powerful than the chipset used in Google Glass (which is significantly slower than chips used in smartwatches). Early benchmarks indicate that the Adreno 430 GPU used in Qualcomm’s upcoming flagship SoCs, like the Snapdragon 810, is a powerhouse capable of handling 4K resolutions and rendering relatively complex 3D content in 1080p.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
It’s not just about sheer rendering performance. GPUs offer a lot of computing potential, and can be used for much more than gaming. Google used the Tegra K1 for <a href="https://www.google.com/atap/projecttango/#project" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">Project Tango</a>, which also deals with a number of technologies that could be very useful for AR or VR devices - automation, driverless cars, and so on. I already mentioned Vuforia, and there are other players in the GPU industry, but Nvidia has the advantage of using CUDA cores – it’s been a market leader in professional graphics and GPGPU compute markets for years.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, we should not be locked into the “what’s out there” mindset. It will take a while before HoloLens goes on sale, and subsequent generations are bound to feature even more powerful hardware. Intel’s new 14nm Atoms are coming soon, while ARM-based 14nm and 16nm SoCs should appear a couple of quarters later. The new non-planar nodes will allow even more performance per watt, drastically improving overall performance without taking a toll on battery life.</div>
<h2 id="streaming-as-an-alternative" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Streaming As An Alternative</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There is also an alternative which I mentioned earlier – cloud computing and streaming could be used to display complex, resource-intensive 3D content. The latest SoCs feature 802.11ac wireless and fast LTE modems, sufficient for high-resolution streaming. The downside to this approach, especially LTE, is lag.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
If additional content is rendered locally, on a PC workstation or possibly even an Xbox One, lag should be limited, but remote cloud rendering could prove problematic. For example, Nvidia is trying to tackle this problem by setting up <a href="http://shield.nvidia.com/grid-game-streaming/" rel="noopener noreferrer" style="border: 0px; box-sizing: border-box; color: #3976cb; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;" target="_blank">GRID</a> servers at strategic locations, in an attempt to cover the biggest markets with low-lag game streaming. Just a few milliseconds of additional lag could compromise the user experience in an AR application.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A mobile SoC should be sufficient for most everyday tasks, such as Skype and some limited augmented reality applications. However, if an architect wants to walk into a construction site and see how the finished building will look using augmented reality, the HoloLens will have to be backed by more hardware; rendering complex scenes with hundreds of thousands or millions of polygons, advanced lighting effects, and so on.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
The upside is that HoloLens could offer a lot of functionality out of the box, with a relatively powerful integrated GPU capable of handling a lot of everyday tasks, such as high resolution video streaming, browsing, and even casual gaming. On the other hand, professionals could employ 802.11ac or LTE to stream more complex content, rendered remotely.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft could practically use the same hardware platform for home users and professionals, with the latter employing local or cloud streaming for more advanced, resource-intensive tasks.</div>
<h2 id="is-there-a-use-case-and-a-market-for-hololens" style="background-color: white; border: 0px; box-sizing: border-box; color: #3863a0; font-family: 'Proxima Nova', Arial, sans-serif; line-height: 1.3em; margin: 2em 0px 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Is There A Use Case And A Market For HoloLens?</h2>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft showed off the HoloLens in a number of different scenarios. While the demos were quite interesting, they did not exactly spell out a realistic and commercially viable use case for the new device.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What I like about HoloLens is the fact that it is halfway between true wearables, like Google Glass, and wired VR solutions, like Oculus Rift. HoloLens does not have to be light and portable enough to wear on the street, but at the same time it does not have to be tethered to a computer or external power source – the best of both worlds. I also like the fact that Microsoft is choosing to lead rather than follow. HoloLens differs from existing concepts and products; it’s innovative, futuristic, and original - a breath of fresh air from Redmond.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
However, this approach also raises a number of important questions about the use case for HoloLens, and the size of the market. It can’t replace a display like VR solutions, yet it can’t be used in everyday situations due to its sheer bulk and appearance. While you may see some commuters and athletes using smart glasses, you probably won’t see skiers or joggers wearing a HoloLens headset.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
What could mainstream users do with HoloLens? What sort of software platforms and operating systems will be supported? What about professional applications? What about HoloLens cross-platform functionality, hardware specifications, retail price, and Bill of Material (BOM)?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
A lot of questions still have to be answered, and it will probably take a while before Microsoft releases all the information.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft will have to target mainstream and professional markets at the same time, with the same hardware. Depending on the price and BOM, Microsoft could leverage its Xbox user base, as well as a segment of the PC gaming market, to bring HoloLens products to mainstream users. Marketing such a product won’t be easy if the price is too high, but the user base is there - and it is willing to spend a lot of money on new gadgets. A mainstream market approach would also help get more developers on board, thus expanding the ecosystem and creating new use cases.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
But if HoloLens products are bound to be priced for the mainstream market, how will Microsoft go after the professional market, and make some money in the process?</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Years ago I used to make a living in offline 3D graphics, and I can see a lot of potential in HoloLens. There are a lot of 3D/CAD users out there and many of them would agree. Does this mean that every designer will be able to pick up a HoloLens device priced for the mainstream market and use it for work? Possibly, but probably not.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
There are other ways of marketing products in this space. I’ve been covering the GPU space for years, and in that time I’ve learned a thing or two about how the industry operates. Although high-end graphics cards for gamers get all the headlines, the real cash cows for Nvidia and AMD are professional graphics and compute solutions. They are the unsung heroes in this duopoly. The BOM for a consumer card and a professional card based on the same GPU is roughly the same, but professional cards cost a lot more, an order of magnitude more. They deliver huge margins, and generate a lot of revenue and profit, in spite of low overall volumes – you can check any Nvidia quarterly earning report for more info.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Microsoft could resort to a similar approach. HoloLens could use the same hardware for both markets, limit functionality on consumer models, and expand it on professional products through different licensing tiers.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
Of course, this is all just speculation at this point - but that’s how this market works. Microsoft does not have to reinvent the wheel.</div>
<div style="background-color: white; border: 0px; box-sizing: border-box; color: #303030; font-family: 'Proxima Nova', Arial, sans-serif; font-size: 1.2em; line-height: 1.5em; margin-bottom: 1em; min-height: 0px; min-width: 0px; padding: 0px; vertical-align: baseline;">
This article was written by <span style="border: 0px; box-sizing: border-box; color: #3976cb; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: 600; letter-spacing: 0.13px; line-height: 19px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-transform: uppercase; vertical-align: baseline;"><a class="link is-blue" href="https://www.toptal.com/blog" style="border: 0px; box-sizing: border-box; color: #103d77; display: inline; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;" target="_blank">NERMIN HAJDARBEGOVIC</a></span><span style="color: #929292; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; letter-spacing: 0.13px; line-height: 19px; text-transform: uppercase;"> - TECHNICAL EDITOR @ </span><a class="link is-blue" href="https://www.toptal.com/" style="border: 0px; box-sizing: border-box; color: #3863a0; display: inline; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; letter-spacing: 0.13px; line-height: 19px; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; text-transform: uppercase; transition: color 150ms, transform, text-shadow, -webkit-transform; vertical-align: baseline;" target="_blank">TOPTAL</a> and can be read <a href="https://www.toptal.com/virtual-reality/microsoft-hololens-bridging-the-gap-between-ar-and-vr">here</a>.</div>
Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-88538496112487561762015-03-24T12:53:00.001-07:002015-03-24T12:54:52.515-07:00Roto - The Chair That SpinsHere is something interesting in the name of gaming and VR:<br />
<br />
<iframe frameborder="0" height="480" scrolling="no" src="https://www.kickstarter.com/projects/rotovr/roto-taking-virtual-reality-to-the-next-level/widget/video.html" width="640"> </iframe><br />
<br />
<a href="https://www.kickstarter.com/projects/rotovr/roto-taking-virtual-reality-to-the-next-level">https://www.kickstarter.com/projects/rotovr/roto-taking-virtual-reality-to-the-next-level</a><br />
<br />
<br />
Interesting idea for sure. As you need to move around in 360 using VR headsets like the Oculus Rift, this makes sense. However, you are still sitting down, and not really moving. Which is what I like about mine. Also, it's quite a pricey chair. Anyway, I wish them all the best with the campaign. :)<br />
<br />Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-20031495670372437162015-02-22T17:31:00.001-08:002015-02-22T17:34:52.520-08:00TreadGaming Dying Light GameplayNew Gameplay video with TreadGaming hardware in action:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="480" src="https://www.youtube.com/embed/a05nqEcEuag" width="640"></iframe><br />
<br />
This time around I spend extra time adding images showing how I trigger things in the game. It's not exact, but will give you some idea.<br />
<br />
Also, I'm now also using the neat functionality I just added where you can hold the top Nunchuck button (C) to trigger things with the stick. Here Nunchuck #1 (left hand) will trigger the D-Pad on a XBox 360 controller, and Nunchuck #2 (right hand) will trigger A, B, X and Y buttons using the stick. If I double click the C buttons, it will be triggering like a normal button. In this case LB and RB on a XBox 360 controller.Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.com0tag:blogger.com,1999:blog-4258209981737157440.post-4848609897522448712015-02-06T21:16:00.000-08:002015-02-06T21:16:23.152-08:00Exergaming Projects Out ThereIt's been a while since I posted about cool projects related to mine, so I though I collect a few and show them here:<br />
<br />
This bike is sweet, but probably quite expensive. Still in concept stage as far as I know:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/nxSpWZjn3eg" width="640"></iframe><br />
<br />
Golf:<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/ywYNI2ZJ9GM" width="640"></iframe><br />
<br />
Sport Simulator:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/uUAdsTMTJkI" width="640"></iframe><br />
<br />
<br />
Oculus Rift + Kinect + KickR = Our Homage to Paperboy: PaperDude VR<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" mozallowfullscreen="" src="//player.vimeo.com/video/71336141" webkitallowfullscreen="" width="640"></iframe> <br />
<br />
<br />
<br />
This is nice work, but no so much "omni treadmill". He just hacked mini steppers to trigger movement. You do know that means "all" or "every" right?<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/aACdB5TiTPQ" width="640"></iframe><br />
<br />
<br />
<br />
Not sure how many would actually go through all this trouble, but hey, exploring limits - Draw real blood while getting hurt? <br />
<br />
<iframe frameborder="0" height="480" scrolling="no" src="https://www.kickstarter.com/projects/1246820613/blood-sport-the-ultimate-in-immersive-gaming/widget/video.html" width="640"> </iframe><br />
<br />
It's on Kickstarter, <a href="https://www.kickstarter.com/projects/1246820613/blood-sport-the-ultimate-in-immersive-gaming">https://www.kickstarter.com/projects/1246820613/blood-sport-the-ultimate-in-immersive-gaming</a>, but suspended for some reason...<br />
<br />
<br />
<br />
CAREN ( Computer Assisted Rehabilitation Environment )<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/a6Quza3WmVA" width="640"></iframe><br />
<br />
<h4>
I would also like to highlight this wonderful site: <a href="http://www.fitness-gaming.com/">http://www.fitness-gaming.com/</a></h4>
Chillancehttp://www.blogger.com/profile/11864546388055718797noreply@blogger.com0