tag:blogger.com,1999:blog-20640719332826448322024-03-20T14:08:17.954-07:00Danny's Art Notesgaining and sharing artistic insight.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.comBlogger29125tag:blogger.com,1999:blog-2064071933282644832.post-80902067862488172772008-11-25T08:37:00.000-08:002008-11-25T08:38:07.833-08:00cointued on DannyBurbol.comI've merged this blog with my main site. So all further updates will be there, not here.<br /><br /><a href="http://www.dannyburbol.com/">http://www.dannyburbol.com</a>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-11740794899202990212008-11-06T10:08:00.000-08:002008-11-06T10:16:14.224-08:00Grim Fandango Design DocI've heard many good things about Grim Fandango, back in the day, but I've never actually played it. I also heard it was story driven and the game part felt more like minigames.<br /><br />But they released the design doc:<br /><a href="http://www.doublefine.com/news.php/site/just_one_more_grim_thing/"><br />http://www.doublefine.com/news.php/site/just_one_more_grim_thing/</a><br /><br />I have to admit, it's a pretty good design doc. It seems *useful*, unlike many, many game design docs I've had to work from that were literally a 200 page brainstorm that was waved in front of the publisher to say "look, we're going to do all this stuff, so give us money"... only to be tossed aside once work on the game actually began.<br /><br />Then at the very end, the publisher says, "what do you mean you're done? We've got this 200 page doc you gave us, and all that stuff is not in the game."<br /><br />*ahem* "doh!" :)<br />~Danny<br /><br />PS: note the last page of the Grim Fandango design doc :)Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-53487574606656812612008-10-15T21:16:00.000-07:002008-10-18T17:56:38.571-07:00Serious/Fast Flash Development (with free tools)So you want to get serious about making flash movies and games? Great! The way to get good is with fast iteration. What I mean by "iteration" is the time it takes to make a change to your game, build the game, test your game and decided if you need to make another change.<br /><br />For the most part, it's easy to iterate with flash, you just test your movie and there you go. What I'm talking about is more advanced flash movies. I'm talking about passing parameters from the page to your swf (mygame.swf?var1=1&var2=2), calling javascript from your swf (ExternalInterface), and swf's getting loaded in other swf's (and you can pass params to the child swf).<br /><br />Basically, there comes a time when just running the movie on your computer isn't good enough and the only way to really test your swf files is by uploading them to a server and viewing them in a browser connected to the web. After all, isn't that how your audience is going to see it?<br /><br />So let's not waste time. Here are the things you'll need to know in order to iterate quickly when building flash movies/games.<br /><br />Note: you'll need a copy of Flash, but everything else I'm about to mention is free.<br /><br /><span style="font-size:130%;">Step 1: Debugging Flash Over The Web:<br /></span><br />[ ] Start by downloading and installing the major web browsers. FireFox, IE and Safari --no whining! --get them all, just because you like one better than the others doesn't mean your viewers agree with you. When you test your movies, be sure to test them in all the major browsers.<br /><br />[ ] Next, Uninstall Your Flash Player:<br />http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_14157<br /><br />[ ] Now Install The *Flash Debugger* (follow the link and scroll down some. Get *both* versions for your OS, meaning, get the pluging for IE and for FireFox)<br />http://www.adobe.com/support/flashplayer/downloads.html<br /><br />[ ] Configure Flash Debugger log file. This log file is the major reason we installed the flash debugger. Follow the directions at this link:<br />http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=logging_125_04.html<br /><br />Note: I had to create the "Logs" directory, I'm not sure if you'll have to do the same or not.<br /><br />[ ] Make a shortcut to this Logs folder and place it in a location that's fast and easy for you to get to (Desktop, etc)<br /><br />[ ] make a batch file to delete the log. In Windows you'd to this by opening notepad and adding this line:<br />rm flashlog.txt<br />and then saving the file IN THE Logs folder as "deleteflashlog.bat". Now, when you double click deleteflashlog.bat, it will delete the log file (thus resetting the log for you).<br /><br />(maybe someone will be kind enough to comment on how to make a similar script for the Mac?)<br /><br />[ ] make a shortcut to this deleteflashlog script. Again, put it in a fast/easy place to locate (I put mine directly on the window's task bar, then I right clicked on it and changed it's icon to an "X")<br /><br />Okay, just to recap, you have all the major browsers and the Flash Debugger installed and configured to save a log file. What does that mean? Well, it means when you view pages with flash movies on them, all the "trace()" commands will get printed to the log file. So now you can debug print movies when they are actually live and on the page. It will also pop up error messages from time to time, which is annoying but WAY more helpful than silence.<br /><br />PS: next time you're looking at a .fla file's publish settings, you'll notice there are check boxes to suppress trace and debugging... now you know why. If you're printing out important info, you're making it very easy for people to hack your swf. So when you're done debugging, turn that stuff off.<br /><br />And Finally, the best debugger in your toolbox:<br />[ ] download and install Firebug because it's frigging awesome!<br />https://addons.mozilla.org/en-US/firefox/addon/1843<br /><br />Yes, you will be using FireFox to do most of your testing. Why? Two reasons. 1) because it has firebug (I can't explain the ins and outs of firebug, you just got to play with it. It's full of awesome.) and 2) because we can set up the cache to clear really easily in FireFox, but not in the other browsers.<br /><br />One of the most annoying problems with trying to test your movies in a web browser is that they all cache your swf files. Then no amount of refreshing or hitting F5 or ctrl+F5 or any of that crap will force the browser to reload the swf you *know* you just changed.<br /><br />All of the browsers have a way to clear the cache, or "delete the history", or "delete temp files" or whatever they choose to call it. However, FireFox let's us specifically say what we want to clear and not clear when we ask it to drop the cache AND it has a hot key to do it.<br /><br />[ ] in FireFox, go to "Tools" > "Options..." Next click the "Privacy" tab at the top, then in the Private Data area, click the "Settings" button.<br />[ ] in the pop up, turn OFF all the check boxes EXCEPT "cache". Make sure "cache" is checked. Click ok<br />[ ] In the "Private Data" area, uncheck the "ask me before clearing private data", then click OK to close the options dialog.<br /><br />Now look in the "Tools" menu and you'll see "Clear Private Data" but more importantly you'll see the hot keys to press.<br /><br />Now, whenever you upload a new version of your swf to the web and you want to force FireFox to update it, just press shift+ctrl+del then f5. This is sooo much faster than digging through menus and clicking "yes, I really mean it!" buttons over and over again.<br /><br />FURTHER MORE, let me spell out the workflow.<br /><ul><li>change your swf</li><li>copy the swf to your server</li><li>click the shortcut to delete your flashlog file</li><li>hit ctrl+shift+del</li><li>hit f5</li><li>there's your *latest* movie and it's sending trace commands to a fresh log file that you can pop open and examine.<br /></li></ul><br /><span style="font-size:130%;">Step 2: writing the code faster<br /></span><br />Of course, you should have Flash on your computer. I won't ask how you got it, but I do advise buying a copy since I have friends who work at Adobe.<br /><br />[ ] download/install Flash Develop<br />http://www.flashdevelop.org<br /><br />This is a pretty snazzy dev environment for Actionscript files. It has auto-complete and syntax highlighting.<br /><br />[ ] In Flash Develop, be sure to set syntax menu to as3 or whatever version you're using, or it will give you auto-complete for the wrong set of library functions and keywords.<br /><br />[ ] Note, In Flash Develop, you can hit F6 to tell Flash to build and test your movie.<br /><br />[ ] Next, download the Tweener AS libraries<br />http://code.google.com/p/tweener/<br /><br />Tweener: it makes it so easy to tween from code. It's like realizing you're allowed to run while everyone else seems to be walking. Checkout some of the syntax online, or just google around and you'll see. It's amazing what you can do in one line. Here's an example:<br /><br /><span style="color: rgb(0, 102, 204);"></span>import caurina.transitions.Tweener<br />Tweener.addTween(myDispObj, {y:10, time:3, delay:1, transition:"linear", onComplete: myFunction});<br /><br />so that's "animate myDispObj's y variable to 10 in 3 seconds. but wait 1 second before starting and call myFunction when you're done". That transition:"linear" is laughable when you see all the possible transition types you have to choose from (http://hosted.zeh.com.br/tweener/docs/en-us/)<br /><br />the best part, the parameters are mix and match. So you can have a call like this:<br />Tweener.addTween(myDispObj, {y:10, time:3});<br />or<br />Tweener.addTween(this, {time:3, onComplete: myFunction});<br /><br />It's awesome. Just get it and play with it :)<br /><br /><span style="font-size:130%;">Final Tips<br /></span><br />Just in case you're logging into some still control panel for your website and uploading files via some slow web-based file manager.... I want to clue you in on the word "ftp" and the name "FileZilla". If you don't know what those are, please google them. Using an ftp is sooo much faster for uploading files to your website.<br /><br />And while I'm talking about searching the web... keep in mind that there are many many great things to read on AS3 and flash.... but there are many more useless things to read.<br /><br />When searching for help, start your searches with "adobe as3".<br />Ex: "adobe as3 loader"<br /><br />this will usually get you the api docs and live docs on Adobe's site, which are pretty handy.<br /><br />Also, if your version of Flash Develop doesn't have find in files, you might want to download "Crimson Editor". Find in Files is a coder's best friend. (but I think Flash Develop 3 has it, so no worries)<br /><br />If you want to see the flashlog.txt file as it's updating, you can download Cygwin (which is a linux shell) and then use the linux tail command. (I'll leave an example some other time... I'm exhausted... til then, please google them)<br /><br />Final workflow:<br /><ul><li>Make changes in Flash Develop.</li><li>Hit F6 in Flash Develop (build movie)</li><li>Copy new swf to server (Filezilla or some ftp)</li><li>Click deleteflashlog short cut</li><li>Hit ctrl+shift+del in FireFox (clear cache)</li><li>Hit F5 in FireFox (reload page)</li><li>See latest version of your movie</li><li>Examing log file if needed.</li></ul>When you get used to it, it's "tap a key", "drag a file", "click a button", "tap a shortcut", "tap a key". Or tap, drag, click, tap, tap.<br /><br />Okay... I think I've said plenty. I hope you found it helpful!<br />~DannyDannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com1tag:blogger.com,1999:blog-2064071933282644832.post-41192490828073319942008-06-18T11:17:00.000-07:002008-06-18T12:03:12.269-07:00Photoshop: Fill instead of Lift<div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja0LyTxhweaCrEBwwtn1XhayBawUh-HqTKPV5zJkN6-h_DdgHd4AkwceAEh6P6Y2eqsQ7k-EQh6v6pMzvaVlMgQp9wapQx-52mZGXuFJJleEPD5k1Uz4E3iyHM8ap5mCxM9HiJ_7ym5LM/s1600-h/01.jpg"><img id="BLOGGER_PHOTO_ID_5213289210260654578" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja0LyTxhweaCrEBwwtn1XhayBawUh-HqTKPV5zJkN6-h_DdgHd4AkwceAEh6P6Y2eqsQ7k-EQh6v6pMzvaVlMgQp9wapQx-52mZGXuFJJleEPD5k1Uz4E3iyHM8ap5mCxM9HiJ_7ym5LM/s400/01.jpg" border="0" /></a><br /><br /><div></div><br /><br /><div>I think this is just one of those tips that reminds us (me!) not to over think the problem.<br /><br />My fiance was helping her friend who had some pictures of some costumes she made. The pictures were taken by placing the costumes on a cloth so they'd stand out and look nice. However, after she got the photos (as in 30 or more) in the computer, she decided the back drop looked too amateur and wanted to lift the costumes off the cloth.<br /><br />We discussed the many ways you could go about this. You could use the stamp tool to remove the wrinkles; you could literally trace around the subject with the eraser; you could try to use the wand select + delete on the background (which works okay, but not great); and so on.<br /><br />All these complex ways to remove the background... then my fiance tried the paint bucket. One click and the background was a solid, uniform color. Yup. "Keep it simple, stupid," wins again. :) </div></div><br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicAghmUf37RdjP0Y7Gl67KJsOkAD6hLN9yVURG4yh_CMHznTrjTHKiOlGRtDEhN4LxmYw5oXVFHcnidXuYn4xPMYfulELa5IxaLE9chSfDkhfBd791qMFrGfiJ57wA63i_jwJnQQyz5bQ/s1600-h/02.jpg"><img id="BLOGGER_PHOTO_ID_5213289473946634882" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicAghmUf37RdjP0Y7Gl67KJsOkAD6hLN9yVURG4yh_CMHznTrjTHKiOlGRtDEhN4LxmYw5oXVFHcnidXuYn4xPMYfulELa5IxaLE9chSfDkhfBd791qMFrGfiJ57wA63i_jwJnQQyz5bQ/s400/02.jpg" border="0" /></a>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-37411578346760485692008-06-17T13:07:00.000-07:002008-06-17T13:14:22.974-07:00Flash Game Tutorials, Lesson 2 Draw & Input<h2>Danny Burbol's How to make a falling blocks style Flash Game Tutorials</h2><br /><br /><h2>Lesson 2: Drawing Blocks & Keyboard Input</h2><br /><br />A Link To: <a href="http://www.dannyburbol.com/games/tutorials">All Lessons' Table Of Contents</a><br />A Link To: <a href="http://www.dannyburbol.com/games/blocks/">The Original Flash Game that started all this</a><br /><br /><p>So here's where we left off at the end of lesson 1. We have a couple self-contained screens that we can navigate between by clicking buttons.</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\00_00.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\00_00.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>You'll notice that I changed my title text, scaled up the title screen buttons with the free transform tool (Tool bar, the black cursor with the box, under the white cursor and above the Lasso) and I've added an extra screen with links to these tutorials. You should be able to make changes like this if you went through lesson 1. The only thing you'll needs is the function to call to open a web link in a new window. Here it is:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\00_01.jpg"></p><br /><br /><p>Note the: import flash.net.*;</p><br /><br /><p>In this lesson we are going to:<ul><br /><li>Learn how to draw a sprite with a rectangle using ActionScript .<br /><li>Learn how to create our main loop callback event (timer events).<br /><li>Learn how to use Sprites for containers.<br /><li>Learn how to use 2 dimensional arrays as an adjacency matrix (the game's board).<br /><li>Learn how to detect simple keyboard keys presses.<br /><li>Learn how to rotate our game's pieces using some simple vector math trick.<br /></ul></p><br /><p>I'm also not going to be going in to as much depth as I did in Lesson 1. Lesson 1 was a "starting from nothing" introduction to flash, but here in Lesson 2, we're going to build on what we've learned rather than reiterate all of it. So don't be afraid to pop open Lesson 1 and review a couple steps when you feel the need. I know it's annoying, but realizing you don't quite know how to do something and having to go dig up the info is actually a great way to train yourself to remember.</p><br /><br /><h2>1. How To Draw a Rectangle With ActionScript</h2><br /><br /><p>Flash uses vector art, which basically mean it holds most of it's visual data as math. For example, if you wanted to draw a smiley face in flash, you'd draw a yellow circle, then on top of that you'd draw two smaller black circles (for eyes), and a maybe a half circle for a mouth. </p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_00.jpg"></p><br /><br /><p>Flash doesn't keep that final image of the smiley face anywhere. Instead, it keeps the list of shapes it needs to draw in order to construct the smiley face every time we want to draw it combine with some information on where to draw these shapes, how big to draw them, and/or at what angle to draw them.</p><br /><br /><p>This is what Sprites are for. Sprites are basically just a list of shapes combine with a position, rotation, and scale for drawing those shapes. You can also think of Sprites like a container full of child objects/shapes. If you move the container, everything inside it moves too.</p><br /><br /><p>So basically, we're going to create a Sprite. Then we are going to add a bunch of shapes to that sprite. Finally, we are going to tell flash that we want that sprite to be drawn on the screen.</p><br /><br /><p>In order to make this example as simple and bare-bones as possible, I'm just going to make a little test function and drop it into your MainApp's constructor.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_01.jpg"></p><br /><br /><p>Notice that we don't have to add the import command for the Sprite because we already have it. MainApp was extended from Sprite. So we just create a new sprite like we'd create any new object.</p><br /><br /><p>Next we make the color white by using the RGB hex value FFFFFF. (Do a web search on "HTML colors" or "RGB colors" if you'd like a more in-depth explanation on why FFFFFF is white). Then we use a few graphics commands to add a shape to the sprite. We use beginFill to specify the color, drawRect to add a rectangle and endFill to say we're done. The values we passed to drawRect were the x and y positions (0 and 0) followed by the width and the height of the rectangle we want (20 and 20).</p><br /><br /><p>Finally we tell Flash we want to draw this sprite. We do this with addChild(). But why does this work? What are we actually doing here? Remember, sprites are like containers. If we have a sprite that is being drawn to the screen, we can add more children to that sprite and it will be drawn to the screen as well. MainApp is a Sprite. MainApp is already being drawn because it's our "Document class" (remember, "AGreatGame.fla" > "Properties" > "Document class: MainApp"). We've already hooked up MainApp to be drawn, so when we add children to MainApp, they get drawn too. This is because Flash works "display lists". When MainApp is told to draw, it tells all it's children to draw and they in turn tell their children to draw, etc.</p><br /><br /><p>So addChild() adds our sprTestBlock to MainApp which is a sprite that's already being drawn. After that we just set the test block's position to (20, 20).</p><br /><br /><p>Don't forget to call DrawATestBlock(); in your constructor, then save your files and test the movie.</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_02.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_02.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>Note, I made my block white because my background was black. I trust if you've made it to lesson 2 you'd be wise enough to make the block a color that will stand out against your IntroScreen's background.</p><br /><br /><p>Also note, the block is in the top left corner of the screen and offset to the right and downward by 20 pixels. That how screens work. The origin is in the top left corner of the screen. Positive x is to the right. Positive y is down.</p><br /><br /><p>So we drew a square and we did it by breaking our nice self-contained AppScreen framework. I only did this because I wanted to make sure you saw all three steps for drawing a block before we separate them.</p><br /><br /><p>Let's start by making a function for drawing a block to any sprite in any color. I'm going to do this by making a small DrawBlock class with a static function member.</p><br /><br /><p>Create a new *.as file. Save it as "DrawBlock.as" and type this into it:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_03.jpg"></p><br /><br /><p>(My header comment got clipped a little bit, but it's something to the affect of: "// a class to hold drawing functions.")</p><br /><br /><p>We do our standard "package" wrapper, followed by importing any api's we are going to use, then we make our DrawBlock class. The only function is a "static" function, which means we will be able to call "WithBorder()" without having to create a "DrawBlock" variable first. </p><br /><br /><p>//so instead of:<br /><br>var tmpDrawBlock:DrawBlock = new DrawBlock();<br /><br>tmpDrawBlock.WithBorder();<br /><br><br /><br>//the static function lets us do it like this:<br /><br>DrawBlock.WithBorder();<br /></p><br /><p>In WithBorder we're drawing more than one square now. We draw a black square. Then we draw a specific color right on top of it. The .5 in beginFill means we're drawing at 50% alpha. So we're drawing a semi-transparent color on top of a black square... which gives us a dark colored square. Then we inset the size of the square and do it again, giving us another shade of the intended color. Finally we inset the size of the square one more time and draw the color we were instructed to use. It's all wrapped in a test for uBlockSize just in case someone calls it with a uBlockSize that will cause us trouble.</p><br /><br /><p>Now I want to bring your attention to the clear() function with my all-caps comment. Say you had a sprite, and you called DrawBlock.WithBorder() on it. It's going to add 4 rectangles to the sprite's list of things it should be drawing. If you don't clear() the list of shapes before adding more, then those 4 rectangles will just keep getting added to the end of the list. It will look fine on screen, but before long you could be drawing a list of hundreds of shapes each time Flash draws your sprite to the screen. It may sound trivial, but if you don't call clear() you could very easily find your game grinding to a halt the longer you play it.</p><br /><br /><p>Okay, now lets go back to MainApp.as and update our test function:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_04.jpg"></p><br /><br /><p>Notice that I switch the color to green so you can actually see what our DrawBlock.WithBorder() function does.</p><br /><br /><p>Save your files and test the movie.</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_05.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_05.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>Next, let's add the block to the right screen in the game, the GameScreen. Pull the "DrawATestBlock();" out of MainApp's constructor and put it in GameScreen_mc's constructor. Also, move the DrawATestBlock() function to the GameScreen_mc class as well. Also, don't forget to add the import for the Sprite.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_06.jpg"></p><br /><br /><p>Now you should have this:</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_07.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\01_07.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>Note: remember, the block draws because our GameScreen is added as a child of MainApp in MainApp's CreateGameScreen() function. So the test sprite is a child of GameScreen which is a child of MainApp.</p><br /><br /><h2>2. Laying out some game framework</h2><br /><br /><p>Before we move to drawing game objects, let's start setting up a framework for our game to operate in. We'll start by addressing these hard-coded numbers in DrawATestBlock(). </p><br /><br /><p>We're going to do this by making a class in a separate file that has nothing but const member variables. So create a new file and call it: FallingBlocks_GameSettings.as </p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\02_01.jpg"></p><br /><br /><p>You can see that I've done three new things. I've imported Point. I've changed our block size from 20 to 18, and I'm calling our position mvBoardScreenPos and I'm moved it to the middle of the screen.</p><br /><br /><p>As the name implies, these will only be the settings for the Falling Blocks Game we're going to make. We won't be cluttering it up with constant variables that are needed on other screen or in other games. Also, the game settings will be completely separate from the game's logic. Later, when we create the game's main class, we will be passing it our FallingBlocks_GameSettings object.</p><br /><br /><p>Why do this? Why not just have a bunch of constant variable members at the top of our game's main class? Well, first of all, it makes it really, really easy to locate and modify the game's settings since they're not mixed in with other game variables. Second, if we design the game's main class to run off settings that we hand it, that means we can hand it different settings very easily. We could extend FallingBlocks_GameSettings with a class like FallingBlocks_GameSettings_DirectorsCut or FallingBlocks_GameSettings_ForTheMacOS. (note, when doing that, you'd need to change the 'const' to 'var' for any variables you want to override in the new class.)</p><br /><br /><p>Make sure to hook up these game setting inside the GameScreen_mc class.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\02_02.jpg"></p><br /><br /><p>Save your files and test your movie. You should have this:</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\02_03.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\02_03.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>Now let's make the game's main class. We'll call it: FallingBlocks_Main.as</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\02_04.jpg"></p><br /><br /><p>Again you see we've extended from Sprite. I did this because I wanted to take advantage of Sprite's container-like qualities as well as the fact that it's a display object.</p><br /><br /><p>You see we have a pointer to the game settings, but we don't create a new FallingBlocks_GameSettings ourselves, we use the one that's passed to us in the constructor.</p><br /><br /><p>I also moved our DrawATestBlock() from GameScreen_mc to here. Note that "addChild()" still works because FallingBlocks_Main extends Sprite.</p><br /><br /><p>Now go back and update GameScreen_mc:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\02_05.jpg"></p><br /><br /><p>We create the new FallingBlocks_Main and used the settings we created on the line before it. We also call addChild( mGameMain ); If you don't do this, you won't see our test block being drawn. Also Note, the DrawATestBlock() function has been deleted and relocated.</p><br /><br /><p>Save your files and test your movie. It should look exactly the same as last time. Same result, better structure.</p><br /><br /><h2>3. Creating a Main Loop with a Timer Event</h2><br /><br /><p>Now let's hookup and test our main loop. If you're used to main loops, you'll notice that this one is slightly different. Normally a main loop is called once per frame at 60 frames per second (well, we shoot for 60 frames per second). However, when working in console and pc games, we do everything ourselves. We do all the drawing, we handle all the input, we decide what happens in the game on *every* frame.</p><br /><br /><p>Flash handles most of that for us. Plus, it uses events to handle input, so we don't ever have to poll it ourselves every frame. So, in our falling blocks game, all we're ever going to do is react to player input events and make the player's current piece fall. Since input is handled with events, all our main loop will ever do is sit around waiting for enough time to go by so we can make the game piece fall down.</p><br /><br /><p>Rather than spend all those cycles in a main loop that just waits on a timer, we're going to do the opposite. We're going to set a timer event that will get called each time the game piece is supposed to fall a row. As the game gets harder, and the game piece needs to fall faster, we'll just updated that timer to be a little faster. So basically, this game doesn't need a main loop that gets called every frame, we just need a timer event to drop the block every second or so.</p><br /><br /><p>Here's how we create a timer event in our FallingBlocks_Main.as</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_01.jpg"></p><br /><br /><p>So we import our Timer and TimerEvent, then we create a new member variable that is a timer. In our constructor we create the timer and set how much time it takes before it calls the callback (you'll see in a moment, muFallSpeed_Start is set to 1 second).</p><br /><br /><p>After that we addEventListener so we can call our callback function OnMakePieceFall when the timer goes off. Then we start the timer.</p><br /><br /><p>Next you'll see our OnMakePieceFall function needs to have a parameter of type TimerEvent. This makes sense because addEventListener was using a TimerEvent.TIMER. Finally, just for testing purposes, I dropped the DrawATestBlock() function in there.</p><br /><br /><p>NOTE: take a good look at DrawATestBlock(). Every time it's called we create a new Sprite and attach it to the FallingBlocks_Main object. This is a prime example of a memory leak. So don't leave your program running over night in this state because it will eat up memory. Remember, DrawATestBlock() is for testing purposes, not final game purposes.</p><br /><br /><p>I've also changed DrawATestBlock to use a random color each time it's called. </p><br /><br /><p>Now jump over to the FallingBlocks_GameSettings file and add in the muFallSpeed_Start.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_02.jpg"></p><br /><br /><p>Again, 1000 milliseconds is 1 second.</p><br /><br /><p>Save your files and test your movie. You should have a block that changes color once a second.</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_03.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_03.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><h3>Bonus use for timer: delay</h3><br /><br /><p>While we're on timers, let's go make our intro screen time-out if we don't press the skip button soon enough. Why don't you go give it a shot and then come back to check your work?</p><br /><br /><p>Okay, so here's what I did in IntroScreen_mc.as:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_04.jpg"></p><br /><br /><p>So again, we import our Timer and TimerEvents, create a timer member variable and a const to control the timer's delay. Then we create it and hook it up in our constructor. </p><br /><br /><p>In our callback, we do what the skip button would have done, so I've reloaded that dispatchEvent into a SkipIntro() function that both event callbacks will call. Now we change SkipIntro() and both the timer event and the button clicked event will stay in sync. </p><br /><br /><p>However, did you notice that you have to stop the timer yourself otherwise it will keep going off and bringing you to the TitleScreen. It seems buggy to me that flash would continue to call a callback in a member function from an object that's been put on the garbage collection list, but the thing about garbage collection is that it's not instant, so it's better to just play it safe, just in this case.</p><br /><br /><p>(You will probably have to refresh the page to see the following swf actually move from the intro to the title screen.)</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_05.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\03_05.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>Also Note: right about now you're going to want to go back to your MainApp constructor and comment out the CreateIntroScreen() and replace it with CreateGameScreen(), so you don't have to click through to the game screen each time you test your movie. When the game is all finished, we can turn the other screens back on. This is totally optional, but makes debugging faster.</p><br /><br /><h2>4. Making the Game's Board</h2><br /><br /><p>Before we go on, let me just be clear on some of my terminology, so we're all on the same page.</p><br /><br /><p><ul><li><strong>Block:</strong> is a colored square in the game board or in a game piece.<br /><li><strong>GamePiece:</strong> is made up of 4 blocks, this is what the player is in control of as it's falling.<br /><li><strong>GameBoard:</strong> is a grid that represents the area the game is played on.<br /><li><strong>GameBoardCell:</strong> is one cell of the gameboard's grid. It's more than just a block. A cell holds information about the block that may or may not be in this grid cell. <br /></ul></p><br /><p>With those terms cleared up, let's talk about how to use a 2 dimensional array to represent the game's board.</p><br /><br /><p>If You don't Know What an Array is, read this:<ul><br /><li>I'd describe an array as "a bunch of something in a row." If you're a Star Trek fan, you may recall the captain saying "fire the forward array," to say "fire all the cannons across the front of the ship."<br /><li>In a computer programming language an array is a bunch of numbers that are lined up in a row. The syntax often uses "[" and "]". So something like "myPhotos[0]" would get the first element in the array of myPhotos, while "myPhotos[1]" would get the second element in the array of myPhotos.<br /><li>Arrays are handy, if you don't know much about them, please do a web search on them because they are pretty basic programmer knowledge and they are pretty crucial to know how to make and use.<br /></ul></p><br /><p>If You don't know what a 2d array is, read this:<ul><br /><li>This is basically an array of arrays. So if we had an array called "columns" which had 10 elements (i.e., 10 columns). Each of these columns might also hold an array (i.e. an array of cells, one for each row in the column). So for example, grid[4] would be the 5th column in our grid. What's in the 5th column? An array of cells. gird[4][1] would get us the grid cell from the 5th column, and the 2nd row. <br /><li>Again, multi-dimensional arrays are handy and if you don't know much about them, please do a web search on them because they are also pretty crucial programmer knowledge.<br /></ul></p><br /><p>Okay, if you're here, you know what 2d arrays are, so here's what they look like in ActionScript3 syntax. (you don't have to type this anywhere, just observe and take it in.)</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_01.jpg"></p><br /><br /><p>Basically, we're going to make the FallingBlocks_GameBoard nothing more than a grid. To keep things easy to read and work with, we're going to make each cell in the grid an object called FallingBlocks_GameBoard_Cell</p><br /><br /><p>So the GameBoard only holds a bunch of cells, and each cell will hold it's own data, things like, "is there a block here or not?" "what color is it?" "is it special?"</p><br /><br /><p>Let's start by defining some more constants. Most falling blocks games use a grid that's 10 wide by 20 tall. So we're just going to stick with that. </p><br /><br /><p>Update your FallingBlocks_GameSettings.as:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_02.jpg"></p><br /><br /><p>Next, I'm going to setup a mostly blank FallingBlocks_GamePiece class simply because I want to define the colors and ids for the pieces that the GameBoard_Cells are going to be using.</p><br /><br /><p>Create a FallingBlocks_GamePiece.as:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_03.jpg"></p><br /><br /><p>We used "static const" so we could access these variables without needing an instance of the class. Also note, the colors are not const because we're going to make the colors change after each level.</p><br /><br /><p>Create a FallingBlocks_GameBoard_Cell.as:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_04.jpg"></p><br /><br /><p>So again we have some static consts to keep track of the cell's states for "IS_EMPTY" and "IS_FULL". </p><br /><br /><p>We have a sprite, which will where we do our DrawBlock.WithBorder().</p><br /><br /><p>We have a BlockId, which refers to the gamepiece who's block is in this cell. We keep this id rather than a color because we can always lookup the color of the block as long as we know which game piece we're part of. This way, when colors of game pieces change, the cell can easily look-up and update to the new color.</p><br /><br /><p>When we create the cell, it automatically creates a sprite and set's is position. Keep in mind this position is in pixels and is measured in relation to the GameBoard's origin.</p><br /><br /><p>Finally, we make some IsEmpty() and IsFull() functions to make our lives easier later.</p><br /><br /><p>Now create a FallingBlocks_GameBoard.as... we'll do this file in two pieces so I can explain as we go:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_05.jpg"></p><br /><br /><p>Again we import Sprit and Point.</p><br /><br /><p>The class extends Sprite because we want to treat our game board like a sprite. It will be drawn, it will have a screen position and it will contain children.</p><br /><br /><p>We have 3 member variables, the Grid is the most important of the data. The GridSize and the BlockSize are just cached values we'll be getting from FallingBlocks_GameSettings, which are passed to use in the constructor.</p><br /><br /><p>The constructor saves the settings we just mentioned and then set's the position of the sprite we extended. After that we create our 2d array for the gird. Notice how we create a FallingBlocks_GameBoard_Cell for each slot in the grid and we give it the pixel offsets from the board's origin.</p><br /><br /><p>Now let's look at the second half of FallingBlocks_GameBoard.as:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_06.jpg"></p><br /><br /><p>Here are some basic functions that we will be using with our GameBoard, a FillCell(), a ClearCell(), and a debug function to FillRandomCell().</p><br /><br /><p>FillCell() takes an offset in the grid, and the id of which piece we want to fill it with. The first thing we do is check if the cell is empty. If so, we need to add it to the GameBoard as a child so it will draw. NOTE: if you call addChild when the child already exists, Flash will be unhappy with you. This is why we check first rather than just blindly call addChild. After all that, we set the Game Piece id to use and Draw that block into our cell's sprite. Note: how we looked up the color in the PIECES_COLORS array.</p><br /><br /><p>Clearing a cell is as simple as not drawing it and clearing out it's IS_FULL state. This is the first time we've used removeChild(), but it's just the opposite of addChild(). If the sprite is no longer a child, it will no longer be drawn.</p><br /><br /><p>Finally, FillRandomCell() gets a random index in the grid and fills the cell with a random piece. The "-1))+1" on the random piece is because we don't want zero as one of the random values returned.</p><br /><br /><p>Okay, now let's hook it all up in FallingBlocks_Main.as</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_07.jpg"></p><br /><br /><p>We add our mGameBoard class member variable, and then create a new one in the constructor. When creating it, we use all GameSettings data. After that we have to add the GameBoard (which extended Sprite) as a child of FallingBlocks_Main (which is also a Sprite), so the board will actually get displayed.</p><br /><br /><p>I commented out all references to DrawATestBlock() because we no longer need it. If you look, creating a new FallingBlocks_GameBoard() replaces the line where were created a Sprite in DrawATestBlock, and we also called addChild(), just like in DrawATestBlock.</p><br /><br /><p>Finally, to make sure the DrawBlock.WithBorder() still happens, we add mGameBoard.FillRandomCell() to our OnMakePieceFall() callback.</p><br /><br /><p>Save your files and test the movie. You should have a gameboard that randomly files with block of color, like this:</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_08.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\04_08.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><h2>5. Setting up and Drawing Game Pieces</h2><br /><br /><p>There is much to do in FallingBlocks_GamePiece.as, however much of it is repetitive. The GamePiece is much like the GameBoard, just an array of blocks that make up the various shapes.</p><br /><br /><p>There's two ways we can go about this. We can make a 2d array that works like a little lookup table or adjacency matrix that tells us, one for one, what the block looks like, or we can make an array of 4 elements that hold the position of each block.</p><br /><br /><p>Let's compare. First, here's what a one for one look up table would look like:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_01.jpg"></p><br /><br /><p>But if we're only ever going to have 4 blocks in a piece, why make a 2d array that has a total of 16 slots?</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_02.jpg"></p><br /><br /><p>This way, we don't have all those empty slots in a 2d array lying around doing nothing.</p><br /><br /><p>But how about we take it one step further? Let think about this. The piece is always going to have a "center" block that the piece rotates around. And since none of the pieces have an empty block that they rotate around, we can guarantee that there will always be one block that all of the pieces have in common.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_03.jpg"></p><br /><br /><p>If you imaging all the pieces rotating around "c" in our look-up grids, you'll see that they all have this one block in common. So let's do everything in relation to that block. Let's say, "c" is at Point( 0, 0 ) instead of Point( 1, 1 ).</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_04.jpg"></p><br /><br /><p>Now, we can probably write our FallingBlocks_GamePiece with an array of *3* block locations because the block at (0,0) never changes.</p><br /><br /><p>However, we're not going to do that. I know some people love to optimize every chance they get, but I like to keep things general and flexible and optimize at the end (rather than optimize ASAP and code myself into a corner)</p><br /><br /><p>Besides, I want you to be able to reuse this gamepiece code in other Falling Blocks style games that might have totally different shaped pieces. So let's keep it general and keep it an array for 4 block locations, but let's capitalize on knowing that they will have a center that they all revolve around. If we make the center block always sit in slot[0] of our array, we can optimize by skipping that slot when ever we can (in loops for all blocks in the game piece), and always fall back on NOT skipping it if we find the need for it. (trust me, all that crap about making "c" equal to Point(0,0) wasn't a waste of time, we'll use it later in this lesson.)</p><br /><br /><p>Okay, so we're going to start filling in FallingBlocks_GamePiece.as. All the stuff we've been talking about will be in the function InitBlocks(), but we're just going to start at the top of the class and work our way down a chunk at a time.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_05.jpg"></p><br /><br /><p>I imported Sprite and Point, and then made our game piece extend Sprite for the same reason we always do (display & container qualities)</p><br /><br /><p>I added some member variables for keeping track of our piece's id, the array of block locations, an array of block sprites, and the block size in pixels.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_06.jpg"></p><br /><br /><p>Notice our constructor defaults to "EMPTY" as a block type. We'll talk about that in a moment.</p><br /><br /><p>We create our array of 4 block locations and also an array of 4 sprites for displaying the blocks. Then we give them an int and add them to the FallingBlocks_GamePiece sprite.</p><br /><br /><p>Now we test what id was passed to us so we can either create the block, or create a random block if nothing was passed to us.</p><br /><br /><p>The MakeNewRandom function is pretty straight forward. We pick a random piece and then Init it.</p><br /><br /><p>CopyPiece is pretty much the same thing, only instead of picking a random piece, we use the id from another piece.</p><br /><br /><p>Okay, now here comes InitBlocks(), which carries out everything we talked about at the beginning of this section.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_07.jpg"></p><br /><br /><p>So I started with a comment that looks like what we talked about in the beginning. If there are any "elite" programmers out there who can't stand seeing diagrams in code, I'd just like to say "you're out numbered by the rest of us" :) . It's called "self-documenting code", get on board.</p><br /><br /><p>Okay, so as we've discussed, slot 0 in maBlockLocs is always 0 and 0. Notice that I didn't say: maBlockLocs[0] = new Point(0,0); I don't care what programming/scripting language you're using, it's usually not wise to create new objects when you don't really need to. As you can already see by the last couple functions, InitBlocks is going to get called more than once, so there's no reason to have it create 4 new Points every time it's called.</p><br /><br /><p>After we init out first slot, the rest of the blocks are init'ed selectively by which piece we're making. It's really not that complicated (especially with that handy diagram comment :)</p><br /><br /><p>I expect everyone will gloss over that "btw" comment about the game piece's screen position, but don't worry, I plan on making that visual.</p><br /><br /><p>Finally, we call an UpdateDisplay() function. Basically, when the blocks change, we need to make sure the sprites that are being used for each block are updated to reflect the change. So let's look at those functions next:</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_08.jpg"></p><br /><br /><p>Our UpdateDiplay() function does two things, updates the colors and the positions of the block sprites.</p><br /><br /><p>In UpdateDisplayColor() we just run through all our block sprites and Draw the correct color in the sprite.</p><br /><br /><p>In UpdateDisplayPos(), we set the position of the block sprites in relation to the GamePiece itself.</p><br /><br /><p>Okay, now all that's left to do is hook it up in FallingBlocks_Main.as and we're good to go.</p><br /><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_09.jpg"></p><br /><br /><p>Why create one FallingBlock_GamePiece when you can create 2, the current piece and the next piece. (I figured it'd be easier to just do them both at once)</p><br /><br /><p>We create out pieces in the constructor and we addChild() with them because, like always, we want these things to be seen.</p><br /><br /><p>I've given the next piece a dummy screen location, but I've left the current piece at (0,0) because I want to show you where (0,0) actually is.</p><br /><br /><p>Finally, down in our timed callback OnMakePieceFall(), we are going to create a new random piece and copy it to the current piece (yes, you may already have noticed those lines seem backwards as far as gameplay goes, but I'm trying to show you something).</p><br /><br /><p>Okay, save your files and test your movie and you should get this:</p><br /><br /><p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_10.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\05_10.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object></p><br /><br /><p>Notice how the current block sits up in the corner and is half cut off sometimes. This is what my "btw" comment in InitBlocks() was referring to. Since we made that center block the (0,0) block, then the screen position of 0,0 is the top left corner of that center block.</p><br /><br /><h2>6. Getting Keyboard Input</h2><br /><br /><p>Keyboard input in flash can be slightly tricky. You need to keep these things in mind:<ul><br /><li>Only the object that has "focus" will get keyboard input.<br /><li>If you use actual letter keys in your game, when you test your movie, you'll have to got up to the "Control" menu and select "Disable Keyboard Shortcuts", otherwise your key presses won't seem to be firing correctly.<br /><li>Windows has something called "Sticky Keys" that automatically enable themselves when you press the shift key 5 times. They are not fun. They will cause you to loose in the middle of a game. Stay away from using the Shift key in your games.<br /></ul></p><br /><p>I've seen some cool keyboard input libraries floating around on line, however they are overkill for our game. Since this tutorial series started off as an introduction to flash, I'm going to implement keyboard input in a very basic, very simple way. (feel free to explore the web for the more complex options if you're interested.)<br /></p><br /><p>Okay, let's keep this section short and sweet. Here's the code for catching keyboard events. Open up MainApp.as and add this:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_01.jpg"><br /></p><br /><p>We're going to have KeyboardEvents so we have to import them first.<br /></p><br /><p>The "stage.focus = this;" is what I mentioned earlier. Regardless of how many objects are listening to keyboard events, only the object that has focus will actually hear those events when they are fired. It can be a little frustrating. You'll be pressing keys and wondering why the game is not working, only to find out the wrong object has focus. I'll show you more of that first hand in a second.<br /></p><br /><p>Next we add our keyboard event listeners. One for detecting key down and one for detecting key up. I've hooked them up to callback functions that just throw out some debug text.<br /></p><br /><p>Save your files and test your movie. (I'd show you an swf, but it's pointless because it's all in the debug print anyway.)<br /></p><br /><p>Notice that as you press some keys, you'll see the key down and key up print outs. Even when the game automatically movies from the intro screen to the title screen. Also notice that if you hold down a key, it will repeatedly fire the key down event.<br /></p><br /><p>Now, click the "Play" or "Credits" button (or maybe you clicked the "Skip" button and have already noticed). After you click a button, you stop getting keyboard events because clicking the button stole our focus. I understand the reason for Flash to work this way, but I wish it didn't. To get the focus back, you can just click somewhere on the game's screen and your input will start working again. But, do you expect the player to figure that out or go find another game to play?<br /></p><br /><p>Basically we have two options. We can give the focus back to the stage manually or we can hardwire it. This is why I attached the KEY_DOWN and KEY_UP event listeners to the "stage" and not the MainApp. The state is a keyword that's accessible from anywhere. So if you want to call "stage.focus = stage;" from any file at any time, you can. Thus we overcome this issue of loosing focus on a case by case basis.<br /></p><br /><p>We can also hardwire it like this:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_03.jpg"><br /></p><br /><p>Now every time the stage gets a "FOCUS_OUT" event, it just sets focus back to itself.<br /></p><br /><p>BE CAREFUL WITH THIS. It may seem nice now but it can bite you later. For example, does your game have any text boxes for type names or messages in to? If so, you may be rendering them all useless.<br /></p><br /><p>Now, let's get that input to our game screen. I'm going to do this via overriding functions in the class AppScreen. It's very simple. Open up AppScreen.as. Notice how the class is empty. Remember the whole point of this class was so we can easily add functionality to all classes that extend it (as in, all of our screens). We're going to drop in the ActionScript equivalent of what C++ calls "a virtual function."<br /></p><br /><p>Basically when the callbacks in main app catch a keyboard event, they are simply going to pass it on to the current screen. There will be a stubbed out function in AppScreen for onKeyDownEvent and onKeyUpEvent that will do nothing.<br /></p><br /><p>Then any screen that inherits from AppScreen will have the option of overriding these two functions to actually do something. So TitleScreen_mc can ignore keyboard events, while GameScreen_mc can use them.<br /></p><br /><p>Here we go, starting with AppScreen.as:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_04.jpg"><br /></p><br /><p>We've imported our KeyboardEvent and we've created two callbacks, but no event listeners.<br /></p><br /><p>Now in MainApp.as<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_05.jpg"><br /></p><br /><p>We update our event callback to pass the event on to the current screen.<br /></p><br /><p>Save your files and test your movie and you should now get the print outs from AppScreen.<br /></p><br /><p>Next we go to GameScreen_mc and override the key event functions using the override keyword, like this:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_06.jpg"><br /></p><br /><p>Save your files and test the movie. Now you'll get that annoyingly long printout from AppScreen on every screen but the Game Screen, which will give us the GameScreen_mc's trace text.<br /></p><br /><p>Next, let's take it one last step and pass the event onto your FallingBlocks_Main class.<br /></p><br /><p>FallingBlocks_Main.as:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_07.jpg"><br /></p><br /><p>Again, we import our KeyboardEvents, we create two functions for key up and key down, and then we drop a trace in there. (Note, if you copy and pasted those functions from the previous file, make sure you delete the "override" keyword).<br /></p><br /><p>Now go back to GameScreen_mc.as and pass along the events:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_08.jpg"><br /></p><br /><p>Save your files and test your movie. It should look just like last time only now the print outs are from FallingBlocks_Main's functions.<br /></p><br /><p>Finally, let's use it to actually change something on screen!<br /></p><br /><p>First let's define our keys in FallingBlocks_GameSettings:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_09.jpg"><br /></p><br /><p>Note; RotateCW stands for "Clock-wise" while RotateCCW stands for "Counter Clock-wise"<br /></p><br /><p>Also Note: remember my warning at the beginning about not using the SHIFT key. The first versions of my game did and I got lots of complaints. That's why we're using SPACE to RotateCCW.<br /></p><br /><p>Now let's hook these keys up in FallingBlocks_Main.as to actually do something. We'll move the current game piece around a block's with at a time.<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_10.jpg"><br /></p><br /><p>So we have a switch statement based on the key that was passed in the event. Each case is a key *from our GameSettings*, NOT a direct test for things like Keyboard.LEFT. (This is so we can remap keys easily).<br /></p><br /><p>Then we just update the mCurPiece's x and y positions (which is just the Sprite x and y from the Sprite class we extended). Since all the blocks in the piece are children of the piece, they will automatically say relative to the pieces new location.<br /></p><br /><p>Save your files and test your move. You should be able to move the current piece around.<br /></p><br /><br /><p><br><br /><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_11.swf"><br /><param name=quality value=high><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\06_11.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object><br /><br></p><br /><br /><p>Also, note how the piece moves if you hold a key down. Flash will send the key down event repeatedly, so the piece will move once, then pause, then keep moving. Which is ideal for our falling blocks game. This is one of the reasons we didn't use one of the fancy keyboard input classes I've seen floating around the web. It would be overkill for this game and we'd have to write extra code just to get that "move once, pause, keep moving" functionality.<br /></p><br /><h2>7. Rotating Game Pieces</h2><br /></p><br /><p>As I mentioned earlier, we went through the trouble to mark the block we rotate around as (0,0) so we could use a simple vector math trick.<br /></p><br /><p>In vector math, you can find the normal to any vector by swapping the x and y values and negating one. It's a pretty common trick for anyone working with 3d games. It looks like this:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\07_01.jpg"><br /></p><br /><p>What's interesting is that the negative determines if we are going in a clockwise or counterclockwise direction from the original vector.<br /></p><br /><p>We're just going to use this to rotate the blocks in our piece.<br /></p><br /><p>FallingBlocks_GamePiece.as:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\07_02.jpg"><br /></p><br /><p>First thing to note is that both of these functions are identical except for the negative signs on line 213 vs. 237.<br /></p><br /><p>The second thing to note is that I've got the function returning a Boolean. If I haven't already mentioned it (and you don't already know) a Boolean is a variable that will only ever be "true" or "false.<br /></p><br /><p>At the beginning of the functions we test for the special case of a Square piece. There's no need for Square pieces to rotate. We return "true" to say "rotation was successful." Because a square rotating 90 degrees around it's actual center point still looks like a square. So there's no reason to return false.<br /></p><br /><p>Next we loop for the 3 block locations that are not our center block. In the loop, we swap the x and y values and negate one, just like we do with vectors. I know some of you may feel the urge to optimize my code and replace "vTmpPoint" with as single "nTmpNumber"... but don't. I did that because later we're going to test our vTmpPoint to make sure the block isn't colliding with something (as in, "is the block *allowed* to rotate?").<br /></p><br /><p>After that, we update the blocks' display position (no need to update the colors, right?). Then we return true for "rotation was successful". <br /></p><br /><p>Again, I'm just planning ahead here with the returning of true. Currently, our function doesn't return false, but in later lessons it might.<br /></p><br /><p>Now go back to FallingBlocks_Main.as and hook these functions up to actual key presses:<br /></p><br /><p><img src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\07_03.jpg"><br /></p><br /><p>Save your files and test your movie. You should be able to move and rotate your current piece.<br /></p><br /><br /><p><br><br /><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="550" height="400"><br /><param name=movie value="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\07_04.swf"><br /><param name=quality value=high><br /><embed src="http://www.dannyburbol.com\games\tutorials\tutorial02_draw_input\data\07_04.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="550" height="400"><br /></embed><br /></object><br /></p><br /><p>And there you have it. The shortest section so far.<br /></p><br /><h2>Summary</h2><br /><br /><p>So what have we learned? We've done so much, I'm sure it's easy to forget what we did in the first section.<br /></p><br /><p>We have:<ul><br /><li>Learned how to draw rectangles in a Sprite.<br /><li>Learned how to make a class with a static function (DrawBlock.WithBorder())<br /><li>Learned how to create a GameSettings class and why we take the time to do so (because it lets us create alternate game settings without having to change our actual game)<br /><li>Learned how to use Timer Events to gave a periodic event for running the game with and for one time delays.<br /><li>Learned the syntax for arrays and 2d arrays.<br /><li>Learned how to make a GameBoard with Cells to hold block data.<br /><li>Learned how to represent Game Pieces with an array of block locations<br /><li>Learned a simple way for getting keyboard input (which is a complex topic you should look into some time)<br /><li>Learned how to apply a small vector concept to the rotation of game pieces.<br /></ul></p><br /><p>I hope by now you've gained a lot of respect for these falling block games. These first two Lessons have been pretty long, and so far, we don't really have a game yet. However we do have all the pieces for a game. In the next lesson we're going to start putting the pieces together and writing the actual game's logic. It's going to be another long lesson, but by the end, you'll have something to play.<br /></p><br /><p>Also, I think most of us would refer to this kind of game as "simple" arcade game -and it is. This is a simple game to play, and a simple game to make. However, now you might be seeing how much programming is involved in a "simple" arcade game. Don't be discouraged, just know that this is a really great "my first game" to be working on. Plus, it's a framework that can be reused and tweaked. Once you finish this game, you'll be able to reuse it to make many different styles of action-puzzle games.<br /></p><br /><p>On top of that, you'll be able to take the next step and make a more "Pac-Man" style games. If you think about it, the 2d grid we're using for our gameboard is much like the grid we'd use to track where a character is and is not allowed to step. (The big hurdle is adding the enemies.)<br /></p><br /><p>For some reason, many people try to make an old-school RPG for their first game. Trust me, RPGs are NOT simple, they are HUGE and complex. I feel for you if you tried to make one before making a falling blocks game... after all, I made that same mistake myself. :)<br /></p><br /><br />A Link To: <a href="http://www.dannyburbol.com/games/tutorials">All Lessons' Table Of Contents</a><br />A Link To: <a href="http://www.dannyburbol.com/games/blocks/">The Original Flash Game that started all this</a>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-35639479599816735282008-06-02T14:27:00.001-07:002008-06-17T13:15:40.496-07:00Flash Game Tutorials, Lesson 1 App Screens<h2>Danny Burbol's How to make a falling blocks style Flash Game Tutorials</h2><br /><h2>Lesson 1: Intro to Flash/ActionScript 3 and App Screens</h2><br /><br />A Link To: <a href="http://www.dannyburbol.com/games/tutorials">All Lessons' Table Of Contents</a><br />A Link To: <a href="http://www.dannyburbol.com/games/blocks/">The Original Flash Game that started all this</a><br /><br /><p>This is a Flash tutorial for introducing some of the basics parts of ActionScript 3 that you'll need to make any Flash Game. It's presented with a goal in mind. We will be using these building blocks to set up a basic framework for making some simple games screen that we'll be able to switch between by click on buttons on the various screens. <br /><br /></p><p>Here's a link to <a href="http://www.dannyburbol.com/games/blocks/">my falling blocks game</a>, it's the reason I started making this tutorial.</p><br /><br /><p>I've been programming console games in c/c++ for years, but Actionscript 3 is pretty new to me. So rather than gloss over everything, I plan on making a more in-depth "how to" for people who have some programming knowledge, but are new to Flash and AS3.<br /><br /></p><p>A work of caution to artist and non-programmers: Making game with Flash using AS3 doesn't *involve* programming, it *is* programming. This tutorial can't teach you how to program, I'm sorry, it's just a topic all to itself, and it's a huge topic at that. So use your best judgment as-to whether or not you want to go through with this tutorial, I don't want to waste your time or make you frustrated. Also, if anyone reading this had some good links for helping others learn some the the basics of programming and programming practices, please leave a comment so others can benefit. (Thanks!)<br /><br /></p><p>By the end of this tutorial we will have a flash application that shows a few screen and lets you click buttons to go between them. For example: a "someone presents" screen, a title screen, a credits screen, and a game screen that we can click buttons to go between.<br /><br /></p><br /><p>So by the of this tutorial, you will have a framework, something like this:<br /><br><br /><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="640" height="480"><br /><param name=movie value="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_05_AGreatGame.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_05_AGreatGame.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="640" height="480"><br /></embed><br /></object><br /><br /></p><p><b><u>Elements I'll be explaingin in this tutorial:</u></b><br /><ul><br /> <li>Make a .fla file<br /> <li>Make a few movie clips (one per screen)<br /> <li>Make a few buttons (for switching screen)<br /> <li>Make a .as file<br /> <li>Make a class<br /> <li>Hook flash to automatically run ActionScript<br /> <li>Hooking up movieclips to work like classes in ActionScript<br /> <li>Hooking up buttons to work like member variables of classes in ActionScript<br /> <li>Catch Generic Flash Events<br /> <li>Make and Catch Your own Events<br /></ul><br /><br /></p><p><b><u>Elements I won't be explaining:</u></b><br /><ul><br /><li>I won't be explaining "how to program", but I will be volunteering as much insight as I can about the Actionscript I'll be showing. Regardless, if you don't know what a "class" or "event" is and you've never heard of "public", "private", "extends", or "override", please stop now. You will be disappoint about halfway through this tutorial. Instead, go check out some programming tutorials and come back to this one later.<br /></ul><br /><br /></p><br /><h2>Step 01: How to Create a new Flash .fla file:</h2><br /><p><br /><ol><br /> <li>open flash<br /> <li>if you're not presented with a splash screen that has the option for creating a new .fla file, then go to the "File" menu and select "New..." In the popup, highlight "Flash File (ActionScript 3.0)" and then click "OK"<br /> <li>this creates an "Untitled" file. So before we do anything, goto "File" > "Save As..." and save it. For this tutorial, I'm going to call it AGreatGame.fla<br /></ol><br /><br /></p><br /><h2>Step 02: How to create a few game screens with Movieclips</h2><br /><p><br /><ol><br /> <li><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_01.jpg"><br /> <br>First of all, we've got lots of great toolbars and window. I'll give a brief description of them *as we use them*, rather than a long list of every single element of the interface. (Also, if you're looking for a long list of every item on in the interface, try the "help" menu, there's lots of element by element information in there. That's where I started.)<br /> <li>Let's start with the "Stage". The stage is the panel that's most likely in the center of your screen with a big blank square on it. You'll also note it has a "timeline" at the top with a "Layer 1" and below that a bar with the word "Scene 1". "Scene 1" is talking about our blank Stage, that white box we're looking at. I just wanted to warn you ahead of time, the process we're about to go through for making screens that we can click and navigate around with are all done in actionscript. So what you see right now is pretty much what you're always going to see, even when you get to the end of my "falling blocks" tutorials. "Scene1" will always be blank. So don't panic or let it bother you.<br /> <li>Resize your flash movie so we're all using the same dimensions. Do this by clicking on the Properties tab at the bottom of the screen. If you don't see it, try the menu bar: Window > Properties > Properties. Now click the Size button and make your movie's dimensions 550 x 400 pixels (if it's not already.)<br /> <li>Next we're going to make a screen in the game by making a movieclip.<br /> <li>Click on the "Library" tab to see the "Library" panel (or find it in the menubar: Window > Library. If something onscreen disappears, then do it again: Window > Library. Basically, you want that "Library" item to have the check next to it in the "Window" menu.<br /> <li>Make a new movie clip:<br /> <ol TYPE=A ><br /> <li>In Our blank Library, somewhere in the white space below "Name" and "Type", right-click and select "New Symbol..."<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_02.jpg"><br /> <li>I'm going to make the title screen first, so I'm naming this movie clip "TitleScreen_mc". Note the "_mc" which means "movie clip". This is not required I just like to see the name of something and know instantly what it is. It's the programmer in me. <br /> <li>Make sure you've got "Type" set to "Movie clip".<br /> <li>Click OK.<br /> </ol><br /> <li>Note the stage has changed. See the bar where it used to say "Scene 1" now says "Scene 1" followed by "TitleScreen_mc". That bar will always tells us our location. The last word will always be the items we are currently editing. It's just like navigating folders on your computer. That same way we can have folders in folders we can also have Moiveclips in Movieclips. So if you ever get lost, look there and it will tell you where you are and what you're currently editing.<br /> <li>Now, let's make a background for our screen. <br /> <ol TYPE=A ><br /> <li>In the timeline, where it says "Layer 1", double click the words "Layer 1" and rename it to "background".<br /> <li>Now, in the same row we just named "background", click on the first box under the "1" (the box has an empty circle in it) This box is frame 1.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_03.jpg"><br /> <li>Next, click on the Rectangle tool (looks like a rectangle, below the line and above the pencil)<br /> <li>Briefly, I'll just say, note the bottom of the toolbar you just clicked on. There is a pencil and a bucket, both with a square of color. These are going to be the border color and the interior color of the rectangle you are about to draw. So pick a couple colors you like.<br /> <li>Draw a rectangle on the stage. Don't worry about size, we're going to make it exact by edit the numbers after we create it.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_04.jpg"><br /> <li>Now got down to the Properties tab (remember, we used this to set the size of the movie.<br /> <li>The movie is 550 x 400, so let's make the box the same size. Set:<br /> <ol TYPE=a ><br /> <li>W: 550<br /> <li>H: 400<br /> <li>X: 0<br /> <li>Y: 0<br /> </ol><br /> <li>Odds are, you're rectangle is in the bottom right corner of the screen and goes out of the stage window. If you hold down the Space bar, your mouse cursor will turn into a hand. As long as you hold down the space bar, you can click and drag to move around the Stage (so you'll see the scroll bars moving instead of the rectangle moving). Do this to center the rectangle on screen... or you can just use the scroll bars.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_05.jpg"><br /> </ol><br /> <li>Now we'll give the screen some text<br /> <ol TYPE=A ><br /> <li>Look up at our layers in the timeline.<br /> <li>Right-click on the word "background" and select "Insert Layer"<br /> <li>Double click on the new layer's text and re-label it "desc"<br /> <li>If "desc" is not above "background", then click and drag the "desc" layer upward to be above "background"<br /> <li>Notice how the boxes under frame "1" in the timeline are different. "desc" is an empty circle, while "background" is a solid black circle. This is because the "background" layer has something on it (the rectangle), while the "desc" layer is empty.<br /> <li>Click on the box for frame 1 for the "desc" layer. (which has the empty circle in it)<br /> <li>Now select the Text Tool from the tool bar (looks like the letter "T", and is below the quill and above the line)<br /> <li>Note all the great stuff in the properties tab at the bottom of the screen. You can do all sorts of stuff to your font. So pick whatever you'd like, just make sure you pick a different color than your background.<br /> <li>Now click somewhere on your rectangle and you'll get a text box to type in. You can pull on the handles on the edges of the box to adjust the text box's size and how the text will wrap to the next line.<br /> <li>Give your game a title. I called mine: "Danny Burbol's Simple Game Screen Tutorial."<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_06.jpg"> <br /> </ol><br /> <li>Play with the layers. Notice you can click and drag the "desc" layer to be below the "background" layer. Notice how you can't see the title text when it's below the "background". This is a useful thing to know. Layers are your friend. Also, if you drag the "desc" layer back to the top, you can hide it by clicking the dot under the icon of the eye. Next to they eye, is a toggle for the lock. The lock means you won't be able to select or edit anything on that layer, and the colored box isn't really that useful but it toggles between drawing the layer or just drawing the layer's outline.<br /> <li>Lock the "desc" and "background" layers by clicking on the dots in each layer below the lock icon. (this way we don't mess them up while we do the next step)<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_07.jpg"> <br /> <li>Next we will add some buttons for letting the player go from screen to screen. We're going to have 4 screens. This title screen, a "someone presents" screen, a credits screen, and a game screen. On this Title screen, we're going to want a button to go to the credits screen and a button to play the game. So let's do that.<br /> <ol TYPE=A ><br /> <li>Create a new layer in the timeline and call it "buttons". (remember how we added the "desc" layer? Double check the last step if you need a refresher).<br /> <li>Make sure to click on frame 1 of the" buttons" layer.<br /> <li>Now rather than making our own buttons, let's just use some of the stock buttons Flash was kind enough to share with us.<br /> <ol TYPE=a ><br /> <li>In the menu bar: "Window" > "Common Libraries" > "Buttons". This will give you the "Library-Buttons.fla panel<br /> <li>Find a button you like and drag from the "Library-buttons" panel to the "library" panel. (Pick a button that already had text on it.) --Note: *don't* drag it directly to the stage, drag it from one library to another.<br /> <li>In the "Library" panel, double click the button's text name and change it to "Play_btn". (I'm not talking about the "enter" text, I'm talking about the text name it's listed as in your "Library" for your AGreatGame.fla)<br /> <li>Drag a second copy of the button over to your library and name this one: "Credits_btn"<br /> <li>In your "Library", double click the little button icon next to the words "Credits_btn".<br /> <li>Notice how the button is on the stage and the location bar now reads: "Scene 1 Credits_btn"<br /> <li>Also notice that the timeline for buttons looks different than the movie clip did. Instead of having frame numbers across the top, there is "up", "over", "down", "hit".<br /> <li>Locate the layer with the button's text on it and unlock it if needed. (I like to turn the layer's visibility off and on until I'm sure I've found the layer that has the button's text on it. Note, my button's text started out as "Enter")<br /> <li>Once you've unlocked the layer with the button text, double click the button text on the stage to edit it to say "Credits". <br /> <li>Now go back to your "Library" panel, double click the button icon for "Play_btn" and change this button's text to "Play" (refer to the steps above if you need a review on how to do that.)<br /> <li>The two buttons are ready to put in on your title screen. Go back to the "TitleScreen_mc" by double clicking on the little movie clip icon next to the "TitleScreen" text in the "library"<br /> <li>With the TitleScreen_mc on the stage, and the first frame of the "buttons" layer selected, drag a copy of "Credits_btn" and "Play_btn" from the Library panel to the stage.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_08.jpg"><br /> </ol><br /> </ol><br /> <li>Finally, we have all the elements for this screen. To keep our Library from getting too cluttered, you can right-click in the Library and select "New Folder". I named my folder "fTitleScreen". Again, I like names that say what they are. In this case, the "f" means "folder"... but at the same time, Flash doesn't like it when two things in the library have the same name. The first time I did this, I name my Title Screen movie clip, "TitleScreen"... and then when I tried to make a folder called "TitleScreen", Flash wouldn't let me. So by getting into the habit of post-fixing and pre-fixing names, I avoid any problems like this.<br /> <li>Now, go back to the beginning of these steps and create a few more screens with a few more buttons. When you're done you should have:<br /> <ol TYPE=A ><br /> <li>IntroScreen_mc<br /> <ol TYPE=a ><br /> <li>Some text that says: "Presented by <your name>" or "A <your name> Production"<br /> <li>A button named "SkipIntro_btn" that says "Skip Intro" on it.<br /> </ol><br /> <li>CreditsScreen_mc<br /> <ol TYPE=a ><br /> <li>Some text that says: "Credits"<br /> <li>Some more text that says: "This game was made by <your name>"<br /> <li>Some more text that says: "Special thanks to the totally helpful flash tutorial on DannyBurbol.com" (well, it'd be nice of you to do that).<br /> <li>A button named "BackToTitle_btn" that says "Back"<br /> </ol><br /> <li>GameScreen_mc<br /> <ol TYPE=a ><br /> <li>Some text that says: "the game will be played on this screen"<br /> <li>A button named "Quit_btn" that says "Quit" on it.<br /> </ol><br /> </ol><br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_09.jpg"><br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_10.jpg"><br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_11.jpg"><br /> <li>After you've create all of these screen, you should put them in 4 folders in your library, "fTitleScreen", "fInfroScreen", "fCreditsScreen", "fGameScreen"<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/02_08b.jpg"><br /></ol><br /><br /></p><p>TIP: if you make a mistake and put all of your screen's elements on the same layer, you can fix it by clicking on the frame in the timeline (the box with the black dot in it) and then right-clicking on one of the highlighted items on the stage and selecting: "Distribute to Layers". Now each item is on it's own layer... just rename the layers to match what's on them... again, you can use the toggle of the eye to turn layers on and off and make sure you know what's on each layer before you rename it.<br /><br /></p><br /><h2>Step 03: How to make and hookup a Document class</h2><br /><p><br /></p><p>If we test our game right now, we should get a blank screen. You can test your game by pressing Ctrl+Enter, or going to the menu bar and selecting "Control" > "Test Movie". (PS, if you have a Mac, I'm sure you're used to figuring out what the Mac equivalents of PC shortcut keys are... in fact, I've been saying "right-click" a lot, and I know that's different for you guys as well. I'm just going to continue in PC terms, please keep translating in your mind like you have been already. Thanks, and sorry for the inconvenience.)<br /><br /></p><p>So, what we want to do is use ActionScript to create an object of type "movie clip" (all of our screens are movie clips). Then we want to show the movie clip we created the in movie's main scene. Of course the question is, "how?"<br /><br /></p><p>We have a couple things to overcome. <br /><ol><br /> <li>We need to get the movie to trigger some ActionScript the moment it starts playing. <br /> <li>Then we need that ActionScript to specifically create one of our movie clip screens. <br /> <li>Finally, we need to get that movie clip to actually display. <br /></ol><br /><br /></p><p>This section is going to cover that first issue: get the moive to trigger some ActionScript the moment it starts playing.<br /><ol><br /> <li>First we need an ActionScript file to call when the movies starts, so let's create an ActionScript file.<br /> <li>in the menubar, select: "File" > "New..." and then select "ActionScript File". Don't select "Flash File (ActionScript 3.0)". I know that one looks tempting, but it's going to create another *.fla file.... what we want is a *.as file.<br /> <li>Our main window changes and we no longer have our stage and timeline. Instead we have a blank screen with two tabs at the top "AGreatGame.fla" and "Script-1".<br /> <li>Before we get distracted, let's name the *.as file. Please note, I had a bit of a run around when my *.as file and the class it contained were not named identically. It could have been a fluke, but I just got in the habit of making sure my names were identical. So just give some thought to your file names is all I'm saying.<br /> <li>Let's "save as" on this file and call it, "MainApp.as" and be sure to save it in the same directory as AGreatGame.fla. (don't call it by the name of your game, you'll regret it later in the tutorial when we actually create an AS file by that name)<br /> <li>Now we type in some ActionScript. Notice I said "type". I don't mean to be a pain in the butt or sound all "holier-than-thou", but copy/pasting stuff is not going to get you anywhere. I heard a great quote: "The Learning is in The Doing". Very wise in my opinion. You learn more by "writing script" than "moving script" from one screen to another with copy/paste. (sorry for the lecture).<br /> <li><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/03_02.jpg"><br /> <li>Save Your MainApp.as file! I don't know why but Flash doesn't automatically save your *.as file when you try to test your movie (as in: ctrl+enter). So just get in the habit of saving often. Also, if you change some script and run your movie only to see that nothing happened, you'll remember my mystical jedi powers of suggestion and recall this paragraph *before* you pull your hair out.<br /> <li>Okay, so what does this script mean? With my one week of AS3 experience I can tell you this:<br /> <ol TYPE=A ><br /> <li>All *.as files that I've seen start with "package"<br /> <li>All *.as files that I've seen have no class or one class in them, but I haven't seen more than one class and I hadn't had a reason to try it.<br /> <li>import is a lot like C++'s #include or using namespace. <br /> <li>trace( ) is basically our debug printf.<br /> </ol><br /> <li>But wait! What's a "class"? what's "public"? what's "extends"? -if you find yourself asking these questions, then you need to take a break from this tutorial and go check out some object oriented programming tutorials. I don't mean to be rude but classes are a basic programming building block these days, and the syntax of ActionScript is very much like Java and C++. So you should read up on them. In all honesty, it broke my heart when I realized just how much programming is involved in ActionScript. I had visions of little kids on Christmas morning, opening their gifts to find that one perfect toy they've been waiting months to play with, only to find out it didn't come with batteries. I really thought Flash with AS3 was going to pretty much be a fun little "game editor" or something... but the reality is, Flash and AS3 are so powerful because they are so much like programming. If you want to make cool games, just bite the bullet and start reading (and doing!) programming tutorials. This is tough love. I'm warning you now because it's only going to get more complex as we move on.<br /> <li>Okay, we have the bare minimum ActionScript to do something, which is just a debug print in our class' constructor. Now we need this class to actually get created when the movie runs. This is why the title of this section is "How to make and hookup a Document class."<br /> <li>If you haven't already, save your MainApp.as file.<br /> <li>click on the tab at the top of the window to go back to your AGreatGame.fla file (you can also use ctrl+tab).<br /> <li>in the location bar, click on "Scene 1" to verify that only the words "Scene 1" appear in the location bar.<br /> <li>Click on the blank stage and then click on the Properties tab.<br /> <li>Remember, this is where we set the movie's size. <br /> <li>Also in this panel, you'll see "Document class". This is where we tell flash the name of the class we want to create when the movie starts running. So type in: MainApp<br /> <li>now hit ctrl+enter to test the movie. The Output window should automatically open and print "MainApp::MainApp()".<br /> <li>tada, this is basically "hello world", only more useful because we've also created an instance of a class.<br /></ol><br /><br /></p><br /><h2>Step 04: How to Link Movie Clips to ActionScript like classes.</h2><br /><p><br /></p><p>This is really cool but not really that intuitive. I followed a tutorial that did this and didn't even pause to explain why. It came back to bite me (of course), so I'm devoting a whole section to it to say:<br /><br /></p><p>"HEY YOU! STOP SKIMMING AND READ THIS!! It's really important and easily overlooked."<br /><br /></p><p>Imagine you could treat a Flash movie clip like a class in Actionscript. Imagine you could create buttons in that movie clip and have them be member variable of that class in Actionscript. That's exactly what we're going to do.<br /><br /></p><p>Exposing your movie clips to ActionsScript 3.0 as classes.<br /><ol><br /> <li>In your AGreatGame.fla, go to your Library and right-click your IntroScreen_mc and select "Linkage" (which is right under "Properties")<br /> <li>In the pop-up, check "Export for ActionScript". The data should automatically fill in.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_01.jpg"><br /> <li>Basically, we're about to say we want a class called "IntroScreen_mc" and we want it to extent "flash.display.MovieClip" which makes sense. Our IntroScreen_mc *is* a Movie Clip and we want to add more functionality to it. Also, the "export in first frame" checkbox should be check.<br /> <li>Now here's one of my first "sad kid with no batteries on Christmas" moments. We click OK and nothing happens. I really expected flash to create a new ActionScript file for us and pop in the one class so we would have not change of screwing it up. This is not the case. You need to *already know* what the class is supposed to look like in *their language*. This, I think, is a lot to ask of any user regardless of one's programming experience. I paid money for this "tool", it should be saving me from cases of potential user error. Oops. </rant><br /> <li>create a new ActsionScript file (remember how we made MainApp.as? go review if you have to.), call this new file "IntroScreen_mc.as".<br /> <li>Here's the code for this file:<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_02.jpg"><br /> <li>Code details:<br /> <ol TYPE=A ><br /> <li>so again we start our file with "package".<br /> <li>We import the MovieClip, which is just like a c++ #include. If we didn't' include the MovieClip, on the next line, Flash would give us a compile error for trying to used an undefined type "MovieClip".<br /> <li>Our class definition is pretty straight forward. You may think it looks a little funny having that "_mc" hanging off the end of the class name. Again, I did this to help ourselves in the future. We're going to make class that are *not* attached to Flash objects with this "Linkage" property. So it's nice to have that "_mc" jump out at you to tell you which things are relying on things in your flash library and which are not. Think about it, if I handed you 100 *.as files and 20 of them ended with "_mc.as", you'd instantly have a much better understanding of what files do what and which are linked to objects in the game's flash library.<br /> <li>Again we put a trace in our constructor because we want to verify that it worked.<br /> </ol><br /> <li>go back to MainApp.as and add a few things.<br /> <ol TYPE=A ><br /> <li><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_03.jpg"><br /> <li>Remember, we have to import the MovieClip so we can use it.<br /> <li>We create a member variable to hold our current screen. Note how AS3 does this. You declare public/private for the variable, then you use "var" to say it's a variable. This is followed by the name of the variable, then the colon and the variable type. Also note that this is a pointer because we just set it to null (a lowercase "null" btw). Why do we have a "var" if it's obviously a MovieClip variable? Later you'll see us replace "var" with things like "const". So it's good to see AS3 allows us to describe our data as "var", "const" and "static".<br /> <li>We created a function CreateIntroScreen() which will do just that. <br /> <ol TYPE=a ><br /> <li>add/removeChild() are for adding the screen's movieclip to the MainApp, which is, in turn, a child of the stage. These functions control whether or not the screen movieclip will be displayed in our flash movie.<br /> <li>I started with an error check, better safe than sorry.<br /> <li>Note, no 'delete' because we're using a garbage collecting language.<br /> <li>and "new" is just like C++.<br /> </ol><br /> <li>Finally, we call CreateIntroScreen(); in our MainApp's conctructor.<br /> </ol><br /> <li>Save your *.as files. Then test it with ctrl+enter.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_03b.jpg"><br /> <br /><br><br /><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="640" height="480"><br /><param name=movie value="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_03_AGreatGame.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_03_AGreatGame.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="640" height="480"><br /></embed><br /></object><br /> <br /> <br /> <li>Finally! We have visual! (notd, the button does nothing) I hate not seeing my game onscreen and it's a shame just how much we have to go through to get to this point. Are their other ways? Yes, of course, but I fell victim to many of those ways when I first starting researching AS3 with the goal of making a falling blocks game. Let me repeat: there *are* easier ways to get something on screen, but I found many of those ways quickly limit us as to where we can go next. This way, we have class, we have encapsulations, --we have all the structure in place to actually start programming an application/game. Again, I use the word "programming", I'm sorry my artist friends, but Flash really did go into the realm of programming on this one. If you're an artist and you want to make a Flash game, you might be happier hooking up with a programmer so they can do what they love (type boring text!) and you can do what you love (make things look awesome!)<br /> <li>btw: you're output window should read:<br /> <br>MainApp::MainApp()<br /> <br>IntroScreen_mc::IntroScreen_mc()<br /> <li>okay, just a note on how I work. I'm a visual person. From here on out I'm going to add a little bit, and then test the movie, and add a little bit, and then test the movie. I'm not going to dump a couple files worth of ActionScript on you and say "1. type all this. 2. 'tada' we're done." We're going to build on what we have and keep building.<br /> <li>BEFORE YOU RUN AHEAD AND IMPLEMENT THE OTHER SCREENS (ie: CreateCreditsScreen(), CreateGameScreen() and CreateTitleScreen() ), first take this next step.<br /> <li>The plan here is to have MainApp manage our screens. The best way to do that is to give MainApp a common API for dealing with all of our screens. Currently mCurrentScreen is a MovieClip, which is nice. Those add/removeChild() functions will work for all of our screens. However, we're going to plan ahead so our screens' common API can get more complex as we progress.<br /> <li>To do this we're going to insert a class between IntroScreen_mc and MovieClip. We'll call this new class "AppScreen". And in the end, all of our screen movieclips will inherit from AppScreen.<br /> <li>So create a new *.as file and name it AppScreen, then fill it with this:<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/04_04.jpg"><br /> <li>now update what IntroScreen_mc extents from MovieClip to AppScreen.<br /> <li>Also update MainApp.as so our mCurrentScreen is no longer of type MovieClip and instead, of type AppScreen.<br /> <li>save your files and test your movie. It should look exactly the same, only you should have different output text:<br /> <br>MainApp::MainApp()<br /> <br>AppScreen::AppScreen()<br /> <br>IntroScreen_mc::IntroScreen_mc()<br /> <li>Now go back to the beginning of this section and use your copy/paste skills to:<br /> <ol TYPE=A ><br /> <li>Link up each screen using the "Linkage" properties.<br /> <li>Create files with classes for: CreditsScreen_mc, GameScreen_mc, and TitleScreen_ms.<br /> <li>Don't forget, your screens are extending AppScreen, not MovieClip.<br /> <li>Create functions in the MainApp class for: CreateCreditsScreen(), CreateGameScreen(), and CreateTitleScreen().<br /> <li>Test those functions by trying each of them in your MainApp::MainApp().<br /> </ol><br /></ol><br /></p><br /><h2>Step 05: How to access Buttons in ActionScript classes.</h2><br /><p><br /><br /></p><p>We're going to do two major things in this section. First we're going to give ActionsScript access to the buttons on each screen. Then we are going to actually listen for when the button gets pressed and give a debug print. We're not actually changing screens just yet, we're just hooking up buttons.<br /><ol><br /> <li>Before we do anything, we need to verify you don't have the "mess everything" checkbox checked in your settings.<br /> <ol TYPE=A ><br /> <li>Go to File > Publish Settings...<br /> <li>Click the "Flash" tab<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/05_01.jpg"><br /> <li>Where it says: "ActionScript version: ActionScript 3.0" and then "Settings..."... click that "Settings..." button.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/05_02.jpg"><br /> <li>Make sure "Stage: [ ] Automatically declare stage instances" is not checked. We're going to declare our instances in each screen's class, if we don't uncheck this, Flash will complain that we're trying to declare something twice.<br /> <li>Click OK, but don't close the Publish Settings window.<br /> <li>While were here, check the "Protect from import" box and anything else you might find useful.<br /> <li>Click OK to close the Publish Settings window.<br /> </ol><br /> <li>now let's hookup a button to our actionscript. We'll start with the IntroScreen_mc, since that's the first screen with the first button we can test with.<br /> <ol TYPE=A ><br /> <li>Double click the icon next to "IntroScreen_mc" in your Library. (so you can get to the edit mode for IntroScreen_mc.<br /> <li>You may need to center the screen in the stage, remember you can do this by holding down the spacebar while clicking and dragging, or you can just move the scroll bars.<br /> <li>Select the Selection tool from the toolbox. (the black pointer at the top of the toolbox)<br /> <li>Single click on the "skip intro" button on the stage to highlight it.<br /> <li>Now, if it's not already open, click on the "Properties" tab at the bottom of the screen.<br /> <li>There should be some gray'ed-out text that reads: <Instance Name>. Change that to be: mInstBtnSkipIntro<br /> <li>Again, we have my extra descriptive prefix. I'm sure your getting tired of them, but let me explain my logic. "m" is about to mean "member variable", "Inst" is "instance", "Btn" is "button". I put all this *before* the SkipIntro because this is going to be a *variable*, while "SkipIntro_btn" is a *type*. This way when you see "mInstSomething" vs "Something_btn" in Actionscript, you'll not right away if it's a variable or if it's something in your flash movie's library that you can edit. Imagine if they were both called "SkipIntro" and "SkipIntro"... it just leads to a runaround if you don't already know what you're looking at.<br /> <li>After naming the instance, open up your IntroScreen_mc.as<br /> <li>Add the following lines:<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/05_03.jpg"><br /> <li>We have to import SimpleButton and MouseEvent because we're about to make SimpleButton variable and listen for mouse events on that button.<br /> <li>public var mInstBtnSkipIntro:SimpleButton; is that same instance we just named in our IntroScreen_mc. Note: "public" not "private", Flash doesn't like it when these types of vars are "private".<br /> <li>mInstBtnSkipIntro.addEventListener function is Flash's standard way of listening for events. (as in: remember this line, you'll be making lots of these in the future).<br /> <ol TYPE=a ><br /> <li>MouseEvent.CLICK is the event we're listening for.<br /> <li>OnSkipIntro is the name of the callback function we want flash to call when the MouseEvent.CLICK event is fired.<br /> <li>false, 0, true : this sets out "useCapture", "priority", and "useWeakReference". We want our game to be fast and not use a lot of memory for events. These settings let us do that.<br /> <li>The OnSkipIntro function is the function that will be called when our button is clicked... we could have called it anything, it's the ev:MouseEvent that's the required part.<br /> </ol><br /> </ol><br /> <li>Save your file and test your movie. You should get a printout every time you click the "skip intro" button.<br /> <li>Now go back the hook up all your buttons in all your movieclip screens.<br /> <li>Be sure to test them all to make sure they are printing out the debug trace correctly before moving on to the next major step. So you should have the following button instance variable and callback functions:<br /> <ol TYPE=A ><br /> <li>In CreditsScreen_mc:<br /> <ol TYPE=a ><br /> <li>mInstBtnBack which is hooked up to call an OnBack function.<br /> </ol><br /> <li>In TitleScreen_mc:<br /> <ol TYPE=a ><br /> <li>mInstBtnPlay which is hooked up to call an OnPlay function.<br /> <li>mInstBtnCredits which is hooked up to call an OnCredits function.<br /> </ol><br /> <li>In GameScreen_mc:<br /> <ol TYPE=a ><br /> <li>mInstBtnQuit which is hooked up to call an OnQuit function.<br /> </ol><br /> </ol><br /></ol><br /><br /></p><br /><h2>Step 06: How to Sent And Receive our own custom Flash Events.</h2><br /><p><br /><br /></p><p>Okay, so we know our buttons are doing something because they are doing a debug print. Now we just need our buttons to actually change screens. Basically, we need a way for our AppScreens to communicate with our MainApp. <br /><br /></p><p>Events are pretty much the standard for objects to communicate with each other these days, and ActionScript 3 is no exception. We've already used one of Flash's standard events to listen for buttons being click. This was when we told each button to "addEventListener" and then specified a function to call when the event was fired.<br /><br /></p><p>You can get pretty far using nothing but Flash's built in events. In fact, rather than have each screen be in charge of listening for it's own buttons (like we just did), I saw plenty of sample code that would have our MainApp class access each specific button in each specific screen and attach a listener function there to handle each button press. This works, but it also breaks the simple idea of encapsulation. Each screen should be self-sustaining, and if we change the buttons on a screen, it seems silly that we would have to also fix references to that button *outside* of the screen's class (as in, the bad MainApp usage I just described).<br /><br /></p><p>So we're just going to bite the bullet and learn how to setup our AppScreens to send and receive our own custom events. Now, instead of having MainApp setup to say "tell me when someone clicks this exact button in this exact screen", we're going to set it up to tell MainApp, "hey, don't ask why, but someone wants to go to this other screen." That way all the logic of what the buttons do is encapsulated in each screen and MainApp never has to know about what screen has which buttons on it.<br /><br /></p><p>So lets get started adding our own events:<br /><ol><br /> <li>First we need to define our events so we can send them later. An example of an event would be that "MouseEvent.CLICK" we used earlier.<br /> <ol TYPE=A ><br /> <li>Create a new *.as file, and save it as "AppScreenEvents.as"<br /> <li>Here's the code for that file:<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_01.jpg"><br /> <li>Again, package comes first and everything goes inside it.<br /> <li>Our AppScreenEvent class extends Event<br /> <li>These next four static const strings are out events. That are the equivalent of that "MouseEvent.CLICK", however we will be using something that looks like "AppScreenEvent.GOTO_TITLESCREEN"<br /> <li>The constructor is just passing on the data to it's super class (Event). This 'super' keyword is awesome in my opinion (having dealt with the way C++ calls super class functions, which involves hard coding the name of the super class followed by the scope operator.)<br /> <li>We also override the clone function. BTW, this is the first time we a colon after the function's closing paranthisis. "clone():Event". This is how we define a funtion's return type in ActionScript 3. So it's consistent with the way they define variable types, and it's carried out with the "return" keyword as expected.<br /> </ol><br /> <li>Save your files and Test your movie, just to make sure all the was typed correctly and didn't cause any problems.<br /> <li>We have our events, now we need to be able to sent these events.<br /> <ol TYPE=A ><br /> <li>Open IntroScreen_mc.as<br /> <li>Update the OnSkipIntro function as follows:<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_02.jpg"><br /> <li>Pretty simple. The OnSkipIntro function gets called when the "Skip Intro" button is press on the Intro Screen. What do what want to happen when went we press this button? We want to go to the Title Screen. So we create an AppScreenEvent using the GOTO_TITLESCREEN static const we just setup.<br /> <li>Now open each *Screen_mc.as file and add the dispatchEvent call after our button's trace output. Just ask yourself "where do I want this button to take me?" and then changed the "GOTO_xxx" to match.<br /> </ol><br /> <li>Save your files and Test your movie, again just so make sure we didn't make an typos or anything. The movie itself is not going to do anything new just yet.<br /> <li>Now, we have custom events that we're sending out when buttons are clicked, we just don't have anyone listening to these events. We do this pretty much the same way we did our "MouseEvent.CLICK". That is, we're going to use the "addEventListener" function again.<br /> <ol TYPE=A ><br /> <li>In MainApp.as add this function:<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_03.jpg"><br /> <li>So basically when mCurrentScreen fires off one of our "GOTO_xxx" events, we go to one of our Create*Screen functions.<br /> <li>This doesn't compile yet, by the way. Remember, an event callback takes a parameter that is the event it heard. Back in IntroScreen_mc.as, we have the OnSkipIntro function that takes the parameter "ev:MouseEvent", because that's what it's listening to, a MouseEvent. We need to make our Create*Screen functions aware of the event they are catching.<br /> <li>So, in MainApp.as, for each of our Create*Screen functions, change the parameters from "( )" to "( ev:AppScreenEvent )". Also, while you're in there, have each of these functions call AddListenersForAppScreenEvents() on the last line of the function.<br /> <br><image src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_04.jpg"><br /> <br><br>Note, you're changing more than want I got in that screen shot<br><br /> <li>The very last step is to go back to the MainApp constructor and have CreateIntroScreen pass a null parameter.<br /> </ol><br /> <li>Save your files and test your movie. You should be able to click buttons and move around from screen to screen.<br /><br><br /><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="640" height="480"><br /><param name=movie value="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_05_AGreatGame.swf"><br /><param name=quality value=high><br /><param name=wmode value=transparent><br /><embed src="http://www.dannyburbol.com/games/tutorials/tutorial01_appscreens/data/06_05_AGreatGame.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="640" height="480"><br /></embed><br /></object><br /></ol><br /><br /></p><br /><h2>The Next Step: What you can do with what we've learned.</h2><br /><p><br /><br /></p><p>This is the end of this tutorial. What have we learned? <br /><br /></p><p>In the end, the most important things we're walking away with here is the ability to:<br /><ul><br /><li>Access movie clips in ActionScript 3 as classes via the "Linkage" property.<br /><li>Access instances, like buttons, in ActionScript 3 and have them be member variables in a class we've used "Linkage" on.<br /><li>We can listen and react to standard events, like MouseEvent.CLICK<br /><li>We can create, send, and listen for our own custom events. This is huge. All the other things I just mentioned are more of a "Basics of Flash Actionscript 3", while custom events are a big step up and are more of an "Intermidiate" topic. Knowing how to do this will set you free to create some really great games in the future, even if you don't follow all my, specific, tutorials. <br /></ul><br /><br /></p><p>We've used the above building blocks to set up a bunch of Screens, each of which is smart enough to manage it's own content. We've also setup a manager to switch from screen to screen when asked to do so by the objects it's in charge of. From here you could make as many screens as you wanted and link them with buttons how ever you wanted. Notice that the way we put things together, all you have to do is add a button to a screen and you can make it bring us to any other existing screen without having to touch MainApp or AppScreenEvent again.<br /><br /></p><p>However, if you want to add more screens, then you'll have to make sure MainApp knows how to create it as well as add a new AppScreenEvent so MainApp can communicate with it's AppScreens about going to this new screen.<br /><br /></p><p>If you were inspired, you could use this framework to make 100 screens and link them together to make a graphical "choose your own adventure" style story.<br /><br /><br /></p><p>You can also go back and make your screens look cooler. We just did the bare minimum as far as graphics go. Now is your change to go wild. However, one word of caution: make sure your WhateverScreen_mc movieclip has one, and only one, frame. I'm talking about CreditsScreen_mc, GameScreen_mc, etc. Originally, I thought it would be cool have an animating title screen where the words animate into view. You can do this, but instead of adding a bunch of frames to your TitleScreen_mc, make a seperate TitleText_mc that had multiple frames and animates the text the way you want. Then just drag that TitleText_mc into your TitleScreen_mc's single frame. It will animate as you want, and will keep you from having odd problems to deal with later in these tutorials.<br /><br /><h2>The Next Lessons: more tutorials.</h2><br /><br /></p><p>The next tutorial will be about drawing a square on the screen and moving it around with the keyboard.<br /><br /></p><p>The tutorial after that will be about using our drawing and keyboard capabilities to make the actual game board and game pieces.<br /><br /></p><p>The tutorial after that will be about getting the game board and the game pieces functioning together like a game. At the end of this tutorial you'll have a bare-minimum falling blocks game.<br /><br /></p><p>The tutorial after that will be about adding sound.<br /><br /></p><p>The tutorial after that will be about adding a score and some game over text.<br /></p><br /><p>If you read all the way to this line. I hope you got a lot out of this tutorial!<br /><br>thanks for reading!<br /><br>~Danny</p><br /><br />A Link To: <a href="http://www.dannyburbol.com/games/tutorials">All Lessons' Table Of Contents</a><br />A Link To: <a href="http://www.dannyburbol.com/games/blocks/">The Original Flash Game that started all this</a>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com3tag:blogger.com,1999:blog-2064071933282644832.post-75821065361001666352008-05-24T13:17:00.000-07:002008-05-24T13:36:36.474-07:00Falling Blocks GameBTW, this is the falling blocks flash game I mentioned in my previous post. (click to play)<br /><br /><center><a href="http://www.dannyburbol.com/games/blocks/"><img src="http://www.dannyburbol.com/games/img/screenshots/blocks.jpg" style="border:1px solid black"></a></center>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-41036822318980086882008-05-24T10:44:00.000-07:002008-05-24T13:22:10.992-07:00Flash AS3: graphics.drawRect Memory Leak<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNMnIhkMmKAVf1pyIFhyRMvCV2pkazSqI2ozxIJE6pSY_v4Hnuqp-O0M4tE_9464UO0gjv9o7VPu88VESo3z9G1Hv8i0zYoUNqdfRbLKEHP5_IXYpNqlNk80VzzCFlrraG_F60s4pKrlk/s1600-h/notepad.jpg"><img id="BLOGGER_PHOTO_ID_5204002668620427650" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNMnIhkMmKAVf1pyIFhyRMvCV2pkazSqI2ozxIJE6pSY_v4Hnuqp-O0M4tE_9464UO0gjv9o7VPu88VESo3z9G1Hv8i0zYoUNqdfRbLKEHP5_IXYpNqlNk80VzzCFlrraG_F60s4pKrlk/s400/notepad.jpg" border="0" /></a><br />I know this is supposed to be an art blog, but as soon as you introduce a computer, the lines between art and engineering start to get blurred. Regardless, I found this Flash AS3 Memory Leak to be such a landmine that I just had to post it somewhere for other people to hopefully find and breath a sigh of relief when they realize why their flash game slows down and grinds to a halt the longer they play it.<br /><br />Okay, no beating around the bush. Do this code once a frame (or more!) and you're flash game will grind to a halt.<br /><br />mySprite.graphics.beginFill( 0xFFFFFF ); <br />mySprite.graphics.drawRect( vPos.x, vPox.y, vSize.x, vSize.y );<br />mySprite.graphics.endFill();<br /><br />This was my "DrawBlock" function for my <a href="http://www.dannyburbol.com/games/blocks/">falling blocks game</a>. I see these three lines posted all over the web in tutorial and in forums. --Worse, I often only see the first two lines and no endFill(). The above code eats memory.<br /><br />This code will NOT eat memory:<br />mySprite.graphics.clear(); // <--- required.<br />mySprite.graphics.beginFill( 0xFFFFFF ); <br />mySprite.graphics.drawRect( vPos.x, vPox.y, vSize.x, vSize.y );<br />mySprite.graphics.endFill();<br /><br />Okay, now I'll begin my rant / explanation of the problem and solution.<br /><br />In 8 years of making professional console games I've never seen a drawRect function eat memory. I'm talking, SNES, Playstation, PS2, Xbox, PS3, Xbox360 --none of them had any reason to use more memory to fill some offscreen pixels with color. So I found this result in Flash, not only unexpected, but jaw-dropping. <br /><br />"drawRect" should do exactly what it says it does. In a console game engine, we would create a new sprite (or something of that effect) and the engine would grab a piece of memory for that sprite. This would happen once. After the sprite has some memory to draw on, there's no need to ever get more. <br /><br />Imagine if you will, a simple square piece of paper --like one of those note pads you most likely have on your desk. Saying "create a new sprite" is like pulling off the top sheet of paper and putting it on the desk in front of you so you can use it.<br /><br />After that, you can scribble on that piece of paper as much as you want and as often as you want. You can draw a rectangle as many times as you want in as many colors as you want but you only ever use ONE piece of paper. And if the paper is too full, you can always erase it or cover the thing with white out or something that allows you to continue to use ONE piece of paper.<br /><br />In computer terms, that piece of paper is a piece of memory, and drawing on it is *ultimately* like changing the color of pixels. It doesn't matter how many times you draw and change the color of the pixels, you'll always have the same number of pixels in your sprite. The idea of a "drawRect" function taking more memory with each call is a big giant "WTF!" because there's no need for it.<br /><br />Now, here's my hypothesis on why flash's drawRect function is eating up memory. (notice I said "hypothesis") I believe that flash's "drawRect" function is really an "addDrawRect" function for one simple reason: Flash obviously capitalizes on vector graphics.<br /><br />I believe "drawRect" doesn't draw a rect at all, I think it just adds a rectangle shape to a list of things to draw when this sprite is told to draw to the screen (later in the frame). Basically, every time you call drawRect, imagine pulling another sheet of paper off your notepad and placing it on top of what you already have in front of you. Each one on of these pieces of paper would have one shape drawn on it. Before long you will have a stack of paper in front of you because, however thin paper is, it adds up.<br /><br />And that's it. In console games, drawing a sprite is usually as simple as copying the sprite's pixels to the screen (aka screen buffer), while drawing a sprite in flash basically runs through a list of every shape in a list and then draws it to the screen based on what the vector math for that shape tells it to do. <br /><br />So in console games, rather than calling a clearRect or clearSprite function every frame, we literally just drop a new color right on top of the old. If a block in my tetris board is red and should be changed to blue, then we just draw blue over the red data because clearing the data and then drawing it blue takes twice as long.<br /><br />With flash, if I used my little draw block function to change the color of a block every frame, the first frame Flash would draw 1 rect (say, red), the second frame Flash would draw 2 rects directly on top of each other (red and then the second color, like blue), on the third frame Flash would draw 3 times (red, blue, and 3rd color), forth frame -4 rects, etc...<br /><br />Here's the catch --drawing (aka copying or writing to memory) is the SLOWEST part of a game. It's the reason we have expensive graphics chips that bench-test based on how many polys they can draw in a frame. <br /><br />So, in the end, Flash is quite the opposite of what I've seen in the past. Rather than finding tricky ways to skip the "clear" function, I should use it every chance I get.<br /><br />so... the next time you use "drawRect" in Flash, think of it as "addDrawRect".<br /><br />Thanks for reading,<br />~Danny<br /><br />PS: my <a href="http://www.dannyburbol.com/games/blocks/">Falling Blocks</a> flash game.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com6tag:blogger.com,1999:blog-2064071933282644832.post-4254885483726244792008-05-09T07:41:00.000-07:002008-05-09T09:32:16.004-07:00Comicking, by Emma<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU1YTAWUTFE_rov3sCZlexna2QMaMrmadtqgJfkuKjlwQzoTaz7rPTws6eKO9AnqQLzIcICZED-fhXBYrlOuUlZwDBa-oMzhHgrFViOa13JDSq9qudLwB24-oVLdGDgo3e8sc-N568nB0/s1600-h/pages.jpg"><img id="BLOGGER_PHOTO_ID_5198389856657641922" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU1YTAWUTFE_rov3sCZlexna2QMaMrmadtqgJfkuKjlwQzoTaz7rPTws6eKO9AnqQLzIcICZED-fhXBYrlOuUlZwDBa-oMzhHgrFViOa13JDSq9qudLwB24-oVLdGDgo3e8sc-N568nB0/s400/pages.jpg" border="0" /></a><br /><div><div>Emma's one of the San Francisco artist I met through <a href="http://www.sketchcrawl.com/">Sketchcrawl.com</a>. She's been making a comicbook, and posted some lessons learned. This is exactly the kind of thing I wish I had more time to post in *this* blog... however I'd rather see you learn something from *her* blog than learn nothing at all. :) </div><div></div><div>Here's the link to Emma's <a href="http://emmacoats.com/?p=165">Comicking</a> over on her blog "Art Plz"</div></div>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-82045678178462280422008-03-15T09:32:00.000-07:002008-03-29T21:34:17.854-07:00Chinese Brush: Color<img src="http://www.dannyburbol.com/web_storage/random_posts/08_03_15_artnotes_color/poppy.jpg" /><br /><br />After working in grays and black for so long, color feels like a breath of fresh air.<br /><br />After much searching on amazon, I found the set we use in class:<br /><br /><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FMaries-Watercolor-Set-Twelve-Eleven%2Fdp%2FB0007NCP4Y%2F&tag=dbw-20&linkCode=ur2&camp=1789&creative=9325"><br /><img src="http://www.dannyburbol.com/web_storage/blog/amazon/color01.jpg" border="0" /></a><br /><br />Our instructor showed us the powered color that her master used to use. They are brilliant, vivid colors. Half are from rocks that have been grounded into dust and half are organic --but almost all of them are poisonous. Which makes sense, all the brightest colors in nature usually warn predators of poison.<br /><br />Because half the colors are minerals and half are organic, if you see ancient paintings, half the colors will still be bright and vivid (the minerals) and half the colors will be fading away (the organic colors).<br /><br />Another interesting not about these powdered colors is that since they are nothing but dust, they need to be mixed with a type of glue to get them to hold together and actually be usable to paint.<br /><br />Thankfully we have the set of paints from above. They are much cheaper than the powers, you don't have to do any work to make them usable and they come directly from china, using the same materials they've used for thousands of years.<br /><br /><strong><span style="font-size:180%;">Using Color</span></strong><br /><br />The tubes are a very thin metal. GENTLY squeeze them from the BOTTOM. They are known to break under the wrong kind of pressure. So if you squeeze from the center, you'll probably create a hole in the bottom end which just leads to a mess. If the opening has dried up, just use a push-pin or something to make a fresh hole.<br /><br />Squeeze out the colors you're going to use into the sections of your pallet from lightest to darkest. The most common colors (the ones I often see on my instructor's pallet) are yellow, indigo (blue), burnt sienna (brown), carmine red, rouge (dark red), and a bright orange.<br /><br />The first thing you'll notice is that there is no green. We mix yellow and indigo blue to create green, but we <u>never premix</u> the colors. Leave yellow and indigo separate. <br /><br />The same way we have been loading the brush from lightest gray to straight black, we also load colors from lightest to darkest. So when we make green, we load the brush with a good amount of yellow, then put some indigo on the tip. Then we move to an empty cell on the pallet and just smear the tip a little so we have a green tip and the rest of the brush is yellow. No when you make a stroke, it will start as green and fade to yellow each time you use it. <br /><br />This is why we don't premix our green. Take a look at my poppy flower's stem. That's one stroke from top to bottom. The way the yellow breaks through give it a warm feeling, like being hit by sunlight. You can't get this effect if you premix the green. <br /><br />When you feel your brush is two yellow, you can just go straight to the indigo again and add more blue to the tip. (no reason to waste all that yellow that's already on the brush).<br /><br />Also note: in my stem, it breaks up a little on the left side. This is because I was moving my brush too fast. Straight color doesn't absorb and spread the way our watery grays do. So slow down a little (unless you're purposely using watery colors, which is a different topic all together).<br /><br />The same technique with two colors on the brush was used for the poppy's leaves and petals. Remember, we don't layer our colors like other styles of painting, so when we painted the petals of the flower, we painted front to back. The petals are just dabs, not strokes. We laid the brush down on it's side and lifted it off the paper. For the petals in the front, I laid the brush all the way down on it's side. For the petals in the back, I just didn't lay the brush down as much and instead held it at a 45 degree angle when I made the dab. The dabs themselves are slow. I laid it on the paper, pushed a little for a second or so, then lifted. It wasn't a fast tapping motion.<br /><br />For the leaves, you see I used the same colors as the petals, but this time I laid the brush on the paper on it's side, pushed a little, rubbed in a small circle, then lifted. It's the rubbing that gives the leaves a more blended, softer look compared to the petals.<br /><br /><strong><span style="font-size:180%;">*DON'T* Clean Up</span></strong><br /><br />When you're done, there's no need to clean up your pallet. Place the entire thing in a zip-lock bag. Later, even if the colors dry, you can reactivate them with some water. An easy way to do this is to get a bottle that sprays a mist of water (like breath freshener or hairspray does)<br /><br />You can also use the mist of water on colors that get a little dry while you're painting.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-61549023071769774102008-03-08T12:53:00.000-08:002008-03-08T13:26:21.282-08:00NEVER USE Network Solutions! -EVER!Serously, pass this post on to everyone you know. I'm furious because <i><u>I know</u></i> they just screwed me. but the average person who's never bought a domain name before won't know the difference. I HATE seeing companies screw people just because they know they can get away with it.<br /><br />if you have a domain name you're thinking about getting <b><u>NEVER</u></b> search for it using NetworkSolutions.com!! they will lock the domain as if a customer is buying it (ie, you) and then try to charge you $35 for it! when the going rate on other sites, like godaddy, is $9 or $10.<br /><br />but since I searched with NetworkSolutions first, now GoDaddy can't register it because <u>NetworkSolutions put a lock on the domain</u>... all GoDaddy can do is offer to "buy on back order" for $20.<br /><br />NEVER USE Network Solutions. They will Screw You instantly.<br /><br />Can you tell, I'm furious!? I just had to pay the $35 and now I know I'm going to have to pay another $12 to transfer the domain name to the host I normally use simply because I thought it would be easy to do a quick search on domain names at Network Solutions (rather than log into my account with my current host.)<br /><br />instead of paying $9, I'll be paying $48 ($35+$12)!<br /><br />I repeat, NEVER USE Network Solutions. When I called in and asked WTF!!? the woman said "it's standard, $35 PER YEAR for a domain name with network solutions." I said "why? other sites charge $9. What is Network Solutions going to give me that's worth $35?", she said "well you get access to the network solutions account manager." --are you kidding me!? You get nothing. zero. they just screw you and try to screw you again EVERY YEAR.<br /><br />NEVER USE Network Solutions.<br /><br />Ever.<br /><br />~Danny<br /><br />Oh and BTW, their account manager is a frigging joke! It's a million buttons and ads for upgrading and buying more domain names/upgrades, and one button up in the corner that actually lets you see your account and do anything useful. I didn't even have to blur out any info on the images below because it's actually that hard to tell if you're actually logged into your account... there's not "account like" infomation like, oh I don't know, the domain I just paid $35 to register.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_03_08_networksolutions/01.jpg"><br /><br><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_03_08_networksolutions/02.jpg"><br /><br />I love that "Hurry, before they're GONE!", which probably means they've already locked them so you can't registar them for $9 elsewhere.<br /><br />Serously, pass this post on to everyone you know. I'm furious because <i>I know</i> the just screwed me. but the average person who's never bought a domain name before won't know the difference. I HATE seeing companies screw people just because they know they can get away with it.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com1tag:blogger.com,1999:blog-2064071933282644832.post-6087674107425972202008-02-26T12:19:00.001-08:002008-02-27T12:36:31.179-08:00Exibiting at a Con<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_26_wondercon/wc07_exhibithall.jpg" border="0" width="180" height="613" alt="Exhibit floor at WonderCon" title="Exhibit floor at WonderCon" align=right style="margin: 25px" />After exhibiting at a few cons, I've got a bit of a routine that I thought would be nice to share with any other aspiring artists out there.<br /><br />I'm swamped with work to do, so I'm going to type this fast, my apologies for typos, etc. (actually, if you could point out typos by leaving comments I'd be really grateful, thanks.)<br /><br /><h3>Con checklist (things to bring)</h3><ul><br /><li><b>Comics</b>: I pack my comics in a box and then drop that box into carry-on suitcase with wheels. The first time I lugged all my stock to the show (5 comics x 100 issues each) and ended up lugging most of them back home after the show was over. This last time (4th time to a con) I packed light. I had 9 comics and didn't bring more than 30 copies of each, in some cases, 20 copies (which I sold out by the end of the second day).<br /><li><b>Prints</b>: prints seem to be a pretty good business model, much better than my print on demand comics (that rarely cover the cost of the very table I'm selling them from).<br /><li><b>Business Cards</b>: if someone doesn't buy your stuff, at least get a business card in their hand. Don't have cards? try VistaPrint.com they're cheep, fast and high quality... you just have to click carefully for the last step of the order where they ask you "hey, do you want us to throw in some extra junk?"<br /><li><b>Extras</b>: every con has it's own mood and tone. Wondercon is all about comics and prints while APE is all about Prints and Odd/Original things like buttons, postcards, stamps, or hats (you know, "alternative press").<br /><li><b>Food & Drink</b>: if you don't want to get ripped off by convention prices, pack a lunch and something to drink. Remember napkins or something too.<br /><li><b>Clothing</b>: Wondercon cranks the A/C waaay up and APE was a sauna. So keep that in mind. Make sure you can add or remove a sweater or something. (at Wondercon, I even brought chap stick and was thankful I did.)<br /><li><b>Shoes</b>: You may be standing on cement all day... wear comfy shoes.<br /><li><b>Stands</b>: books stands, business card stands, etc.<br /><li><b>box tape and scissors</b>: You never know. I always bring this and I always find a use for it. Making signs, keeping things in place, etc.<br /><li><b>Paper or Index cards</b>: for making little signs with<br /><li><b>Sharpie</b>: for making signs and signing comics with<br /><li><b>Camera</b>: get a picture of your fans and your booth! (and make sure your batteries are charged!... I made that mistake this time...)<br /><li><b>Pack Light</b>: I know I just listed off a bunch of stuff, but remember, you have to carry all that crap from the car to the booth/table. <br /></ul><br /><br /><h3>Con checklist (things to do)</h3><ul><br /><li><b>Pack the day before</b>: you're going to be rushing around the next day, so just do yourself a favor and put all that stuff to bed before you go to sleep.<br /><li><b>Parking</b>: the best way to loose any profit you might make is by getting price gouged on convention parking. You may be used to paying $15 for hanging around a Con for 2 hours... but when you are there from open to close, the price goes up FAST! Try to be smart. If you can get a friend to drop you off at the front door with all your stuff and then park farther away (or maybe your wife doesn't want to go to the show at all, which is perfect). DON'T expect to leave your car unattended out front while you drop off your stuff, odds are the security guards won't let you. I've gotten in the habit of getting dropped off the first day and then taking the train/bus to the event on the following days. Then I arrange for someone to pick me and my stuff up on the last day.<br /><li><b>Price Exhibitor Badges</b>: just take a look at the price of a 3 day pass to the show, vs the price of a full blown Exhibitor pass. If you're going to have a friend help work the booth, you probably want the cheaper of the two. The only real difference is getting into the show an hour early or not.<br /><li><b>Get a better business model than me.</b>: seriously, I lose money when I sell comics at a convention, lots of money. My print on demand comics are like $4 each, so I have to sell them for $5. While the big guys pay $0.66 to print a copy and sell them for $3 (or sometimes $5!). Give it some thought. I'm going to try some large prints at the next show (as in, the kind of print you frame and hang on the wall.) They cost less to make and will probably be a better business model then the print on demand comics. (in short, don't quick your day job until you figure out how to walk away from a convention with thousands of dollars in your pocket... oh, and when you figure that out, tell me how you did it :)<br /><li><b>Be honest with your friends</b>: You friends will come to see you at the Con and will want to chat. That's cool, just make sure they know not to block your table. Have them stand a little to the side (or invite them behind the table) so people can still get to your table and possibly buy your stuff.<br /><li><b>Deflect Leaches</b>: You'll get that guy who comes up and stands in front of your table, blocking it off from everyone else, and then just stand there and reads every page of every one of your comics. Then says "You're stuff is great!" and walks away. If you'd like him to stand a little to the side and read, just tell him. If you want him to move on, just tell him the price of the comic he's holding and put your hand out like you expect money right now. He'll most likely panic and run off, or panic and pay you.<br /><li><b>Make Friends</b>: even if you're not good at talking to people, introduce yourself to the exhibitors around you. You'll probably see them again at other conventions and you'll probably be asking them to watch your stuff when you run to the rest room.<br /><li><b>Start a Tradition</b>: This may sound silly, but you'll appreciate it years later. For example, I take the business cards of people around me and stick them in my badge holder... after the show, I throw all my badges in the same drawer, not in the trash. Some times it's cool to got through them, and with the business cards in the badge holder, you'll remember all the funny stories when you show them to others. (I still have a badge from E3 when I was working at Namco that I had the guys from penny-arcade.com sign... good times.)<br /></ul><br /><br />Best of luck to you at the show!Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-49370915491946859802008-02-11T18:23:00.000-08:002008-02-11T19:59:30.232-08:00On the go Sketching<img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_11_snackbag/indexcard_bamboo.jpg"><br /><br />I don't really like lugging around a bag just to have my sketchbook and pencil box with me. Especially since I find that if I do bring it along, I don't always get a chance to sketch and if I don't bring it along I often end up sitting somewhere bored and wish I had my sketchbook. Plus the packing and unpacking of stuff makes it pretty inconvenient on a daily bases.<br /><br />Lately, I've been keeping a stack of maybe 10 index-cards in my jacket pocket at all times. I clipped them together with a couple of <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FBinder-clips-capacity-wide-dozen%2Fdp%2FB0006Z5HDY%3Fie%3DUTF8%26s%3Doffice-products%26qid%3D1202784212%26sr%3D1-1&tag=dbw-20&linkCode=ur2&camp=1789&creative=9325">binder clips</a> so they don't get messed up in my pocket (keeps edges from getting messed up and also keeps them from rubbing against each other and smearing the sketches). However it turns out having them clipped together also makes it really easy to draw on the top card in the stack while standing up. So I can be standing in line somewhere and just pull the cards out of my pocket, and start sketching. Then jam them back in my pocket when I've got to get moving again.<br /><br />As a result, I always have them with me and I've been doodling more, which is always good. <br /><br />The second half of that equation are the pens and pencils I bring with me. I recently discovered "snack bags" in the grocery store. <br />For years, they only had "sandwich bags", but now you can find "snack bags," which are half the size. They're the perfect size for stashing a few pens and putting them in your pocket.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_11_snackbag/snackbag.jpg"><br /><br />The last ingredients are the caps for the pencils. I originally started capping my pencils because I got tired of them putting holes in my pockets or stabbing me in the hand when I reached into my pocket. I find pen caps are too big, but my fiance's eyeliner caps are nearly perfect. I just slipped in a small piece of paper to make sure they're nice and snug.<br /><br />Hope these tricks help you sketch on the go!Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-77576311032196463222008-02-09T17:57:00.000-08:002008-02-09T18:14:28.540-08:00Even Loose Looks Better Clean<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_09_cleanup/01.jpg"><br /><br />I've been making a comic journal and a vacation comic journal (as you can tell by the links at the top of the page). In both cases I knew I had a lot of ground to cover in a short amount of time. I needed a style that would get the point of the content across to the viewer but also something that was moderately fast to crank out. So I went with a loosely drawn Sunday comic strip style. It worked great. The looseness of the lines kept me moving and discouraged me from getting bogged down and spending 3 hours adding excessive detail to an otherwise lighthearted story.<br /><br />However, one day I went back and cleaned up one of the pages and realized that it looked better. Not night and day, but definitely better. Here's an example:<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_09_cleanup/02.jpg"><br /><br />I thought loose drawing *had* to look sloppy. I thought having lines meet in overlapping intersections was what made it classified as "loose drawing." However, now I realize you can still have a loose drawing with clean lines and corners. And I think it looks better. So, yes, I went back and cleaned up every page.<br /><br />It's really surprising how fast a few clicks of the eraser tool can really cleanup a sketch. I'll definitely be setting aside more time to cleanup my work more often.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-38710318953790758592008-02-06T12:38:00.000-08:002008-02-06T12:45:41.873-08:00Photoshop: Coloring with Colorfill Layers<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_06_colorfill/shading_with_masks_tutorial.jpg"><br /><br />I use this technique a lot. For example, the self-portrait in <a href="http://dannyartnotes.blogspot.com/2008/01/window-glow.html">the first post</a> on this blog:<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/dannyburbol_comicbook_style.jpg">Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-60133491326624735852008-02-05T09:07:00.000-08:002008-02-06T11:45:56.263-08:00Virtual Tracing Paper<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_05_virtual_trace/virtual_trace.jpg"><br /><br />"Remember, there are no rules, just tools." ~<a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FVilppu-Drawing-Manual-Glenn%2Fdp%2F1892053039%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1202231458%26sr%3D8-1&tag=dannyswebsite-20&linkCode=ur2&camp=1789&creative=9325">Glen Vilppu</a><br /><br />If you're anything like me, you don't have a lot of time to begin with, so the little time you have to sketch or make art is very valuable. At the same time making art is all about spending as much time as you need to "finish" the piece. A buzz word in game development right now is "iteration time." The more times you iterate on something, the better it can be in the end. If it takes 10 to 20 iterations before something is just the way you like it, wouldn't you want to iterate as fast and clean as possible? Wouldn't you want to safely experiment for a few iterations without ruining all the work you've do so far (like destroying your original)?<br /><br />Enter this technique, which I'm calling "Virtual Tracing Paper." Traditionally, one of the first things you learn is to sketch very very VERY lightly with a lighter pencil. Then you make iterations by very slowly moving to a darker pencil and finally to ink. I'm bad at this, I'm too heavy handed (and I do still practice this BTW, so I am getting better). That leads us to the next traditional technique of tracing paper and/or light-boxes. If you make all your iterations on a new sheet of paper, then a world of possibilities open up for the direction you can take the piece you're working on.<br /><br />Virtual Tracing Paper is the idea of leveraging the computer as if it were a light-box. It requires a scanner and a printer. Basically scan in the image you're working on, lighten it up, and print it back out. Continue to work on the printout.<br /><br /><strong><span style="font-size:130%;">Advantages:</span></strong> <ul><li><strong>you can re-size/rotate things.</strong><br />for example: take a small doodle and grow it to be the size of the page for the next iteration, or grow one detail to the size of the page so you can work on all the little hard to reach areas. If you have a sketch that's to tall or two wide, you can squash or stretch it. If you draw at an angle, you can tilt it to be more upright.<br /><br /><li><strong>you can move things.</strong><br />think "proportions." it's always easy to look at a drawing and say "crap, that's too long," or too short or too far apart, etc. But it's a pain in the but to do something about it. In many cases it's faster to just start over than to try to "save" the sketch. However if you scan it in and print it out you can move or re-size parts of the sketch to achieve the proportions you wanted. It will look bad because parts won't line up, but as soon as you lighten the sketch and print it back out, you can use everything as guides to draw new, better lines.<br /><br /><li><strong>flip it!</strong><br />it's a common trick to hold a piece of paper up to the light and look at it through the back side. You see everything in reverse so it helps your brain spot problem areas. Now you can just mirror the sketch and print it out and keep working.<br /><br /><li><strong>experiments and shading.</strong><br />print out 5 copies of your line-work, shade each one differently. Suddenly you can experiment without worrying about messing up the original.</li></ul><br /><br /><strong><span style="font-size:130%;">The Next Level<br /></span></strong><br />If you want to bring the technique to a 2.0, get a tablet. If you have a tablet you can skip the printing out part and just alpha out your current layer, create a new layer, and go to town on it. Iterations become extremely easy.<br /><br /><strong><span style="font-size:130%;">A word of caution.<br /></span></strong><br />This can be a fun and fast way to work and experiment, however it can also be one hell of a crutch. As soon as you can move, rotate, re-size, and stretch your sketch, you start making a habit of not getting your proportions right the first time. So don't stop drawing on paper and don't stop trying to make traditional pieces the traditional way. Remember, you'll learn more if you start a piece over from scratch to fix and proportions than if you just use the computer to fix the proportions. If you want to get better, you've got to bite the bullet and do the practice work involved with getting better. In the end, use your best judgment for what your personal goals are.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-60406442781519489492008-02-04T18:15:00.000-08:002008-02-06T12:06:11.487-08:00Tell A Friend About Creative Commons<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_04_cc/Creative_Block_by_lukeroberts.jpg"><br />(Image From: <a href="http://lukeroberts.deviantart.com/art/Creative-Block-43033454">lukeroberts on deviantart</a>)<br /><br />Well, I've finally arrived. I had my first piece of art ripped off yesterday. It was an accident really, the person meant well, but none the less, they took an image I spent hours making and pasted it right into their own work.<br /><br />I always knew these things happen to artists, but it's pretty unsettling when it happens to you. Thankfully, it was exactly what I thought, just someone who meant well, but didn't realize they were crossing a line when they used it without asking permission first.<br /><br />This is the reply I sent to him. Please, educate your friends and family about Creative Commons so we can all be creative together without stepping on each other's toes.<br /><br /><blockquote><p>Hey man, thanks for taking it down. but I just want to make sure you know I'm not angry or mad at you. I had a feeling it was an accident, but it was a very unsettling feeling to see how easily things can get ripped off (even with the best of intentions).<br /><br />believe it or not, I was more worried about you than my image. I'm not too broken-up about it, but I was worried you might accidentally tick someone off someday if I didn't speak up. (as in, tick off someone with lawyers or something)<br /><br />the good news is, it's really easy to tell when artists do and don't want others to edit their work.<br /><br />Just look for: "Creative Commons" here's a link to wikipedia:<br /><a href="http://en.wikipedia.org/wiki/Creative_commons">http://en.wikipedia.org/wiki/Creative_commons</a></p><p>Flickr has Creative Common options and I noticed that DeviantArt is doing it now too. So just look for that and you should be all set to have fun with an image.<br /><br />Here's an example: <a href="http://lukeroberts.deviantart.com/art/Creative-Block-43033454">http://lukeroberts.deviantart.com/art/Creative-Block-43033454</a></p><p><br />notice the (CC) instead of (C)?<br /><br />Pass on the word. The more people who know about these things, the better.<br /><br />Best of Luck to You,<br />~Danny </p></blockquote>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-78464970589302230192008-02-04T09:15:00.000-08:002008-02-06T12:11:04.950-08:00100 Photoshop Tutorials<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_04_100tutorial/01.jpg"><br /><br />I don't want this blog to turn into nothing but off-site links, but this was too good to pass up. It's not easy to find good photoshop tutorials. Searches usually turn up lots of 1st-day-beginner stuff and photo touch-ups), but the <a href="http://www.linesandcolors.com/2008/02/04/100-photoshop-tutorials/">lines and color</a> blog just posted a link to this:<br /><br /><a href="http://www.3dtotal.com/ps100/pstut100.html">100 Photoshop Tutorials for creating beautiful art</a>.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-1563147793271322202008-02-03T12:29:00.000-08:002008-02-06T11:59:52.739-08:00Using Real Sanguine<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_04_sanguine/01.jpg"><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_04_sanguine/02.jpg"><br /><br />I saw this post on the <a href="http://www.drawingboard.org/">DrawingBoard.org</a><br /><br /><a href="http://www.drawingboard.org/viewtopic.php?t=58097">Renaissance Style Drawing (Sanguine) -- A Tutorial</a> (images above are from here)<br /><br />"If you have read books on Renaissance-era drawing, you may have noticed the media listed as sanguine. Sanguine is a natural mineral, hematite, or basically a rusty rock. They didn't have Conté crayons or pastel pencils in the 1500s, so this is what they used."<br /><br />Edit: the <a href="http://www.linesandcolors.com/2008/02/06/sanguine-drawing/#comment-306048">lines and colors</a> blog tracked the author back to <a href="http://vrdisplays.blogspot.com/">KM Scott Moore</a>.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-14388509170707468592008-02-01T14:38:00.001-08:002008-02-01T15:23:37.439-08:00Chinese Brush: Work AreaI finally got all the stuff needed to paint at home (even if a lot of it is whatever I had on hand), so I thought I'd give you a quick look at what's involved.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_01_chinesebrush07/table.jpg"><br /><br /><b>note:</b> I crowded everything in so I could fit it all in the pictures, but you probably want to spread out a little and leave some blank space around your paper so you're not knocking your brush into other things while you're trying to paint.<br /><br /><b>also note:</b> I'm left handed, so odds are, your setup will have all the brushes and ink on the other side of the paper.<br /><br />Here's a little more detail:<br /><ul><br /><li><b><u>Bamboo Brush Wrap:</u></b>happened to be there so I labeled it... really, it's just taking up table space.<br /><li><b><u>Roll of Paper:</u></b> always good. Note, to get off some nice sections to paint on, fold the paper, make a crease, then run a wet brush down the fold, and then rip it. Try to keep the wet area as skinny as possible (she how jagged my paper is on the right side? I used too much water.)<br /><li><b><u>Clean Water:</u></b> try to keep one of your rinse containers clean. This is the water I was using to tear the paper. I'm using a pasta jar.<br /><li><b><u>Dirty Water:</u></b> as in, rinse water. I'm using a coffee can, but I'm not sure if it will rust or not, so I'll probably switch to another jar.<br /><li><b><u>Light & Dark Gray:</u></b> I'm using single serving yogurt containers.<br /><li><b><u>Ink:</u></b> it's empty in the picture, but that's where it would be.<br /><li><b><u>Brush Rest:</u></b> there are fancy brush rests, but I'm just using the lid to the coffee can. Basically, the tips are wet and it's nice to keep them off the table a little.<br /><li><b><u>Shape Tip:</u></b> I just wanted to point out that there is a spot on the lid where I've been shaping the tip when it's loaded with ink. You could also use another container or something, but basically, you want an alternative to the dabbing cloth. The cloth will suck ink out of the brush and make it dry as you're shaping the tip, the plastic lid won't.<br /><li><b><u>Dab Cloth:</u></b> I found a fat stack of washcloths on sale for $2, so I grabbed them.<br /><li><b><u>Weights:</u></b> these serve two purposes: keep the rolled up paper flat and keep the paper still so it doesn't move while you're in the middle of making a stroke. I grabbed whatever was at arm's length, which happened to be tea candles and some heavier tea candle holders (in class we literally just use some flat rocks.)<br /><li><b><u>Felt:</u></b> the table is covered with some felt cloth. It's cheap (paid $1 or $2 a yard) and works well.<br /><li><b><u>Drying:</u></b> just a reminder, things need somewhere to dry. I let them dry there on the felt for a while before stacking them up or whatever.<br /><li><b><u>Not Pictured:</u></b><br /><ul><li><u>an eye dropper:</u> if you want to put any ink back in the bottle and your containers aren't as easy to deal with as my yogurt containers.<br /><li><u>a masterpiece:</u> look at that terrible bamboo! yuck! :) Yours will be better.<br /></ul><br /></ul>Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-74346016925939662902008-01-31T22:17:00.000-08:002008-01-31T23:00:05.999-08:00Accidental Denim<img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/dannyburbol_realistic_style.jpg" /><br /><br />This is my second self-portrait for ArtistDojo.com's <a href="http://www.artistdojo.com/f/viewtopic.php?f=3&t=4">self-portrait challenge</a>. The style of the challenge was basically as realistic as you can get it.<br /><br />The jacket just didn't work out well... it was supposed to be leather, but looks like denim. So on the down side, I'll have to practice my leather, on the upside, I have an accidental denim technique. I basically did it with small scribbles stacked on top of each other.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/denim000.jpg" /><br />above: all layers turned off.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/denim100.jpg" /><br />above: if you look to the bottom right, you can see my scribbly pattern. I also did some partial erasing for the shiny areas.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/denim010.jpg" /><br />above: this is the second scribbly layer. I basically just duplicated the first scribble layer (before I made the shiny spots) and offset it... so you 'll see in the following image, since it's offset, it darkens in more of the texture.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/denim110.jpg" /><br />above: here are both of the scribbly layers on at the same time.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_25_selfportrait/denim001.jpg" /><br />above: and finally, this is the layer under the scribbles that gives it all the shadows.Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-27288952325980522182008-01-31T15:46:00.000-08:002008-02-01T15:20:46.056-08:00Chinese Brush: Make A Bird with Split Brush<img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_01_chinesebrush07/bird_fix.jpg"><br /><br />Edit History:<ul><li>(02/01/2008): Fixed bird's belly and added photos of split brush</ul><br /><br /><strong><span style="font-size:180%;">Split Brush</span></strong><br />I said be gentle on your brush when dabbing, and this is no exception. After you rinse the brush, hold it vertically with the tip facing down and touch it to your dabbing cloth. Put a little bit of pressure on the brush so the bristles bend a little, then twist the brush in between your fingers. <br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_01_chinesebrush07/split_brush01.jpg"><br /><br />The tip will split into many smaller tips.<br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_01_chinesebrush07/split_brush02.jpg"><br /><br />Touch the brush to the dabbing cloth horizontally to narrow the tip. You should end up with a cylindrical shape that's spiky on the tip. <br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_01_chinesebrush07/split_brush03.jpg"><br /><br />Load the brush with ink like normal and go for it.<br /><br /><strong><span style="font-size:180%;">Make A Bird</span></strong><br /><strong>Step 1:</strong> use a detail brush to make the beak and the eye.<br /><strong>Step 2:</strong> use a hard bristle brush, using split brush technique, to make those nice scratchy strokes for the top of the bird's head and then the top of the body. Notice how we make another stroke in the middle of the body for a little definition in the wing.<br /><strong>Step 3:</strong> use a hard bristle brush, NO LONGER with the split brush tip, to add in a line for each wing-tip and then a couple lines for the tail.<br /><strong>Step 4:</strong> make a light gray stroke under the head and another under the body. Let them be a little wet, so it's fuzzy looking on the bird's underside.<br /><strong>Step 5:</strong> use a detail brush to make the legs and talons.<br /><strong>Step 6:</strong> make it up! These are the techniques I used for that specific bird in that specific pose, but now that you know the techniques, just go get some reference of some birds and have fun! Just remember, we made the beak and eye first so we could control where we ended up using or not using our wet on wet techniques.<br /><br /><strong><span style="font-size:180%;">Dirty Water</span></strong><br />Take a really good look at the belly of my bird. <br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_30_chinesebrush06/bird.jpg"><br />The original bird was a lot fatter and cuter. I thought I was being sly by using a brush directly from the dirty rinsing water because I wanted a very light gray belly. Well, when it dried, my strokes completely disappeared (because it was just water!)<br /><br />Let me tell you, that fat little bird was sooo cute... until I got home. After the ink dried, the fat belly disappeared! And now my bird just has a big head! :)<br /><br />Lesson: Dirty water is still water! It's NOT a substitute for your light gray pallet.<br /><br />Edit: I fixed the bird last time I had the inks out:<br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_02_01_chinesebrush07/bird_fix.jpg">Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-11771117348535543352008-01-31T10:19:00.000-08:002008-02-01T15:25:53.982-08:00Chinese Brush: A New BrushEdit History:<ul><li>(2/1/2008): be sure to checkout i-paint's comment about new brush caps.</ul><br /><br />We have our own brushes now and it leads to questions about how to care for a brush.<br /><br /><strong><span style="font-size:180%;">The Glue</span></strong><br />First of all, new brushes have glue in the tip to make them look all perfectly straight and beautiful when you buy them. This can also be used to conceal the quality of the brush since it looks great in the store and my act different when you start using it and the glue comes out. So just be cautious about that. Expect glue, but try not to get ripped off.<br /><br />Soak your new brushes in water for about 10 or 15 minutes to get the glue out or they may act a little strange when you use them. For Example, my hard bristle brush was acting like a soft bristle brush (it didn't have any spring to it, it would bend and stay bent after each stroke).<br /><br /><strong><span style="font-size:180%;">Use Gently<br /></span></strong>I found that I was much to rough when rinsing and dabbing my brushes. You don't really think about these things when you're using the community materials in an art class or something, but you start to question more once you spend $20 or more on a brush.<br /><br />When you rinse your brush in between strokes, DON'T push the brush all the way to the bottom of the container and bend or pound the tip. There's no reason for it. It's not getting the brush any cleaner and it's bending the bristles. I found that pounding the brush also made it difficult to get a perfectly thin straight tip.<br /><br />Instead, dip the brush in the water, don't touch the bottom at all, and just swirl it around in a circle. Then, *touch* it to the side of the container a few times –don't *press* it to the side of the contain. After that go directly to your dabbing cloth. Again, don't press, bend, or pound the tip into the cloth. Instead hold the brush horizontally and touch the whole side of the tip to the cloth. You can also drag it a little and help all the bristles point in the correct direction. Rotate the brush between your fingers and do it again.<br /><br />When you're done, you'll notice that the brush tip is pretty dry, as well as nice and narrow with a pretty nice, if not perfect, tip.<br /><br />The same goes with your pallet, no need to be rough or over flex the brush.<br /><br />Make it a habit, be gentle on the brush. I'm a big dumb guy, so I find myself pounding the brush into the rinse water like an ape with a stick. I have to really make a conscious effort to be gentle, but BELIEVE IT OR NOT, I find that when I'm rough on the brush I can't paint because I'm messing up the bristles and I'm unconsciously tensing up. As soon as I make a conscious effort to be gentle on the brush, the brush works better and I can't help but relax more, and suddenly I'm painting better. That's my favorite part so far. When you're doing it right, Chinese Brush Painting is calming and relaxing.<br /><br /><strong><span style="font-size:180%;">Putting them away</span></strong><br />Rinse the brushes gently under some water, then PAT them dry WITH a towel (don't DAB them dry ON a towel).<br /><br />You can leave them on a brush rest to air dry, but ultimately you want to either store them in a roll-up or hang them with the tips pointing down. In both cases, the idea is to get the tip to stay nice and straight. <br /><br />I did a search on amazon, and here are a couple roll-ups like the one I have:<br /><table><tr><td><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FSumi-Brushes-Seven-Brushes-Bamboo%2Fdp%2FB000HEIII0%3Fie%3DUTF8%26s%3Dhome-garden%26qid%3D1201800456%26sr%3D8-2&tag=dbw-20&linkCode=ur2&camp=1789&creative=9325"><br /><img border=0 src="http://www.dannyburbol.com/web_storage/blog/amazon/rollup01.jpg"></a></td><td><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FSumi-Brushes-Bamboo-Brush-Wrap%2Fdp%2FB0006TZNWA%3Fie%3DUTF8%26s%3Doffice-products%26qid%3D1201800632%26sr%3D8-1&tag=dbw-20&linkCode=ur2&camp=1789&creative=9325"><br /><img border=0 src="http://www.dannyburbol.com/web_storage/blog/amazon/rollup02.jpg"></a></tr></table><br /><br /><br />Note, I can't vouch for those specific brushes because I've never used them :) <br />Also Note: those links go to "Sumi" Brushes. Sumi (or Sumi-e) is a Japanese style of brush painting. Here's what Wikipedia has to say about it.<br /><a href="http://en.wikipedia.org/wiki/Sumi-e">http://en.wikipedia.org/wiki/Sumi-e</a><br /><br />Here's what the stands look like (sorry, couldn't find any good amazon links)<br /><br /><img border=0 src="http://www.dannyburbol.com/web_storage/blog/amazon/stand02.jpg"><br /><br />If you store all your brushes by jamming them into a can or jar, odds are you're not doing the brushes much good. If the tip is aiming upward, then gravity will effect the bristles and bend them over time. If the tip is at the bottom, then it's probably bending under the weight of the brush.<br /><br />So, if you love your brushes, DON'T use anything that looks like this:<br /><img border=0 src="http://www.dannyburbol.com/web_storage/blog/amazon/stand01.jpg">Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com2tag:blogger.com,1999:blog-2064071933282644832.post-9242575877009564232008-01-28T19:54:00.000-08:002008-01-28T20:03:36.880-08:00Chinese Brush: Make BambooBamboo is a very common warm-up. My instructor says, if you're calm and relaxed, paint flowers; if you're stressed out, paint bamboo. And like everything, you could spend a lifetime perfecting it.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/07.jpg" /><br /><br />That's my best so far. It's not terrible, but it's not beautiful either. My instructor paints like poetry in motion. Every leaf is breath-taking. I'll ask if I can post the example she made in class.<br /><br />Until then, here's a link to her gallery (no bamboo I'm afraid):<br /><a href="http://www.brushpaintingcircle.com/art/artworkone.html">http://www.brushpaintingcircle.com/art/artworkone.html</a><br /><br />Okay, moving on: I'm sharing what little I've been able to grasp, but DON'T copy me. You'd be dooming yourself to mediocrity. Instead, go find some photo reference and try to paint what you see and throw in these techniques to help get the ball rolling.<br /><br /><strong><span style="font-size:180%;">Step 1: The Trunk<br /></span></strong>--load a hard bristle brush with the three tones of gray to make a gradient.<br />--hold the brush at a 15 degree angle and make a stroke upward. Remember to have a start and end point so you get a bone shape.<br />--there is a small space between sections.<br />--as you make the sections of the trunk, lessen the tilt on the brush so the trunk sections get thinner.<br />--remember the trunk sections are straight, so if the stalk of bamboo curves at all, it's usually at the joints and it's usually very subtle.<br />--after making the sections of the trunk, come back with black and make a connecting line through the joints. Again it's bone shaped and the points on either end tend to flick upward.<br /><br /><strong><span style="font-size:180%;">Step 2: Branches</span></strong><br />--branches are just like the trunk technique.<br />--keep in mind, branches only shoot out from the main trunk at knots between sections.<br />--keep in mind branches have the same basic direction as the trunk (upward). So don't make them shoot out at a 90 degree angle, make them 45 or 30 degrees upward.<br />--don't forget to add a line thought the knots of the branch sections (or two dabs when the branch gets thinner.<br />--as the branches get to be extremely thin, the last section can be a pointing stroke.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/branches.jpg" /><br /><br />Here's some branch practice I did. Note: the pointing technique should only be used for the LAST section of a thin branch. Mine are WRONG (red arrows). See how I used pointing stroke after pointing stroke and they don't seem to hold together as one branch, verses the thicker branch (blue arrow) which have a thicker start and end point between the sections... those endpoints and the bone shape are key.<br /><br />Also note, these branches don't have the line and dabs at the joints, so don't forget about those.<br /><br /><br /><strong><span style="font-size:180%;">Step 3: Leaves</span></strong><br />--The technique is simple, but takes much practice to master.<br />--we're going to be varying pressure, so you should use a *hard bristle brush* (you will find it pretty hard to do with a soft bristle brush)<br />--use black ink or a little dark gray + black ink.<br />--hold the brush at LESS THAN 90 degree angle in relation to the page. (it's tempting to do center brush, but you get better results if you tilt a little in the direction you plan on travel with your motion)<br />--it will be one stroke that has a nice almond shape.<br />--when we make the stroke, the motion is in a straight line, starting with the base and ending with the tip of the leaf.<br />--the pressure gives us a thicker base and then we fade away to the tip.<br />--remember to re-shape your brush tip before each stroke<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/shape.jpg" /><br /><br />Here is just a little of the many, many leaves I did. I've made blue arrows to the only two that are even close to correct. However, as always, let's identify the mistakes.<br /><br />Near the bottom middle, we see a lot of fuzzy fat leaves, my brush was too wet.<br /><br />Near the bottom right, we see leaves that have mult-pronged tips. At first this might look like my brush was dry, but it turned out, I forgot to reshape the tip of my brush (so the tip was not perfect before I started, and only got worse with each leaf).<br /><br /><span style="font-size:180%;"><strong>Characteristics of a Bamboo Leaf</strong><br /></span>--long and smooth. My biggest problem was that I kept making leaves that were too short, and as soon as they are too short, they also tend to look too fat.<br />--the leaves are usually found in bunches of three, but don't make them look like chicken feet. Vary their size, direction, length, and starting points.<br />--There are two types of bamboo leaves, young and old.<br />----Younger leaves are thinner and tend to point up (or in the direction of the branch they came from). They also appear near the end of the branch (last/thinnest sections)<br />----Older leaves are bigger and wider and tend to hang down. The appear close to where the branch breaks away from the trunk.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/wet.jpg" /><br /><br />in this example, everything is just too wet. Everything blurred all over the place. On top of that, my leaves are so perfectly symmetric along the branch that they just look fake. And in some places the leaves actually shoot out at 90 degree angles, which looks even less natural.<br /><br />Also, because my leaves are mostly not long enough, they appear fat and stubby.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/05.jpg" /><br /><br />in this example, all my leaves point up (no 90 degree angles). I varied their size some, but not their direction, so they all look like young leaves, which looks out of place and wrong.<br /><br />Also note: on the bottom left, again I forgot to reshape my brush tip, and my leaf tips are not a single point as a result. However, in that same spot, we can see how varying the starting point can look more interesting and less like a 3 toed chicken foot.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/06.jpg" /><br /><br />This one remind me of a fern instead of bamboo. There are just so many leaves of such a uniform size on each branch that it looks like a different type of plant.<br /><br />However, there are a few older looking leaves on the bottom left branch that are not a bad variation (if only I had used them more).<br /><br /><strong><span style="font-size:180%;">Step 4: Stem Detail</span></strong><br />--if you varied the placement of your leaves well, they should appear to be growing out of thin air in places. Use a detail brush to draw very thin lines from a knot on the branch to the base of the floating leaves to get them connected correctly. This detail add so much.<br /><br /><strong><span style="font-size:180%;">Step Zero: Composition</span></strong><br />Composition is a whole subject unto itself, so let's not get too deep into that. Basically, we're just looking for a nice balanced final painting. And the only way to do that is to plan ahead (which is why I called it "step zero.")<br /><br />Scroll up a little and look at the previous example (with the 6 in the bottom corner of the paper.) Doesn't it look out of place? It's just a bamboo trunk shooting straight up out of nowhere. Then there are lots of branches and leaves on the left side, and not so much on the right side. It feels unnatural and out of place.<br /><br />A common layout is to have a bigger bamboo trunk a little off center, then a smaller one off to the side and a very small one on the other side.<br /><br />I'll leave you with this last example. Again, it's not the best, but it shows progress and I'm sure you can appreciate what went into it much more now here at the end, compared to when you first saw it at the beginning of this post.<br /><br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_23_chinesebrush05/07.jpg" />Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0tag:blogger.com,1999:blog-2064071933282644832.post-50549607812580223812008-01-28T16:54:00.001-08:002008-01-28T16:54:56.450-08:00Chinese Brush: Make A ShrimpIn the previous post, I had a picture of two shrimp which I used as an example for various types of brush stokes. I realized it had some misleading text jotted down at the top, so I'll just explain how to make the shrimp so no one gets frustrated by trying to follow that silly text.<br /><br />Here's the shrimp again:<br /><img src="http://www.dannyburbol.com/web_storage/random_posts/08_01_17_chinesebrush03/shrimp.jpg" /><br /><br /><strong><span style="font-size:180%;">Step 1: the body</span></strong><br />Use a soft bristle brush. Load it up for a gradient, but make it mostly lighter gray (that bottom, bbq'ed, shrimp was a mistake :) Make a dab for the first bigger section of the body while holding the brush at 15 degrees or so.<br /><br />Note that the soft bristle brush will stay bent after the stroke. Keep it bend and make the rest of the body sections using the curve of the brush to cup the curve of the last dab on the paper.<br /><br />Hold the brush with less and less of an angle as you go so the body sections get smaller.<br /><br /><strong><span style="font-size:180%;">Step 2: soft brush extras.</span></strong><br />--Add a few tail dabs at the end for a tail<br />--make lots of little feet (I forgot to do this on the top shrimp)<br />--with black ink, make some wet on wet dabs down the back of the shrimp.<br /><br /><strong><span style="font-size:180%;">Step 3: hard bristle brush extras</span></strong><br />--use pulling strokes to make the area in front of the mouth and the arms. (remember bone shaped strokes)<br />--use a detail brush and pointing strokes to make the whiskers<br />--don't forget dabs for the eyes (I forgot this for the top shrimp as well)Dannyhttp://www.blogger.com/profile/16707396225947283069noreply@blogger.com0