tag:blogger.com,1999:blog-38493528109234336442024-03-13T14:52:37.727-04:00Computational ContemplationsAnonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comBlogger24125tag:blogger.com,1999:blog-3849352810923433644.post-16042068000841212652017-12-03T11:28:00.003-05:002017-12-03T11:31:48.374-05:00Upcoming Book: Java Game Development with LibGDX (second edition)I recently finished writing and editing the manuscript for <i>Java Game Development for LibGDX</i>! Hopefully it will be in print by January 2018; the <a href="https://www.apress.com/us/book/9781484233238" target="_blank">book website</a> is up at Apress.com. This is a second edition of my earlier book on Java game development, but so much has changed, it feels like an entirely new book. About 200 pages longer, this edition also covers new topics such as visual novel games, rhythm tapper games, and advanced topics such as random maze generation algorithms and shader (GPU) programming with OpenGL.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmiZHi_-9QHwhXQk9WM1J9dqkjUt5vAbCIGlv3mAQ-Y5hBTAGIuPpsVUOcQD8Wu7TGV6XgYg4vuBGmuncZyrJ3w_O69N_1RxlwQFyu6sN7Pt6IfEs-UESg2QHetLUgoR55yeFxl-3dbYo/s1600/Stemkoski_JavaGameHiRes.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1122" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmiZHi_-9QHwhXQk9WM1J9dqkjUt5vAbCIGlv3mAQ-Y5hBTAGIuPpsVUOcQD8Wu7TGV6XgYg4vuBGmuncZyrJ3w_O69N_1RxlwQFyu6sN7Pt6IfEs-UESg2QHetLUgoR55yeFxl-3dbYo/s320/Stemkoski_JavaGameHiRes.jpg" width="224" /></a></div>
<br />
Here is a brief overview of what you will learn in this book.<br />
<br />
<div class="BodyTextFirst">
<b><span style="font-size: 12.0pt;"><u>Part 1: Fundamental Concepts</u></span></b></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextFirst">
In the first part, you will be introduced to the LibGDX
library, and build a custom framework on top of this library to simplify
creating a variety of games.<o:p></o:p></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextFirst">
<!--[if gte vml 1]><v:shapetype id="_x0000_t75"
coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe"
filled="f" stroked="f">
<v:stroke joinstyle="miter"/>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"/>
<v:f eqn="sum @0 1 0"/>
<v:f eqn="sum 0 0 @1"/>
<v:f eqn="prod @2 1 2"/>
<v:f eqn="prod @3 21600 pixelWidth"/>
<v:f eqn="prod @3 21600 pixelHeight"/>
<v:f eqn="sum @0 0 1"/>
<v:f eqn="prod @6 1 2"/>
<v:f eqn="prod @7 21600 pixelWidth"/>
<v:f eqn="sum @8 21600 0"/>
<v:f eqn="prod @7 21600 pixelHeight"/>
<v:f eqn="sum @10 21600 0"/>
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
<o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="Picture_x0020_1" o:spid="_x0000_s1026" type="#_x0000_t75"
style='position:absolute;left:0;text-align:left;margin-left:422.9pt;
margin-top:72.3pt;width:117pt;height:94.35pt;z-index:251658240;visibility:visible;
mso-wrap-style:square;mso-width-percent:0;mso-height-percent:0;
mso-wrap-distance-left:9pt;mso-wrap-distance-top:0;mso-wrap-distance-right:9pt;
mso-wrap-distance-bottom:0;mso-position-horizontal:absolute;
mso-position-horizontal-relative:margin;mso-position-vertical:absolute;
mso-position-vertical-relative:margin;mso-width-percent:0;
mso-height-percent:0;mso-width-relative:margin;mso-height-relative:margin'>
<v:imagedata src="file:///C:\Users\STEMKO~1\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png"
o:title="1-6 helloworldimage"/>
<w:wrap type="square" anchorx="margin" anchory="margin"/>
</v:shape><![endif]--><!--[if !vml]--><strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter 1: Getting Started with Java and LibGDX</span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
This chapter explains how to set up BlueJ, a Java development
environment, which is chosen for simplicity and user-friendliness. Instructions for setting up the LibGDX software library are given, and a
visual “Hello, World!” program is presented (which displays an image of the
world in a window).<o:p></o:p></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEIdYhK1EnjUWFQAFQ97FdAIJ-WdxHyfdxWD5MLnMKKKpYqgzj_BvfV0FDkm7GOCyHsPYPQtg-PQs-nHi2gmnPbQtCq5ng7ER0s0CMljOJRTNMUbNP9ifY9-DtW8yUP2FEGN9E6I99nJk/s1600/1-6+helloworldimage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="445" data-original-width="552" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEIdYhK1EnjUWFQAFQ97FdAIJ-WdxHyfdxWD5MLnMKKKpYqgzj_BvfV0FDkm7GOCyHsPYPQtg-PQs-nHi2gmnPbQtCq5ng7ER0s0CMljOJRTNMUbNP9ifY9-DtW8yUP2FEGN9E6I99nJk/s320/1-6+helloworldimage.png" width="320" /></a></div>
<span id="goog_918381354"></span><span id="goog_918381355"></span><br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
2: The LibGDX Framework</span></strong></div>
<br />
<div class="BodyTextCont">
This chapter begins by discussing the overall structure
of a video game program, including the stages that a game program progresses
through, and the tasks that must be accomplished at each stage. Many of the
major features and classes of the LibGDX library are introduced in the process
of creating a basic game called Starfish Collector. This game is a recurring
example throughout the book: features will be added to this project when
introducing new topics.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPz9Q6ePUBxEDE2PfsyOrJij9t4zy8oTz-m85EoUbiAYoqEb-oiMM7r6bpGtyZtq9CYPte-hTL7MF3A7bbncSUXJBMH73N99BHuNvyPuVP_-gM-XS8IDMcr3-qM4JahKgooKW8fli5H34/s1600/2-1+starfish+collector.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="521" data-original-width="710" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPz9Q6ePUBxEDE2PfsyOrJij9t4zy8oTz-m85EoUbiAYoqEb-oiMM7r6bpGtyZtq9CYPte-hTL7MF3A7bbncSUXJBMH73N99BHuNvyPuVP_-gM-XS8IDMcr3-qM4JahKgooKW8fli5H34/s320/2-1+starfish+collector.png" width="320" /></a></div>
</div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
3: Extending the Framework<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you’ll start with one of the core LibGDX
classes that represents game entities, and create an extension of this class to
support animation, physics-based movement, improved collision detection, and
the ability to manage multiple instances of an entity using lists.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijxBInmirKB4yGTUpzaSLpM3de5e-LVCjfwtt4O0AdnZpR53MVJ0nDFI-Sagz6PpC44Ul7bHsa_bVxNgevqXNgUDfx6GKDMWlczMXOqwLxK5CmlVMGLyknaAo1M_ghkrHcaCkmA1vFP18/s1600/3-1+starfish+collector.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="519" data-original-width="632" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijxBInmirKB4yGTUpzaSLpM3de5e-LVCjfwtt4O0AdnZpR53MVJ0nDFI-Sagz6PpC44Ul7bHsa_bVxNgevqXNgUDfx6GKDMWlczMXOqwLxK5CmlVMGLyknaAo1M_ghkrHcaCkmA1vFP18/s320/3-1+starfish+collector.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
4: Shoot-em-up Games<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
This chapter demonstrates the power of the framework you
have created by using that framework to make an entirely new game: Space Rocks,
a space themed shoot-em-up game inspired by the classic arcade game Asteroids.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCc8av8h3BUpZViesi0BDPC80yfSyY_9cZNfcjKVMUNuIEvGMrM-uq7BUUuH1zsq3rkwv7SVBr93XFzsesNVkf2bGOBdfCHCy-dcpfwUOPne_djP9ZugS5wQdBNIV0aMH0XvVdMS-rCw/s1600/4-1+space+rocks.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="437" data-original-width="699" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCc8av8h3BUpZViesi0BDPC80yfSyY_9cZNfcjKVMUNuIEvGMrM-uq7BUUuH1zsq3rkwv7SVBr93XFzsesNVkf2bGOBdfCHCy-dcpfwUOPne_djP9ZugS5wQdBNIV0aMH0XvVdMS-rCw/s320/4-1+space+rocks.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
5: Text and User Interfaces<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will learn how to display text,
create buttons that display an image or text, and design a user interface using
tables. First, you will be introduced to these skills by adding these features
to the Starfish Collector game from Chapter 3. Then you will build on and
strengthen these skills while learning how to create cutscenes (sometimes
called in-game cinematics) that provide a narrative element to your games. In the final section, you will create a visual novel style game called The
Missing Homework, which focuses on a story and allows the player to make
decisions about how the story proceeds.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDTd8VbYSsJ7zpXZAUYv5iwaznz8VULBqomdv4hlNlIH0_5ADh61PtaLOeIUX0Bn_H0nbJZrH-h87OBjJCQE6_aevLPFWG9NMeKaIUpOQ-E8w9Y96ACiloaePs-OYnF7xusNF6SsUQa_k/s1600/5-3+missing+homework.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="685" data-original-width="987" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDTd8VbYSsJ7zpXZAUYv5iwaznz8VULBqomdv4hlNlIH0_5ADh61PtaLOeIUX0Bn_H0nbJZrH-h87OBjJCQE6_aevLPFWG9NMeKaIUpOQ-E8w9Y96ACiloaePs-OYnF7xusNF6SsUQa_k/s320/5-3+missing+homework.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
6: Audio<o:p></o:p></span></strong></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will learn how to add audio elements
- sound effects and background music - to your game. First, you will be
introduced to these topics by adding these features to the Starfish Collector.
Then you will build on these skills by a musical
rhythm-based game called <em><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Rhythm
Tapper</span></em>, in which the player presses a sequence of keys indicated visually
and synchronized with music playing in the background.<o:p></o:p><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihcNzabCivHNks5N7A5-1PQjOV4GREHhzpGlaO0SjSBpQlfRokfAqwX7ElBzKF0tzIT3r0-kPZEu1ma8Xk8vSWBFtm0eo9NqxRBdE4-fp4ze-x2WywmzAVD02mA2H56HvOHrtIhWzGEIc/s1600/6-1+rhythm+tapper.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="590" data-original-width="791" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihcNzabCivHNks5N7A5-1PQjOV4GREHhzpGlaO0SjSBpQlfRokfAqwX7ElBzKF0tzIT3r0-kPZEu1ma8Xk8vSWBFtm0eo9NqxRBdE4-fp4ze-x2WywmzAVD02mA2H56HvOHrtIhWzGEIc/s320/6-1+rhythm+tapper.png" width="320" /></a></div>
<br />
<div class="ChapterTitle">
<b><u>Part 2: Intermediate Examples</u></b><o:p></o:p></div>
<div class="ChapterTitle">
<br /></div>
<div class="BodyTextFirst">
With the solid foundation in the fundamental concepts
and classes in LibGDX and the custom framework you developed and refined in
Part 1, you are now prepared to create a variety of video games from different
genres, each featuring different mechanics. <o:p></o:p></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
7: Side-Scrolling Games<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will create a side-scrolling action
game called Plane Dodger, inspired by modern smartphone games such as Flappy
Bird and Jetpack Joyride. Along the way, you will learn how to create an
endless scrolling background effect, simulate gravity using acceleration
settings, and implement a difficulty ramp that increases the challenge to the
player as time passes.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2V5xP6VQcUijPebJgiMW1iip8W_FWjULEsFm2TuusBbzR8vG7-z5yT8xEqqCSKDWGJp7R-Ht8yGjWKHjnS3XpASil6JHc3P-WDVrCASAf1D2Cc-qcj2pGEF24L2o5eylS1WUE-PhEpA4/s1600/7-1+plane+dodger+screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="591" data-original-width="796" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2V5xP6VQcUijPebJgiMW1iip8W_FWjULEsFm2TuusBbzR8vG7-z5yT8xEqqCSKDWGJp7R-Ht8yGjWKHjnS3XpASil6JHc3P-WDVrCASAf1D2Cc-qcj2pGEF24L2o5eylS1WUE-PhEpA4/s320/7-1+plane+dodger+screenshot.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter 8:
Bouncing and Collision Games<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will create a ball-bouncing,
brick-breaking game called Rectangle Destroyer, inspired by arcade and early
console games such as Breakout and Arkanoid. New features that will be
implemented in this game include moving an object using the mouse, simulating
objects bouncing off of other objects, and creating power-up items that the
player can collect.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikN5JI-9fzI2LTJ-6n9bKSCvgbZJBey9bEDPqZjv1DBRFp2PLsd_EHln8VCdhOHYGQHm1raRmw5b2vFUWFSBMOqA09nvn_Dn_THl1Hwp6J2p7Yj18oNbafQslIs9oH969YBM4r0V5jE1o/s1600/8-1+screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="597" data-original-width="799" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikN5JI-9fzI2LTJ-6n9bKSCvgbZJBey9bEDPqZjv1DBRFp2PLsd_EHln8VCdhOHYGQHm1raRmw5b2vFUWFSBMOqA09nvn_Dn_THl1Hwp6J2p7Yj18oNbafQslIs9oH969YBM4r0V5jE1o/s320/8-1+screenshot.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
9: Drag and Drop Games<o:p></o:p></span></strong></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will learn how to add drag and drop
functionality to your games, and create a new class containing the related
code. To demonstrate the flexibility of this new class, you will create two new
games that make use of this class. The first will be a jigsaw puzzle game,
which consists of an image that has been broken into pieces and must be
rearranged correctly on a grid. The second will be a solitaire card game called
52 Card Pickup, where a standard deck of playing cards must be organized into
piles.<o:p></o:p><br />
<br /></div>
<div class="BodyTextFirst">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6dMBw-FEah0iLHV3V_rNyIJ3R1KXEWIsKAMs2Ktnc-gEREuFfhgh_5YtwDOhk-PckF5Q9tbmLi3xqwhusU0YoZrhIRefO63cKfpsXIukXYIuQzBL2_ozFpgwkbfgfaNV7n5fmxL0unh8/s1600/9-1+jigsaw+puzzle.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="594" data-original-width="792" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6dMBw-FEah0iLHV3V_rNyIJ3R1KXEWIsKAMs2Ktnc-gEREuFfhgh_5YtwDOhk-PckF5Q9tbmLi3xqwhusU0YoZrhIRefO63cKfpsXIukXYIuQzBL2_ozFpgwkbfgfaNV7n5fmxL0unh8/s320/9-1+jigsaw+puzzle.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJREmNbSlSDXZcoozuTR-m_e2VI8OWr0ZkOMhRIJXwmtZjWSEGyjd4x46403zecmHb_857yjz46cgvogiIswZppSPNXZsOoPscrhGk9ptTZPJWZl0xLqBwXHfqZ6dXGqnWqC0OAZ0oim4/s1600/9-2+solitaire.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="595" data-original-width="800" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJREmNbSlSDXZcoozuTR-m_e2VI8OWr0ZkOMhRIJXwmtZjWSEGyjd4x46403zecmHb_857yjz46cgvogiIswZppSPNXZsOoPscrhGk9ptTZPJWZl0xLqBwXHfqZ6dXGqnWqC0OAZ0oim4/s320/9-2+solitaire.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter 10:
Tilemaps<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
This chapter will explain how to use Tiled, a
general-purpose map editing software program that can be used for multiple
aspects of the level design process. Then you will create a class that allows
you to import the data from tilemap files into the custrom framework you have
developed. This knowledge will be used to improve two previous game
projects: for the Starfish Collector
game, you will design a maze-like level (using rocks for walls) and add some
scenery, while for the Rectangle Destroyer game, you will design a colorful
layout of bricks. <o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyiAibiapiR9pEJkWPfMlJhLe2UgslFbmmRU-Rj5mSVh8G3nta98jJqJuMD7mBiMhctiMSU4eLRif3vuXzkiXD3D3sZSZtzfpdpjaIwGPEbRyx9c7wiaRiuSz85-7klbE0XLz3Zw1Pwx0/s1600/10-1+starfish+collector+tilemap+version.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="585" data-original-width="797" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyiAibiapiR9pEJkWPfMlJhLe2UgslFbmmRU-Rj5mSVh8G3nta98jJqJuMD7mBiMhctiMSU4eLRif3vuXzkiXD3D3sZSZtzfpdpjaIwGPEbRyx9c7wiaRiuSz85-7klbE0XLz3Zw1Pwx0/s320/10-1+starfish+collector+tilemap+version.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNnxX9oGlZrkpHOdSFkc06EoNqWWCo8AzAEcOWmliEb64WjJHCgQHs4t_hMxJqghLGP9zYigcRiX0JlJr5cQg1H0wDkAze_-pbuoWX4DKqhHUH-SsoRmNwV5iAvZGALkJabARQRLsq19A/s1600/10-2+rectangle+destroyer+tilemap+version.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="642" data-original-width="834" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNnxX9oGlZrkpHOdSFkc06EoNqWWCo8AzAEcOWmliEb64WjJHCgQHs4t_hMxJqghLGP9zYigcRiX0JlJr5cQg1H0wDkAze_-pbuoWX4DKqhHUH-SsoRmNwV5iAvZGALkJabARQRLsq19A/s320/10-2+rectangle+destroyer+tilemap+version.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
11: Platform Games<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will learn how to create the
platform game <em><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Jumping Jack</span></em>,
inspired by arcade and console games such as Donkey Kong and Super Mario Bros.
New concepts introduced in this chapter include game entities with multiple
animations, platform physics, using extra actors as "sensors" to
monitor the area around an object for overlap and collision, jump-through
platforms, and key-and-lock mechanics.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGQDfyCPBzZK7kfCPGUj5M6za2UUXV_8MEkSvusVAHckpfQB3iw0-q0uXamvaDf3McJuZCd0jczr-KF2M4QuymYiMnUTqNqNy2P2d82XzSjY4Suj1J9S1Sncz2uw-NvQwzAwNO0JiWmOw/s1600/10-1+jumping+jack.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="625" data-original-width="799" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGQDfyCPBzZK7kfCPGUj5M6za2UUXV_8MEkSvusVAHckpfQB3iw0-q0uXamvaDf3McJuZCd0jczr-KF2M4QuymYiMnUTqNqNy2P2d82XzSjY4Suj1J9S1Sncz2uw-NvQwzAwNO0JiWmOw/s320/10-1+jumping+jack.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
12: Adventure Games<o:p></o:p></span></strong></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<br /></div>
<div class="BodyTextCont">
This chapter features the most ambitious game project in
the entire book: a combat-based adventure game named Treasure Quest, inspired
by classic console games such as The Legend of Zelda. This game uses new
features such as enemy combat with two different types of weapons (a sword and
an arrow), non-player characters (NPCs) with messages that depend on the state
of the game (such as the number of enemies remaining), and an item shop
mechanic.<o:p></o:p><br />
<br /></div>
<div class="MsoNormal">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzrPlr4kHyVWQ199w_5kfjqH4kRa_y4a27ZqjEPibmg0Ervg4Ygycip89NZWHaK5H4iFUPz-I8S3JGpkZKlypK3YcjQ1naY8V8IIrPdjLfMiL-eD1vAAj55v8fmZWsMTBGYt7EJFE_Oog/s1600/12-1+sword+swing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="663" data-original-width="991" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzrPlr4kHyVWQ199w_5kfjqH4kRa_y4a27ZqjEPibmg0Ervg4Ygycip89NZWHaK5H4iFUPz-I8S3JGpkZKlypK3YcjQ1naY8V8IIrPdjLfMiL-eD1vAAj55v8fmZWsMTBGYt7EJFE_Oog/s320/12-1+sword+swing.png" width="320" /></a></div>
<br /></div>
<div class="ChapterTitle">
<b><u>Part 3: Advanced Topics</u></b><o:p></o:p></div>
<div class="ChapterTitle">
<br /></div>
<div class="BodyTextFirst">
This final part of the book contains some additional
optional features that can be added to many of the previous projects, and some game projects and involve advanced algorithms and graphics.<o:p></o:p></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
13: Alternative Sources of User Input<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
This chapter will explore two alternative sources of user
input: gamepad controllers and touch-screen controls. In particular, you will
add these alternative sources of user input to the Starfish Collector game that
has been featured in previous chapters.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQJ9RbDCGERvX1YMpnFDk7KLCLByvdnvx_Ish_hxctcuRApZtCBMySHwIunnbZkKR8Gtmy_yZNNLWCxi3CxwDYuZEKJDDd5yi1dsbHVnyJpYhQBaA0mUhQFWRX88vvXAhQmwwi8iwH2rQ/s1600/13-4+touchpad+area.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="789" data-original-width="792" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQJ9RbDCGERvX1YMpnFDk7KLCLByvdnvx_Ish_hxctcuRApZtCBMySHwIunnbZkKR8Gtmy_yZNNLWCxi3CxwDYuZEKJDDd5yi1dsbHVnyJpYhQBaA0mUhQFWRX88vvXAhQmwwi8iwH2rQ/s320/13-4+touchpad+area.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter 14:
Maze Games<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will learn how to create the
maze-based game Maze Runman, inspired by arcade games such as Pac-Man and the early
console game Maze Craze. The main new concepts in this chapter are algorithms
for generating and solving mazes.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnQXN7wht5ppwWydBWgAnJZMlHqgUHy0-k1JId1p3ywseiCeaTKZ-_9sY4-JxyaI5luE-ao193fiZXfrMOPxArUTQhMjUzNX27wLaAsaZJl-oKIizRGJrgni_mLemQiFClh046frE6r5g/s1600/14-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="700" data-original-width="769" height="289" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnQXN7wht5ppwWydBWgAnJZMlHqgUHy0-k1JId1p3ywseiCeaTKZ-_9sY4-JxyaI5luE-ao193fiZXfrMOPxArUTQhMjUzNX27wLaAsaZJl-oKIizRGJrgni_mLemQiFClh046frE6r5g/s320/14-1.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextFirst">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter 15:
Advanced 2D Graphics<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
In this chapter, you will learn two techniques for
incorporating sophisticated graphics into your projects. The first topic is
particle systems, which can create special effects such as explosions, which
will be incorporated into the Space Rocks game in place of spritesheet-based
animations. The second topic is shader programming, which manipulate the pixels
of a rendered image to create effects such as blurring or glowing, which will
be incorporated into the Starfish Collector game.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicCI-2ha74IfM-OMQY6Z49kLY6RHkMflpRoQM-T44Ul0ZTsYKKsD78HHtX4ruD2_fITPyTP959h06xXMOBQiUGX1tgX5RSGnDPOq0Dp3Vo9hLlgbYdQWwFtht3gajiLL_ows_x0FVUJLw/s1600/15-7+space-rocks-particles.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="421" data-original-width="582" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicCI-2ha74IfM-OMQY6Z49kLY6RHkMflpRoQM-T44Ul0ZTsYKKsD78HHtX4ruD2_fITPyTP959h06xXMOBQiUGX1tgX5RSGnDPOq0Dp3Vo9hLlgbYdQWwFtht3gajiLL_ows_x0FVUJLw/s320/15-7+space-rocks-particles.png" width="320" /></a></div>
<br /></div>
<div class="BodyTextCont" style="text-indent: 0in;">
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter
16: Introduction to 3D Graphics and Games<o:p></o:p></span></strong></div>
<div class="BodyTextFirst">
<br /></div>
<div class="BodyTextCont">
This chapter introduces some of the 3D graphics
capabilities of LibGDX and the concepts and classes necessary to describe and
render a three-dimensional scene. You’ll create the game Starfish Collector 3D, a
three-dimensional version of the Starfish Collector game introduced at the
beginning of the book.<o:p></o:p><br />
<br /></div>
<div class="BodyTextCont">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwOWVCacsppTGfebJLitXQx1x4KCYYac8rBkmmSMXTesSgQWUgKqAiDd1Sz8HUfFXUHr3geRtqU5rmxpkg08c-pLM5AV_qnvOzQq2NzhRJDiZuEqKOfa_cQbnh5z8eCUXww4Bu51JGi9M/s1600/16-1+starfish+collector+3D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="610" data-original-width="989" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwOWVCacsppTGfebJLitXQx1x4KCYYac8rBkmmSMXTesSgQWUgKqAiDd1Sz8HUfFXUHr3geRtqU5rmxpkg08c-pLM5AV_qnvOzQq2NzhRJDiZuEqKOfa_cQbnh5z8eCUXww4Bu51JGi9M/s320/16-1+starfish+collector+3D.png" width="320" /></a></div>
<br />
<strong><span style="font-family: "utopia" , serif; mso-bidi-font-family: "Times New Roman"; mso-bidi-theme-font: minor-bidi;">Chapter 17: The Journey Continues<o:p></o:p></span></strong></div>
<div class="BodyTextCont">
<br /></div>
<div class="BodyTextCont">
This final chapter presents a variety of steps to
consider as you continue on in game development. Among these, you’ll explore
working on additional projects, learning skills in related areas, and bringing
your games to a wider audience. Along the way, the chapter presents lists of
resources of all types, and general advice for many situations.<o:p></o:p></div>
<br />
<div class="MsoNormal">
<br /></div>
</div>
<div class="BodyTextCont">
</div>
<div class="MsoNormal">
<br /></div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-35759943022826146652017-06-01T13:51:00.001-04:002017-06-01T13:54:41.178-04:00Book published! Game Development with Construct 2I've published another book: <i>Game Development with Construct 2</i>.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp5cV9lIBnrfnihEUXJi3K-pbKgCjmwS6AggaX_xHq_wGy7CRfvTvgd5AgevVy9hlyxd-3Ym1JwjNUAiA_DBNy8kOUHYWVgNsnkCiskVPjxe8Zdj-V6ULDLuoAEMdVAYwTlCgKwpeDkqg/s1600/GameDevConstruct2.jpg" imageanchor="1"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp5cV9lIBnrfnihEUXJi3K-pbKgCjmwS6AggaX_xHq_wGy7CRfvTvgd5AgevVy9hlyxd-3Ym1JwjNUAiA_DBNy8kOUHYWVgNsnkCiskVPjxe8Zdj-V6ULDLuoAEMdVAYwTlCgKwpeDkqg/s320/GameDevConstruct2.jpg" width="213" /></a></div>
<br />
The book is currently available at:<br />
<a href="https://www.amazon.com/Game-Development-Construct-Design-Realization/dp/1484227832/">https://www.amazon.com/Game-Development-Construct-Design-Realization/dp/1484227832/</a><br />
and<br />
<a href="http://www.apress.com/us/book/9781484227831">http://www.apress.com/us/book/9781484227831</a> <br />
(The Apress site contains downloadable graphics used to create the games.)<br />
<br />
What is this book about? From the introduction:<br />
<br />
<blockquote class="tr_bq">
In this book, you’ll learn how to create video
games using the <a href="https://www.scirra.com/">Construct 2</a> game engine, an ideal program for aspiring game
developers who have no prior experience, as well as experienced game developers
looking for a tool to rapidly create prototypes of games. The games you will
create in this book are inspired by classic arcade games such as Asteroids,
Frogger, Breakout, and PacMan, general genres such as car racing or tower
defense games, and console games such as Super Mario Bros. and The Legend of
Zelda.</blockquote>
<br />
<blockquote class="tr_bq">
Construct 2 is both user-friendly and powerful.
The software has been around for more than five years, has been downloaded more
than 3.5 million times, and has an active user community and responsive
development team. Games created with Construct 2 can be exported to run on a
variety of platforms and operating systems, such as web browsers (HTML5),
Windows, MacOS, Linux, Android, and iOS. A free version of Construct 2 is
available for download, and is sufficient for all the game projects contained
in this book.</blockquote>
<br />
<blockquote class="tr_bq">
Much like the software itself, this book does not
assume that you have any prior programming or game development experience. Over
the course of the book, you will be guided in creating a series of 12 different
video games of increasing complexity that will teach you both the features of
the Construct 2 game engine, as well as game development topics and logical programming
concepts that can serve you well for software development in general.</blockquote>
<div class="FMTextContCxSpFirst">
<o:p></o:p></div>
<div class="FMTextContCxSpMiddle">
<o:p></o:p></div>
<br />
<div class="FMTextContCxSpLast">
<o:p></o:p></div>
<div class="FMTextContCxSpLast">
<br /></div>
<div class="FMTextContCxSpLast">
Finally, here are some screenshots from the games you can learn to create in this book:</div>
<div class="FMTextContCxSpLast">
<br /></div>
<div class="FMTextContCxSpLast">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl5p35afUJngZWH1FEl_4bpy5mS6DXdaeyFCVV4hKm0f797zW9xyqz-2iddVJMNIardewx6u3yhDtrsqjmRnraAGIKNMSQuWi14upQePePLkwWH6t0bgyNMLOmzIWrJZtpEnSXe6_BbQw/s1600/2.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl5p35afUJngZWH1FEl_4bpy5mS6DXdaeyFCVV4hKm0f797zW9xyqz-2iddVJMNIardewx6u3yhDtrsqjmRnraAGIKNMSQuWi14upQePePLkwWH6t0bgyNMLOmzIWrJZtpEnSXe6_BbQw/s320/2.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Starfish Collector<br />
(an item-collecting game)</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbq-T5Kqsm6AToup3Xe-z9Zlh5oFnWdhOWHlmT0XyvoNQeLmRDnvVIRL90igo7LiH0kSWLyNB8G4W-2DUrV4QSkG64wncsfGRh_JpDAEfgkrZeq02jqMoeTF0BZwtfWXXy4XxYoWaVOis/s1600/3.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbq-T5Kqsm6AToup3Xe-z9Zlh5oFnWdhOWHlmT0XyvoNQeLmRDnvVIRL90igo7LiH0kSWLyNB8G4W-2DUrV4QSkG64wncsfGRh_JpDAEfgkrZeq02jqMoeTF0BZwtfWXXy4XxYoWaVOis/s320/3.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Space Rocks<br />
(inspired by Asteroids)</td></tr>
</tbody></table>
<div class="FMTextContCxSpLast">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9qan1GOUaqomS8rc1TEuuq6H30-G3esaCeVomXF0L0ffVpOLDyFRrk-mCfDwxWrdbmta453oA7GxjohbGTpaIpdsnMSxRYfkMWDTNyI3islH8VGbgA6LpbBFUr6eGwWUdY4q_ZKr4fqE/s1600/4.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9qan1GOUaqomS8rc1TEuuq6H30-G3esaCeVomXF0L0ffVpOLDyFRrk-mCfDwxWrdbmta453oA7GxjohbGTpaIpdsnMSxRYfkMWDTNyI3islH8VGbgA6LpbBFUr6eGwWUdY4q_ZKr4fqE/s320/4.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cleanup Challenge<br />(inspired by Frogger)</td></tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi90NIkNoCOgYi8oNSuLSi05RSKy1uAZzHkix9TPIUJrTXEsObUcKpTEwnDDW420gJfu1lRE91dCNr9aNG2oYpLmQv15H4tOLUAoD99frdjU1OVf2BNN76npB5W9sbgL1oi9m05upAqqoY/s1600/6.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi90NIkNoCOgYi8oNSuLSi05RSKy1uAZzHkix9TPIUJrTXEsObUcKpTEwnDDW420gJfu1lRE91dCNr9aNG2oYpLmQv15H4tOLUAoD99frdjU1OVf2BNN76npB5W9sbgL1oi9m05upAqqoY/s320/6.1.png" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Plane Dodger<br />
(inspired by Flappy Bird)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPrid7VZ_Z8e-7gL52eAugcC9AGtyhEg_9F_7XCbVQhoaGXjTqJTcbDuucnBtD8TAASu-NCm8FuSaqEtUtzeml8aeanUuPrFU2YaFIBsotuJsgZX6zhIZjtdUSIsYPxm7rvL3gEgSFucE/s1600/7.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPrid7VZ_Z8e-7gL52eAugcC9AGtyhEg_9F_7XCbVQhoaGXjTqJTcbDuucnBtD8TAASu-NCm8FuSaqEtUtzeml8aeanUuPrFU2YaFIBsotuJsgZX6zhIZjtdUSIsYPxm7rvL3gEgSFucE/s320/7.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Racecar 500<br />
(a top-down racing game)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPDj5cXzile683JrzNRJxpgk04GVwdKUczk1sbzzsOOrEt8hsez0KDB0skr9agpKtEjpPfcOH4NJM7gtWKnvTYaeoMfCwvc_z1XqR-AXC4Vej3nkWkilTH7G25mW4s3Q2TP4d9fTxMsto/s1600/8.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPDj5cXzile683JrzNRJxpgk04GVwdKUczk1sbzzsOOrEt8hsez0KDB0skr9agpKtEjpPfcOH4NJM7gtWKnvTYaeoMfCwvc_z1XqR-AXC4Vej3nkWkilTH7G25mW4s3Q2TP4d9fTxMsto/s320/8.1.png" width="245" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Rectangle Destroyer<br />
(inspired by Breakout and Arkanoid)</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Ujnr7dUfSgQdLdPkfMclphZ512JC2cU5SZDJbvfNq3FlvmUjoaCmDRlYPKz0tkrlToYk681rovO18y2yJvG5HCe_jrXWapEGwhF9h8nmPtWj_ngvY9D0ijrmA1S_SEAZVfWW45yC4Gw/s1600/9.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Ujnr7dUfSgQdLdPkfMclphZ512JC2cU5SZDJbvfNq3FlvmUjoaCmDRlYPKz0tkrlToYk681rovO18y2yJvG5HCe_jrXWapEGwhF9h8nmPtWj_ngvY9D0ijrmA1S_SEAZVfWW45yC4Gw/s320/9.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Spell Shooter<br />
(a top-down targeting game)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXF9MYl-RnBz6wj-aDKWQfdHbG8J1hLTbABo3p3wiygcTySvypGVZWHkVbCz29YKr_iuox8GW4ZNKrQi2JT7Lvs7pw_M5gpAEvDNRr1nRmo2wHRdgT9Q2Z2Ljpm_g4-Mt0ZzdoTeaWG74/s1600/10.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXF9MYl-RnBz6wj-aDKWQfdHbG8J1hLTbABo3p3wiygcTySvypGVZWHkVbCz29YKr_iuox8GW4ZNKrQi2JT7Lvs7pw_M5gpAEvDNRr1nRmo2wHRdgT9Q2Z2Ljpm_g4-Mt0ZzdoTeaWG74/s320/10.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Airplane Assault<br />
(inspired by the arcade game 1942)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP_uM3xdMiEpv1ZD_aq3RlqtJhVQ5sB1Moq5j81OhmE-zbXy6FO72k_3Z1Aw8pF_KbK9CUzsGQNHSlEMZeUuyDrkAj8Oc_gwZ22mlNodH3hWkVnamUOcID5by1P_BEmnzM75Dql1Xi9Xs/s1600/11.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP_uM3xdMiEpv1ZD_aq3RlqtJhVQ5sB1Moq5j81OhmE-zbXy6FO72k_3Z1Aw8pF_KbK9CUzsGQNHSlEMZeUuyDrkAj8Oc_gwZ22mlNodH3hWkVnamUOcID5by1P_BEmnzM75Dql1Xi9Xs/s320/11.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tower Defenders<br />
(a tower defense style game)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZwUXCr21OajbOv2o1ZYWAh4OrBbiP1tFLzylzGYaN_Lv048sKHiOjdl52a18nHdNeyMHOBAUDCcTUNybupDOrLo1W0ChmSvJ9QPo9-glwO7tohC933uudFhS42xWrmsU_uNbo7VHotVs/s1600/12.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="319" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZwUXCr21OajbOv2o1ZYWAh4OrBbiP1tFLzylzGYaN_Lv048sKHiOjdl52a18nHdNeyMHOBAUDCcTUNybupDOrLo1W0ChmSvJ9QPo9-glwO7tohC933uudFhS42xWrmsU_uNbo7VHotVs/s320/12.1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Maze Runman<br />
(inspired by PacMan)</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaFgvz-VRqcSYPUXfy_ikS7cKfHFS42cxyDpd2tZQ0yiRnsxZh8EK61hyL3BFLlRnudUdsBmKcSnLYSmNYiTAZA6bThuKxmbB3Wxzyh13KTNWagc1DWciFODkDv5DhYcJR2eS_XB3hJ2U/s1600/13-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaFgvz-VRqcSYPUXfy_ikS7cKfHFS42cxyDpd2tZQ0yiRnsxZh8EK61hyL3BFLlRnudUdsBmKcSnLYSmNYiTAZA6bThuKxmbB3Wxzyh13KTNWagc1DWciFODkDv5DhYcJR2eS_XB3hJ2U/s320/13-1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Jumping Jack<br />
(inspired by Super Mario Bros.)</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRhzmEoESO47cbyBJ8mt2osR0R74nkzv9N0mondyATGxNsCikmRoFKHHeHLyyQJc7-TFrQALOlNJx6u897PiCgF-W7Gcn4DJnv96cD23Ju86yjtcfbuiaK0RIz8-YvYRMDV5X5ymSAXWk/s1600/14-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRhzmEoESO47cbyBJ8mt2osR0R74nkzv9N0mondyATGxNsCikmRoFKHHeHLyyQJc7-TFrQALOlNJx6u897PiCgF-W7Gcn4DJnv96cD23Ju86yjtcfbuiaK0RIz8-YvYRMDV5X5ymSAXWk/s320/14-1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Treasure Quest<br />
(inspired by the Legend of Zelda)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-26757458646329222422016-01-06T16:20:00.001-05:002016-01-06T16:23:44.941-05:00LibGDX game jam - dev log #2The next big addition to my LibGDX game jam project has been the addition of character dialog menus, inspired by those from the early Final Fantasy games.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi73UKJ8KW5zjy_0hyhVu-Gihwiv9mSnMBIDzVgqlacPZbdue2VNDtfKxKVv76vAPKyH11X5vaLj18sXQM96-dthK_-NU7-aS9Icg_dbiuM3Mj3jWpXtixqjgyuoCoOaJzTqX24al-L9yA/s1600/libgdx-dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi73UKJ8KW5zjy_0hyhVu-Gihwiv9mSnMBIDzVgqlacPZbdue2VNDtfKxKVv76vAPKyH11X5vaLj18sXQM96-dthK_-NU7-aS9Icg_dbiuM3Mj3jWpXtixqjgyuoCoOaJzTqX24al-L9yA/s320/libgdx-dialog.png" width="306" /></a></div>
<br />
<br />
To support this feature, the main additions have been:<br />
<ul>
<li>a <span style="font-family: Courier New, Courier, monospace;">DialogSequence</span> object, which contains an <span style="font-family: Courier New, Courier, monospace;">ArrayList</span> of <span style="font-family: Courier New, Courier, monospace;">String</span>s to store the lines of text that appear, and an <span style="font-family: Courier New, Courier, monospace;">Iterator</span> and some basic access methods for convenience (<span style="font-family: Courier New, Courier, monospace;">add</span>, <span style="font-family: Courier New, Courier, monospace;">next</span>, <span style="font-family: Courier New, Courier, monospace;">hasNext</span>)</li>
<li>a <span style="font-family: Courier New, Courier, monospace;">DialogTrigger</span> object, which extends the <span style="font-family: Courier New, Courier, monospace;">Box2DActor</span> class and contains:</li>
<ul>
<li>a <span style="font-family: Courier New, Courier, monospace;">DialogSequence</span> object</li>
<li>a <span style="font-family: Courier New, Courier, monospace;">boolean</span> variable called <span style="font-family: Courier New, Courier, monospace;">displayOnce</span> that, as the name suggests, determines if the dialog displays only once, or will appear repeatedly</li>
</ul>
<li>a set of corresponding user interface elements: the text is displayed in a <span style="font-family: Courier New, Courier, monospace;">Label</span> (with a <span style="font-family: Courier New, Courier, monospace;">NinePatch</span> background) on the <span style="font-family: Courier New, Courier, monospace;">Stage</span> containing the user interface elements. The alignment is managed with a <span style="font-family: Courier New, Courier, monospace;">Table</span>. To continue, the user needs to press the C key. Thus, in addition, there is an <span style="font-family: Courier New, Courier, monospace;">Image</span> of the keyboard C key overlayed on the lower right corner of the <span style="font-family: Courier New, Courier, monospace;">Label</span>, with is accomplished using a <span style="font-family: Courier New, Courier, monospace;">Stack</span> object.</li>
</ul>
<br />
When the player comes into contact with a <span style="font-family: Courier New, Courier, monospace;">DialogTrigger</span> object (as determined by a Box2D <span style="font-family: Courier New, Courier, monospace;">ContactListener</span> object), the text is displayed on the dialog <span style="font-family: Courier New, Courier, monospace;">Label</span> and the <span style="font-family: Courier New, Courier, monospace;">Stack</span> containing the objects discussed above is set to visible. While the dialog text is visible, the program automatically returns from the <span style="font-family: Courier New, Courier, monospace;">update</span> method, which means that the physics simulation does not run and continuous user inputs are not polled (thus none of the game world entities move). However, <span style="font-family: Courier New, Courier, monospace;">Actions</span> are still processed, and discrete user input is still processed - this enables a subtle animated "pulsing" effect on the keyboard key image to take place, and also allows the user to press the key to cycle through the text contained in the <span style="font-family: Courier New, Courier, monospace;">DialogSequence</span> object.<br />
<br />
Some of the <span style="font-family: Courier New, Courier, monospace;">DialogTrigger</span> data can be set up in Tiled; this is particularly useful for situations where dialog should be triggered when the player walks over a certain area that doesn't correspond to a pre-existing game world object. This is accomplished by creating a Rectangle on the Object layer, named "DialogTrigger", and then by adding a set of properties whose names contain the letters "Text" (Text0, Text1, Text2, etc.) and whose data are the strings to be displayed. By including a property called "Once", the <span style="font-family: Courier New, Courier, monospace;">DialogTrigger</span> object will be configured (a boolean value will be set) so that the dialog sequence only displays once. Other dialog sequences can be configured in the code itself to be displayed when a pre-existing object should trigger a dialog sequence -- for example, when obtaining a key, you may want to display the message "You obtained a key!"<br />
<br />
Finally, if the <span style="font-family: Courier New, Courier, monospace;">DialogTrigger</span> field <span style="font-family: Courier New, Courier, monospace;">displayOnce</span> is set to true, then when the message is complete, it gets added to <span style="font-family: Courier New, Courier, monospace;">removeList</span>, which removes the corresponding body (that triggered the interaction) from the physics world, and also removes the object from its previously set "parentList", the <span style="font-family: Courier New, Courier, monospace;">ArrayList</span> of <span style="font-family: Courier New, Courier, monospace;">DialogTrigger</span> objects contained in the room, so even if the room is reloaded again later, the dialog will not display again.<br />
<br />
The code that implements these features is currently <a href="https://github.com/stemkoski/LibGDX-Jam">posted on GitHub</a>.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-90857539403999621842015-12-29T22:18:00.000-05:002016-01-09T15:02:56.361-05:00LibGDX game jam - dev log #1<br />
The LibGDX Game Jam is on!<br />
<br />
In addition to using LibGDX for the coding, I'll be using Tiled (<a href="http://www.mapeditor.org/">http://www.mapeditor.org/</a>) for level design and Box2D (<a href="http://box2d.org/">http://box2d.org/</a>) for physics. For prototyping I'll be using some spritesheets from (<a href="http://kenney.nl/">http://kenney.nl/</a>). If time permits, I'll work on some custom art assets later.<br />
<br />
All the code will be posted on GitHub at <a href="https://github.com/stemkoski/LibGDX-Jam">https://github.com/stemkoski/LibGDX-Jam</a><br />
<br />
The timing is great, as I've just finished writing <i>Beginning Java Game Development with LibGDX</i>, and this will be an excellent opportunity to build on the foundations presented by that book (source code from the book can be downloaded at <a href="http://www.apress.com/9781484215012">http://www.apress.com/9781484215012</a>). To get things up and running quickly, I'll be using (and improving) the following Java classes developed in the book:<br />
<br />
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">BaseGame </span>and <span style="font-family: Courier New, Courier, monospace;">BaseScreen</span>. These are abstract classes that extend the LibGDX <span style="font-family: Courier New, Courier, monospace;">Game </span>and <span style="font-family: Courier New, Courier, monospace;">Screen </span>classes, respectively.</li>
<li><span style="font-family: Courier New, Courier, monospace;">BaseActor</span>. Extends the LibGDX <span style="font-family: Courier New, Courier, monospace;">Actor </span>class, contains <span style="font-family: Courier New, Courier, monospace;">Texture </span>data and collision <span style="font-family: Courier New, Courier, monospace;">Shape </span>data (which we won't use, instead delegating collision handling to Box2D).</li>
<li><span style="font-family: Courier New, Courier, monospace;">AnimatedActor</span>. Extends the <span style="font-family: Courier New, Courier, monospace;">BaseActor </span>class, contains <span style="font-family: Courier New, Courier, monospace;">Animation </span>data. </li>
<li><span style="font-family: Courier New, Courier, monospace;">Box2DActor</span>. Extends the <span style="font-family: Courier New, Courier, monospace;">AnimatedActor </span>class, contains physics-related (<span style="font-family: Courier New, Courier, monospace;">Body</span>) data for Box2D.</li>
<li>GameUtils. A utility class containing methods to simplify (1) creating animations from files, and (2) processing collisions from Box2D.</li>
<li><span style="font-family: Courier New, Courier, monospace;">ParticleActor</span>. Extends the <span style="font-family: Courier New, Courier, monospace;">Actor </span>class, is useful for particle effects created with the LibGDX particle editor.</li>
</ul>
<br />
<br />
The theme for the LibGDX game jam is "Life in Space". My first thought was outer space -- planets, stars, rocketships, asteroids, etc. From a game design perspective, I've always had a great deal of respect for the classic arcade game <i>Asteroids</i>, for two reasons:<br />
<br />
<ul>
<li>its use of immersion: the controls move the spaceship relative to <i>its </i>orientation, rather than relative to the screen directions</li>
<li>the shape of its universe: this game features wraparound (the left side of the screen is connected to the right; the top side of the screen is connected to the bottom), and so the <i>Asteroids </i>universe actually exists on the surface of a torus (the shape of a doughnut)</li>
</ul>
<br />
And this train of thought led me to my interpretation of the theme: a key gameplay mechanic is going to be the player figuring out the shape of the space they are in. There will be a series of rooms, but in this universe, they will not be connected as a flat grid. This game will be more puzzle/maze based rather than combat based.<br />
<br />
The first step is going to be creating a data structure (called a <span style="font-family: Courier New, Courier, monospace;">Room</span>) to hold tilemap data, physics objects, stage objects, etc. The current plan is for each map created with Tiled to have three layers: a tile image layer, a layer for interactive game objects (keys, doors, etc.), and a layer to store non-interactive physics objects (the walls). Each room will have an ID, a number of <span style="font-family: Courier New, Courier, monospace;">SpawnPoint </span>objects (each with its own ID), and a number of <span style="font-family: Courier New, Courier, monospace;">Portal </span>objects (which contain a destination room ID and spawn point ID). The main game will read in the Tiled TMX files, store each in a custom Room object, and store the set of Rooms in a HashMap (indexed by ID).<br />
<br />
The images below show a room in Tiled, and as rendered in LibGDX.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZLTMXmml40QfCL-8knHPhjI3T53D68N5VrgIBwDT4xC14MhGbbj0or5B5EV_rdVacNakWvor_i6R0lmBGg2gLHj6F4iBLP4pKLEO48RPuPqityXL87eKpwVzlilOyHl6dwLRi3GLbW5k/s1600/Image+3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZLTMXmml40QfCL-8knHPhjI3T53D68N5VrgIBwDT4xC14MhGbbj0or5B5EV_rdVacNakWvor_i6R0lmBGg2gLHj6F4iBLP4pKLEO48RPuPqityXL87eKpwVzlilOyHl6dwLRi3GLbW5k/s320/Image+3.png" width="311" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">a room in Tiled</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiKSzGqaEsaERa2O7r5v6QDPLZH4subYxCE8cFsSIJuWScye4XGmjTZwEDh4uZe59xAPaV4wUEk0wvbkrl9dimJlo2-HU3C2k6PlGtmK_-pdpxaTwm6pQ5MJjSkl_6owvQJWc0W9kH9Ec/s1600/Image+2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiKSzGqaEsaERa2O7r5v6QDPLZH4subYxCE8cFsSIJuWScye4XGmjTZwEDh4uZe59xAPaV4wUEk0wvbkrl9dimJlo2-HU3C2k6PlGtmK_-pdpxaTwm6pQ5MJjSkl_6owvQJWc0W9kH9Ec/s320/Image+2.png" width="307" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">room rendered in LibGDX</td></tr>
</tbody></table>
<br />
Working code that implements these steps is currently available on <a href="https://github.com/stemkoski/LibGDX-Jam">GitHub</a>.<br />
<br />
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-27849610105524425032015-12-28T23:40:00.001-05:002016-01-09T15:02:41.363-05:00Book Published! Beginning Java Game Development with LibGDX<br />
<div>
I've written a book called <i>Beginning Java Game Development with LibGDX</i>, published by Apress, and available here: <a href="http://www.apress.com/9781484215012">http://www.apress.com/9781484215012</a></div>
<div>
<br />
<a href="http://bit.ly/LibGDX-Book"></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi19b3hf4xRNqL5SetNWXOlp7sBbToNZIkmxXXOW-DD5LxGsqn6tQAPE-QwQNW-NgTOYWfe_LFjOdqWRBAaeUuDXWF3SUMSupJEbD_utgzqABCssg0qs4qifV1VH9u9Bwvv1v1ttPKseIA/s1600/libgdx-book-cover.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi19b3hf4xRNqL5SetNWXOlp7sBbToNZIkmxXXOW-DD5LxGsqn6tQAPE-QwQNW-NgTOYWfe_LFjOdqWRBAaeUuDXWF3SUMSupJEbD_utgzqABCssg0qs4qifV1VH9u9Bwvv1v1ttPKseIA/s320/libgdx-book-cover.jpg" width="224" /></a></div>
<div>
<br /></div>
<div>
Here's what the book is about (quoted from the introduction):</div>
<div>
<blockquote class="tr_bq">
In this book, you’ll learn how to program games in Java using the LibGDX game development framework. The LibGDX libraries are both powerful and easy to use, and they will enable you to create a great variety of games quickly and efficiently. LibGDX is free and open-source, can be used to make 2D and 3D games, and integrates easily with third-party libraries to support additional features. Applications created in LibGDX are truly cross-platform; supported systems include Windows, Mac OS X, Linux, Android, iOS, and HTML5/WebGL. </blockquote>
<blockquote class="tr_bq">
I have taught courses in Java programming and video game development for many years, and I’ve often struggled to find game programming books that I can recommend to my students without reservation, which led me to write this book. In particular, you will find that this book contains the following unique combination of features, chosen with the aspiring game developer in mind:<br />
<ul>
<li>This book recommends and explains how to use a simple Java development environment (BlueJ) so that you can move on to programming games more quickly.</li>
</ul>
<ul>
<li>By using the LibGDX framework, you won’t have to “reinvent the wheel” for common programming tasks such as rendering graphics and playing audio. (An explanation of how to write such code from scratch could easily require fifty or more additional pages of reading.) LibGDX streamlines the development process and allows you to focus on game mechanics and design.</li>
</ul>
<ul>
<li>This book contains many examples of video games that can be developed with LibGDX. The first few example projects will introduce you to the basic features provided by the framework; these starter projects will be extended in the chapters that follow to illustrate how to add visual polish and advanced functionality. Later projects will focus on implementing game mechanics from a variety of genres: shoot-’em-ups, infinite side scrollers, drag-and-drop games, platform games, adventure games with a top-down perspective, and 2.5D games. I believe that working through many examples is fundamental in the learning process; you will observe programming patterns common to many games, you will see the benefits of writing reusable code in practice, you will have the opportunity to compare and contrast code from different projects, and you will gain experience by implementing additional features on your own.</li>
</ul>
<ul>
<li>At the beginning of this book, I am only assuming that you have a basic familiarity with Java programming. (Details about what background knowledge you need are discussed in the appendix.) Throughout the first few chapters of this book, advanced programming concepts will be introduced and explained as they arise naturally and are needed in the context of game programming. By the time you reach the end of this book, you will have learned about many advanced Java programming topics that are also useful for software development in general.</li>
</ul>
</blockquote>
</div>
<div>
And here are some screenshots of some of the many games and demos you'll create in the book:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTqGU9vLdJrt6UOjznf2S28iEjMWkj_LVPgUQQS6XNl65U4njk-Df18wgabt2dnTEr22Jr5OoaXyZ99mh1p_2WJ4UqWnmnoITZxzW4tPBkz1N2EzXTGHUy3zWEETtS_zh0DkTz7NhmWho/s1600/1-cheese-please-blog.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTqGU9vLdJrt6UOjznf2S28iEjMWkj_LVPgUQQS6XNl65U4njk-Df18wgabt2dnTEr22Jr5OoaXyZ99mh1p_2WJ4UqWnmnoITZxzW4tPBkz1N2EzXTGHUy3zWEETtS_zh0DkTz7NhmWho/s320/1-cheese-please-blog.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cheese, Please!</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX3sANbCrUXkWZQi4rhADcURvDB97-0QHsYUL7gN83iKiCPz624qzZlpNeQYzgbq5b9D7OVu3UO2YXSpNzyfMeVjOBnq2cuGHoneVR41k6bXgI105tn9PZzhVr4KnOuzn4dWVtC4lMzZE/s1600/1-balloon-buster-blog.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX3sANbCrUXkWZQi4rhADcURvDB97-0QHsYUL7gN83iKiCPz624qzZlpNeQYzgbq5b9D7OVu3UO2YXSpNzyfMeVjOBnq2cuGHoneVR41k6bXgI105tn9PZzhVr4KnOuzn4dWVtC4lMzZE/s320/1-balloon-buster-blog.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Balloon Buster</td></tr>
</tbody></table>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVUBT3jX71vvNQpnkBWPX6qioifShpz2GuA_AJU73_0XPviPoNjDOvqau0xDnlB2muPgXnnHFi3xxfiRmwn8jHZLMP1X7HVnUdPOyZEESMsLE8J_x0dtTtjQIFGOcdpyXEUHD9VMGWWYc/s1600/4-2-game-screen-blog.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVUBT3jX71vvNQpnkBWPX6qioifShpz2GuA_AJU73_0XPviPoNjDOvqau0xDnlB2muPgXnnHFi3xxfiRmwn8jHZLMP1X7HVnUdPOyZEESMsLE8J_x0dtTtjQIFGOcdpyXEUHD9VMGWWYc/s320/4-2-game-screen-blog.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Starfish Collector</td></tr>
</tbody></table>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzWuEedtKykgoqetYnMWyt180Gsi6cby6mO1xyHX7MCGqWtltJ3SzkZYfnRlSsaml91MeebG2ZsEWvMOkRc6K9Z_zdQBGStM-M40dbXcKuouAS2qwzyRbtPrAGklysPXdeuRjC07tjn5I/s1600/6-1-space-rocks.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzWuEedtKykgoqetYnMWyt180Gsi6cby6mO1xyHX7MCGqWtltJ3SzkZYfnRlSsaml91MeebG2ZsEWvMOkRc6K9Z_zdQBGStM-M40dbXcKuouAS2qwzyRbtPrAGklysPXdeuRjC07tjn5I/s320/6-1-space-rocks.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Space Rocks - inspired by Asteroids</td></tr>
</tbody></table>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj4dl2H3iiS67o7SWw_Kx6hHiJrrFHcybKonLhFGfZ2VSJUMqaERtroeqL0MBgpgvKJWu2Z-M7NbgOmUWSbBmBAqiJOcuhWHg4-jya7B60q9idfGUV0nAPnsr_dcZMDu-K9GEZVWRU46U/s1600/6-4-plane-dodger.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj4dl2H3iiS67o7SWw_Kx6hHiJrrFHcybKonLhFGfZ2VSJUMqaERtroeqL0MBgpgvKJWu2Z-M7NbgOmUWSbBmBAqiJOcuhWHg4-jya7B60q9idfGUV0nAPnsr_dcZMDu-K9GEZVWRU46U/s320/6-4-plane-dodger.png" width="320" /></a></td></tr>
<tr><td class="tr-caption">Plane Dodger - inspired by Flappy Bird</td></tr>
</tbody></table>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn_9P5xVYhCEu-RQ4FMrORFjDWZxK-0-JxcRO0dGXVpY0n37Tsidm_sGTAcEGvNXX8D_uCgf40qbUtKcHS-akSks4gMTe2j84monjPrH5T5SkKSLJN0JZXJNt87zrLL0kLa3DU3APhbQg/s1600/rectangle-destroyer.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn_9P5xVYhCEu-RQ4FMrORFjDWZxK-0-JxcRO0dGXVpY0n37Tsidm_sGTAcEGvNXX8D_uCgf40qbUtKcHS-akSks4gMTe2j84monjPrH5T5SkKSLJN0JZXJNt87zrLL0kLa3DU3APhbQg/s320/rectangle-destroyer.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Rectangle Destroyer - inspired by Breakout</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6n9j57Yvoqin7Cdj0fDbPgNfQitbT750gwxwQzVefMVqTTM7XgzqflhAYhlouTjydIN3bZ-WAF8M_Wp6geZHrJScF8wQhbzHBR9YoiRhLe66Kldv7smgWnAAVKiXL6v3ab54asmKbqhY/s1600/6-11-screenshot-52-card-pickup.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6n9j57Yvoqin7Cdj0fDbPgNfQitbT750gwxwQzVefMVqTTM7XgzqflhAYhlouTjydIN3bZ-WAF8M_Wp6geZHrJScF8wQhbzHBR9YoiRhLe66Kldv7smgWnAAVKiXL6v3ab54asmKbqhY/s320/6-11-screenshot-52-card-pickup.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">52 Card Pickup</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg-fpyj5pG5AhCmWv_cweYx8GGqdXDAWExXLL5LgAXN-ZFVF8e5MtSHejjki9j455P6J-jhnZQPfPMt_-NXFBq00MMtdwJp_Lb9gUfcHK-pf1SuOntjjpQa_fHCpjAGezPKOcM3W_a6pM/s1600/starscape-screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg-fpyj5pG5AhCmWv_cweYx8GGqdXDAWExXLL5LgAXN-ZFVF8e5MtSHejjki9j455P6J-jhnZQPfPMt_-NXFBq00MMtdwJp_Lb9gUfcHK-pf1SuOntjjpQa_fHCpjAGezPKOcM3W_a6pM/s320/starscape-screenshot.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Starscape - a particle effects demo</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkzsntl6j49q5KO8zghZPeQsoPQ_3WM9vt6Qz8_pwpY9x5UJaiLH22XxDBdhtB2Gd0ZJniojMsHcWNvsB9dyA45tfx8nnBFnAUN0lrf_YcyGMK-6UegnbYNOpSSE4FuvVIiw1vQDRmDps/s1600/JumpingJack-screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkzsntl6j49q5KO8zghZPeQsoPQ_3WM9vt6Qz8_pwpY9x5UJaiLH22XxDBdhtB2Gd0ZJniojMsHcWNvsB9dyA45tfx8nnBFnAUN0lrf_YcyGMK-6UegnbYNOpSSE4FuvVIiw1vQDRmDps/s320/JumpingJack-screenshot.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Jumping Jack - a sandbox style physics demo</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg54hzERhPqPzVawAmMOgTHqM6CS6rXjRJTyVhdhHlTkQOVVaXVxQ8ULszFFquyah8zM8IUJFQGRIN6cF0qH7bBN55rJ6s7FaGsrjrHlX4EQN5zRuGsq8LbT2vpOV826pHgxJeeZJR2Tdo/s1600/jumpingjack2-screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg54hzERhPqPzVawAmMOgTHqM6CS6rXjRJTyVhdhHlTkQOVVaXVxQ8ULszFFquyah8zM8IUJFQGRIN6cF0qH7bBN55rJ6s7FaGsrjrHlX4EQN5zRuGsq8LbT2vpOV826pHgxJeeZJR2Tdo/s320/jumpingjack2-screenshot.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Jumping Jack 2 - a platformer game</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyPXmvHTOiO4pyIlyKzOA1K53qnbsJ6FTh840oPnSgEpjIBxXW0OLl12quwsJiAwIXLXlnq-49y7ak5NW5QEWv9Xpaom0uqlfQ2B4SjrA0As82uDySOkY4SYqCwfk-6Uc3nnTFYd-9fjg/s1600/TreasureQuest-screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyPXmvHTOiO4pyIlyKzOA1K53qnbsJ6FTh840oPnSgEpjIBxXW0OLl12quwsJiAwIXLXlnq-49y7ak5NW5QEWv9Xpaom0uqlfQ2B4SjrA0As82uDySOkY4SYqCwfk-6Uc3nnTFYd-9fjg/s320/TreasureQuest-screenshot.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Treasure Quest - a top-down adventure/rpg style game</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC3GCx4zdIVCb42boHzq_1JvR_fYXXD3e_a4vx-eJhiYST1SJWoZ3Gc9H4cgOtqMzmKqSazS15IFY80sCS4ffvtUlAuY4w6PcDcninTA4TbPzWgpxT1Taar8RTiH1-Bw5QotkCefFfHfY/s1600/8-8-pirates-cove.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC3GCx4zdIVCb42boHzq_1JvR_fYXXD3e_a4vx-eJhiYST1SJWoZ3Gc9H4cgOtqMzmKqSazS15IFY80sCS4ffvtUlAuY4w6PcDcninTA4TbPzWgpxT1Taar8RTiH1-Bw5QotkCefFfHfY/s320/8-8-pirates-cove.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pirate's Cove - an interactive 3D (2.5D) demo</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Interested? Check it out <a href="http://bit.ly/LibGDX-Book">a</a>t: <a href="http://www.apress.com/9781484215012">http://www.apress.com/9781484215012</a>!</div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-61267214954437033132013-12-05T13:42:00.002-05:002013-12-05T13:42:55.738-05:00Interactive Earth with Three.jsI have always been amazed by the Small Arms Import/Export Chrome Experiment at <a href="http://www.chromeexperiments.com/detail/arms-globe/">http://www.chromeexperiments.com/detail/arms-globe/</a> -- it combines data visualization (geography and timeline) with an interactive 3D model of the Earth, using the amazing Javascript library <a href="http://www.threejs.org/">Three.js</a>. The code is open source, <a href="http://github.com/dataarts/armsglobe">available on GitHub</a>, and I wanted to adapt part of it to a project I've been working on.<br />
<br />
As a first step, I wanted to implement the country selection and highlighting. I tried reading through the source code, but eventually got lost in the morass of details. Fortunately, I stumbled upon a blog post written by Michael Chang about creating this visualization; read it at <a href="http://mflux.tumblr.com/post/28367579774/armstradeviz">http://mflux.tumblr.com/post/28367579774/armstradeviz</a>. There are many great ideas discussed here, in particular about encoding information in images. Summarizing briefly: to determine the country that is clicked, there is a grayscale image in the background, with each country colored a unique shade of gray. Determine the gray value (0-255) of the pixel that was clicked and the corresponding country can be identified by a table lookup. (This technique is also mentioned at <a href="http://well-formed-data.net/archives/808/images-as-datastore">well-formed-data.net</a>.) The highlighting feature is similarly cleverly implemented: a second image, stored as a canvas element with dimensions 256 pixels by 1 pixel, contains the colors that will correspond to each country. The country corresponding to the value X in the previously mentioned table lookup will be rendered with the color of the pixel on the canvas at position (X,0). A shader is used to make this substitution and color each country appropriately. When a mouse click is detected, the canvas image is recolored as necessary; if the country corresponding to value X is clicked, the canvas pixel at (X,0) is changed to the highlight color, all other pixels are changed to the default color (black).<br />
<br />
For aesthetic reasons, I also decided to blend in a satellite image of Earth. Doing this with shaders is straightforward: one includes an additional texture and then mixes the color (vec4) values in the desired ratio in the fragment shader. However, the grayscale image that Chang uses is slightly offset and somehow differently projected from standard Earth images, which typically place the longitude of 180 degrees aligned with the left border of the image. So I did some image editing, using the satellite image as the base layer and Chang's grayscale image as a secondary translucent layer, then I attempted to cut and paste and move and redraw parts of the grayscale image so that they lined up. The results are far from pixel perfect, but adequate for my purposes. (If anyone reading this knows of a source for a more exact/professional such image, could you drop me a line? Either stemkoski@gmail or @ProfStemkoski on Twitter.) Then I used an edge detection filter to produce an image consisting of outlined countries, and also blended that into the final result in the fragment shader code. The result:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDwXPavsvsSZhD8KJaZ565ZJgYTfKsaxMdlTPp8IeyFk5JbSjEfNoMDiJ4hhnP3mqFQ_3dwpAFga1cfVaqKJVTOwvCRTHhTh-doIFMXHTyT8JreMmy7kID2PkO7Zvhgn6KYjvHd8Qx_zI/s1600/Earth-Country-Selection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDwXPavsvsSZhD8KJaZ565ZJgYTfKsaxMdlTPp8IeyFk5JbSjEfNoMDiJ4hhnP3mqFQ_3dwpAFga1cfVaqKJVTOwvCRTHhTh-doIFMXHTyT8JreMmy7kID2PkO7Zvhgn6KYjvHd8Qx_zI/s320/Earth-Country-Selection.png" width="320" /></a></div>
<br />
The code discussed above is available online at <a href="http://stemkoski.github.io/Three.js/Country-Select-Highlight.html">http://stemkoski.github.io/Three.js/Country-Select-Highlight.html</a>. <br />
<br />
More posts to follow on this project...<br />
<br />
Happy coding!<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-90918122537045301722013-07-05T11:41:00.001-04:002013-07-05T13:54:44.419-04:00Shaders in Three.js: glow and halo effects revisitedWhile updating my <a href="http://stemkoski.github.io/Three.js/">collection of Three.js examples</a> to v58 of <a href="http://threejs.org/">Three.js</a>, I decided to clean up some old code. In particular, I hoped that the selective glow and atmosphere examples could be simplified - removing the need for blending the results of a secondary scene - by using shaders more cleverly. I posted a <a href="http://stackoverflow.com/questions/17455776/three-js-shader-code-for-halo-effect-normals-need-transformation/17492162">question</a> at StackOverflow, and as it often happens, the process of writing the question as clearly as possible for an audience other than myself, helped to clarify the issue. The biggest hint came from a <a href="http://john-chapman-graphics.blogspot.com/2013/01/good-enough-volumetrics-for-spotlights.html">post at John Chapman's Graphics blog</a>:<br />
<blockquote class="tr_bq">
<i>The edges ... need to be softened somehow, and that's where the vertex normals come in. We can use the dot product of the view space normal ... with the view vector ... as a metric describing how how near to the edge ... the current fragment is.</i></blockquote>
Linear algebra is amazingly useful. Typically, for those faces that appear (with respect to the viewer) to be near the center of the mesh, the normal of the face will point in nearly the same direction as the "view vector" -- the vector from the camera to the face -- and then the dot product of the normalized vectors will be approximately equal to 1. For those faces that appear to be on the edge as viewed from the camera, their normal vectors will be perpendicular to the view vector, resulting in a dot product approximately equal to 0. Then we just need to adjust the intensity/color/opacity of the material based on the value of this dot product, and voila! we have a material whose appearance looks the same (from the point of view of the camera) no matter where the object or camera is, which is the basis of the glow effect. (The glow shouldn't look different as we rotate or pan around the object.) By adjusting some parameters, we can produce an "inner glow" effect, a "halo" or "atmospheric" effect, or a "shell" or "surrounding force field" effect. To see the demo in action, check out <a href="http://stemkoski.github.io/Three.js/Shader-Glow.html">http://stemkoski.github.io/Three.js/Shader-Glow.html</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Shader-Glow.html"><img border="0" height="174" src="http://stemkoski.github.io/Three.js/html-images/Shader-Glow.png" width="320" /></a></div>
<br />
<br />
In particular, click on the information button in the top left and adjust the values as recommended (or however you like) to see some of the possible effects.<br />
<br />
Happy coding!<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-77478244645705122572013-06-23T15:01:00.002-04:002013-06-23T15:03:59.674-04:00Creating a particle effects engine in Javascript and Three.jsA particle engine (or particle system) is a technique from computer graphics that uses a large number of small images that can be used to render special effects such as fire, smoke, stars, snow, or fireworks. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjukaagfv7qrWoowzEG7nTQTcsr5CQYuNzeu60tjDqlY2-f0iSGq9CjgFHWPTl97SL05pSiyGp3il1sf3vLKhWTPlhzMTUtSbI8xwAR5sfQYAypvb7cAoHaHFSN0cO5NXCXY-hD1Kgre5k/s1600/Particle-Engine.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjukaagfv7qrWoowzEG7nTQTcsr5CQYuNzeu60tjDqlY2-f0iSGq9CjgFHWPTl97SL05pSiyGp3il1sf3vLKhWTPlhzMTUtSbI8xwAR5sfQYAypvb7cAoHaHFSN0cO5NXCXY-hD1Kgre5k/s320/Particle-Engine.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Image of Particle Engine Example</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/gtr5QLu9RaI?feature=player_embedded' frameborder='0'></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Video of Particle Engine Examples</span><br />
<a href="http://www.youtube.com/watch?v=gtr5QLu9RaI">http://www.youtube.com/watch?v=gtr5QLu9RaI</a></div>
<br />
The engine we will describe consists of two main components: the particles themselves and the emitter that controls the creation of the particles.<br />
<br />
Particles typically have the following properties, each of which may change during the existence of the particle:<br />
<br />
<ul>
<li>position, velocity, acceleration (each a Vector3)</li>
<li>angle, angleVelocity, angleAcceleration (each a floating point number). this controls the angle of rotation of the image used for the particles (since particles will always be drawn facing the camera, only a single number is necessary for each)</li>
<li>size of the image used for the particles</li>
<li>color of the particle (stored as a Vector3 in HSL format) </li>
<li>opacity - a number between 0 (completely transparent) and 1 (completely opaque)</li>
<li>age - a value that stores the number of seconds the particle has been alive</li>
<li>alive - true/false - controls whether particle values require updating and particle requires rendering</li>
</ul>
<br />
Particles also often have an associated function that updates these properties based on the amount of time that has passed since the last update.<br />
<br />
A simple Tween class can be used to change the values of the size, color, and opacity of the particles. A Tween contains a sorted array of times [<i>T0</i>, <i>T1</i>, ..., <i>Tn</i>] and an array of corresponding values [<i>V0</i>, <i>V1</i>, ..., <i>Vn</i>], and a function that, at time <i>t</i>, with <i>Ta</i> < <i>t</i> < <i>Tb</i>, returns the value linearly interpolated by the corresponding amount between <i>Va</i> and <i>Vb</i>. (If <i>t</i> < <i>T0</i>, then <i>V0</i> is returned, and if <i>t</i> > <i>Tn</i>, then <i>Vn</i> is returned.)<br />
<div>
<br /></div>
Typically, we never interact with individual particle data directly, rather, we do it through the emitter.<br />
<br />
Our emitter will contains the following data:<br />
<br />
<ul>
<li>base and spread values for all the particle properties (<i>except</i> age and alive).<br />When particles are created, their properties are set to random values in the interval (<i>base - spread / </i>2<i>, base + spread / </i>2); particle age is set to 0 and alive status is set to false.</li>
<li>enum-type values that determine the shape of the emitter (either rectangular or spherical) and the way in which initial velocities will be specified (also rectangular or spherical)</li>
<li>base image to be used for each of the particles, the appearance of which is customized by the particle properties</li>
<li>optional Tween values for changing the size, color, and opacity values</li>
<li>blending style to be used in rendering the particles, typically either "normal" or additive (which is useful for fire or light-based effects)</li>
<li>an array of particles</li>
<li>number of particles that should be created per second</li>
<li>number of seconds each particle will exist</li>
<li>number of seconds the emitter has been active</li>
<li>number of seconds until the emitter stops -- for a "burst"-style effect, this value should be close to zero; for a "continuous"-style effect, this value should be large.</li>
<li>the maximum number of particles that can exist at any point in time, which is calculated from the number of particles created per second, and the duration of the particles and the emitter </li>
<li>Three.js objects that control the rendering of the particles: a THREE.Geometry, a THREE.ShaderMaterial, and a THREE.ParticleSystem.</li>
</ul>
<br />
The emitter also contains the following functions:<br />
<br />
<ul>
<li>setValues - sets/changes values within the emitter </li>
<li>randomValue and randomVector3 - takes a base value and a spread value and calculates a (uniformly distributed) random value in the range (<i>base - spread / </i>2<i>, base + spread / </i>2). These are helper functions for the createParticle function</li>
<li>createParticle - initializes a single particle according to parameters set in emitter</li>
<li>initializeEngine - initializes all emitter data</li>
<li>update - spawns new particles if necessary; updates the particle data for any particles currently existing; removes particles whose age is greater than the maximum particle age and reuses/recycles them if new particles need to created </li>
<li>destroy - stops the emitter and removes all rendered objects</li>
</ul>
Fortunately, all the graphics processing is handled by Three.js. There is an object in Three.js called "THREE.ParticleSystem" which allows you to assign an image to individual vertices of a geometry. The appearance of the particles is controller by a "THREE.ShaderMaterial", which requires us to write a custom vertex shader and a custom fragment shader with attributes which take all of our particle properties into account (image, angle, size, color, opacity, visibility) when rendering each particle.<br />
<br />
To try out a live demo, go to: <a href="http://stemkoski.github.io/Three.js/Particle-Engine.html">http://stemkoski.github.io/Three.js/Particle-Engine.html</a><br />
<br />
Also, feel free to check out the <a href="https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/js/ParticleEngine.js">Particle Engine source code</a>, the <a href="https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/js/ParticleEngineExamples.js">parameters for the examples in the demo</a>, and <a href="https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Particle-Engine.html">how to include the particle engine in a Three.js page</a>.<br />
<br />
Happy coding!<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-89514920061578984002013-05-31T12:57:00.001-04:002013-05-31T13:01:30.946-04:00Motion Detection and Three.jsThis post was inspired by and based upon the work of Romuald Quantin: he has written an excellent demo (play a xylophone using your webcam!) at <a href="http://www.soundstep.com/blog/2012/03/22/javascript-motion-detection/">http://www.soundstep.com/blog/2012/03/22/javascript-motion-detection/</a> and an in-depth article at<a href="http://www.adobe.com/devnet/html5/articles/javascript-motion-detection.html"> http://www.adobe.com/devnet/html5/articles/javascript-motion-detection.html</a>. Basically, I re-implemented his code with a few minor tweaks:
<br />
<br />
<ul>
<li>The jQuery code was removed.</li>
<li>There are two canvases: one containing the video image (flipped horizontally for easier interaction by the viewer), the second canvas containing the superimposed graphics</li>
<li>For code readability, there is an array (called "buttons") that contains x/y/width/height information for all the superimposed graphics, used for both the drawImage calls and the getImageData calls when checking regions for sufficient motion to trigger an action.</li>
</ul>
<br />
<br />
<div>
The first demo is a minimal example which just displays a message when motion is detected in certain regions; no Three.js code appears here.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.io/Three.js/html-images/Webcam-Motion-Detection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="http://stemkoski.github.io/Three.js/html-images/Webcam-Motion-Detection.png" width="320" /></a></div>
<div style="text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Webcam-Motion-Detection.html">http://stemkoski.github.io/Three.js/Webcam-Motion-Detection.html</a></div>
<div>
<br /></div>
<div>
The second demo incorporates motion detection in a Three.js scene. When motion is detected over one of three displayed textures, the texture of the spinning cube in the Three.js scene changes to match.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.io/Three.js/html-images/Webcam-Motion-Detection-Texture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="175" src="http://stemkoski.github.io/Three.js/html-images/Webcam-Motion-Detection-Texture.png" width="320" /></a></div>
<div style="text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Webcam-Motion-Detection-Texture.html">http://stemkoski.github.io/Three.js/Webcam-Motion-Detection-Texture.html</a></div>
<div>
<br /></div>
<div>
Here is a YouTube video of these demos in action:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/ehkqgaGwGcw?feature=player_embedded' frameborder='0'></iframe></div>
<div>
<br /></div>
<div>
Happy coding!</div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-58535580821061816032013-05-27T22:57:00.001-04:002013-05-27T22:57:29.074-04:00Animated Shaders in Three.js (Part 2)<br />
After my <a href="http://stemkoski.blogspot.com/2013/05/animated-shaders-in-threejs.html">previous post on animated shaders</a>, I decided to build on the shader code to create a more visually sophisticated "fireball effect". This time, my inspiration came from Jaume Sánchez Elias' <a href="http://www.clicktorelease.com/blog/experiments-with-perlin-noise">experiments with perlin noise</a>, particularly his great article on <a href="http://www.clicktorelease.com/blog/vertex-displacement-noise-3d-webgl-glsl-three-js">vertex displacement</a>. <br />
<br />
In the previous post, we have shader code for animating a "noisy" random distortion of a texture (the "base texture"). The noise is generated from the RGB values of a second texture (the "noise texture"). This time around, we add the following features:<br />
<br />
<ul>
<li>allow repeating the textures in each direction (<span style="font-family: Courier New, Courier, monospace;">repeatS</span> and <span style="font-family: Courier New, Courier, monospace;">repeatT</span>)</li>
<li>a second texture (the "blend texture") that is randomly distorted (at a different rate) and then additively blended with the base texture; we also pass in a float that controls the speed of distortion (<span style="font-family: Courier New, Courier, monospace;">blendSpeed</span>) and a float value (<span style="font-family: Courier New, Courier, monospace;">blendOffset</span>) that is subtracted from the pixel data so that darker parts of the blend texture may result in decreasing values in the base texture</li>
<li>randomly distort the positions of the vertices of the sphere using another texture (the "bump texture"); the rate at which these distortions change is controlled by a float value (<span style="font-family: Courier New, Courier, monospace;">bumpSpeed</span>) and the magnitude is controlled by a second float value (<span style="font-family: Courier New, Courier, monospace;">bumpScale</span>).</li>
</ul>
<br />
<br />
Causing the texture to repeat and blending in the color values takes place in the fragment shader, as follows:<br />
<br />
<pre class="prettyprint"><script id="fragmentShader" type="x-shader/x-vertex">
uniform sampler2D baseTexture;
uniform float baseSpeed;
uniform float repeatS;
uniform float repeatT;
uniform sampler2D noiseTexture;
uniform float noiseScale;
uniform sampler2D blendTexture;
uniform float blendSpeed;
uniform float blendOffset;
uniform float time;
uniform float alpha;
varying vec2 vUv;
void main()
{
vec2 uvTimeShift = vUv + vec2( -0.7, 1.5 ) * time * baseSpeed;
vec4 noise = texture2D( noiseTexture, uvTimeShift );
vec2 uvNoiseTimeShift = vUv + noiseScale * vec2( noise.r, noise.b );
vec4 baseColor = texture2D( baseTexture, uvNoiseTimeShift * vec2(repeatS, repeatT) );
vec2 uvTimeShift2 = vUv + vec2( 1.3, -1.7 ) * time * blendSpeed;
vec4 noise2 = texture2D( noiseTexture, uvTimeShift2 );
vec2 uvNoiseTimeShift2 = vUv + noiseScale * vec2( noise2.g, noise2.b );
vec4 blendColor = texture2D( blendTexture, uvNoiseTimeShift2 * vec2(repeatS, repeatT) ) - blendOffset * vec4(1.0, 1.0, 1.0, 1.0);
vec4 theColor = baseColor + blendColor;
theColor.a = alpha;
gl_FragColor = theColor;
}
</script>
</pre>
<br />
The bump mapping occurs in the vertex shader. Bump mapping is fairly straightforward -- see the article above for an explanation; the key code snippet is:<br />
vec4 newPosition = position + normal * displacement<br />
However, there are two particularly interesting points in the code below:<br />
<br />
<ol>
<li>Using time-shifted UV coordinates seems to create a "rippling" effect in the bump heights, while using the noisy-time-shifted UV coordinates seems to create more of a "shivering" effect.</li>
<li>There is a problem at the poles of the sphere -- the displacement needs to be the same for all vertices at the north pole and south pole, otherwise a tearing effect (a "jagged hole") appears, as illustrated at <a href="http://stackoverflow.com/questions/15876848/why-does-my-implementation-of-a-displacement-map-in-three-js-disconnect-vertices">StackOverflow</a> (and solved by WestLangley). This is the reason for the conditional operator that appears in the assignment of the distortion (and introduces not-so-random fluctuations at the poles).</li>
</ol>
<br />
Without further ado, The code for the new and improved vertex shader is:<br />
<br />
<pre class="prettyprint"><script id="vertexShader" type="x-shader/x-vertex">
uniform sampler2D noiseTexture;
uniform float noiseScale;
uniform sampler2D bumpTexture;
uniform float bumpSpeed;
uniform float bumpScale;
uniform float time;
varying vec2 vUv;
void main()
{
vUv = uv;
vec2 uvTimeShift = vUv + vec2( 1.1, 1.9 ) * time * bumpSpeed;
vec4 noise = texture2D( noiseTexture, uvTimeShift );
vec2 uvNoiseTimeShift = vUv + noiseScale * vec2( noise.r, noise.g );
// below, using uvTimeShift seems to result in more of a "rippling" effect
// while uvNoiseTimeShift seems to result in more of a "shivering" effect
vec4 bumpData = texture2D( bumpTexture, uvTimeShift );
// move the position along the normal
// but displace the vertices at the poles by the same amount
float displacement = ( vUv.y > 0.999 || vUv.y < 0.001 ) ?
bumpScale * (0.3 + 0.02 * sin(time)) :
bumpScale * bumpData.r;
vec3 newPosition = position + normal * displacement;
gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
}
</script>
</pre>
<br />
The code for integrating these shaders into Three.js:<br />
<br />
<pre class="prettyprint">// base image texture for mesh
var lavaTexture = new THREE.ImageUtils.loadTexture( 'images/lava.jpg');
lavaTexture.wrapS = lavaTexture.wrapT = THREE.RepeatWrapping;
// multiplier for distortion speed
var baseSpeed = 0.02;
// number of times to repeat texture in each direction
var repeatS = repeatT = 4.0;
// texture used to generate "randomness", distort all other textures
var noiseTexture = new THREE.ImageUtils.loadTexture( 'images/cloud.png' );
noiseTexture.wrapS = noiseTexture.wrapT = THREE.RepeatWrapping;
// magnitude of noise effect
var noiseScale = 0.5;
// texture to additively blend with base image texture
var blendTexture = new THREE.ImageUtils.loadTexture( 'images/lava.jpg' );
blendTexture.wrapS = blendTexture.wrapT = THREE.RepeatWrapping;
// multiplier for distortion speed
var blendSpeed = 0.01;
// adjust lightness/darkness of blended texture
var blendOffset = 0.25;
// texture to determine normal displacement
var bumpTexture = noiseTexture;
bumpTexture.wrapS = bumpTexture.wrapT = THREE.RepeatWrapping;
// multiplier for distortion speed
var bumpSpeed = 0.15;
// magnitude of normal displacement
var bumpScale = 40.0;
// use "this." to create global object
this.customUniforms = {
baseTexture: { type: "t", value: lavaTexture },
baseSpeed: { type: "f", value: baseSpeed },
repeatS: { type: "f", value: repeatS },
repeatT: { type: "f", value: repeatT },
noiseTexture: { type: "t", value: noiseTexture },
noiseScale: { type: "f", value: noiseScale },
blendTexture: { type: "t", value: blendTexture },
blendSpeed: { type: "f", value: blendSpeed },
blendOffset: { type: "f", value: blendOffset },
bumpTexture: { type: "t", value: bumpTexture },
bumpSpeed: { type: "f", value: bumpSpeed },
bumpScale: { type: "f", value: bumpScale },
alpha: { type: "f", value: 1.0 },
time: { type: "f", value: 1.0 }
};
// create custom material from the shader code above
// that is within specially labeled script tags
var customMaterial = new THREE.ShaderMaterial(
{
uniforms: customUniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var ballGeometry = new THREE.SphereGeometry( 60, 64, 64 );
var ball = new THREE.Mesh( ballGeometry, customMaterial );
scene.add( ball );
</pre>
<br />
For a live example, check out the demo in my GitHub collection, which uses this shader to create an animated fireball.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Shader-Fireball.html"><img border="0" height="174" src="http://stemkoski.github.io/Three.js/html-images/Shader-Fireball.png" width="320" /></a><span id="goog_1986041230"></span><span id="goog_1986041231"></span><a href="http://www.blogger.com/"></a></div>
<div style="text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Shader-Fireball.html">http://stemkoski.github.io/Three.js/Shader-Fireball.html</a></div>
<br />
Happy coding!<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-21056669547837729812013-05-25T22:49:00.002-04:002013-05-27T23:09:36.965-04:00Animated Shaders in Three.jsOnce again I have been investigating Shaders in <a href="http://threejs.org/">Three.js</a>. My <a href="http://stemkoski.blogspot.com/2013/03/using-shaders-and-selective-glow.html">last post</a> on this topic was inspired by glow effects; this time, my inspiration comes from the <a href="http://threejs.org/examples/webgl_shader_lava.html">Three.js lava shader</a> and Altered Qualia's <a href="http://alteredqualia.com/three/examples/webgl_shader_fireball.html">WebGL shader fireball</a>. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://threejs.org/files/examples/webgl_shader_lava.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://threejs.org/files/examples/webgl_shader_lava.jpg" /></a></div>
<br />
For these examples, I'm really only interested in changing the pixel colors, so I'll just worry about the fragment shader. <br />
<br />
The Three.js (v.56) code for the a simple fragment shader that just displays a texture would be:<br />
<pre class="prettyprint"><script id="fragmentShader" type="x-shader/x-vertex">
uniform sampler2D texture1;
varying vec2 vUv;
void main()
{
vec4 baseColor = texture2D( texture1, vUv );
gl_FragColor = baseColor;
}
</script>
</pre>
<div>
(note that this code is contained within its own script tags.)</div>
<div>
<br /></div>
<div>
Then to create the material in the initialization of the Three.js code:</div>
<div>
<pre class="prettyprint">var lavaTexture = new THREE.ImageUtils.loadTexture( 'images/lava.jpg' );
lavaTexture.wrapS = lavaTexture.wrapT = THREE.RepeatWrapping;
var customUniforms = { texture1: { type: "t", value: lavaTexture } };
// create custom material from the shader code above within specially labeled script tags
var customMaterial = new THREE.ShaderMaterial(
{
uniforms: customUniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );</pre>
<br />
What we would like to create a more realistic effect is to:</div>
<div>
<ul>
<li>add a bit of "random noise" to the texture coordinates vector (vUv) to cause distortion</li>
<li>change the values of the random noise so that the distortions in the image change fluidly</li>
<li>(optional) add support for transparency (custom alpha values)</li>
</ul>
</div>
<div>
To accomplish this, we can add some additional parameters to the shader, namely:</div>
<div>
<ul>
<li>a second texture (<span style="font-family: Courier New, Courier, monospace;">noiseTexture</span>) to generate "noise values"; for instance, we can add the red/green values at a given pixel to the x and y coordinates of vUv, causing an offset</li>
<li>a float (<span style="font-family: Courier New, Courier, monospace;">noiseScale</span>) to scale the effects of the "noise values" </li>
<li>a float (<span style="font-family: Courier New, Courier, monospace;">time</span>) to pass a "time" value to the shader to continuously shift the texture used to generate noise values</li>
<li>a float (base<span style="font-family: Courier New, Courier, monospace;">Speed</span>) to scale the effects of the time to either speed up or slow down rate of distortions in the base texture</li>
<li>a float (<span style="font-family: Courier New, Courier, monospace;">alpha</span>) to set the transparency amount</li>
</ul>
</div>
<div>
The new version of the fragment shader code looks like this:</div>
<div>
<pre class="prettyprint"><script id="fragmentShader" type="x-shader/x-vertex">
uniform sampler2D baseTexture;
uniform float baseSpeed;
uniform sampler2D noiseTexture;
uniform float noiseScale;
uniform float alpha;
uniform float time;
varying vec2 vUv;
void main()
{
vec2 uvTimeShift = vUv + vec2( -0.7, 1.5 ) * time * baseSpeed;
vec4 noise = texture2D( noiseTexture, uvTimeShift );
vec2 uvNoisyTimeShift = vUv + noiseScale * vec2( noise.r, noise.g );
vec4 baseColor = texture2D( baseTexture, uvNoisyTimeShift );
baseColor.a = alpha;
gl_FragColor = baseColor;
}
</script></pre>
<br />
The new code to create this shader in Three.js:</div>
<div>
<pre class="prettyprint">// initialize a global clock to keep track of time
this.clock = new THREE.Clock();
var noiseTexture = new THREE.ImageUtils.loadTexture( 'images/noise.jpg' );
noiseTexture.wrapS = noiseTexture.wrapT = THREE.RepeatWrapping;
var lavaTexture = new THREE.ImageUtils.loadTexture( 'images/lava.jpg' );
lavaTexture.wrapS = lavaTexture.wrapT = THREE.RepeatWrapping;
// create global uniforms object so its accessible in update method
this.customUniforms = {
baseTexture: { type: "t", value: lavaTexture },
baseSpeed: { type: "f", value: 0.05 },
noiseTexture: { type: "t", value: noiseTexture },
noiseScale: { type: "f", value: 0.5337 },
alpha: { type: "f", value: 1.0 },
time: { type: "f", value: 1.0 }
}
// create custom material from the shader code above within specially labeled script tags
var customMaterial = new THREE.ShaderMaterial(
{
uniforms: customUniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );</pre>
<br />
and in the update or render method, don't forget to update the time using something like:<br />
<pre class="prettyprint">var delta = clock.getDelta();
customUniforms.time.value += delta;</pre>
<br />
That's about it -- for a live example, check out the demo in my GitHub collection, which uses this shader to create an animated lava-style texture and animated water-style texture.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Shader-Animate.html"><img border="0" height="174" src="http://stemkoski.github.io/Three.js/html-images/Shader-Animate.png" width="320" /></a></div>
<div style="text-align: center;">
<a href="http://stemkoski.github.io/Three.js/Shader-Animate.html">http://stemkoski.github.io/Three.js/Shader-Animate.html</a></div>
<div>
<br /></div>
<div>
Happy coding!</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-55193487383369172112013-03-16T11:56:00.001-04:002013-03-16T14:24:23.931-04:00Using Shaders and Selective Glow Effects in Three.jsWhen I first started working with <a href="https://github.com/mrdoob/three.js/">Three.js</a>, in addition to the <a href="http://mrdoob.github.com/three.js/">awe-inspiring collection of examples</a> from <a href="https://plus.google.com/113862800338869870683">Mr.doob</a>, I was also dazzled by the "glow examples" of <a href="http://bkcore.com/">Thibaut Despoulain</a>: the <a href="http://demo.bkcore.com/threejs/webgl_tron_glow.html">glowing Tron disk</a>, the <a href="http://demo.bkcore.com/threejs/webgl_tron_glow_seq.html">animated glowing Tron disk</a> (with <a href="http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html">accompanying blog post</a>), the <a href="http://demo.bkcore.com/threejs/webgl_tron_iso.html">Tron disk with particles</a>, and more recently, the <a href="http://demo.bkcore.com/threejs/webgl_tron_godrays.html">volumetric light approximation</a> (with <a href="http://bkcore.com/blog/3d/webgl-three-js-volumetric-light-godrays.html">accompanying blog post</a>). At the time, I didn't know anything about shaders (although there were some excellent tutorials at Aerotwist, <a href="http://www.aerotwist.com/tutorials/an-introduction-to-shaders-part-1/">part 1</a> and <a href="http://www.aerotwist.com/tutorials/an-introduction-to-shaders-part-2/">part 2</a>).<br />
<br />
Recently, I learned about the <a href="https://www.udacity.com/course/cs291">Interactive 3D Graphics course</a> being offered (for free!) at <a href="https://www.udacity.com/">Udacity</a>, that teaches participants all about Three.js. This course is taught by Eric Haines (<a href="https://plus.google.com/101252446341510025731/">Google+</a>, <a href="http://www.realtimerendering.com/blog/">Blog</a>), who has written the excellent book <i><a href="http://www.realtimerendering.com/book.html">Real-Time Rendering</a></i>. Eric stumbled across my own <a href="http://stemkoski.github.com/Three.js/">collection of introductory examples for Three.js</a>, and recommended a really great article about an <a href="http://www.airtightinteractive.com/2013/02/intro-to-pixel-shaders-in-three-js/">introduction to pixel shaders in Three.js</a> (a.k.a. fragment shaders) by Felix Turner at <a href="http://www.airtightinteractive.com/">Airtight Interactive</a>. This motivated me to do two things: (1) sign up for the Udacity course (which is really excellent, and highly recommended!), and (2) to update my collection of Three.js examples for the latest release of Three.js (version 56 at the time of writing).<br />
<br />
While updating, I noticed that a number of new classes had been created for shaders and post-processing effects, and so I spent a lot of time looking through source code and examples, and eventually created two new demos of my own: a <a href="http://stemkoski.github.com/Three.js/Shader-Simple.html">minimal example</a> of using a Three.js pixel shader, and a <a href="http://stemkoski.github.com/Three.js/Shader-Explorer.html">shader explorer</a>, which lets you see the results of applying a variety of the Three.js shaders (sepia, vignette, dot screen, bloom, and blur) and the effects of changing the values of their parameters.<br />
<br />
Inspired, I revisited the glowing Tron disk examples, hoping to use the BlendShader.js now included as part of the Three.js github repo. Alas, the search term "THREE.BlendShader" is almost a <a href="http://en.wikipedia.org/wiki/Googlewhack">Googlewhack</a>, with only two results appearing (at the time of writing, which will hopefully change soon); using these links as a starting point, I found a nice example of using the BlendShader to create a neat <a href="http://jabtunes.com/labs/jscamp_asia/webgl_jscampasia4-fake-shadow-motion-blur.html">motion blur effect</a> on a spinning cube. <br />
<br />
Next came some experimentation to implement the approach described by Thibaut above, which requires the creation of two scenes to achieve the glow effect. The first is the "base scene"; the second contains copies of the base scene objects with either bright textures (for the objects that will glow) or black textures (for nonglowing objects, so that they will block the glowing effect properly in the combined scene). The secondary scene is blurred and then blended with the base scene. However, BlendShader.js creates a linear combination of the pixels from each image, and this implementation of the glow effect requires additive blending. So I wrote <a href="https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/js/shaders/AdditiveBlendShader.js">AdditiveBlendShader.js</a>, which is one of the simplest shaders to write, as you are literally adding together the two color values at the pixels of the two textures you are combining. The result (with thoroughly commented code) can be viewed here:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.com/Three.js/Selective-Glow.html"><img border="0" height="174" src="http://stemkoski.github.com/Three.js/html-images/Selective-Glow.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://stemkoski.github.com/Three.js/Selective-Glow.html">Selective Glow Effect using Shaders</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Hopefully other Three.js enthusiasts will find this example helpful!<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-80161825660036595132012-10-05T13:54:00.001-04:002012-10-05T13:54:54.860-04:00Using Game Controllers for Browser-Based GamesWith the recent release of Google Chrome version 22, the Gamepad API is ready for action (no manual adjustment of chrome://flags required). <div>
<br /></div>
<div>
Recommended reading:</div>
<div>
<br /></div>
<div>
<a href="http://active.tutsplus.com/tutorials/games/an-introduction-to-the-html5-gamepad-api/">http://active.tutsplus.com/tutorials/games/an-introduction-to-the-html5-gamepad-api/</a></div>
<div>
<br /></div>
<div>
<a href="http://buildnewgames.com/console-experience-on-the-web/">http://buildnewgames.com/console-experience-on-the-web/</a></div>
<div>
<br /></div>
<div>
<a href="http://www.html5rocks.com/en/tutorials/doodles/gamepad/">http://www.html5rocks.com/en/tutorials/doodles/gamepad/</a></div>
<div>
<br /></div>
<div>
A great interface to use:</div>
<div>
<a href="https://github.com/sgraham/gamepad.js/issues/8">http://github.com/sgraham/gamepad.js</a></div>
<div>
However, due to issues as described in the post:</div>
<div>
<a href="https://github.com/sgraham/gamepad.js/issues/8">http://github.com/sgraham/gamepad.js/issues/8</a></div>
<div>
for the time being, it is better to use the patched version of the code posted at: </div>
<div>
<div>
<a href="https://github.com/inequation/gamepad.js">http://github.com/inequation/gamepad.js</a></div>
</div>
<div>
(a GitHub fork of sgraham's code)</div>
<div>
at least until the main branch is updated with these changes.</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-5412289626572627532012-09-09T20:39:00.002-04:002012-09-09T20:46:30.739-04:00Digital HumanitiesI was recently asked to attend an informal discussion about the "Digital Humanities". Some quick Google searching revealed a wealth of interesting links, which I'm posting here for my own (and possibly others' ?) future reference:<br />
<br />
<br />
<b>Wikipedia</b><br />
<a href="http://en.wikipedia.org/wiki/Digital_humanities">http://en.wikipedia.org/wiki/Digital_humanities</a><br />
"...today digital humanities embrace a variety of topics ranging from curating online collections to data mining large cultural data sets. Digital Humanities currently incorporates both digitized and born-digital materials and combines the methodologies from the traditional humanities disciplines ... with tools provided by computing (such as data visualisation, information retrieval, data mining, statistics, computational analysis) and digital publishing."<br />
<br />
<b>Alliance of Digital Humanities Organizations</b><br />
<a href="http://digitalhumanities.org/">http://digitalhumanities.org/</a><br />
<a href="http://digitalhumanities.org/dhq/">http://digitalhumanities.org/dhq/</a><br />
<a href="http://digitalhumanities.org/answers/topic/what-is-digital-humanities">http://digitalhumanities.org/answers/topic/what-is-digital-humanities</a><br />
"The Alliance of Digital Humanities Organizations (ADHO) promotes and supports digital research and teaching across all arts and humanities disciplines, acting as a community-based advisory force, and supporting excellence in research, publication, collaboration and training."<br />
<br />
<b>CUNY Digital Humanities Resource Guide</b><br />
<a href="http://commons.gc.cuny.edu/wiki/index.php/The_CUNY_Digital_Humanities_Resource_Guide">http://commons.gc.cuny.edu/wiki/index.php/The_CUNY_Digital_Humanities_Resource_Guide</a><br />
"...a collaboratively produced introduction to the field of Digital Humanities..."<br />
<br />
<b>Digital Humanities Now</b><br />
<a href="http://digitalhumanitiesnow.org/">http://digitalhumanitiesnow.org/</a><br />
"Digital Humanities Now showcases the scholarship and news of interest to the digital humanities community through a process of aggregation, discovery, curation, and review. Digital Humanities Now also is an experiment in ways to identify, evaluate, and distribute scholarship on the open web through a weekly publication and the quarterly Journal of Digital Humanities."<br />
<br />
<b>Humanities Blast </b><br />
<a href="http://humanitiesblast.com/publications/">http://humanitiesblast.com/publications/</a><br />
"Engaged Digital Humanities Scholarship"<br />
<br />
<b>National Endowment for the Humanities</b><br />
<a href="http://www.neh.gov/divisions/odh">http://www.neh.gov/divisions/odh</a><br />
"...supports projects that employ digital technology to improve humanities research, education, preservation, access, and public programming. To that end, ODH works with the scholarly community, and with other funding agencies in the United States and abroad, to encourage collaboration across national and disciplinary boundaries. In addition to sponsoring grant programs, ODH also works collaboratively with the field, participating in conferences and workshops with scholars, librarians, scientists, and other funders to learn more about how to best serve digital scholarship."<br />
Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-70628168670124502692012-08-16T15:36:00.002-04:002012-08-16T15:46:57.706-04:00Google Apps ScriptTime to prep for the Fall semester classes. I typically create a spreadsheet of topics on Google Docs Drive, and for student-ease-of-use I would like to use that data in a Google Calendar. To get these two apps talking, I'm learning Google Apps Script. It is simple to complete <a href="https://developers.google.com/apps-script/your_first_script">https://developers.google.com/apps-script/your_first_script</a> in a matter of minutes, the syntax is quite readable and easy to understand...<br />
<br />
Helpful links:<br />
<a href="https://developers.google.com/apps-script/defaultservices">https://developers.google.com/apps-script/defaultservices</a>
<br />
<br />
Functions for interacting with spreadsheets:<br />
<a href="https://developers.google.com/apps-script/class_spreadsheetapp">https://developers.google.com/apps-script/class_spreadsheetapp</a>
<br />
<br />
Functions for interacting with calendars:<br />
<a href="https://developers.google.com/apps-script/class_calendarapp">https://developers.google.com/apps-script/class_calendarapp</a>
<br />
<br />
Here's the function I wrote to export data (lists of dates and topic names for a Calculus 2 course for Fall 2012) to a calendar. <br />
<br />
To use it: from Google Spreadsheets, go to Tools -- Script Editor... and enter in the function below (changing variable values as necessary). Save it, then execute the script from Tools -- Script Manager..., accept all the permission requests (only necessary on the first run, as in the tutorial example linked to above), and then execute this script again.<br />
<br />
<pre class="prettyprint">function SpreadsheetToCalendar()
{
// This function should be executed from the
// spreadsheet you want to export to the calendar
var mySpreadsheet = SpreadsheetApp.getActiveSheet();
var myCalendar = CalendarApp.openByName("Calculus 2");
// optional - delete existing events
var events = myCalendar.getEvents(new Date("January 1, 2011 EST"),
new Date("January 1, 2013 EST"));
for (var i = 0; i < events.length; i++)
{
events[i].deleteEvent();
}
var dataRange = mySpreadsheet.getRange("B2:C46");
var data = dataRange.getValues();
// process the data
for (i in data)
{
var row = data[i];
// assume that each row contains a date entry and a text entry
var theDate = row[0]; // First column of row
var theTitle = row[1]; // Second column of row
myCalendar.createAllDayEvent(theTitle, theDate);
}
}
</pre>
P.S. I've switched to using <a href="http://www.stylifyyourblog.com/2012/07/syntax-highlighting-in-blogger-using.html">http://www.stylifyyourblog.com/2012/07/syntax-highlighting-in-blogger-using.html</a> and <a href="http://www.tools.stylifyyourblog.com/p/postify.html">http://www.tools.stylifyyourblog.com/p/postify.html</a> to format code snippets in this blog... highly recommended!Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-81242342856936691422012-06-09T12:54:00.002-04:002012-09-09T20:40:52.517-04:00Three.js examples on GitHubIn the process of learning Three.js, I am creating my own comprehensive set of examples. For my own convenience as well as anyone else that may be interested, I'm posting all the code on GitHub at:<br />
<br />
<a href="http://stemkoski.github.com/Three.js">http://stemkoski.github.com/Three.js</a><br />
<br />
(As an added bonus, I'm learning how to use GitHub.)Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-57906744562985957442012-06-02T14:05:00.002-04:002012-06-06T14:59:11.757-04:003D Javascript using three.jsRecently stumbled upon one of the most amazing libraries I have ever seen -- interactive 3D graphics using JavaScript. Yes, JavaScript.<br />
<div>
<br /></div>
<div>
What it is - slideshow:</div>
<div>
<a href="http://fhtr.org/BasicsOfThreeJS/#2">http://fhtr.org/BasicsOfThreeJS/#2</a></div>
<div>
Sample projects:</div>
<div>
<a href="http://mrdoob.github.com/three.js/">http://mrdoob.github.com/three.js/</a>
<br />
<a href="http://alteredqualia.com/">http://alteredqualia.com</a></div>
<div>
Download at:</div>
<div>
<a href="https://github.com/mrdoob/three.js/">https://github.com/mrdoob/three.js/</a></div>
<div>
<div>
Fantastic resources and additional libraries:</div>
<div>
<a href="http://learningthreejs.com/">http://learningthreejs.com/</a></div>
</div>
<div>
Getting started:</div>
<div>
<a href="http://www.aerotwist.com/tutorials/getting-started-with-three-js/">http://www.aerotwist.com/tutorials/getting-started-with-three-js/</a></div>
<div>
Further tutorial:<br />
<a href="http://www.smashinglabs.pl/three-js-tetris-tutorial">http://www.smashinglabs.pl/three-js-tetris-tutorial</a><br />
<a href="http://www.96methods.com/2012/01/three-js-moving-objects/">http://www.96methods.com/2012/01/three-js-moving-objects/</a> (and more)<br />
<a href="http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html">http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html</a> (glow effects)<br />
Integration with Blender:<br />
<a href="http://blenderscripting.blogspot.com/2012/04/threejs-and-blender.html">http://blenderscripting.blogspot.com/2012/04/threejs-and-blender.html</a></div>
<div>
Reddit:</div>
<div>
<a href="http://www.reddit.com/r/threejs/">http://www.reddit.com/r/threejs/</a>
</div>
<div>
<br /></div>
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-87886889427603499882012-03-30T14:04:00.002-04:002012-03-30T14:04:30.729-04:00Simple Fast Multimedia Library - setup with Code::BlocksI love this library. Compiling and running the basic program was a bit tricky; I had a bunch of "<i>libgcc_s_dw2-1.dll is missing</i>" errors. What I ended up doing to solve these errors was:<div>
<ul>
<li>First, download the compiler "mingw-with-gcc-4.4.zip" discussed on the webpage <a href="http://www.sfml-dev.org/tutorials/1.6/start-cb.php">http://www.sfml-dev.org/tutorials/1.6/start-cb.php</a>; unzip it into an easy-to-find directory such as C:\MinGW</li>
<li>Next, install the Code::Blocks IDE from <a href="http://www.codeblocks.org/downloads/26">http://www.codeblocks.org/downloads/26</a> -- but choose the one that does <b><i>not</i> </b>include MinGW. When installing, if Code::Blocks doesn't automatically find the MinGW directory you set up earlier, you can configure the compiler afterwards as follows: </li>
<ul>
<li>In the menu bar, go to "Settings", select "Compiler and Debugger..."</li>
<li>In the new window make sure the "Global Compiler Settings" image on the left is highlighted/selected</li>
<li>In the "Selected Compiler" dropdown list choose "GNU GCC Compiler"</li>
<li>In the tabs underneath the dropdown list, click on "Toolchain Executables". </li>
<li>There will be a textbox where you can type the name of the directory where you unzipped the MinGW compiler</li>
</ul>
<li>In the window described above <br />("Settings -> "Compiler and Debugger..." -> "Global Compiler Settings"), click the "Linker Settings" tab, and in the textbox labelled "Other Linker Options", enter the following five lines of text:<br /> -static-libgcc<br /> -static-libstdc++<br /> -lsfml-graphics<br /> -lsfml-window<br /> -lsfml-system</li>
</ul>
<div>
Hope this helps somebody out there (perhaps even my future self?).</div>
<div>
<br /></div>
</div>Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-37863360594673919852012-03-29T14:13:00.004-04:002012-03-29T21:37:19.637-04:00(re)learning C++I haven't really used C++ since my undergraduate days -- I've mostly worked in Java recently. Feeling nostalgic, I decided to refresh these particular skills. I'll be using the freely available C++ IDE called Code::Blocks (available at <a href="http://www.codeblocks.org/">http://www.codeblocks.org/</a>) and the tutorials at <a href="http://www.cplusplus.com/doc/tutorial/introduction/">http://www.cplusplus.com/doc/tutorial/introduction/</a> (where Code::Blocks appears to be recommended above Dev-C++). Running the "Hello World" program was easy, but to stop the exiting immediately, I recommend adding an int "dummy" variable and a "cin" to the standard code, e.g.,<br />
<br />
<pre class="brush:c">// my first program in C++
#include <iostream>
using namespace std;
int main ()
{
int pauseVariable;
cout << "Hello World!" << endl;
cout << "Type something and press Enter to continue..." << endl;
cin >> pauseVariable;
return 0;
}
</pre>
P.S. Figured out syntax highlighting thanks to
<a href="http://mlawire.blogspot.com/2009/07/blogger-syntax-highlighting.html">http://mlawire.blogspot.com/2009/07/blogger-syntax-highlighting.html</a> except that (at the time of posting) "Edit HTML" is located under the Template menu in your Blogger dashboard.<br />
P.P.S. Code::Blocks integrates nicely with the Simple and Fast Multimedia Library - <a href="http://www.sfml-dev.org/">http://www.sfml-dev.org/</a>Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-11635524351607576062012-02-19T22:51:00.001-05:002012-02-19T22:51:39.628-05:00Learning From The Masters: Level Design In The Legend Of ZeldaRecommended reading:<br />
<a href="http://www.gamasutra.com/view/feature/6582/learning_from_the_masters_level_.php">http://www.gamasutra.com/view/feature/6582/learning_from_the_masters_level_.php</a>
<br />
<br />
The classics will always have something to teach us.Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-42650452827505854652012-02-16T22:47:00.003-05:002012-02-16T22:47:59.214-05:00What Every Computer Science Major Should KnowRecommended reading:<br />
<a href="http://matt.might.net/articles/what-cs-majors-should-know/">http://matt.might.net/articles/what-cs-majors-should-know/</a><br />
I appreciate the specific suggestions in this article, and I particularly agree with the need for a portfolio (including code samples). Thanks to Steve Bloch for the link.<br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-82071353408954411002012-02-15T11:02:00.001-05:002012-02-15T11:02:21.736-05:00Construct 2<a href="http://www.scirra.com/">Construct 2</a> is an amazing drag-and-drop style game editor that compiles games to HTML5 and JavaScript, which can then be hosted on <a href="http://www.scirra.com/arcade">Scirra's Arcade</a> or on <a href="http://www.kongregate.com/html5-games">Kongregate</a>. The free version that has 95% of the capabilities of the paid version. JavaScript plugins are easy to write. The user community forums are active and helpful. Try it out!Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-7972273307218554472011-09-13T20:04:00.000-04:002012-02-15T10:54:33.059-05:00jMonkeyEngineStarting to write some jMonkeyEngine 2.0 tutorials; Nick will be posting them online.<br />
<a href="http://www.adelphi.edu/~ni18128/jmet/index.html">http://www.adelphi.edu/~ni18128/jmet/index.html</a><br />
<br />Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.comtag:blogger.com,1999:blog-3849352810923433644.post-30883410066393596002011-09-01T13:36:00.001-04:002011-09-01T13:47:15.513-04:00First Post<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;">Hello, world!</span><br />
<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;">\[ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} \]</span>Anonymoushttp://www.blogger.com/profile/01983140684726917595noreply@blogger.com