Classic Snake In HTML5
While I’ve been developing Rich Internet Applications for the past five years, it has been a long time since I’ve had to program true HTML5, CSS and JavaScript. The last time I wrote a legitimate HTML based webpage, the industry standard was laying out the content in tables. Attempting to dive in and learn all the new pieces seemed daunting. I decided to start my focus on the Canvas component in HTML5 because of its relative closeness to the Canvas component in Flex.
My goal was to develop something that was animated, took advantage of keyboard and mouse clicks, and could be used on mobile devices. I created the classic game Snake. Use your WSDA keys to control the movement. Alternatively, for mobile devices without key support you can click in the top, bottom, right and left purple squares to move the snake in that direction.
[iframe: src="http://www.dcholth.com/html5/20101103/snake/snake.html" frameborder="0" width="410" height="410" scrolling="no"]
Drawing on the Canvas requires you to call the stroke() function. I feel silly even mentioning this, but it took me at least twenty frustrated minutes thinking my code wasn’t executing at all until I figured this out. If you do not call this function after creating your paths, nothing shows up on screen…
{code type=javascript}
gDrawingContext.beginPath();
gDrawingContext.strokeStyle = “#FF00FF”;
gDrawingContext.moveTo( 0, yB+ yB);
gDrawingContext.lineTo( gWidth, yB+ yB);
gDrawingContext.stroke(); /* CALL ME */
{/code}
Redrawing on the canvas is slow. At least it is on the iPad and my Droid Incredible. I had done a previous experiment where I had red squares bouncing all over the screen. This effect was made by redrawing both the grid and the red pixels each interval. While it looked smooth on my computer screen, it was extremely choppy on the mobile devices. To make the Snake game smooth, I’m only redrawing what is necessary. For the Snake, I’m drawing black squares over the tail, and adding red squares to the head to create the movement effect. I know that there must be ways to have smooth animations on mobile devices (I’ve seen them!) but they currently elude me. More research on this to come.
Clicking a Canvas within the mobile device browsers has a significant delay. While it does register the clicks, there is a delay between clicking, and having the snake change directions. I believe this is an issue with the touch screens trying to determine the intentions of the users finger on the screen within a browser. I’d like to do further tests to find out if this is something that I can fix, or at least predict exact delays. I noticed on the Droid Incredible, clicking the Snake game causes the entire Canvas to highlight green, as if its reacting to it like one big button.
There does not seem to be a ‘focus’ in HTML5 Canvas. I had originally programmed the game to use the arrow keys to control the direction of the snake. I had to change this because there doesn’t appear to be a way to differentiate that the arrows are supposed to control the Snake game (IE: The snake game has focus) and not the scrollbars of the webpage. So clicking down would send the snake in a downward direction, but it would also scroll your page down. This is a little difficult to see on my blog, because I am embedding the Snake game in an iFrame to make it work with WordPress.
Thats all for now! Feel free to browse the project code. The major code components to this application are:
- http://www.dcholth.com/html5/20101103/snake/snake.html
- http://www.dcholth.com/html5/20101103/snake/snake_code.js
Flash Player 10 Rotation XYZ Fun
I’ve been playing around a lot with Flash Player 10′s rotation XYZ. After doing a series of experimentation and actually implementing it into a new project, I had some doubts about Adobe’s implementation of 3D.
Experiment #1: http://blog.dcholth.com/beta/RotTester/RotTester.html
The images are laid out in a grid, with each image’s rotations (XY & Z) being set to the values of the numeric sliders at the top. As you can see, each image’s perspective looks different, because they are placed in a 3D environment with the ‘camera’ being set to a specific point. I had a heck of a time figuring out how to set that camera!
If you look at http://livedocs.adobe.com/flex/3/langref/flash/display/DisplayObject.html#rotationX it says “Indicates the x-axis rotation of the DisplayObject instance, in degrees, from its original orientation relative to the 3D parent container.”
Well, in the example above, each image is placed in its own Canvas – my best guess was that the parent canvas should be its ’3D Container’ so the rotation should be based off of that, but clearly it was basing off some other point at the Application level.
I posted my frustrations with this a few places, and finally fellow Universal Minder, Ryan Graff came to the rescue, with the missing piece: PerspectiveProjection
Setting the PerspectiveProjection of your target’s Transform will give you the results I believe most developers will be looking for.
Experiment 2: http://blog.dcholth.com/files/PanelTest/PanelTest.html
The image in the TitleWindow on the left has its PerspectiveProjection set to be the center of the TitleWindow, where as the image in the TitleWindow on the right has the default properties. Notice that dragging the TitleWindow on the right around the screen results in distortion of the image, where the image on the left remains tilted exactly how we want.
Experiment 3: http://blog.dcholth.com/files/RotatorTest/RotatorTest.html
Back to our grid of images, here we set the images PerspectiveProjection to point towards the red dot. Drag it around the screen to see how it effects how each image is percieved.
In conclusion, I believe that most developers will want to take advantage of the PerspectiveProjection’s properties when working rotations of UIComponents in 3dSpace.
One CommentExtending the State Class
Flex offerers a wide range of utilities to make working with complicated components and applications simpler. One such feature is the use of States. States are often thought of as only visual or GUI related, but in they are perfect for dividing up logic. In my current project I am building a series of learning activities, and some have activities within activities… needless to say it can get complicated quickly. While breaking up the logic into separate components was one option, I didn’t want to have any risk of ‘flashes’ of GUI while pieces are refreshed, moved, or risk messing up data by passing all these pieces around.
I started to build out my activity component using states. One state for when you enter the activity, one for each of the three phases, a cleanup state and finally an exiting state. As I developed the components and created their enterState and exitState functions, as well as many functions only used while in a specific state, I realized that my component was getting to be well over a thousand lines of code and a bit unmanageable. To find the logic pertaining to the current section I was working on, I had to sift through hundreds of lines of code. I decided there had to be a better way… and there was!
I started by creating an AbstractActivityState that extended the State class. This had had any common properties and logic, as well as a bindable “Activity” object. This worked well for accessing the public variables of the activity. The problem came with private variables. While I would have had access to these if I had written all my logic within the Activity MXML, since I was passing the Activity object into my states, they were inaccessible.
There were three solutions I found for this problem:
- Make all the properties you need access to within the state public, and break encapsulation rules.
- Add additional Bindable properties to the the custom state classes and pass in the bindable private variables.
- Create a StateMiniModel that had all the bindable properties I needed and simply pass it to the custom state. This is handy if you don’t want to break encapsulation but have a great many common private variables to be passed to all your custom classes.
To make things even more simple, I added some listeners and protected ‘enter/exit’ classes to be called from within the AbstractActivityState so I when declaring my states in MXML I didn’t need to give it anything other than a name.
No CommentsSpeaking At FlashMN on Wednesday March 19
I will be speaking on developing MapQuest’s TripPix application (formerly MapMyPix) at the next FlashMN users group on Wednesday, March 19th. For those of you unfamiliar with the FlashMN users group, it meets at 7 on the third Wednesday of each month at Easel Training in Saint Paul.
The talk will include information on building application using the MapQuest Advantage API, AIR and Flex Builder 3.
No Comments"My God… Its full of stars!"
Have I mentioned how much I like the BitmapData class? Had a request pass by desk last week asking me to create a little app to be used in a presentation. They wanted it so that when a user clicked on a button in the middle, a star would fly across the screen to a random location, twinkling while it moved, then stay on the screen until the user clicked clear. They wanted somewhere between 30 and 100 stars on the screen.
While I think flash could have handled having that many MovieClips on screen pretty easily on its own, I wanted to see if I could make it more efficient. The solution I came up with was to use two BitmapData layers, one for moving the stars on the screen and creating the ‘twinkling trails’ and the other for housing all the stars in their final resting place.
The two layers of BitmapData (trailsCanvasBmp, and finalBallCanvasBmp) and a ParticleManager class to track the movement of the stars and slowly fades out the trailsCanvasBmp to give the twinkling effect while its moving. A star is created in the center of the screen, then shoots off to its random location. When the tween is complete the star is drawn to the top finalBallCanvasBmp class which is never cleared.
On each frame a random pixel is chosen from the finalBallCanvasBmp and if that pixel is NOT black (0×000000), then it attaches an mcTwinkle MovieClip which destroys itself upon finishing its animation.
The effect is really quite cool! You get the sense that each star is operating under its own principles, but its actually just two BitmapData objects interacting with the ParticleManager.
You will notice some major performance hits if you tell it to make too many stars at one time, or if the screen gets literally filled with stars, their may be more twinkling than your computer can handle. We’re on some beefy machines here at work, and I have had over 20,000 stars and haven’t noticed a performance hit. So your movies can truly be “Full of Stars”. ($1 to who ever can name the movie reference*)
There are a few other things going on here that I can elaborate on if requested. The background is generated using Perlin noise (so really there are 3 Bitmaps). Each star is colored using my Pallet class I can upload if desired. Full code for this project can be uploaded.
2 CommentsWeb Spinner Revealed
As promised, you can now download the code used for my web spinning projects. There is one fla, and four classes.
I made some modifications to Grant Skinner’s grid based proximity manager to take advantage of an IProximityDetectable interface. For a full explanation on how grid based proximity management works, check out Grant’s original post on the subject. The IProximityDetectable interface has only two methods:
interface IProximityDetectable { public function getPosX():Number; public function getPosY():Number; }
As might be assumed, they retrieve the ‘x’ and ‘y’ position of an object. Why implement this? Well, the original ProximityManager used the _x and _y values of a MovieClip, but my spider web particles don’t actually have any MovieClips. Its just adjusting x and y values of an object in memory, and drawing lines to the new distance. The ProximityManager is used for drawing the lines between particles based on how close they are to each other.
So how do the particles move? Each onEnterFrame the ParticleManager calls the tick function for each particle.
public function tick():Void { canvas.moveTo(x,y); x += xVel; y += yVel; xVel *= drag; yVel *= drag; yVel += yGravity; xVel += xGravity; var f:Number = Math.abs(xVel) + Math.abs(yVel); alpha -= f/__lifeSpan; canvas.lineStyle(2, rgb, alpha); canvas.lineTo(x,y); if(alpha <= 0){ manager.removeSpark(this); } var n:Array = pm.getNeighbours(this); var l:Number = n.length; for(var i:Number = 0; i < l; i++){ canvas.lineStyle(1, rgb, alpha); canvas.moveTo(x, y); canvas.lineTo(n[i].getPosX(), n[i].getPosY()); } }
Each particle starts out with random velocities for x and y. These velocities are added to the x and y position of the particle. Drag is applied to the velocities to slow them down. The drag is set to such a small value in this particular instance that it really doesn’t have much of an effect. Gravity along the x and y axis is then applied to the particle The gravity values are generated randomly when the particle is first created and unlike the velocities, has no baring on its parents value (in the instance of a branched particle). Since gravity is random, it may pull particles up, down, left or right. After all moving is done, the particle uses asks who its neighbors are and draws lines to them.
Speaking of branching, the ParticleManager does a probability calculation for each particle during the onEnterFrame which determines if a particle will branch. Each particle has a chance to branch, so growth can occur exponentially. To keep particles from branching too much, this calculation is ignored if the maximum number of particles has been reached (default to 40).
Once each particle has been moved and had its connections drawn, the entire image is drawn to a Bitmap and color/alpha adjusted to fade away slowly. All and all a pretty neat little effect.
I’d like to move this to AS3 eventually to see if I get crazy speed increases! I’ve put one last experiment below which allows you some control over different variables in the spider webs. Be careful when making adjustments… You can easily give your computer a heart attack.
Cartoon Smoke Using Particle Systems
Earlier this week I had the pleasure of attending my first FlashBelt conference and had a great time! If you ever get the opportunity to attend, FlashBelt is definitely worth it!
Seb Lee-Delisle gave a great presentation on Particles for the Non-Physicist. I have worked a bit with particles on my own, but never really understood the possibilities of what a particle system could do. Seb pointed out all the spots on the Plug-in Media website that have particles – way more systems going on there than I expected.
I had a chance to speak with Seb after the session as to how he made the merging borders around the cartoon smoke effects and dripping ooze (from the Plug-in Media main page). He said you needed to have multiple layers of particles. So, when I got home, I downloaded the demonstration files and got to work. Below you can see the results. Its a really cool effect.
The important thing when creating the two layers of particles, is that each layers of particles must have matching properties – only the linked movieclip is changed. You can see that the background particle is darker and larger than the foreground, but they move and grow in unison. This allows the background particle to be the border around the lighter front particles and merge together seamlessly.
My next step is to figure out how to use a particle system to make a MovieClip appear on fire. If you’ve seen my fire effect code, it uses a computationally-heavy method of duplicating, distorting, coloring and fading the MovieClip. I think the particle-system effects could be used to create the fire instead.
One Comment


