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

<channel>
	<title>Entropy Interactive</title>
	<atom:link href="http://entropyinteractive.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://entropyinteractive.com</link>
	<description>Shaping the chaos</description>
	<lastBuildDate>Wed, 06 Apr 2011 14:07:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>GJK Algorithm</title>
		<link>http://entropyinteractive.com/2011/04/gjk-algorithm/</link>
		<comments>http://entropyinteractive.com/2011/04/gjk-algorithm/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 14:05:07 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Collision detection]]></category>
		<category><![CDATA[Computer science]]></category>
		<category><![CDATA[Gilbert Johnson Keerthi]]></category>
		<category><![CDATA[GJK]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=335</guid>
		<description><![CDATA[The Gilbert-Johnson-Keerthi (GJK) algorithm is an efficient method for computing the distance between two convex shapes. It has become a popular method for real-time 3D collision detection. While less commonly used for 2D collision detection, the GJK algorithm still maintains &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/04/gjk-algorithm/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>The Gilbert-Johnson-Keerthi (GJK) algorithm is an efficient method for computing the distance between two convex shapes. It has become a popular method for real-time 3D collision detection. While less commonly used for 2D collision detection, the GJK algorithm still maintains several of its advantages. Its biggest disadvantage is that the algorithm can be conceptually difficult to understand (although it is easy to implement). This tutorial will explain how the GJK algorithm works in detail and demonstrate how to apply it to 2D collision detection.</p>
<p><span id="more-335"></span></p>
<h3>Minkowski Sum (and Difference)</h3>
<p>The Minkowski sum is a simple operation to describe, but can be difficult to visualize. Given two sets, the Minkowski sum is the set of every element in the first set, added to every element in the second set. For example, consider the following two sets of points:</p>
<p>Set A: (1, 1), (2, 1)<br />
Set B: (-2, 2), (-1, 2)</p>
<p>The Minkowski sum of A and B would be these four points:</p>
<p>(1, 1) + (-2, 2) = (-1, 3)<br />
(1, 1) + (-1, 2) = (0, 3)<br />
(2, 1) + (-2, 2) = (0, 4)<br />
(2, 1) + (-1, 2) = (1, 3)</p>
<p>Figure 1 shows the Minkowski sum between the polygons A and B. Notice that while the resulting shape contains an infinite number of points, its boundary is defined by a very small subset of those. Not even all of the combinations of the vertices of A and B are needed to create the shape. This will turn out to be one of the reasons the GJK algorithm is efficient.</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/03/Minkowski-Sum.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/03/Minkowski-Sum.png" alt="" title="Minkowski Sum" width="410" height="306" class="aligncenter size-full wp-image-360" /></a><br />
<em>Figure 1: The Minkowski sum between polygons A and B.</em></p>
<p>The GJK algorithm uses a closely related operation, often called the Minkowski difference. Instead of adding the points, they are subtracted. This would be the equivalent of a Minkowski sum with the negative of the second set of points. Using the same to shapes from before, figure 2 shows their Minkowski difference.</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/03/Minkowski-Difference.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/03/Minkowski-Difference.png" alt="" title="Minkowski Difference" width="410" height="306" class="aligncenter size-full wp-image-358" /></a><br />
<em>Figure 2: The Minkowski difference between polygons A and B.</em></p>
<p>The most important property of the Minkowski difference is the fact that if two objects are overlapping, the Minkowski difference of their shapes must contain the origin. It is simple to see why this is the case. Because the Minkowski difference subtracts every point in one set from every point in another, if there is any point in common between the two sets, that point is subtracted from itself. The Minkowski difference must therefore contain the point (0, 0), which is the origin. Figure 3 demonstrates the Minkowski difference between two intersecting polygons. The resulting shape contains the origin as expected.</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/03/Minkowski-Difference-Intersect.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/03/Minkowski-Difference-Intersect.png" alt="" title="Minkowski Difference Intersect" width="410" height="306" class="aligncenter size-full wp-image-359" /></a><br />
<em>Figure 3: When polygons A and B intersect, their Minkowski difference contains the origin.</em></p>
<h3>Support Function</h3>
<p>We can determine if two shapes intersect by finding whether their Minkowski difference contains the origin or not. The GJK algorithm does this by attempting to construct a triangle (or tetrahedron in the three dimensional case), with corners on the boundary of the Minkowski difference, that contains the origin. If the two shapes are convex, it is possible to form such a triangle if and only if the two shapes intersect.</p>
<p>Instead of constructing the Minkowski difference directly, a support function is used. It takes a direction, and returns the point in the Minkowski difference that is furthest in that direction. Let the Minkowski sum between shapes A and B be expressed as the following:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=A%5Coplus%20B%3D%5C%7Ba%2Bb%5C%3B%5Cmid%5C%3B%20a%5Cin%20A%2C%5C%3B%20b%5Cin%20B%5C%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A\oplus B=\{a+b\;\mid\; a\in A,\; b\in B\} ' title='A\oplus B=\{a+b\;\mid\; a\in A,\; b\in B\} ' class='latex' /><br />
</p>
<p>The Minkowski difference can then be written as this:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=A%5Cominus%20B%3DA%5Coplus%28-B%29%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A\ominus B=A\oplus(-B) ' title='A\ominus B=A\oplus(-B) ' class='latex' /><br />
</p>
<p>The support function must therefore return the following:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=%5C%7B%5Cmax%28dir%5Ccdot%20x%29%5C%3B%5Cmid%5C%3B%20x%5Cin%20A%5Cominus%20B%5C%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\{\max(dir\cdot x)\;\mid\; x\in A\ominus B\} ' title='\{\max(dir\cdot x)\;\mid\; x\in A\ominus B\} ' class='latex' /><br />
</p>
<p>This has not improved the situation yet. The point in the Minkowski difference that maximizes this dot product still needs to be found, but using some algebra, this can be reduced to a simpler problem. Substituting the definition of the Minkowski difference into the support function results in this:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=%5C%7B%5Cmax%28dir%5Ccdot%28a-b%29%29%5C%3B%5Cmid%5C%3B%20a%5Cin%20A%2C%5C%3B%20b%5Cin%20B%5C%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\{\max(dir\cdot(a-b))\;\mid\; a\in A,\; b\in B\} ' title='\{\max(dir\cdot(a-b))\;\mid\; a\in A,\; b\in B\} ' class='latex' /><br />
</p>
<p>The distributing the dot product gives this:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=%5C%7B%5Cmax%28dir%5Ccdot%20a-dir%5Ccdot%20b%29%5C%3B%5Cmid%5C%3B%20a%5Cin%20A%2C%5C%3B%20b%5Cin%20B%5C%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\{\max(dir\cdot a-dir\cdot b)\;\mid\; a\in A,\; b\in B\} ' title='\{\max(dir\cdot a-dir\cdot b)\;\mid\; a\in A,\; b\in B\} ' class='latex' /><br />
</p>
<p>The maximize function can now be divided:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=%5C%7B%5Cmax%28dir%5Ccdot%20a%29-%5Cmax%28-dir%5Ccdot%20b%29%5C%3B%5Cmid%5C%3B%20a%5Cin%20A%2C%5C%3B%20b%5Cin%20B%5C%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\{\max(dir\cdot a)-\max(-dir\cdot b)\;\mid\; a\in A,\; b\in B\} ' title='\{\max(dir\cdot a)-\max(-dir\cdot b)\;\mid\; a\in A,\; b\in B\} ' class='latex' /><br />
</p>
<p>Because both maximize functions are independent, these can be split into separate function:</p>
<p><img src='http://s.wordpress.com/latex.php?latex=%5C%7B%5Cmax%28dir%5Ccdot%20a%29%5C%3B%5Cmid%5C%3B%20a%5Cin%20A%5C%7D-%5C%7B%5Cmax%28-dir%5Ccdot%20b%29%5C%3B%5Cmid%5C%3B%20b%5Cin%20B%5C%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\{\max(dir\cdot a)\;\mid\; a\in A\}-\{\max(-dir\cdot b)\;\mid\; b\in B\} ' title='\{\max(dir\cdot a)\;\mid\; a\in A\}-\{\max(-dir\cdot b)\;\mid\; b\in B\} ' class='latex' /><br />
</p>
<p>The original support function can be divided into two separate support functions. By taking the support of the first shape and subtracting the support of the second shape in the opposite direction, we get the same result. Intuitively it is easy to understand why this works. If we want the point that is furthest in a given direction in the Minkowski difference, first we would go as far as possible in that direction in the first shape. Because the second shape is being subtracted from the first, we would then want the point that is furthest in the opposite direction. Using this technique, the Minkowski difference no longer needs to be explicitly constructed.</p>
<h3>Construction the Simplex</h3>
<p>A simplex is simply a generalization of a triangle. A 0-simplex is a single point, 1-simplex is a line, a 2-simplex is a triangle, and a 3-simplex is a tetrahedron. Because we are working in two dimensions, only the 0-simplex, 1-simplex, and 2-simplex are of interest. The goal of the GJK algorithm is to build a 2-simplex (a triangle) that contains the origin or determine that such a simplex cannot be constructed. This can be done by choosing a random direction and calling the support function. After that, points will be iteratively added and removed from the simplex. The algorithm is outlined in the following pseudo-code.</p>
<pre class="brush: delphi; title: ; notranslate">
function boolean intersects(Shape a, Shape b)
    // chose an initial direction
    Vector direction = (1, 0)
    // create the initial simplex
    Simplex simplex
    simplex = [getSupport(a, b, direction)]
    // set the direction to point towards the origin
    direction = -simplex.first()

    while(true)
        // add a new point
        simplex.add(getSupport(a, b, direction))
        // see if the new point was on the correct side of the origin
        if(!isSameDirection(direction, simplex.a)
            return false
        // process the simplex
        if(processSimplex(simplex, direction))
            return true

function Vector getSupport(Shape a, Shape b, Vector direction)
    return a.getSupport(direction) - b.getSupport(-direction)

function boolean isSameDirection(Vector v1, Vector v2)
    return v1.dot(v2) &gt; 0
</pre>
<p>Other than processSimplex, that is the entire algorithm. The first thing we do is create an initial simplex. Since only one point is needed, an arbitrary direction is chosen and the support function is called with that direction. After the first point is added, a new direction is needed. Every time a new direction is chosen, it should be in towards the origin. With only one point, this is easy. The negative of our first point is the vector from that point, to the origin. After the initial simplex is created, the main loop is entered.</p>
<p>The main loop performs three actions. First a new point is added to the simplex using the getSupport function and the previous direction. We then check if the new point is on the same side of the origin as the last direction. If it is not, we have tried to get a point that was as far as possible in the chosen direction, but could not get all the way to the origin. This means there are no points on the other side of the origin, so the simplex will never be able to contain it. The algorithm can therefore terminate with the conclusion that the shapes do not intersect. The last step is the most complicated and that is the processSimplex function.</p>
<p>The process simplex function does three things. It checks if the origin is in the existing simplex. If this is the case, the shapes intersect. Second, it choses a new direction to expand the simplex in. This direction should be the vector from the closest point on the simplex to the origin. Finally, it removes any points from the simplex that are no longer necessary. How this is done is dependent on the size of the simplex. As mentioned earlier, because we are working in 2D, we are concerned with the 0-simplex, 1-simplex, and 2-simplex.</p>
<h6>0-Simplex</h6>
<p>The 0-simplex is a single point, and is the easiest to handle. The desired direction if simply the vector from the point to the origin. This case does not even need to be handled explicitly. We always have at least one point in the simplex and just before calling processSimplex, another is added. A 0-simplex will therefore never be passed into processSimplex.</p>
<h6>1-Simplex</h6>
<p>The 1-Simplex is a line. Let A be the most recent point added to the simplex. The area around the line can be divided into four regions as shown in figure 4.</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/03/1-Simplex.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/03/1-Simplex.png" alt="" title="1-Simplex" width="336" height="274" class="aligncenter size-full wp-image-410" /></a><br />
<em>Figure 4: A 1-simplex and the regions around it where the origin may lie.</em></p>
<p>We need to determine which of these regions the origin lies in. First, region 4 can immediately be eliminate because we were previously at B, then move towards the origin. A must be in the same direction as the origin or we would have terminated already so region 4, which is in the opposite direction, cannot contain the origin. To test if the origin is in region 1, we simply need to determine if the vector AB is in the same direction as AO. If it is, A becomes the new simplex (a 0-simplex) and the new direction vector is AO.</p>
<p>If the origin is not in region 1, it must be in region 2 or 3. These can be handled as a group. We first need a vector perpendicular to AB. In two dimensions, a vector perpendicular to (x, y) is simply (-y, x). This vector also needs to be in the direction of AO. If it is not, simply negate it. Instead of performing this check using an if statement, the dot product is used. Remember that the dot product is positive if two vectors are in the same direction, and negative if they are in opposite directions.</p>
<h6>2-Simplex</h6>
<p>The 2-simplex is the most complicated of the three cases. Let A, B, and C be the points of the simplex with A being the most recently added followed by B then C. Figure 5 shows the seven regions around the 2-simplex.</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/03/2-Simplex.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/03/2-Simplex.png" alt="" title="2-Simplex" width="336" height="274" class="aligncenter size-full wp-image-414" /></a><br />
<em>Figure 5: The 2-simplex and surrounding regions.</em></p>
<p>Again, we need to determine which region contains the origin. Regions 1, 2, and 3 can be immediately eliminated. This is because in the previous iterations we already determined that the origin must be between B and C and in the direction of A.</p>
<p>There are four remaining regions. If the origin is in the direction of AB and in the direction of the vector perpendicular to AB facing away from C, it is in region 4. Similarly, if the origin is in the direction of AC and in the direction of the vector perpendicular to AC facing away from B, it is in region 6. If the origin is in the opposite direction as both AB and AC, it is in region 5. Finally, if none of these cases are true, the origin is in region 7.</p>
<p>If the origin is in region 4, A and B become the new simplex and the search direction is perpendicular to AB facing away from C. Region 6 is similar with AC becoming the new simplex. If the origin is in region 5, A becomes the new simplex and the search direction is AO. Finally, if the origin is in region 7, we have determined that the Minkowski difference does contain the origin and the shapes intersect. The 2-simplex can be resolved using four if statements, of which only two ever need to be evaluated.</p>
<pre class="brush: delphi; title: ; notranslate">
function boolean processSimplex(Simplex simplex, Vector direction)
    // we only need to handle to 1-simplex and 2-simplex
    if(simplex.size == 2) // 1-simplex
        // AO is in the same direction as AB
        if(isSameDirection(-simplex.a, simplex.b - simplex.a))
            // get the vector perpendicular to AB
            direction = (simplex.b - simplex.a).perpendicular
            // set direction to face O
            // if AO is not in the same direction as AB, the dot product will be negative
            // the scaling will therefore flip the direction to the opposite (correct) direction
            direction.scale(-simplex.a.dot(direction))
            // A and B remain in the simplex
            simplex = [simplex.a, simplex.b]
        else
            direction = -simplex.a
            // only A remains in the simplex
            simplex = [simplex.a]
    else // 2-simplex
        Vector AB = simplex.b - simplex.a
        Vector AC = simplex.c - simplex.a
        Vector AO = - simplex.a
        // the vector perpendicular to AB facing away from C
        Vector ACB = AB.perpendicular
        ACB = ACB.scale(ACB.dot(-AC))
        // the vector perpendicular to AC facing away from B
        Vector ABC = AC.perpendicular
        ABC= ABC.scale(ABC.dot(-AB))
        if(ACB.isSameDirection(AO))
            if(AB.isSameDirection(AO)) // region 4
                direction = ACB
                simplex = [simplex.a, simplex.b]
                return false
            else // region 5
                direction = AO
                simplex = [simplex.a]
                return false
        else if(ABC.isSameDirection(AO))
            if(AC.isSameDirection(AO)) // region 6
                direction = ABC
                simplex = [simplex.a, simplex.c]
                return false
            else // region 5 (again)
                direction = AO
                simplex = [simplex.a]
                return false
            else // region 5
        else // region 7
            return true
</pre>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/04/gjk-algorithm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GJK Algorithm Demo</title>
		<link>http://entropyinteractive.com/2011/03/gjk-algorithm-demo/</link>
		<comments>http://entropyinteractive.com/2011/03/gjk-algorithm-demo/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 18:08:18 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Entropy Engine]]></category>
		<category><![CDATA[Site News]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Applet]]></category>
		<category><![CDATA[Collision detection]]></category>
		<category><![CDATA[Computer science]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Entropy engine]]></category>
		<category><![CDATA[Gilbert Johnson Keerthi]]></category>
		<category><![CDATA[GJK]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=330</guid>
		<description><![CDATA[The Gilbert-Johnson-Keerthi (GJK) algorithm is a method that can be used to find the minimum distance between two convex objects. The algorithm is often used for 3D collision detection in video games. I decided to write up a 2D implementation &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/03/gjk-algorithm-demo/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>The Gilbert-Johnson-Keerthi (GJK) algorithm is a method that can be used to find the minimum distance between two convex objects. The algorithm is often used for 3D collision detection in video games. I decided to write up a 2D implementation to try it out. So far, I have been very happy with the results. I am now planning on replacing the existing collision detection in the Entropy Engine (line-line intersection testing), with the GJK algorithm. I will also write a tutorial on the algorithm in the next week or so. In the mean time, you can see it in action <a href="http://entropyengine.sourceforge.net/applets/gjk-demo/">here</a>.</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/03/GJKDemo.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/03/GJKDemo.png" alt="" title="GJK Demo" width="360" height="280" class="aligncenter size-full wp-image-331" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/03/gjk-algorithm-demo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Entropy Engine &#8211; Basics</title>
		<link>http://entropyinteractive.com/2011/03/entropy-engine-basics/</link>
		<comments>http://entropyinteractive.com/2011/03/entropy-engine-basics/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 13:52:18 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Entropy Engine]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Entropy engine]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Input]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Loop]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=310</guid>
		<description><![CDATA[Entropy Engine provides several classes to simplify the creation of Java based games. This tutorial will describe how to use those classes. Included is how to create a game, how to control the game loop, and how to use the &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/03/entropy-engine-basics/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Entropy Engine provides several classes to simplify the creation of Java based games. This tutorial will describe how to use those classes. Included is how to create a game, how to control the game loop, and how to use the input system. More information on the Entropy Engine can be found on the <a href="http://entropyinteractive.com/entropy-engine/">Entropy Engine</a> page.</p>
<p><span id="more-310"></span></p>
<h3>A Basic Game</h3>
<p>There are three main components to a basic game. The first is the <em>GameLoop</em>. This class manages the running of the game, calling update and draw at appropriate times. The <em>GameContainer</em> acts as an abstract interface between the game logic and the underlying implementation of the graphics, input, and other low level systems. Finally, the update and draw logic is contained in the class implementing the <em>Game</em> interface. Following is an example of a simple game:</p>
<pre class="brush: java; title: ; notranslate">
import com.entropyinteractive.Game;
import com.entropyinteractive.GameContainer;
import com.entropyinteractive.GameLoop;
import com.entropyinteractive.WindowedGame;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;

public class Main implements Game
{
    public static void main(String[] args)
    {
        // create a stand-alone game
        GameContainer gc = new WindowedGame(&quot;Basic Game&quot;, 640, 480);
        // run the game with the default game loop
        gc.run(new GameLoop(), new Main());
        // exit when the game is finished
        System.exit(0);
    }

    @Override
    public void draw(GameContainer gc, Graphics2D g)
    {
        // add drawing logic here
    }

    @Override
    public void shutdown(GameContainer gc)
    {
        // add shutdown logic here
    }

    @Override
    public void startup(GameContainer gc)
    {
        // add startup logic here
    }

    @Override
    public void update(GameContainer gc, double delta)
    {
        // stop the game if the escape key is pressed
        if(gc.getKeyboard().isKeyPressed(KeyEvent.VK_ESCAPE)) gc.halt();
        // add update logic here
    }
}
</pre>
<p>The code is very simple. First a new game container is created. In this case the game container is a windowed game (i.e. a game running in AWT frame). Next, <em>run</em> is called on that game container passing in a game loop and a game to be run. This begins the game loop, which will continue until <em>halt</em> is called on the game container. Finally, when the game finishes running, the program exits.</p>
<p>The <em>Main</em> class itself is what implements the <em>Game</em> interface. It must therefore provide the <em>draw</em>, <em>startup</em>, <em>shutdown</em>, and <em>update</em> methods. The <em>startup</em> method is called immediately after the game loop begins running, and <em>shutdown</em> just before the game loop ends. The other two methods, <em>update</em> and <em>draw</em>, are called repeatedly by the game loop while the game is running.</p>
<h3>The Game Loop</h3>
<p>The game loop in Entropy Engine is intended to be flexible. It is design to robustly run a game in using several styles of update logic. The exact behavior can be set using the following four parameters:</p>
<ul>
<li><strong>minDelta:</strong> This is the minimum time between updates. Update will never be called with a delta time less than this value, and if both update and draw finish in less time than minDelta, the game loop will sleep until minDelta seconds have passed.</li>
<li><strong>maxDelta:</strong> This is the maximum time between updates. Update will never be called with a delta time greater than this value. Depending on the next two parameters, if the game is running slow, multiple updates may be queued with maxDelta as the delta time to catch up. In this case, some calls to draw may be skipped to help the game catch up.</li>
<li><strong>maxUpdateDelay:</strong> This is the maximum amount of time an update will be delayed. If the game is running greater than maxUpdateDelay seconds behind, the game loop will re-sync with the real time and the queued updates will be skipped.</li>
<li><strong>maxDrawDelay:</strong> This is the maximum amount of time a draw will be delayed. If it has been greater than maxDrawDelay seconds since the last draw, draw will be called regardless of whether or not the game is running slow.</li>
</ul>
<p>By setting these parameters appropriately, many different behaviors can be achieved. For example, setting minDelta to 0 and maxDelta to infinity would result in the simplest delta time game loop. Setting minDelta and maxDelta to the same value results in a fixed logic rate game loop. If maxUpdateDelay is 0, the game will slow down if the updates and draws are taking to long. Setting maxDrawDelay to 0 will result in a draw being called after every update.</p>
<h3>Input</h3>
<p>The three input types in Entropy Engine are keyboard, mouse, and mouse wheel. Each game container provides three methods to retrieve each of these. For example, during a call to <em>update</em>, the <em>gc.getKeyboard()</em> could be used to get the current instance of the keyboard input manager.</p>
<p>Each of the input managers provides several ways to access the input. All three include the <em>getEvents</em> method to retrieve a linked list of every input event that occurred since the last update. They also implement the <em>Iterable</em> interface to conveniently iterate over the those events. Each of the input classes includes various methods for common input related tasks. Details on these methods can be found in the <a href="http://entropyengine.sourceforge.net/javadoc/">Javadoc</a>.</p>
<p><em>-Eric</em></p>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/03/entropy-engine-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; Component Based Entities</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-component-based-entities/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-component-based-entities/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 17:51:23 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Composition]]></category>
		<category><![CDATA[Entity]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=260</guid>
		<description><![CDATA[Component based entities are becoming increasingly popular. They are a design pattern that can greatly improve the maintainability and flexibility of your game code. This tutorial will describe what component based entities are and how to design them. A Java &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-component-based-entities/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Component based entities are becoming increasingly popular. They are a design pattern that can greatly improve the maintainability and flexibility of your game code. This tutorial will describe what component based entities are and how to design them. A Java implementation is provided which can easily be translated to other languages.</p>
<p><span id="more-260"></span></p>
<h3>Object Hierarchies</h3>
<p>Traditionally, game entities used object hierarchies. Each layer added some amount of functionality. At the root was some form of generic object, and as you proceeded down the branches, the classes got increasingly specific. This tree like structure is a logical organization for objects that have a clear supertype-subtype relationship. In games, however, this can be very limiting. Consider the following example:</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/02/Simple-Object-Hierarchy.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/Simple-Object-Hierarchy.png" alt="" title="Simple Object Hierarchy" width="420" height="190" class="aligncenter size-full wp-image-284" /></a></p>
<p>This object hierarchy is simple enough. The shack, mansion, and bank all fit in well defined categories. What happens if an new object, such as a apartment, needs to be added?</p>
<p><a href="http://entropyinteractive.com/wp-content/uploads/2011/02/Confused-Object-Hierarchy.png"><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/Confused-Object-Hierarchy.png" alt="" title="Confused Object Hierarchy" width="420" height="190" class="aligncenter size-full wp-image-289" /></a></p>
<p>It is not clear what the apartment should inherit from. It has properties of both a a home and a business. The object hierarchy could always be refactored, but depending on its complexity, that may be easier said then done.</p>
<h3>Composition</h3>
<p>The alternative to object hierarchies is a concept called composition. The &#8220;is-a&#8221; relationship of inheritance is converted to a &#8220;has-a&#8221; relationship. The game entities become containers for various components, which determine its state and behavior. In the above example, an apartment may contain a building, home, and business object.</p>
<p>There are several advantages to this design pattern. First, the various components can remain loosely coupled. With a deep object hierarchy, a change near the root can have far reaching and unexpected consequences. In a composition, only the components that directly communicate are affected by changes to one another.</p>
<p>Composition can also make game entities more flexible. Adding additional behavior is as simple as adding a new component to the entity. In the above example, if banks and apartments now require rent, a new rent component can be added to those two components. The rent component could then ask the respective tenant components to pay their rent. This ability to quickly add and remove behavior from entities is a great advantage during development.</p>
<p>A third advantage is that the program becomes easier to understand. It is clear which behaviors and properties an entity has, simply by looking at its list of components.</p>
<h3>Communication</h3>
<p>The difficulty of a composition is communication. To build more complex behavior, the various components must be able to relay their state and events to each other. One possible way of doing this is by making the game entities store a reference to every type of component. At creation, an entity initializes the components it needs and leaves the remaining ones empty. When one component needs to communicate with another, it looks up the other component&#8217;s reference, and performs whatever actions are needed. This design works, but can become awkward when there is a large number of components, or when components are often added and removed from an entity (such as during development).</p>
<p>On the other end of the spectrum is the abstract approach. The entity knows nothing of the components it contains. It views them as abstract objects. Communication is facilitated via messages. When a component&#8217;s state changes, a message is created. This message is then forwarded to all of the other components in the entity. They may choose to handle it however they want. The problem with this approach is that there is a non-trivial amount of overhead when sending these messages. For may applications, this overhead is not important, and the messaging system offers a great deal flexibility.</p>
<h3>A Hybrid Approach</h3>
<p>The implementation described here lies somewhere between the two previous methods. When a component is added to an entity, all of the other components in that entity are informed. It is then their responsibility to keep a reference to the new component or not. Similarly, the components are informed whenever a component is removed from the entity.</p>
<p>This method has both advantages and disadvantages. The entity does not need to know anything about the components contained within, but the messaging overhead occurs only when components are added or removed (most commonly during entity construction). The components also have the option of communicating in whatever manner is most appropriate, whether it be through events, polling, or direct access.</p>
<p>This primarily comes at the cost of memory. Because each component must hold its own references, if multiple components depend on the same object, those references become redundant. Object creation can also become expensive. The number of messages passed at object creation is the square of the number of components.</p>
<p>Reducing the memory overhead would be difficult using this design, but the object creation cost can be reduced. First, the components can be divided into two categories, lightweight and heavyweight. Lightweight components do not need to know about other components. They are strictly data providers. This does not mean that they can not have behaviors of their own, they just do not need to know about the other components in the entity. The complexity of entity construction is now dependent primarily on the number of heavyweight components. It can contain many lightweight components without issue.</p>
<p>The second optimization is allowing for sub-entities. Entities can be added to other entities as if they were components. This creates a tree structure. Events are propagated horizontally and away from the root the tree. This creates an isolation between various components. For example, a physics entity can be created that will hold all of the physics related entities. Externally, other components may only need to be aware of the objects position, but internally there can be many components influencing its behavior. These two design choices will allow for the performance of the entity to be tuned, as well as grant some additional organizational options.</p>
<h3>Implementation</h3>
<p>Provided below is a minimalist implementation of the described entity system. The code is written in Java, but depends on very little on Java specific functionality.</p>
<p><em>-Eric</em></p>
<p><strong>Component Interface:</strong></p>
<pre class="brush: java; title: ; notranslate">
public interface Component
{
    void componentAdded(Component c);
    void componentRemoved(Component c);
    boolean isLightweight();
}
</pre>
<p><strong>Entity Class:</strong></p>
<pre class="brush: java; title: ; notranslate">
public class Entity implements Component
{
    private ArrayList&lt;Component&gt; heavyComps = new ArrayList&lt;Component&gt;();
    private ArrayList&lt;Component&gt; lightComps = new ArrayList&lt;Component&gt;();

    public Entity()
    {
        // do nothing
    }

    public final void addComponent(Component comp)
    {
        // safety check
        if(comp == null)
            Log.error(new NullPointerException(&quot;component == null&quot;));

        // inform the heavyweight components that a new component has been added
        for(Component c : heavyComps) c.componentAdded(comp);

        if(comp.isLightweight())
        {
            // add the new component to the lightweight components
            lightComps.add(comp);
        }
        else
        {
            // inform the new component of the existing components
            for(Component c : lightComps) comp.componentAdded(c);
            for(Component c : heavyComps) comp.componentAdded(c);
            // add the new component to the heavyweight components
            heavyComps.add(comp);
        }
    }

    public final void removeComponent(Component comp)
    {
        // safety check
        if(comp == null)
            Log.error(new NullPointerException(&quot;component == null&quot;));

        if(comp.isLightweight())
        {
            // remove the component from the lightweight components
            lightComps.remove(comp);
        }
        else
        {
            // remove the component from the heavyweight components
            heavyComps.remove(comp);
            // inform the other components that this component is being removed
            for(Component c : lightComps) comp.componentRemoved(c);
            for(Component c : heavyComps) comp.componentRemoved(c);
        }

        // inform this component that all the other componets are no longer
        // accesible
        for(Component c : heavyComps) c.componentRemoved(comp);
    }

    public void componentAdded(Component comp)
    {
        for(Component c : heavyComps) c.componentAdded(comp);
    }

    public void componentRemoved(Component comp)
    {
        for(Component c : heavyComps) c.componentRemoved(comp);
    }

    public final boolean isLightweight()
    {
        return false;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-component-based-entities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; A Simple Game</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-a-simple-game/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-a-simple-game/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 20:40:36 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Asteroids]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Window]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=234</guid>
		<description><![CDATA[Now that we have created a game loop, window, and input manager, we can create a very simple game. This will be a short tutorial, but will demonstrate the use of the components we have created. We will begin by &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-a-simple-game/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Now that we have created a game loop, window, and input manager, we can create a very simple game. This will be a short tutorial, but will demonstrate the use of the components we have created. We will begin by creating the main class AsteroidsInfinity. It will extend Game, the window manager we created earlier.</p>
<p><span id="more-234"></span></p>
<pre class="brush: java; gutter: false; title: ; notranslate">
public class AsteroidsInfinity extends Game
{
    private Path2D.Double ssTriangle;
    private double shipX;
    private double shipY;
</pre>
<p>Our simple game will require only three members, the shape used to draw the ship, and its x and y position. We will assign these values in the startup method.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    public void gameStartup()
    {
        Log.info(getClass().getSimpleName(), &quot;Starting up game&quot;);

        // construct our ship
        ssTriangle = new Path2D.Double();
        ssTriangle.moveTo(0.0, -30.0);
        ssTriangle.lineTo(20.0, 20.0);
        ssTriangle.lineTo(0.0, 10.0);
        ssTriangle.lineTo(-20.0, 20.0);
        ssTriangle.closePath();
        // assign the initial location of the ship
        shipX = getWidth() / 2;
        shipY = getHeight() / 2;
    }
</pre>
<p>This creates the arrow shaped ship, and assigns it location to the center of the screen. Next is the update logic.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    public void gameUpdate(double delta)
    {
        Keyboard keyboard = getKeyboard();
        // poll the input for the arrow keys to control movement
        if(keyboard.isKeyPressed(KeyEvent.VK_UP))
            shipY -= 100.0 * delta;
        if(keyboard.isKeyPressed(KeyEvent.VK_DOWN))
            shipY += 100.0 * delta;
        if(keyboard.isKeyPressed(KeyEvent.VK_LEFT))
            shipX -= 100.0 * delta;
        if(keyboard.isKeyPressed(KeyEvent.VK_RIGHT))
            shipX += 100.0 * delta;

        // check the list of key events for a pressed escape key
        LinkedList&lt;KeyEvent&gt; keyEvents = keyboard.getEvents();
        for(KeyEvent event : keyEvents)
        {
            if((event.getID() == KeyEvent.KEY_PRESSED) &amp;&amp;
                    (event.getKeyCode() == KeyEvent.VK_ESCAPE))
            {
                stop();
            }
        }
    }
</pre>
<p>First we get the keyboard manager. To control the space ships movement we will use the polling style interface. We check each of the of the arrow keys and adjust the ships position appropriately if any of those keys are pressed. If the user presses the escape key, we want our program to exit. We don&#8217;t want to miss this event, so we will examine every key press during the last update interval. If the escape key was pressed, we will call stop to end the game. Now we need to implement the draw method.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    public void gameDraw(Graphics2D g)
    {
        // offset our drawing to the ships location
        g.translate(shipX, shipY);
        // draw the ship (fill then outline)
        g.setColor(Color.gray);
        g.fill(ssTriangle);
        g.setColor(Color.white);
        g.draw(ssTriangle);
    }
</pre>
<p>The drawing method first translates the canvas to the ships location, then fills and outlines the ship&#8217;s shape. The shutdown method also needs to be implemented, but it does not need to do anything.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    public void gameShutdown()
    {
        Log.info(getClass().getSimpleName(), &quot;Shutting down game&quot;);
    }
</pre>
<p>What remains is the constructor and the main method.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    public AsteroidsInfinity()
    {
        // call game constructor
        super(&quot;Asteroids Infinity&quot;, 640, 480);
    }

    public static void main(String[] args)
    {
        Game game = new AsteroidsInfinity();
        game.run(1.0 / 60.0);
        System.exit(0);
    }
</pre>
<p>The constructor calls Game&#8217;s constructor with our desired title and size. The main method first creates an instance of AsteroidsInfinity, then calls run with the target logic rate. Finally, after run returns (after stop is called), we exit the program.</p>
<p>We have now completed a simple game. Next we will re-factor this code into the basis of our game engine. The complete source code for this example can be found in &#8220;Asteroids Infinity &#8211; Phase 1.zip&#8221;, <a href="https://sourceforge.net/projects/entropyengine/files/Asteroids%20Infinity/">here</a>.</p>
<p><em>-Eric</em></p>
<p><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/Asteroids-Infinity-Phase-1.png" alt="Asteroids Infinity - Phase 1" /></p>
<pre class="brush: java; title: ; notranslate">
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.geom.Path2D;
import java.util.LinkedList;

public class AsteroidsInfinity extends Game
{
    private Path2D.Double ssTriangle;
    private double shipX;
    private double shipY;

    public static void main(String[] args)
    {
        Game game = new AsteroidsInfinity();
        game.run(1.0 / 60.0);
        System.exit(0);
    }

    public AsteroidsInfinity()
    {
        // call game constructor
        super(&quot;Asteroids Infinity&quot;, 640, 480);
    }

    public void gameStartup()
    {
        Log.info(getClass().getSimpleName(), &quot;Starting up game&quot;);

        // construct our ship
        ssTriangle = new Path2D.Double();
        ssTriangle.moveTo(0.0, -30.0);
        ssTriangle.lineTo(20.0, 20.0);
        ssTriangle.lineTo(0.0, 10.0);
        ssTriangle.lineTo(-20.0, 20.0);
        ssTriangle.closePath();
        // assign the initial location of the ship
        shipX = getWidth() / 2;
        shipY = getHeight() / 2;
    }

    public void gameUpdate(double delta)
    {
        Keyboard keyboard = getKeyboard();
        // poll the input for the arrow keys to control movement
        if(keyboard.isKeyPressed(KeyEvent.VK_UP))
            shipY -= 100.0 * delta;
        if(keyboard.isKeyPressed(KeyEvent.VK_DOWN))
            shipY += 100.0 * delta;
        if(keyboard.isKeyPressed(KeyEvent.VK_LEFT))
            shipX -= 100.0 * delta;
        if(keyboard.isKeyPressed(KeyEvent.VK_RIGHT))
            shipX += 100.0 * delta;

        // check the list of key events for a pressed escape key
        LinkedList&lt;KeyEvent&gt; keyEvents = keyboard.getEvents();
        for(KeyEvent event : keyEvents)
        {
            if((event.getID() == KeyEvent.KEY_PRESSED) &amp;&amp;
                    (event.getKeyCode() == KeyEvent.VK_ESCAPE))
            {
                stop();
            }
        }
    }

    public void gameDraw(Graphics2D g)
    {
        // offset our drawing to the ships location
        g.translate(shipX, shipY);
        // draw the ship (fill then outline)
        g.setColor(Color.gray);
        g.fill(ssTriangle);
        g.setColor(Color.white);
        g.draw(ssTriangle);
    }

    public void gameShutdown()
    {
        Log.info(getClass().getSimpleName(), &quot;Shutting down game&quot;);
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-a-simple-game/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; SVN</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-svn/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-svn/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 21:42:54 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=229</guid>
		<description><![CDATA[I have set up a SVN repository at Sourceforge.net. If you have an SVN client installed (such as TortoiseSVN), you can check out a copy of the current game engine code. The repository location is https://entropyengine.svn.sourceforge.net/svnroot/entropyengine/trunk/entropyengine. I will also be &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-svn/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I have set up a SVN repository at <a href="http://sourceforge.net/projects/entropyengine/">Sourceforge.net</a>. If you have an SVN client installed (such as <a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a>), you can check out a copy of the current game engine code. The repository location is <em>https://entropyengine.svn.sourceforge.net/svnroot/entropyengine/trunk/entropyengine</em>. I will also be packaging various releases to go along with the tutorials, so if you don&#8217;t want to use SVN you can simply download a .zip file. A word of warning, the game engine is still in early development and may not be the most stable. If you have any comments or questions, let me know.<br />
<em>-Eric</em></p>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-svn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; Game Window</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-game-window/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-game-window/#comments</comments>
		<pubDate>Fri, 18 Feb 2011 14:44:24 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Frame]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Game loop]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Window]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=209</guid>
		<description><![CDATA[Now it is time to create a window for our game. In this tutorial, we will extend the game loop class from earlier. The goal is to create a simple window for drawing. This tutorial is mostly Java specific. If &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-game-window/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Now it is time to create a window for our game. In this tutorial, we will extend the game loop class from earlier. The goal is to create a simple window for drawing. This tutorial is mostly Java specific. If you are using a different language or API, you will need to handle window creation differently, though you may still want to extend the game loop in a similar way.</p>
<p><span id="more-209"></span></p>
<p>From before, we have a game loop class which manages the running of the game. We will extend this class to add the window functionality. We will also need to include the input handling, as they need to be aware of the window in order to receive input events. The four abstract methods that need to be implement are the following:</p>
<ul>
<li>startup()</li>
<li>update()</li>
<li>draw(double)</li>
<li>shutdown()</li>
</ul>
<h3>Creating a Window</h3>
<p>Before we get to implementing these, we need to create our window. It will have three parameters, title, height, and width. Here is the beginning of the new Game class:</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
public abstract class Game extends GameLoop
{
    private Frame frame;
    private Canvas canvas;
    private BufferStrategy buffer;
    private Keyboard keyboard;
    private Mouse mouse;
    private MouseWheel mouseWheel;

    public Game(String title, int width, int height)
    {
        Log.debug(&quot;Game&quot;, &quot;Creating game &quot; +
                title + &quot; (&quot; + width + &quot;, &quot; + height + &quot;)&quot;);
</pre>
<p>The game class will hold references for our frame and a canvas that we will draw to. There is also a buffer, which we will get to in a little bit. The keyboard, mouse, and mouse wheel will manage the user input. For the constructor, we are passing in a title for our window and it dimensions. The next few lines will create the window.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
        // create frame and canvas
        frame = new Frame(title);
        frame.setResizable(false);
        canvas = new Canvas();
        canvas.setIgnoreRepaint(true);
        frame.add(canvas);
        // resize canvas and make the window visible
        canvas.setSize(width, height);
        frame.pack();
        frame.setVisible(true);
</pre>
<p>First the frame and canvas are created. We set the frame to be non-resizable so that we don&#8217;t need to worry about supporting multiple window sizes (for now). Our game loop is managing the drawing of the canvas so the repaint requests should be ignored. After we add the canvas to the frame we set its size and call pack(). This resizes the frame so that it properly fits the canvas. Finally we set the frame to visible so that we can see our game.</p>
<h3>Double Buffering</h3>
<p>Double buffering is an important feature to include. We don&#8217;t want the user to see the drawing as it takes place. If the drawing routine takes a while, this will result in flickering and a generally unprofessional look. Instead we will perform all of the drawing on a back buffer. Once we are done, the back buffer will be swapped with the front buffer (either by switching pointers of copying the data). This way the user will never see incomplete scenes. Java provides built in functions to perform double buffering.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
        // create buffer strategy
        canvas.createBufferStrategy(2);
        buffer = canvas.getBufferStrategy();
</pre>
<p>The buffer strategy manages the front and back buffers, but they must be created after the frame is visible. The only thing remaining to do in our constructor is add the input listeners.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
        // create our input classess and add them to the canvas
        keyboard = new Keyboard();
        mouse = new Mouse();
        mouseWheel = new MouseWheel();
        canvas.addKeyListener(keyboard);
        canvas.addMouseListener(mouse);
        canvas.addMouseMotionListener(mouse);
        canvas.addMouseWheelListener(mouseWheel);
        canvas.requestFocus();
    }
</pre>
<p>First the three input containers are created, then we add all their implemented listeners to the canvas. Finally, we request that the canvas gain focus. This ensures that user input is actually sent to our game.</p>
<h3>Implementing the Abstract Game Loop Methods</h3>
<p>With the constructor finished, we now need to do something about the abstract methods from the game loop class. First, we will create four new abstract methods our game will need to implement.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    public abstract void gameStartup();
    public abstract void gameUpdate(double delta);
    public abstract void gameDraw(Graphics2D g);
    public abstract void gameShutdown();
</pre>
<p>This design is a bit awkward, but we will fix that when we re-factor the project a bit later. The abstract methods from the game loop, startup() and shutdown(), are trivial to implement. We simply need to call gameStartup() and gameShutdown() for the two, respectively. The update() method needs a bit more work. Before we call gameUpdate(double), we need to call the update() methods on each of the input handlers. This ensures that our game will have access to the most current input. For the the draw() method, we first need the Graphics2D object that will allow us to modify the back buffer. We will clear the buffer before sending it to the gameDraw(Graphics2D). After the program has returned, we call buffer.show() to flip the buffers and make the drawing visible.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
    protected void startup()
    {
        gameStartup();
    }

    public void update(double delta)
    {
        // call the input updates first
        keyboard.update();
        mouse.update();
        mouseWheel.update();
        // call the abstract update
        gameUpdate(delta);
    }

    public void draw()
    {
        // get the current graphics object
        Graphics2D g = (Graphics2D)buffer.getDrawGraphics();
        // clear the window
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
        // send the graphics object to gameDraw() for our main drawing
        gameDraw(g);
        // show our changes on the canvas
        buffer.show();
        // release the graphics resources
        g.dispose();
    }

    protected void shutdown()
    {
        gameShutdown();
    }
</pre>
<p>We have now created a simple graphics window. We can extend this class with our game to add our own logic and rendering code. Below is the full class. I have added a few get methods and it should be pretty clear what they do.</p>
<pre class="brush: java; title: ; notranslate">
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

/**
 * Game that creates a window and handles input.
 * @author Eric
 */
public abstract class Game extends GameLoop
{
    private Frame frame;
    private Canvas canvas;
    private BufferStrategy buffer;
    private Keyboard keyboard;
    private Mouse mouse;
    private MouseWheel mouseWheel;

    /**
     * Creates a new game window.
     *
     * @param title title of the window.
     * @param width width of the window.
     * @param height height of the window.
     */
    public Game(String title, int width, int height)
    {
        Log.debug(&quot;Game&quot;, &quot;Creating game &quot; +
                title + &quot; (&quot; + width + &quot;, &quot; + height + &quot;)&quot;);

        // create frame and canvas
        frame = new Frame(title);
        frame.setResizable(false);
        canvas = new Canvas();
        canvas.setIgnoreRepaint(true);
        frame.add(canvas);
        // resize canvas and make the window visible
        canvas.setSize(width, height);
        frame.pack();
        frame.setVisible(true);

        // create buffer strategy
        canvas.createBufferStrategy(2);
        buffer = canvas.getBufferStrategy();

        // create our input classess and add them to the canvas
        keyboard = new Keyboard();
        mouse = new Mouse();
        mouseWheel = new MouseWheel();
        canvas.addKeyListener(keyboard);
        canvas.addMouseListener(mouse);
        canvas.addMouseMotionListener(mouse);
        canvas.addMouseWheelListener(mouseWheel);
        canvas.requestFocus();
    }

    /**
     * Get the width of the window.
     *
     * @return the width of the window.
     */
    public int getWidth()
    {
        return canvas.getWidth();
    }

    /**
     * Get the height of the window.
     *
     * @return the height of the window.
     */
    public int getHeight()
    {
        return canvas.getHeight();
    }

    /**
     * Returns the title of the window.
     *
     * @return the title of the window.
     */
    public String getTitle()
    {
        return frame.getTitle();
    }

    /**
     * Returns the keyboard input manager.
     * @return the keyboard.
     */
    public Keyboard getKeyboard()
    {
        return keyboard;
    }

    /**
     * Returns the mouse input manager.
     * @return the mouse.
     */
    public Mouse getMouse()
    {
        return mouse;
    }

    /**
     * Returns the mouse wheel input manager.
     * @return the mouse wheel.
     */
    public MouseWheel getMouseWheel()
    {
        return mouseWheel;
    }

    /**
     * Calls gameStartup()
     */
    protected void startup()
    {
        gameStartup();
    }

    /**
     * Updates the input classes then calls gameUpdate(double).
     * @param delta time difference between the last two updates.
     */
    public void update(double delta)
    {
        // call the input updates first
        keyboard.update();
        mouse.update();
        mouseWheel.update();
        // call the abstract update
        gameUpdate(delta);
    }

    /**
     * Calls gameDraw(Graphics2D) using the current Graphics2D.
     */
    public void draw()
    {
        // get the current graphics object
        Graphics2D g = (Graphics2D)buffer.getDrawGraphics();
        // clear the window
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
        // send the graphics object to gameDraw() for our main drawing
        gameDraw(g);
        // show our changes on the canvas
        buffer.show();
        // release the graphics resources
        g.dispose();
    }

    /**
     * Calls gameShutdown()
     */
    protected void shutdown()
    {
        gameShutdown();
    }

    public abstract void gameStartup();
    public abstract void gameUpdate(double delta);
    public abstract void gameDraw(Graphics2D g);
    public abstract void gameShutdown();
}
</pre>
<p><em>-Eric</em></p>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-game-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; Input</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-input/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-input/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 19:12:16 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Input]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Module]]></category>
		<category><![CDATA[Thread-safe]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=174</guid>
		<description><![CDATA[This tutorial will develop a system to handle game input. We will go over the features we want in our input system, and some concerns regarding input will be addressed. We will then implement an input system for the game &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-input/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>This tutorial will develop a system to handle game input. We will go over the features we want in our input system, and some concerns regarding input will be addressed. We will then implement an input system for the game engine. Unfortunately, user input is generally platform and API dependent. The implementation provided here is Java AWT specific, but the information provided on the first page is intended to be as general as possible.</p>
<p><span id="more-174"></span></p>
<p>There are many different types of input. We are focusing on the PC platform, and are therefore most concerned with mouse and keyboard input. A mouse has multiple buttons that may be pressed or released, the mouse can move, and the scroll wheel can be rotated. A keyboard has dozens of keys and millions of key combinations, all which may be pressed or released. There are two main paradigms used to monitor these inputs.</p>
<h3>Polling vs. Interrupt</h3>
<p>The first way to measure user input is with polling. Using this method, the program repeatedly asks what is the current state of the input device. For example, if a player is supposed to move forward while the up arrow is pressed, each loop the program will check the up arrow key&#8217;s current state. If it is pressed, the program will perform the appropriate actions. This is simple and works well for many types of input, but there is a drawback. If an event happens very quickly, it can be missed by the program.</p>
<p>In interrupt based input, every time an input event occurs, an appropriate function is called. This solves the problem of missed events, but introduces its own issues. Events can occur at any time, so you must be very careful to have all code relating to input thread-safe. Both polling and interrupt systems and have another subtle problem. Because the input is asynchronous, it is possible that the state of the input will change part way through the game loop. This could lead to unexpected (and very difficult to debug) behavior.</p>
<p>To fix these issues we will buffer the input. Events that occur will be stored until they can be processed safely. We will also create a polling like interface because of its convenience. Java&#8217;s input is interrupt based, so the first step is to create a method of handling events in a thread-safe way.</p>
<h3>The EventQueue class</h3>
<p>The EventQueue class below will be the base class for our various input devices. This class must be synchronized (thread-safe) so that we do not make concurrent modifications to the buffer. Events can be added at any time using addEvent(T). Update() is called at the beginning of each game loop. This moves all the events from the protected internal buffer to the public one. As they are moved to the public buffer, processEvent(T) is called on each event. This will be used later to handle our polling style interface.</p>
<p>The next two pages of this post (links below) include the implementations for mouse and keyboard input.</p>
<pre class="brush: java; title: ; notranslate">
import java.util.Collection;
import java.util.LinkedList;

/**
 * Provides basic thread-safe and deterministic event handling for input.
 *
 * Events that occur between update calls are placed into the event queue.
 * When update is called, each event is processed, then the event queue is
 * moved to the publicly accessible events.
 * &lt;p&gt;
 * The motivation for this design is three fold.
 * First, events are handled in a thread-safe way (i.e. the list of events wont
 * be modified while the game thread is using it.
 * Second, the program will act more deterministically.
 * While an event may happen at any time, changes to the queue will only occur
 * during the call to {@link #update()}.
 * Finally, through use of the {@link #addEvents(java.util.Collection)} method,
 * user input can be exactly reproduced.
 * Simply add new events in the frame before they are needed, and
 * {@link #update()} will process them as if they had been the result of a user
 * action.
 *
 * @author Eric
 */
public abstract class EventQueue&lt;T&gt;
{
    private LinkedList&lt;T&gt; events = new LinkedList&lt;T&gt;();
    private LinkedList&lt;T&gt; eventQueue = new LinkedList&lt;T&gt;();

    /**
     * Returns a list of events that occurred before the last update.
     *
     * @return list of events
     */
    public LinkedList&lt;T&gt; getEvents()
    {
        return events;
    }

    /**
     * Processes the event queue.
     *
     * {@link #processEvent(java.lang.Object)} is called for each event in the
     * event queue.
     * Then events is set to the event queue and a new event queue is created.
     * As events is no longer needed, the user is free to modify it however
     * they chose.
     * If a reference is to events is not saved before the next update, its
     * contents will be lost.
     */
    public synchronized void update()
    {
        for(T event : eventQueue)
        {
            processEvent(event);
        }
        events = eventQueue;
        eventQueue = new LinkedList&lt;T&gt;();
    }

    /**
     * Override to perform any custom processing for events.
     *
     * When {@link #update()} this will be called for each event in the queue.
     *
     * @param event
     */
    protected void processEvent(T event)
    {
        return;
    }

    /**
     * Adds an event to the queue
     *
     * @param newEvent the event to be added
     */
    public synchronized void addEvent(T newEvent)
    {
            eventQueue.add(newEvent);
    }

    /**
     * Adds events to the event queue.
     *
     * The events will be processed at the next update.
     *
     * @param newEvents
     */
    public synchronized void addEvents(Collection&lt;T&gt; newEvents)
    {
        eventQueue.addAll(newEvents);
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-input/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; The Game Loop</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 05:04:23 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Game loop]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Loop]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=141</guid>
		<description><![CDATA[This tutorial will cover one of the most basic components of a game, the game loop. The game loop is what actual drives your game. It manages the calls to your logic and drawing functions. While doing this, it performs &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>This tutorial will cover one of the most basic components of a game, the game loop. The game loop is what actual drives your game. It manages the calls to your logic and drawing functions. While doing this, it performs the vital role of maintaining a consistent game speed (also called a logic rate). Creating a game loop is not always an easy thing. Many newer programmers get stuck on this. This tutorial will explain what a game loop is, how to create one, and what are some common pitfalls.</p>
<p><span id="more-141"></span></p>
<h3>A Simple (and Flawed) Game Loop</h3>
<p>First, what is a game loop? At its most basic a game loop is a state machine. For a game there are usually four main states.</p>
<ul>
<li><strong>Start:</strong> This is where the program performs any initialization.</li>
<li><strong>Stop:</strong> Here, any open resources should be released.</li>
<li><strong>Update:</strong> Here is your game logic.</li>
<li><strong>Draw:</strong> This is where all the drawing goes.</li>
</ul>
<p>The simplest game loop may consist of these four states. Start is called first, performing any initialization then the main game loop is entered. Update and draw are called repeatedly until the program exits to the stop state. Figure 1 shows a diagram of this simple game loop.</p>
<p><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/A-simple-game-loop.png" alt="A simple game loop." /><br />
<em>Figure 1: A simple game loop.</em></p>
<p>A game loop like this is as easy to implement as it is to draw.</p>
<pre class="brush: java; title: ; notranslate">
public abstract class GameLoop
{
    private boolean runFlag = false;

    public void run()
    {
        runFlag = true;

        startup();
        while(runFlag)
        {
            update();
            draw();
        }
        shutdown();
    }

    public void stop()
    {
        runFlag = false;
    }

    public abstract void startup();
    public abstract void shutdown();
    public abstract void update();
    public abstract void draw();
}
</pre>
<p>This method has a significant problem. Because the game loops as fast as possible, update will be called much more frequently on a fast computer than a slow one. This means that the game will run at different speeds for different users, something that you definitely don&#8217;t want.</p>
<h3>A Frame Rate Limited Game Loop</h3>
<p>There are several options at this point. The first would be making the update aware of how much time the loop took. For example, if the loop takes half as long as expected, only move the objects half as far. Unless you are very careful, this can cause problems particularly when updates are very fast or slow. This also makes the behavior of the game much less repeatable.</p>
<p>Another option would be to repeat the drawing step until it is time to update again. This would work, but it is not necessary and could in fact be harmful. If the game is not being updated then the drawing probably is not changing either. The harm can come from overworking the graphics card. Starcraft 2 had this problem when it was released, because the frame rate was not capped in menu screens.</p>
<p>What we will do is put the program to sleep if we finish the loop early. Figure 2 shows the new state diagram. Sleeping has a few additional benefits. If our game is multi-threaded, this gives other parts of the code time to execute. It also behaves better with the other processes on the computer (or other system).</p>
<p><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/A-frame-rate-limited-game-loop.png" alt="A frame rate limited game loop." /><br />
<em>Figure 2: A frame rate limited game loop.</em></p>
<p>Here is the code for the frame rate limited game loop.</p>
<pre class="brush: java; title: ; notranslate">
public abstract class GameLoop
{
    private boolean runFlag = false;

    /**
     * Begin the game loop
     * @param delta time between logic updates (in seconds)
     */
    public void run(double delta)
    {
        runFlag = true;

        startup();
        // convert the time to seconds
        double nextTime = (double)System.nanoTime() / 1000000000.0;
        while(runFlag)
        {
            // convert the time to seconds
            double currTime = (double)System.nanoTime() / 1000000000.0;
            if(currTime &gt;= nextTime)
            {
                // assign the time for the next update
                nextTime += delta;
                update();
                draw();
            }
            else
            {
                // calculate the time to sleep
                int sleepTime = (int)(1000.0 * (nextTime - currTime));
                // sanity check
                if(sleepTime &gt; 0)
                {
                    // sleep until the next update
                    try
                    {
                        Thread.sleep(sleepTime);
                    }
                    catch(InterruptedException e)
                    {
                        // do nothing
                    }
                }
            }
        }
        shutdown();
    }

    public void stop()
    {
        runFlag = false;
    }

    public abstract void startup();
    public abstract void shutdown();
    public abstract void update();
    public abstract void draw();
}
</pre>
<p>There are a few subtleties to notice in the code. First, we now have an additional parameter called delta. This is the amount of time between each logic (and drawing) update. When we update nextTime, delta is added to it. What we don&#8217;t want to do is get the time again and add delta to it. That may result in lost pieces of time, particularly if the update is late. Second, every loop either updates and draws OR sleeps. If this was not the case, we would need to re-sample the time because it would be outdated by the time we reached the sleep section.</p>
<h3>An Advanced Game Loop</h3>
<p>We are not done improving our game loop yet. So far we have draw being called every time update is. What if our program is running slow? It may be a good idea to skip some of the calls to draw so that we continue to update at the correct rate. We can now update our state diagram to figure 3.</p>
<p><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/An-advanced-game-loop.png" alt="An advanced game loop" /><br />
<em>Figure 3: An advanced game loop.</em></p>
<p>We only need to change one line of the code to implement this change.</p>
<pre class="brush: java; first-line: 25; title: ; notranslate">
                draw();
</pre>
<p>becomes&#8230;</p>
<pre class="brush: java; first-line: 25; title: ; notranslate">
                if(currTime &lt; nextTime) draw();
</pre>
<h3>A More Advanced Game Loop</h3>
<p>The game loop so far should work just fine in most situations, but what if the updates get significantly behind? Currently, the game loop would try to run as many updates as necessary to catch up. This may cause the game to skip a significant amount ahead, a major problem if players are expected to react quickly to events. What we need to do is allow the nextTime to skip ahead if we have fallen to far behind.</p>
<p>Another potential problem when the game is running slow is that draw will never get called. This can be fixed by forcing the game to be drawn every so often. Both of these changes have the consequence that the game may no longer run at the correct rate is the updates and draws are taking to long. Whether or not this is acceptable depends on the game, but keeping the game responsive is often more important. If you do not want that functionality, just don&#8217;t include the last two changes. Figure 4 shows the final state diagram.</p>
<p><img src="http://entropyinteractive.com/wp-content/uploads/2011/02/A-more-advanced-game-loop.png" alt="A more advanced game loop" /><br />
<em>Figure 4: A more advanced game loop.</em></p>
<p>Here is the final source code:</p>
<pre class="brush: java; title: ; notranslate">
public abstract class GameLoop
{
    private boolean runFlag = false;

    /**
     * Begin the game loop
     * @param delta time between logic updates (in seconds)
     */
    public void run(double delta)
    {
        runFlag = true;

        startup();
        // convert the time to seconds
        double nextTime = (double)System.nanoTime() / 1000000000.0;
        double maxTimeDiff = 0.5;
        int skippedFrames = 1;
        int maxSkippedFrames = 5;
        while(runFlag)
        {
            // convert the time to seconds
            double currTime = (double)System.nanoTime() / 1000000000.0;
            if((currTime - nextTime) &gt; maxTimeDiff) nextTime = currTime;
            if(currTime &gt;= nextTime)
            {
                // assign the time for the next update
                nextTime += delta;
                update();
                if((currTime &lt; nextTime) || (skippedFrames &gt; maxSkippedFrames))
                {
                    draw();
                    skippedFrames = 1;
                }
                else
                {
                    skippedFrames++;
                }
            }
            else
            {
                // calculate the time to sleep
                int sleepTime = (int)(1000.0 * (nextTime - currTime));
                // sanity check
                if(sleepTime &gt; 0)
                {
                    // sleep until the next update
                    try
                    {
                        Thread.sleep(sleepTime);
                    }
                    catch(InterruptedException e)
                    {
                        // do nothing
                    }
                }
            }
        }
        shutdown();
    }

    public void stop()
    {
        runFlag = false;
    }

    public abstract void startup();
    public abstract void shutdown();
    public abstract void update();
    public abstract void draw();
}
</pre>
<p><em>-Eric</em></p>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Game Engine Design &#8211; Logging</title>
		<link>http://entropyinteractive.com/2011/02/game-engine-design-logging/</link>
		<comments>http://entropyinteractive.com/2011/02/game-engine-design-logging/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 03:04:34 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[Game engine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Log]]></category>
		<category><![CDATA[Logger]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Module]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://entropyinteractive.com/?p=112</guid>
		<description><![CDATA[The first part of the game engine I will cover is the logger. It may not be the most interesting, but most of the other components will need access to the log so it needs to be finished first. Logging &#8230;<p class="read-more"><a href="http://entropyinteractive.com/2011/02/game-engine-design-logging/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>The first part of the game engine I will cover is the logger. It may not be the most interesting, but most of the other components will need access to the log so it needs to be finished first. Logging is very important in all but the simplest of games. During development, it provides feedback about the current state of the program. Later, once the game is released, it is your only source of feedback on the game. This information is invaluable when debugging.</p>
<p><span id="more-112"></span></p>
<p>A logging system can be a simple or complex as you need it. For our purposes, we will only need a simple system. Her is an outline of the key requirements:</p>
<ul>
<li><strong>Flexible output stream:</strong> We should be able to change were the log is written to, whether it be a file, the console, or some other location.</li>
<li><strong>Thread-safe:</strong> There is no telling where in the program the logger will be needed. It therefore must be safe to access it from multiple threads.</li>
<li><strong>Multiple priority levels:</strong> There are times when less information is needed. By giving the log multiple priority levels we can control the output without changing all of the code.</li>
<li><strong>Accessible:</strong> Writing an entry to the log should be as simple as possible. The easier it is to use, the more likely it will get used.</li>
</ul>
<p>With these requirements in mind, let&#8217;s consider a few design decisions. First, we need to be able to set the output stream. Instead of always writing to the console we will write to the output stream saved in the Log class. In java we can use the PrintStream for this. Its two most important functions will be print(String s) and flush(). The print function has its obvious uses. The flush command is also vital. Normally when you write to a stream, the output is buffered. This results in more efficient writes, but if the program crashes before the buffer has been written, we lose that output. That is something we really want to avoid in a logger.</p>
<p>Next we need the logger to be thread-safe. This is relatively simple. Synchronization needs to be performed when the log is written to or when one of its settings is change. Java provides the synchronized keyword to do just that.</p>
<p>For multiple message priorities,  we will introduce an enumeration of the various priority levels. Each will contain a name and an integer priority. Once the priority level of the logger has been set, we can simply compare the level of the message to this setting. If the message is sufficiently important, it will be written to the log. Otherwise, it will be discarded.</p>
<p>For convenience, we will make the class a singleton. While some people will insist that you should never use a singleton, loggers are an excellent example of where they can be useful. Rather than passing a reference to every class, we will be able to use global methods. Another option is to create a logger for each module, but we wont do that here. There will also be several convenience methods to directly log a message at a given level.</p>
<p>Here is the source code for the logger:</p>
<h3>The Log.java Class</h3>
<pre class="brush: java; title: ; notranslate">
import java.io.PrintStream;

/**
 * A simple thread safe logging class.
 *
 * Messages sent to the logger are sent to its {@link java.io.PrintStream}
 * based on priority.
 * Only messages above the minimum priority are written to the log.
 * The priority levels from least to most important are DEBUG, INFO, WARNING,
 * and ERROR.
 * The log can be set to write to any print stream, with a null value
 * defaulting to System.err.
 * Convenience methods are provided for the logging levels.
 *
 * Messages are formatted as the following:&lt;br&gt;
 * Level name (module name):&lt;br&gt;
 * Message text
 *
 * @author Eric
 */
public class Log
{
    /**
     * Enumeration of the logging levels.
     */
    public enum Level
    {
        DEBUG(&quot;Debug&quot;, 0),
        INFO(&quot;Info&quot;, 1),
        WARNING(&quot;Warning&quot;, 2),
        ERROR(&quot;Error&quot;, 3);

        /**
         * Name to be output when logged.
         */
        private String name;
        /**
         * Priority of level.
         */
        private int priority;

        /**
         * Create a new level.
         *
         * @param name name to be displayed in log messages.
         * @param value priority value (higher value has priority).
         */
        private Level(String name, int priority)
        {
            this.name = name;
            this.priority = priority;
        }

        /**
         * Returns the name of the level.
         * @return the name of the level.
         */
        public String getName()
        {
            return name;
        }

        /**
         * Get the priority of the level.
         * @return the priority of the level (higher value has priority).
         */
        public int getPriority()
        {
            return priority;
        }
    }

    /**
     * Minimum priority of messages to log.
     */
    private static Level minLevel = Level.DEBUG;
    /**
     * {@link java.io.PrintStream} to write messages to.
     */
    private static PrintStream ps = null;

    /**
     * Log a message at the DEBUG level.
     * @param module module the message originated from.
     * @param message message to be logged.
     */
    public static void debug(String module, String message)
    {
        logMessage(Level.DEBUG, module, message);
    }

    /**
     * Log a message at the INFO level.
     * @param message message to be logged.
     */
    public static void info(String module, String message)
    {
        logMessage(Level.INFO, module, message);
    }

    /**
     * Log a message at the WARNING level.
     * @param message message to be logged.
     */
    public static void warning(String module, String message)
    {
        logMessage(Level.WARNING, module, message);
    }

    /**
     * Log a message at the ERROR level.
     * @param message message to be logged.
     */
    public static void error(String module, String message)
    {
        logMessage(Level.ERROR, module, message);
    }

    /**
     * Returns the minimum priority level.
     * @return the current minimum priority level.
     */
    public static Level getMinimumPriorityLevel()
    {
        return minLevel;
    }

    /**
     * Sets the minimum priority level.
     * @param level the minimum level set to.
     */
    public static synchronized void setMinimumPriorityLevel(Level level)
    {
        Log.minLevel = level;
    }

    /**
     * Returns the print stream.
     * @return the current print stream.
     */
    public static PrintStream getPrintStream()
    {
        return Log.ps;
    }

    /**
     * Set the print stream to write messages to.
     * @param ps the desired print stream or null for the console.
     */
    public static synchronized void setPrintStream(PrintStream ps)
    {
        Log.ps = ps;
    }

    /**
     * Log a message at the desired level.
     * @param level priority level of message.
     * @param module module name.
     * @param message message to be logged.
     */
    public static synchronized void logMessage(
            Level level,
            String module,
            String message)
    {
        // check if message has high enough priority
        if(level.getPriority() &gt;= minLevel.getPriority())
        {
            // construct the message
            String logMessage = level.getName() +
                                &quot; (&quot; + module + &quot;):\n&quot; +
                                message;
            // write to the print stream or System.err if null
            if(ps == null)
            {
                System.err.println(logMessage);
                System.err.flush();
            }
            else
            {
                ps.println(logMessage);
                ps.flush();
            }
        }
    }
}
</pre>
<h3>A Simple Example</h3>
<p>The class has the flexibility we wanted, is thread-safe, and simple to use. Here is a brief example.</p>
<pre class="brush: java; title: ; notranslate">
import java.io.File;
import java.io.PrintStream;

public class LogExample
{
    public static void main(String[] args)
    {
        Log.debug(&quot;Example&quot;, &quot;This text is logged&quot;);
        Log.setMinimumPriorityLevel(Log.Level.INFO);
        Log.debug(&quot;Example&quot;, &quot;This text is not logged&quot;);
        Log.warning(&quot;Example&quot;, &quot;This text is also logged&quot;);
        try
        {
            Log.setPrintStream(new PrintStream(new File(&quot;log.txt&quot;)));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        Log.info(&quot;Example&quot;, &quot;This text has been written to a file&quot;);
    }
}
</pre>
<p><strong>Console output</strong></p>
<pre class="brush: plain; title: ; notranslate">
Debug (Example):
This text is logged
Warning (Example):
This text is also logged
</pre>
<p><strong>Contents of log.txt</strong></p>
<pre class="brush: plain; title: ; notranslate">
Info (Example):
This text has been written to a file
</pre>
<p><em>-Eric</em></p>
]]></content:encoded>
			<wfw:commentRss>http://entropyinteractive.com/2011/02/game-engine-design-logging/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

