-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
196 lines (169 loc) · 11.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>
Frozen Blog -
</title>
<meta name="description" content="Blog for the FrozenJS HTML5 Game Engine">
<meta name="author" content="Iced Dev">
<meta name="ROBOTS" content="ALL">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="alternate" type="application/rss+xml" title="Frozen Blog - feed" href="/index.xml" />
<link href='http://fonts.googleapis.com/css?family=Bowlby+One+SC' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link type="text/css" rel="stylesheet" href="static/styles/normalize.css">
<link type="text/css" rel="stylesheet" href="static/styles/prism.css">
<link type="text/css" rel="stylesheet" href="static/styles/jsdoc-default.css">
<style>
.main {
margin-top: 15px;
}
</style>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-27771989-2', 'frozenjs.com');
ga('send', 'pageview');
</script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body class="language-javascript examplepage">
<header class="header">
<h1 class="logo">Frozen Blog</h1>
<nav class="mainnav">
<a href="http://frozenjs.com/index.html">Home</a>
<a href="http://frozenjs.com/docs/">Docs</a>
<a href="http://frozenjs.com/examples/">Examples</a>
<a href="http://blog.frozenjs.com">Blog</a>
</nav>
</header>
<div class="main">
<section>
<article>
<div class="articles">
<article class="post">
<div class="title">
<h1><a href="./2013-04-25-building-breakouts-with_frozenjs.html">building breakouts with_frozenjs</a></h1>
<p class="post-date">april 25th 2013</p>
</div>
<div class="post-content">
<h2>Breakouts is the TodoMVC of HTML5 games.</h2>
<p><img src="images/breakouts_logo.png" alt="Breakouts"></p>
<p>If you're looking for a framework for building Single Page Applications, you'll want to visit the <a href="http://todomvc.com/">TodoMVC project</a>.
TodoMVC is a collection of several implemenations of a simple Todo web applications using various toolkits and frameworks.</p>
<p>Similarly, to make an informed decision on which HTML5 game engine to use you'll want to compare implementations of the same game. Matt Greer's <a href="http://city41.github.io/breakouts/">Breakouts project</a> does just that using the classic game Breakout as the target.</p>
<p>As of this writing, the <a href="http://city41.github.io/breakouts/frozen/index.html">FrozenJS implementation</a> of Breakout is the latest. We had fun implementing the game, and think our version is particularly good.</p>
<hr>
<h2>The FrozenJS game engine.</h2>
<p><img src="images/frozen_logo.png" alt="Breakouts"></p>
<p>From our website:</p>
<blockquote>
<p><em>Frozen is an open-source HTML5 game engine delivering ease-of-use, rapid development through tooling and modularity.</em></p>
<p><em>Our goal is to apply techniques used in building modern webapps to game development, such as AMD modules, dependency management, build process, and project scaffolding.</em></p>
</blockquote>
<p>TL;DR; FrozenJS rocks.</p>
<p>Let's get started...</p>
<hr>
<h2>Scaffolding a game with Frozen</h2>
<p>We'll assume your development machine already has a recent version of node.js, chrome or firefox, and a good text editor.</p>
<p>The easiest way to get started with Frozen is to use volo. Install volo if you don't already have it.</p>
<p><code>npm install volo -g</code></p>
<p>Use volo to scaffold out the project:</p>
<p><code>volo create MyGame frozenjs/boilerplate/boxgame</code></p>
<p>This did a few things for you:</p>
<p>It pulled in all the dependencies you need and put them into a deps folder.
Created the HTML, CSS, and JavaScript files you'll need to get started writing your code.
Sets up development configuration for linting, testing, and packaging</p>
<p>Now launch your game!</p>
<p><code>volo grunt</code></p>
<p>Point chrome to <a href="http://localhost:8080"><a href="http://localhost:8080">http://localhost:8080</a></a></p>
<p>ok, there isn't much of a game there yet... let's get into Breakout's code :)</p>
<hr>
<h2>Breakout code layout</h2>
<p><img src="images/modularize_all_the_js.png" alt="Modularize ALL the things!"></p>
<p>The main entry point to the game is the game.js module.</p>
<pre><code class="lang-JavaScript"><span class="regexp">//</span>pull <span class="keyword">in</span> some dependences...
<span class="reserved">var</span> game = <span class="keyword">new</span> BoxGame({
<span class="regexp">//</span>a bit <span class="keyword">of</span> intialization...
game.run();</code></pre>
<p>We pull in dependenices, configure a game instance, do a bit of initialization, and launch.</p>
<p>The rest of the modules for the Breakout game:</p>
<ul>
<li>typical game functions: handle player input, update the game state, and draw to the canvas.</li>
<li>game classes: Ball, Brick, Paddle, etc.</li>
<li>Also modules containing data for game levels and physics.</li>
</ul>
<p>Aside from JavaScript and HTML, we have a resources folder containing the images and sounds from the original Breakouts project.</p>
<hr>
<h2>Breakout specific physics and logic</h2>
<p>To simplify things we deferred the physics calculations of the game to <a href="https://code.google.com/p/box2dweb/">box2d</a>.</p>
<p>This allowed us to use the <a href="http://phated.github.io/frozen-editor/">Frozen box2d physics editor</a>. We dropped the pre-rendered game background into the editor and simply traced the walls in the game as static rectangles. That gave us the JSON we used in the walls.js module that we add to the box2d world instance in the game.</p>
<h3>Physics tweaks:</h3>
<p>Although it might appear that the balls fall towards the paddle in Breakout, we really don't wan't a realistic gravity set in our enviroment. In the game the ball moves in straight lines. With gravity the ball would curve back downward after being propelled upward from the paddle.</p>
<p>The restitution property for balls in the game is set to 1.0. This ensures that the ball will bounce back off of bricks and walls at the same force that it struck them with.</p>
<h3>... and then everything went sideways</h3>
<p><img src="images/breakouts_ball.png" alt="Breakouts ball sideways"></p>
<p>An interesting problem is that with zero gravity, a ball could potentially get stuck bouncing back and forth horizontally where it's not hitting a brick, but doesn't fall back down towards the paddle. To solve this, we check the linear velocity for each game loop iteration, and if the velocity stays horizontal a couple times in a row, we push the ball downwards. This happens quickly enough, that it isn't really perceptable to the user.</p>
<h3>One last thing: The paddle.</h3>
<p>The paddle is a dynamic box2d object that is pinned horizontally by use of a Prismatic Joint.</p>
<p>In the game breakout, players have control of which direction the ball launches towards the bricks by the position that the ball strikes the paddle. Just handing that off to box2d would result in the ball rebounding normally as though it just hit another wall.</p>
<p>To solve this, when there's a collision with a ball and the paddle we check the distance from the center of the ball to the center of the paddle and apply an upward impulse between -45 degrees (left corner of paddle) to +45 degrees (right corner).</p>
<hr>
<h2>Packaging it all up</h2>
<p>While developing, having a bunch of little modules is great. We can separate our logic into small re-usable components. However when we're ready to share our awesome game, we want to bundle the JavaScript into a single minified file so that it quickly loads into the browser.</p>
<p>To do this we simply have grunt run the build process:</p>
<p><code>volo grunt build</code></p>
<p>That command outputs all of our game's code and dependencies into a single game.js file in the dist folder.
The HTML file that loads the game actually tries to use that single file first, so you don't have to make any changes to the HTML to load this compressed version.</p>
<p>If you want to remove the compressed version and continuing developing your modules you can run:</p>
<p><code>volo grunt clean:dist</code></p>
<hr>
<h2>Conclusion</h2>
<p>We learned a few things.</p>
<h3>Use Lo-Dash</h3>
<p><a href="http://lodash.com/">Lo-Dash</a> is a great general purpose JavaScript utility library. It has everything that underscore has, but with much better performance.</p>
<p>Sixteen milliseconds to handle user input, update game state, and render to the screen is not very much time. You'll want to make sure that common low-level JavaScript tasks perform as quickly as possible.</p>
<p>Also, we tended to often re-imlpement certain JavaScript functions in various games. With Lo-Dash we were able to <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> up quite a bit of code. Because it supports <a href="http://requirejs.org/docs/whyamd.html">AMD</a>, we were able to easily include it in our project and build it into our minified JavaScript output.</p>
<p>Lo-Dash will be part the next version of FrozenJS.</p>
<h3>Screens/Scenes</h3>
<p>Although it uses the same background, there's a few state changes in the game: The start screen, the game playing, and the game over screen.</p>
<p>This isn't difficult to handle in the update and draw methods of this simple game, however we feel that it could be a bit easier. This is something we'll be looking into for future versions of the game engine.</p>
<h3>This was a fun experiment.</h3>
<p> It showed where FrozenJS shines as well as places that things could be a little better. If you want to get into HTML5 game development, our <a href="https://github.com/iceddev/breakouts">Breakouts source</a> is not a bad place to start. If you're creating a game engine, I encourage you to implement Breakouts.</p>
</div>
<div class="post-navigation">
<span class="comment-link"><a href="./2013-04-25-building-breakouts-with_frozenjs.html#comments">View Comments</a></span>
</div>
</article>
<hr />
<article class="post">
<div class="title">
<h1><a href="./2013-04-18-welcome.html">welcome</a></h1>
<p class="post-date">april 18th 2013</p>
</div>
<div class="post-content">
<p>The FrozenJS Blog is live!</p>
<h2>What is it for?</h2>
<p>We needed a place to write articles showing how to use Frozen or best practices, so we made this blog.</p>
<p>Not to mention, we want to spotlight things we are doing, or being done by others, with Frozen.</p>
</div>
<div class="post-navigation">
<span class="comment-link"><a href="./2013-04-18-welcome.html#comments">View Comments</a></span>
</div>
</article>
</div>
</article>
</section>
</div>
<footer>
Copyright Iced Dev, 2013.
</footer>
<script src="static/scripts/prism.js"> </script>
</body>
</html>