search
top
Currently Browsing: Hints and Tips

Browser Extension: Arrange Tumblr Posts in Chronological Order

Creating little browser extensions is a great way to learn JavaScript. You don’t need to worry about cross-browser compatibility, you can make the project as small or large as you like, and you can fix problems in other people’s websites that bug you, specifically. In this post, we’ll create a short script that automatically rearranges Tumblr archive pages to read in chronological order – and we’ll learn about NodeList on the way.


The Problem

This week, Ryan North started a new Tumblr, in which he’s going through the novelization of the first Back to the Future movie, one page at a time. This is a thing I wish to read.

BtotheFClick to read.

However, Tumblr displays its posts in reverse chronological order – that is, with the most recent posts first. This makes sense for a lot of sites on Tumblr, but in this instance, I really want to read them in the order they were written. The current site layout means that, to do that, I have to scroll down to the top of the first (first written) post, scroll down as I read it, and then scroll up to the top of the second post, and scroll down through that…

This is a tiny, tiny first world problem – totally trivial and almost embarrassing to mention. But that doesn’t mean I don’t want to fix it.

By the end of this tutorial, you’ll make this Tumblr – or any Tumblr you choose – display its posts in chronological order on the page, automatically.


How Can We Do This?

We don’t have control over the BtotheF site design; it offers no options to us, so we can’t change the order in which the posts are displayed on the page server-side.

But once the HTML is sent to the browser, it’s ours. We can manipulate it however we want. And, of course, the language with which we can do this is JavaScript.

I’ll give a quick demo. I’ll be using Chrome, and recommend that you do, too – if you can’t, or don’t want to, then grab a copy of Firebug.

Browse to http://btothef.tumblr.com/ and open the JavaScript console (Tools > JavaScript Console, in Chrome). Type:

alert("Hi");

…and hit Enter.

JavaScript Console Demo

Wow! … Okay, fine, that didn’t prove much. Try this:

document.body.appendChild(document.createTextNode("Hi"));

This will take the HTML document’s <body> element, and append a new text node – a piece of text, basically – containing the word “Hi”. If you didn’t follow any of that, get up to speed with HTML.

To see the result, scroll right down to the bottom of the Tumblr:

JavaScript Console Demo

Slightly more impressive, since we’ve actually changed the contents of the page. The new text node is right at the bottom because we’ve used appendChild() – which adds the specified node after everything else inside the <body>. As far as our browser is concerned, the last few lines of HTML now look like this:

<!-- END TUMBLR CODE -->

Hi
</body>
</html>

So! Now we have two issues:

  1. How do we use JavaScript to rearrange all the posts in the page?
  2. How do we make this happen automatically, without having to mess around in the console every time we read the Tumblr?

We’ll address these in order.


Rearranging the Posts

First, let’s figure out how to “find” all of the posts in the HTML. In Chrome, right-click somewhere in the top post, and select “Inspect element”. (Firebug should add the same shortcut to Firefox; for other browsers, try the magnifying glass icon.)

Inspect Element (Chrome)

The Elements tab of the Developer Tools will appear, with the element you selected highlighted:

Elements Tab

As you hover over different elements in this HTML view, you’ll see them highlighted in the page itself. Eventually, you’ll find that the entire post is contained in a div with a class of post. As you can see from the screenshot above, there are several other such div elements, and they are all contained in a master div with an id of contents.

We can select all of these post elements at once with a single line of code; type this into the JavaScript console:

document.getElementById("contents").getElementsByClassName("post");

(Technically, we could have just written document.getElementsByClassName("post"), but who cares?)

You’ll see – again, in Chrome – some feedback:

All the posts

Great! This indicates that it worked. If you click the arrows, you’ll see the contents of each div.

We might as well assign this to a variable, to save us having to type it out over and over:

var posts = document.getElementById("contents").getElementsByClassName("post");

(This time, the console will return undefined; you can check that it assigned the variable correctly by just typing the word posts in the console.)

We can loop through all of the elements in posts as if it were an array:

for (var i=0; i < posts.length; i++) {
     console.log(posts[i]);
}

Hit Shift-Enter to add a new line to your code without running it, in the JavaScript console. console.log() just traces its contents to the console, which is far less annoying than an alert() and far less disruptive than adding text to the HTML DOM.

The result of this simple loop will just be a list of all the div elements. Cool. So presumably we can do something like this…

var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     posts.push(posts[i]);
}

Try it out! You’ll see this:

TypeError: Object #<NodeList> has no method 'push'

Rats.

A NodeList Is Not an Array

When we use getElementsByClassName(), we don’t retrieve a simple array of elements, we retrieve a NodeList. Like an array, this is a collection of elements; unlike an array, the collection is updated in real time. If the HTML DOM is modified, the contents of posts gets modified to match.

For example, let’s create a new div with a class of post and append it to the contents div:

var newPostDiv = document.createElement("div");
newPostDiv.setAttribute("class", "post");
document.getElementById("contents").appendChild(newPostDiv);

Run that, then type posts and hit Enter. You’ll see an extra div in the list – even though we haven’t touched the posts variable.

Since a NodeList is not an array, it doesn’t have most of the methods and properties of Array, such as push() In fact, we’ve already used the only property: length. The only method is .item(n), which just gets the nth item in the list.

However, our earlier demonstration with appendChild() does suggest an alternative solution: what if, instead of trying to rearrange the elements of the NodeList within the NodeList, we rearranged them within the page?

First, we’ll run through the list in reverse order, and append each element in turn to the contents div; then, we’ll remove the original posts.

Refresh the Tumblr page to clear out all the extra rubbish we’ve added to the DOM, then do the first step, of adding the elements in reverse order:

//have to define posts again, since we lost it when we refreshed
var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

Okay, now we… wait, what?

description of image

The (chronological) first post is already at the top, and the last post is at the bottom, with no posts repeated. This may seem surprising, but it makes sense: we didn’t clone any elements of the NodeList, we just appended them to the contents div, in reverse order. Since the NodeList always reflects the contents of the HTML DOM, we just moved each of the 11 elements to a new position – the 11th element got added to the end (no change in position); then the 10th got moved to be after that; the 9th after that, and so on, until the 1st element was right at the end.

So, problem solved, in five simple lines of code. Now let’s automate it.


Turning It Into a Browser Extension

Three of the top four browsers allow you to create browser extensions – installable add-ons – using JavaScript. (It will not surprise you to learn that Internet Explorer is the exception.) Here are the instructions for Chrome, the instructions for Firefox, and the instructions for Safari.

But we’re not going to use any of those. Instead, we’ll use a great add-on called Greasemonkey, which allows you to install little JS scripts without needing to package them up as full-blown browser extensions. Essentially, it injects snippets of JavaScript into the page, once it’s loaded.

Chrome already has Greasemonkey support baked in. Opera has something very similar to Greasemonkey baked in: UserJS. For Firefox, you’ll need to install the Greasemonkey extension. For Safari, install SIMBL, and then GreaseKit. For IE, install IE7Pro or Trixie.

Writing the Greasemonkey Script

Create a new text file, and name it ChronologicalTumblr.user.js. Make sure you remove the default .txt extension, and that you use .user.js, rather than just .js – this is the extension for a Greasemonkey script.

Copy our post rearrangement code into the file:

var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

Now, we need to add some extra metadata at the top of the script – details about the script itself. All these details should go in comments, starting with ==UserScript== and ending with ==/UserScript==:

// ==UserScript==
//
// ==/UserScript==

var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

First, we’ll add a name and a description:

// ==UserScript==
// @name          Chronological Tumblr
// @description	  Displays Tumblr posts in chronological order
// ==/UserScript==

var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

Then, we’ll specify a namespace. The combination of the name and the namespace is what uniquely identifies the script; if you try to install another Greasemonkey script with the same name and namespace as an existing script, it will overwrite the old one – if only the name or the namespace match, it’ll just install the new one alongside the old.

It’s common to use a URL here, so I’ll use Activetuts+’s. You should use your own, since you’re in control of it:

// ==UserScript==
// @name          Chronological Tumblr
// @description	  Displays Tumblr posts in chronological order
// @namespace      http://active.tutsplus.com/
// ==/UserScript==

var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

Now we need to specify which URLs this script should affect – that is, on which web pages the JavaScript should automatically be injected into. I want this script to work on the BtotheF homepage, plus the other archive pages, like http://btothef.tumblr.com/page/2:

// ==UserScript==
// @name          Chronological Tumblr
// @description	  Displays Tumblr posts in chronological order
// @namespace      http://active.tutsplus.com/
// @include       http://btothef.tumblr.com/
// @include       http://btothef.tumblr.com/page/*
// ==/UserScript==

var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

The * is a wildcard; it ensures that the script will be inserted into every single archive page of the BtotheF Tumblr.

We could use a wildcard to make every single Tumblr’s archive pages display in chronological order:

// ==UserScript==
// @name          Chronological Tumblr
// @description	  Displays Tumblr posts in chronological order
// @namespace      http://active.tutsplus.com/
// @include       http://*.tumblr.com/
// @include       http://*.tumblr.com/page/*
// ==/UserScript==

var posts = document.getElementById("contents").getElementsByClassName("post");
var numPosts = posts.length;
for (var i=numPosts - 1; i >= 0; i--) {
     document.getElementById("contents").appendChild(posts[i]);
}

In this case, it might be a good idea to improve your script to insert a button or link into the page that rearranges the posts when clicked. That way, you can use it when appropriate, without having to manually add every single Tumblr’s URL as an @include parameter.

There are other metadata parameters you could add, but this is all we need for now.

Finishing Off

Installing the script in Chrome is easy: just drag and drop it from your hard drive into a browser window. It’ll warn you that scripts could potentially be dangerous (just click Continue), and then check again that you want to install this specific one:

Are you sure?

Hit Install. If you’re using another browser, refer to the relevant Greasemonkey script’s manual – in any case, it’ll be simple.

Once it’s installed, you can see it in your list of extensions:

Just like any other extension.

Head back to http://btothef.tumblr.com/, or hit refresh if you still have it open.

description of image

The posts are now automatically displaying in chronological order!

It’s not perfect: you may have noticed that the navigation buttons have been moved to the top of the page, since they are contained in a div with a class of post. But hey – if that bugs you, you have the tools to fix it now.



View full post on Activetuts+

Quick Tip: How to Debug an AS3 Error #1203

In this Quick Tip, we’ll discuss the confusing AS3 error 1203, “no constructor found”, which crops up without provocation and is rather unfortunately worded. We’ll examine the scenario in which it will appear, and how to fix it.


Step 1: An Obligatory But Somewhat Useless Description of Error 1203

First, here is the language of the error:

1203: No default constructor found in base class flash.display:BitmapData.

It’s difficult to break this down into plain English. So let’s next move on to a scenario that produces this error.


Step 2: A Busted Project

You can find this project in the download package, in the folder “busted“. It consists of the following (which you can use to re-create this project if you prefer a hands-on approach):

  1. A FLA named Busted.fla. It is empty, but is linked to the document class described next.
  2. A document class named Busted.as. This extends Sprite and simply creates an instance of the class described next, and adds it to the stage.
    The contents of the class are as follows:

        package {
            import flash.display.*;
            public class Busted extends Sprite {
                public function Busted() {
                    var bmp:Bitmap = new Bitmap(new BustedBitmap());
                    addChild(bmp);
                }
            }
        }
    

    The BustedBitmap class extends BitmapData, and so we use it to feed a Bitmap object, which is then added to the stage.

  3. Another class file named BustedBitmap.as. As mentioned previously, this extends BitmapData, and its purpose is to be a BitmapData that automatically supplies itself with some Perlin noise. Its contents are:

        package {
            import flash.display.*;
            public class BustedBitmap extends BitmapData {
                public function BustedBitmap() {
                    perlinNoise(100, 100, 2, 1024, false, false, 7, true);
                }
            }
        }
    

    So, in the BustedBitmap constructor, we call perlinNoise() and thus we automatically have something interesting in the pixel data, so we can see something right away when displaying on the stage.

Now, go ahead and test the movie. You will get Error 1203, pointed at line 4 of BustedBitmap.as. And line 4 is…


public function BustedBitmap() {

Step 3: What’s All This, Then?

So what happened? The big thing to keep in mind is that we’re writing a class that is a subclass of another class (BitmapData in this case). Also keep in mind that when a class is instantiated, the constructor is called as part of the “new” process.

If you do not actually write a constructor, ActionScript will imply one for you. It will look like this:

public function [NameOfClass]() {

}

Where “[NameOfClass]” will match the name of your class.

Similarly, if you write a subclass, and don’t call super() in it, then ActionScript will imply that call for you, as well. It will look like this:

public function [NameOfSubclass]() {
    super();
    // Other explicit code in subclass constructor
}

Note that it happens on the first line, and is simply a call to super with no arguments.

Finally, we get to the root of the problem. If your subclass omits an explicit call to super, and your superclass’s constructor has required parameters, then your implicit call to super does not supply the required parameters. You’d think that an argument mismatch error could catch this, but consider that since there isn’t any code actually written to make the mismatch, ActionScript can only complain that the lack of a default constructor.

In our example, BustedBitmap extend BitmapData, which has a constructor defined in the documentation as so:

BitmapData(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF)

The first two parameters are required, and we’re not supplying them.


Step 4: It’s as Simple As…

The solution is, once you understand the problem, extremely simple. You need to explicitly call the super constructor, at least if there are required parameters. In other words, in our BustedBitmap class, this following highlighted line will fix the problem:

package {
    import flash.display.*;
    public class BustedBitmap extends BitmapData {
        public function BustedBitmap() {
            super(600, 400);
            perlinNoise(100, 100, 2, 1024, false, false, 7, true);
        }
    }
}

And that will do it.

As a teachable moment, I’d like to add that, when extending another class, it’s generally a good idea to include the explicit call to super. Even if there are no parameters at all, required or otherwise (as in Sprite or MovieClip), an explicit call can declare intention and awareness of the nature of the subclass. More practically, explicit calls give you an opportunity to run some code prior to the call to super, which may be helpful in certain situations.


Step 5: …And That Is All

Yet another error demystified; the challenge for this one is that the real cause of the error is quite buried. Once you become handy with a shovel, though, the fix is easy enough.

Thanks for reading, and be ready for more debugging tips.



View full post on Activetuts+

Best of Tuts+ in January 2012

Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you’d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!


Psdtuts+ — Photoshop Tutorials

  • Create a Pimped Out Truck Using Photoshop and Point and Shoot Photos

    Create a Pimped Out Truck Using Photoshop and Point and Shoot Photos

    Making modifications to your car or truck in Photoshop can be a lot of fun. In this tutorial we will demonstrate how to create a pimped out truck modification using photos taken with a simple point and shoot camera, with no advanced lighting setup. Let’s get started!

    Visit Article

  • Create an Elephant Sundae Using Photo Manipulation Techniques

    Create an Elephant Sundae Using Photo Manipulation Techniques

    Photoshop is great at seamlessly combing photos to create an entirely new scene. In this tutorial we will create an elephant sundae using several stock photos. Let’s get started!

    Visit Article

  • The Incredible Digital Art of Michael Oswald

    The Incredible Digital Art of Michael Oswald

    In this article we will be featuring the work of Michael Oswald. Oswald is a digital artist with a unique style. His technique involves a combination of photo manipulation and digital painting techniques and the results are often stunning. Let’s take a look!

    Visit Article


  • Nettuts+ — Web Development Tutorials

  • Sublime Text 2 Tips and Tricks (Updated)

    Sublime Text 2 Tips and Tricks (Updated)

    Sublime Text 2 is one of the fastest and most incredible code editors to be released in a long time! With a community and plugin ecosystem as passionate as this one, it just might be impossible for any other editor to catch up. I’ll show you my favorite tips and tricks today.

    Visit Article

  • An In Depth Analysis of HTML5 Multimedia and Accessibility

    An In Depth Analysis of HTML5 Multimedia and Accessibility

    In this tutorial, youll learn how HTML5 helps to provide you with several ways of presenting your media content to users. As a result, youll increase the availability of your media to users with different
    needs and requirements, making it more accessible.

    Visit Article

  • Writing an API Wrapper in Ruby with TDD

    Writing an API Wrapper in Ruby with TDD

    Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can experience network issues and data inconsistencies (the API results may change). Let’s review how we can avoid all of this effort with Ruby.

    Visit Article


  • Vectortuts+ — Illustrator Tutorials

  • How to Illustrate a Microscope in Illustrator

    How to Illustrate a Microscope in Illustrator

    The microscopes is a symbol of our civilization. Throughout this tutorial on how to illustrate a vector microscope you’ll take advantage of numerous Illustrator tools. You will learn how to use blends, art brushes and 3D rendering in Adobe Illustrator. Let’s get started!

    Visit Article

  • Create a Picture Gallery in Illustrator

    Create a Picture Gallery in Illustrator

    This work is a common project created together with Iaroslav Lazunov and Alexander Egupov. We have used 3D rendering, Blends, Opacity masks, making this three-dimensional stage with vanishing points. Learn every step in how to create this picture gallery work.

    Visit Article

  • 13 Important Resources for Learning How to Design Typefaces and Full Fonts

    Important Resources for Learning How to Design Typefaces and Full Fonts

    If you’re serious about creating a typeface design, then you’ll need some solid resources to get started. Learn effective typeface design workflows, how to take an initial spark of an idea from sketch, through Illustrator, into Fontlab, and then work your creation into a complete and custom font design. Here are multiple tutorials that show you how to create fonts in Illustrator and Fontlab, and you can also dive into articles that describe the foundation of quality type design with ample inspirational examples.

    Visit Article


  • Webdesigntuts+ — Web Design Tutorials

  • A Beginner’s Guide to Pairing Fonts

    A Beginner’s Guide to Pairing Fonts

    Pairing fonts can be a challenge. Selecting two or more fonts which work well is one thing – selecting two which work together to achieve your typographic aims may have you reaching for the aspirin. Let’s see if we can alleviate any headaches. This guide will help you get started with font pairing for the web.

    Visit Article

  • Design a Series of Smart Banner Ads in Photoshop

    Design a Series of Smart Banner Ads in Photoshop

    With the continuous growth of the Internet, online marketing has gotten bigger every year, and along with it, the advertising industry. One major factor in all this craziness is buying and selling ads.

    Visit Article

  • Twitter Bootstrap 101: Introduction

    Twitter Bootstrap 101: Introduction

    Twitter’s Bootstrap is an excellent set of carefully crafted user interface elements, layouts, and javascript tools, freely available to use in your next web design project. This video series aims to introduce you to Bootstrap; taking you all the way from downloading the resources, to building a complete Bootstrap-based website.

    Visit Article


  • Phototuts+ — Photography Tutorials

  • HDR: Love it or Leave It?

    HDR: Love it or Leave It?

    There are few techniques in the photography world that divide our community as much as HDR. High dynamic range images, or HDR images, are a special type of composite image that combines several images at different exposure settings in order to create an image with increased dynamic range. The look provided by HDR is loved by many, and disliked by perhaps just as many. In today’s article, we’re going to take a better look at what HDR is, and get some opinions from photographers using HDR.

    Visit Article

  • 50 Inspiring Images of Cars and Motorcycles

    Inspiring Images of Cars and Motorcycles

    Cars and motorbikes have been around for 100 years. Throughout the century, they have looked beautiful, satisfied our need for speed and become a symbol for thrill seeking. Today, we’ll look at photos ranging from brand new Ferrari’s to classic muscle cars.

    Visit Article

  • Quick Tip: GIMP Portable – Take Your Editing Software With You

    Quick Tip: GIMP Portable – Take Your Editing Software With You

    While a number of smartphones now offer photo editing basics (and a plethora of apps to expand things even more), the portability of a solid photo editing program has been hard to come by. Photoshop is a monster in regards to space requirements and its ability to work on any system where it is not expressively installed. Picasa can be fairly ‘lightweight’ but lacks many of the more advanced photo editing tools. So what about GIMP?

    Visit Article


  • Cgtuts+ — Computer Graphics Tutorials

  • Modeling, UVmapping And Texturing A Low Poly T-Rex In Blender, Part 1

    Modeling, UVmapping And Texturing A Low Poly T-Rex In Blender, Part 1

    In the first tutorial of 2012 you’ll learn how to create an awesome low-poly dinosaur using Blender and Gimp. In today’s post artist Karan Shah will walk you through the entire modeling process step by step, and show you how to create an optimized model suitable for use in any game engine.

    Visit Article

  • Create A Realistic Explosion In Maya Using Maya Fluids

    Create A Realistic Explosion In Maya Using Maya Fluids

    Today you’ll learn to animate and shade fluids, understand all of the major attributes, learn how adding fields will allow you to gain better control over your simulation, and how to light and render the final animation.

    Visit Article

  • SpeedTree To UDK: The Complete Workflow, Part 1 Creating The Tree

    SpeedTree To UDK: The Complete Workflow, Part 1 Creating The Tree

    Due to the shear number of polygons often required to make believable 3D trees, creating realistic ones for use “in-game” can be a challenging, time consuming task. SpeedTree from IDV aims to change all that with it’s intuitive UI, ease of use and powerful toolset. Making believable trees and plants has literally never been easier!

    Visit Article


  • Aetuts+ — After Effects Tutorials

  • “Dominoes” CameraTracker and Cinema 4d Case Study – Day 1

    Dominoes” CameraTracker and Cinema 4d Case Study – Day 1

    In this tutorial we’re going to go over the principle functionality of CameraTracker from The Foundry, learning basic workflow, optimizing results, aligning the ground plane and exporting this data from After Effects to Cinema 4d.

    Visit Article

  • Make An Amazing Motion Reactant Flame – Tuts+ Premium

    Make An Amazing Motion Reactant Flame – Tuts+ Premium

    Using just a few video elements of torch flames, we composite a burning hand by using a series of null objects and expressions to drive a time lagged displacement effect to simulate fire burning from a moving source. We use the Puppet tool for the distortion and throw on some tracked lighting effects and a displacement map for the Heat. This principle can be used to add realistic, fluid motion to any tracked object.

    Visit Article

  • 10 Key Tips To Becoming A Successful Video Freelancer

    Key Tips To Becoming A Successful Video Freelancer

    Youve watched thousands of tutorials. Youve put in countless hours and spent many late nights working on personal projects. Youve finally come to the conclusion that this may just be something you would like to do for a career. It can seem a little intimidating at first, because how are you going to convince someone to pay you to do this? Up until now youve been your only client. How do you get more? Im going to share my insight and experiences on how to successfully launch your freelance career this year!

    Visit Article


  • Audiotuts+ — Audio & Production Tutorials

  • 8 Free Professional Quality Audio Unit Plug-ins for Mac

    Free Professional Quality Audio Unit Plug-ins for Mac

    Lets face it, software is expensive. While there are hundreds of free plug-ins available online, more often than not two problems will arise: One, most of them are for PCs leaving us Mac users feeling left out. Two, most of them are vary poor quality.

    While I do agree with the saying, “The tools are only as good as the artist,” I also believe the opposite is true; that at some point the artist can only be as good as his tools are.

    Visit Article

  • Quick Tip: Drum Processing Part 4: Tips and Tricks

    Quick Tip: Drum Processing Part 4: Tips and Tricks

    This short series of quick tips is designed to give you a good overview of the audio processing techniques involved in creating a professional sounding drum beat for use in house, electro and breaks in Cubase. In this final part we will look at a few ways to add even more life to your drums.

    Here is a sample of the type of beat you could expect to end up with at the end of this series of tips:

    Visit Article

  • Quick Tip: Use the Doubling Technique for Quick Drums

    Quick Tip: Use the Doubling Technique for Quick Drums

    It’s 3:30 in the afternoon when your phone rings. The head of a music library is calling and she needs your help. They have a commercial for an A-list client that needs music, and they want you to submit an entry. You’ll get $10,000 if you land the gig.

    Visit Article


  • Activetuts+ — Flash, Flex & ActionScript Tutorials

  • Create a Microphone-Controlled Flash Game: Code

    Create a Microphone-Controlled Flash Game: Code

    In this mini-series, we’re creating a spaceship game where the main control is via the microphone: shout louder to make the ship fly higher. So far, we’ve created all the required graphical elements for the game. Now, it’s time to work on our code. We’ve got a lot to do, so let’s get started!

    Visit Article

  • Why Bother With jQuery? A Guide for (Former) Flash Developers

    Why Bother With jQuery? A Guide for (Former) Flash Developers

    If you, like many Flash developers, are looking into using HTML5 for your web apps, you’ll almost certainly have come across jQuery. It’s a very popular JavaScript library, used by a large percentage of the most visited websites – but what’s all the fuss about, and should you use it?

    Visit Article

  • An Introduction to the HTML5 Gamepad API

    An Introduction to the HTML5 Gamepad API

    As HTML games begin to gradually increase in popularity, vendors are starting to introduce some exciting new APIs to make gaming that little bit sweeter for both us developers and our end players. One of these is the GamepadAPI, which allows you to connect your good old console gamepad into your computer and use it for browser based games, plug and play style. Let’s dive in!

    Visit Article


  • Wptuts+ — WordPress Tutorials

  • The Rise of HTML5 in WordPress

    The Rise of HTML5 in WordPress

    2011 was a big year for the advancement of HTML5 in the web development community. It became pretty widely adopted, especially for the mobile web. There have been major projects that help developers use HTML5, like Paul Irish’s HTML5 Boilerplate (technically 2010, but popularized in 2011) and books galore!

    Visit Article

  • Reusable Custom Meta Boxes Part 3: Extra Fields

    Reusable Custom Meta Boxes Part 3: Extra Fields

    In Part 1 and Part 2 of our custom meta box template tutorial series, we learned how to create a field array to loop through and create a custom meta box with your standard fields. Now let’s throw in a bit of JavaScript for some fancy, but highly useful fields.

    Visit Article

  • The Ultimate Quickstart Guide to Speeding Up Your WordPress Site

    The Ultimate Quickstart Guide to Speeding Up Your WordPress Site

    Give your site a boost! Implement crucial optimization techniques that will improve not only your ySlow score, but your Google rank too. In this tutorial we will cover all aspects of W3 caching, ySlow, Google page speed, CSS sprites & htaccess rules, to achieve a high ySlow score like i have done on my blog.

    Visit Article


  • Mobiletuts+ — Mobile Development Tutorials

  • iOS SDK: Creating an Awesome Carousel

    iOS SDK: Creating an Awesome Carousel

    Engage your users with stunning carousels. We’ll look at how easy and clean it can be to implement scrollable, interactive carousels in your iOS applications. With high configurability, you can have 3D, flat, rotating, and endless scrolling arrays for data, images, or buttons.

    Visit Article

  • PhoneGap From Scratch: Introduction

    PhoneGap From Scratch: Introduction

    Want to learn how to use PhoneGap, but don’t know where to get started? Join us as we put together “Sculder”, not only a tribute to an excellent science fiction TV series, but a fully-fledged native mobile application for the believer in you!

    Visit Article

  • Mobile Flash is Far From Dead: Setting the Record Straight

    Mobile Flash is Far From Dead: Setting the Record Straight

    In light of recent announcements from Adobe, there has been a lot of confusion over the state of the Flash Platform – specifically in regard to Flash content on mobile devices. This article seeks to clarify many of the misconceptions that exist by addressing the main points of confusion around these announcements regardless of the initial, monumental, and absolutely unbelievable blunders from failed public (and private) relations messaging and general marketing surrounding these announcements.

    Visit Article



View full post on Activetuts+

Free Flash Debugger: Commando (With Premium Source Files)

Commando is a Flash debugger that lets you change variables at runtime and run your own custom commands. It will allow you to try out whatever tweaks you want, without the hassle of changing your code and recompiling every time. This debugger also comes with its own memory monitor, and an output panel that is similar to the output dialog in the Flash IDE.


See Commando in Action


Why Use Commando?

Using Commando you can change your code at runtime. Let’s pretend you are making a platformer game. You have a jumpPower variable, but when testing your game you feel that the player can’t jump high enough. So instead of going back and changing your code, you can just type set jumpPower(25) in Commando and you can try out the new value.

Of course, this is just a simple demonstration; Commando can be extended even more. Just continue reading…


Configuration

First, download the ZIP file included with this article. Then, add the SWC file to your project’s library path.

The Library Path Dialog

Once you have added the SWC to your project’s library path, all you need are three lines of code to add an instance of Commando on the stage:

import com.pxlcoder.debug.Commando;

var commando:Commando = new Commando(flash.ui.Keyboard.ENTER, this);
addChild(commando);

Now press CTRL+ENTER (CMD+ENTER on a Mac), and you will see Commando up and running in your Flash project!


Explore

Commando comes with eight built-in functions. In this section I will explain what they are and how to use them.

Math

Using the Math function you can do addition, subtraction, multiplication and division between two numbers. The Math function can also calculate the square root of a number. For example, type math 1+1 or math sqrt(144) in the Commando dialog. The answer will show up in the output dialog.

Hide

You can use the Hide function to hide objects. You can type hide monitor or hide output to hide the two panels at the bottom. You can also use the Hide function with movieclips or buttons by simply typing hide myInstanceName.

View

You can use the View function to view hidden objects. You can type view monitor or view output to show the two panels at the bottom. You can also use the View function with movieclips or buttons by simply typing view myInstanceName. If any of your objects have their visible property set to false, typing view myInstanceName will set it to true.

Set

Using the Set function you can set values of your variables or you can set properties of your objects. To use the Set function on variables type set myVariable(myValue). To use the Set function on objects, type set myInstanceName(myPropertyName,myValue).

Get

Using the Get function you can get the values of your variables and properties. To use the Get function type get myVariable. You can also get properties by typing get myInstanceName.myPropertyName.The values will show up in the output dialog.

Probe

Using the Rrobe function you can get the probe all of the properties of an object. To use the Probe function type: probe myObjectInstanceName. The properties will be traced in the Flash IDE, rather than in the Commando output dialog.

Remove

You can use the Remove function to remove objects from the stage. To use the Remove function type remove myInstanceName.

Add

You can use the Add function to add objects back on to the stage. To use the Add function type add myInstanceName.

Note: Commando’s built-in functions each evaluate a single string, so after you type your function name and press space, make sure to type your arguments without any spaces. Instead, type your arguments as one continuous word, with commas if necessary.


Extend

While Commando has many great built-in functions, you may want something more. To solve this problem, Commando comes with a function to add your own custom commands.

Here is a quick code example of how you can create your own custom commands:

import com.pxlcoder.debug.Commando;

var commando:Commando = new Commando(flash.ui.Keyboard.ENTER, this);
addChild(commando); 

commando.addCommand("output", outputFunction); //Sets the command keyword to "output" and calls the outputFunction below

public function outputFunction(s:String):void {
     commando.output(s); //A call to Commando's built-in output dialog
}

Now press CTRL+ENTER (CMD+ENTER on a Mac), to run your code. In the Commando dialog, type output hello, and press Enter. The output dialog will now say hello!

Commando says hello!

You can also remove commands from Commando by using the removeCommand() function.

import com.pxlcoder.debug.Commando;

var commando:Commando = new Commando(flash.ui.Keyboard.ENTER, this);
addChild(commando); 

commando.removeCommand("output");

Recap: Commando has three functions that you can access; addCommand(), output() and removeCommand().


Conclusion

At the end of the day, debugging is the most important part in the development process. Commando has everything you could ever ask for in a debugger. You can use it for anything and everything.

If you’re a Tuts+ Premium member, you can download the source files for Commando – just log in and head to the Source File page.

Any questions, comments or concerns? Feel free to get in touch in the comments.

Take control of your Flash projects!



View full post on Activetuts+

Create an HTML5 Canvas Tile Swapping Puzzle

In this tutorial we will be working with the HTML5 canvas and Javascript to create a dynamic tile swapping game. The result will be a puzzle that works with any given image, and has flexible difficulty levels that are easily adjusted.


The Complete HTML5 Canvas Puzzle

Here is a quick shot of the puzzle we will be building:

Final HTML5 Puzzle

Click to play

A couple of notes:

  • Cross-browser compatibility: This puzzle was tested and works in all versions of Safari, Firefox, and Chrome that support the canvas element.
  • Mobile: The code provide here works in the above-mentioned desktop browser and is not optimised for mobile. The puzzle will load and render just fine, but because of the touch and drag behaviors in mobile browsers, optimization is required for it to function correctly. Optimizing this puzzle for mobile will be covered in a future tutorial.
  • Adjustable Difficulty: The code contains a constant, PUZZLE_DIFFICULTY, that determines the number of pieces. In the demo above, this is set to 4, giving a 4×4 puzzle. We can easily change this – for example, this version has a PUZZLE_DIFFICULTY of 10.

Getting Started

To get started, create a directory for the project. Place an image in the directory that you want to use as your puzzle. Any web friendly image will do, and it can be any size your heart desires – just make sure it fits within the fold of your browser’s window.


Step 1: Creating the HTML Template

Open a new file using your favorite text editor and save it inside your project directory, next to your image. Next, fill out this basic HTML template.

<!DOCTYPE html>
<html>
<head>
    <title>HTML5 Puzzle</title>
    <script>

    </script>
</head>

<body onload="init();">
    <canvas id="canvas"></canvas>
</body>

</html>

All we need to do here is create a standard HTML5 template containing one canvas tag with the id of “canvas”. We’ll write an onload listener in the body tag which will call our init() function when fired.

Now place by placing your cursor inside the script tag. From here on out it’s all javascript. With the exception of the initial variables, I’ll be organising the sections by function. First showing you the code and then explaining the logic.

Ready? Let’s get right to it!


Step 2: Setting Up Our Variables

Let’s set up our variables and take a look at each one.

const PUZZLE_DIFFICULTY = 4;
const PUZZLE_HOVER_TINT = '#009900';

var _canvas;
var _stage;

var _img;
var _pieces;
var _puzzleWidth;
var _puzzleHeight;
var _pieceWidth;
var _pieceHeight;
var _currentPiece;
var _currentDropPiece;

var _mouse;

First we have a couple of constants: PUZZLE_DIFFICULTY and PUZZLE_HOVER_TINT. The PUZZLE_DIFFICULTY constant holds the number of pieces in our puzzle. In this application, the rows and columns always match, so by setting PUZZLE_DIFFICULTY to 4, we get 16 puzzle pieces in total. Increasing this increases the difficulty of the puzzle.

Next is a series of variables:

  • _canvas and _stage will hold a reference to the canvas and to its drawing context, respectively. We do this so we don’t have to write out the entire query each time we use them. And we’ll be using them a lot!
  • _img will be a reference to the loaded image, which we will be copying pixels from throughout the application.
  • _puzzleWidth, _puzzleHeight, _pieceWidth, and _pieceHeight will be used to store the dimensions of both the entire puzzle and each individual puzzle piece. We set these once to prevent calculating them over and over again each time we need them.
  • _currentPiece holds a reference to the piece currently being dragged.
  • _currentDropPiece holds a reference to the piece currently in position to be dropped on. (In the demo, this piece is highlighted green.)
  • _mouse is a reference that will hold the mouse’s current x and y position. This gets updated when the puzzle is clicked to determine which piece is touched, and when a piece is being dragged to determine what piece it’s hovering over.

Now, on to our functions.


Step 3: The init() Function

function init(){
    _img = new Image();
    _img.addEventListener('load',onImage,false);
    _img.src = "mke.jpg";
}

The first thing we want to do in our application is to load the image for the puzzle. The image object is first instantiated and set to our _img variable. Next, we listen for the load event which will then fire our onImage() function when the image has finished loading. Lastly we set the source of the image, which triggers the load.


Step 4: The onImage() Function

function onImage(e){
    _pieceWidth = Math.floor(_img.width / PUZZLE_DIFFICULTY)
    _pieceHeight = Math.floor(_img.height / PUZZLE_DIFFICULTY)
    _puzzleWidth = _pieceWidth * PUZZLE_DIFFICULTY;
    _puzzleHeight = _pieceHeight * PUZZLE_DIFFICULTY;
    setCanvas();
    initPuzzle();
}

Now that the image is successfully loaded, we can set the majority of the variables declared earlier. We do this here because we now have information about the image and can set our values appropriately.

The first thing we do is calculate the size of each puzzle piece. We do this by dividing the PUZZLE_DIFFICULTY value by the width and height of the loaded image. We also trim the fat off of the edges to give us some nice even numbers to work with and assure that each piece can appropriately swap ‘slots’ with others.

Next we use our new puzzle piece values to determine the total size of the puzzle and set these values to _puzzleWidth and _puzzleHeight.

Lastly, we call off a few functions – setCanvas() and initPuzzle().


Step 5: The setCanvas() Function

function setCanvas(){
    _canvas = document.getElementById('canvas');
    _stage = _canvas.getContext('2d');
    _canvas.width = _puzzleWidth;
    _canvas.height = _puzzleHeight;
    _canvas.style.border = "1px solid black";
}

Now that our puzzle values are complete, we want to set up our canvas element. First we set our _canvas variable to reference our canvas element, and _stage to reference its context.

Now we set the width and height of our canvas to match the size of our trimmed image, followed by applying some simple styles to create a black border around our canvas to display the bounds of our puzzle.


Step 6: The initPuzzle() Function

function initPuzzle(){
    _pieces = [];
    _mouse = {x:0,y:0};
    _currentPiece = null;
    _currentDropPiece = null;
    _stage.drawImage(_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight);
    createTitle("Click to Start Puzzle");
    buildPieces();
}

Here we initialize the puzzle. We set this function up in such a way that we can call it again later when we want to replay the puzzle. Anything else that needed to be set prior to playing will not need to be set again.

First we set _pieces as an empty array and create the _mouse object, which will hold our mouse position throughout the application. Next we set the _currentPiece and _currentPieceDrop to null. (On the first play these values would already be null, but we want to make sure they get reset when replaying the puzzle.)

Finally, it’s time to draw! First we draw the entire image to display to the player what they will be creating. After that we create some simple instructions by calling our createTitle() function.


Step 7: The createTitle() Function

function createTitle(msg){
    _stage.fillStyle = "#000000";
    _stage.globalAlpha = .4;
    _stage.fillRect(100,_puzzleHeight - 40,_puzzleWidth - 200,40);
    _stage.fillStyle = "#FFFFFF";
    _stage.globalAlpha = 1;
    _stage.textAlign = "center";
    _stage.textBaseline = "middle";
    _stage.font = "20px Arial";
    _stage.fillText(msg,_puzzleWidth / 2,_puzzleHeight - 20);
}

Here we create a fairly simple message that instructs the user to click the puzzle to begin.
Our message will be a semi-transparent rectangle that will serve as the background of our text. This allows the user to see the image behind it and also assures our white text will be legible on any image

We simply set fillStyle to black and globalAlpha to .4, before filling in a short black rectangle at the bottom of the image.

Since globalAlpha affects the entire canvas, we need to set it back to 1 (opaque) before drawing the text. To set up our title, we set the textAlign to ‘center’ and the textBaseline to 'middle'. We can also apply some font properties.

To draw the text, we use the fillText() method. We pass in the msg variable and place it at the horizontal center of the canvas, and the vertical center of the rectangle.


Step 8: The buildPieces() Function

function buildPieces(){
    var i;
    var piece;
    var xPos = 0;
    var yPos = 0;
    for(i = 0;i < PUZZLE_DIFFICULTY * PUZZLE_DIFFICULTY;i++){
        piece = {};
        piece.sx = xPos;
        piece.sy = yPos;
        _pieces.push(piece);
        xPos += _pieceWidth;
        if(xPos >= _puzzleWidth){
            xPos = 0;
            yPos += _pieceHeight;
        }
    }
    document.onmousedown = shufflePuzzle;
}

Finally it’s time to build the puzzle!

We do this by building an object for each piece. These objects will not be responsible for rendering to the canvas, but rather to merely hold references on what to draw and where. That being said, let’s get to it.

First off, let’s declare a few variables that we’ll be reusing through the loop. We want to set up the loop to iterate through the number of puzzle pieces we need. We get this value by multiplying PUZZLE_DIFFICULTY by itself – so in this case we get 16.

In the loop:

    for(i = 0;i < PUZZLE_DIFFICULTY * PUZZLE_DIFFICULTY;i++){
        piece = {};
        piece.sx = xPos;
        piece.sy = yPos;
        _pieces.push(piece);
        xPos += _pieceWidth;
        if(xPos >= _puzzleWidth){
            xPos = 0;
            yPos += _pieceHeight;
        }
    }

Start by creating an empty piece object. Next add the sx and sy properties to the object. In the first iteration, these values are 0 and represent the point in our image where we will begin to draw from. Now push it to the _pieces[] array. This object will also contain the properties xPos and yPos, which will tell us the current position in the puzzle where the piece should be drawn. We’ll be shuffling the objects before its playable so these values don’t need to be set quite yet.

The last thing we do in each loop is increase the local variable xPos by _pieceWidth. Before continuing on with the loop, we determine if we need to step down to the next row of pieces by checking whether xPos is beyond the width of the puzzle. If so, we reset xPos back to 0 and increase yPos by _puzzleHeight.

Now we have our puzzle pieces all stored away nicely in our _pieces array. At this point the code finally stops executing and waits for the user to interact. We set a click listener to the document to fire the shufflePuzzle() function when triggered, which will begin the game.


Step 9: The shufflePuzzle() Function

function shufflePuzzle(){
    _pieces = shuffleArray(_pieces);
    _stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);
    var i;
    var piece;
    var xPos = 0;
    var yPos = 0;
    for(i = 0;i < _pieces.length;i++){
        piece = _pieces[i];
        piece.xPos = xPos;
        piece.yPos = yPos;
        _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, xPos, yPos, _pieceWidth, _pieceHeight);
        _stage.strokeRect(xPos, yPos, _pieceWidth,_pieceHeight);
        xPos += _pieceWidth;
        if(xPos >= _puzzleWidth){
            xPos = 0;
            yPos += _pieceHeight;
        }
    }
    document.onmousedown = onPuzzleClick;
}
function shuffleArray(o){
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
}

First things first: shuffle the _pieces[] array. I’m using a nice utility function here that will shuffle the indices of the array passed into it. The explanation of this function is beyond the topic of this tutorial so we’ll move on, knowing that we have successfully shuffled our pieces. (For a basic introduction to shuffling, take a look at this tutorial.)

Let’s first clear all graphics drawn to the canvas to make way for drawing our pieces. Next, set up the array similar to how we did when first creating our piece objects.

In the loop:

    for(i = 0;i < _pieces.length;i++){
        piece = _pieces[i];
        piece.xPos = xPos;
        piece.yPos = yPos;
        _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, xPos, yPos, _pieceWidth, _pieceHeight);
        _stage.strokeRect(xPos, yPos, _pieceWidth,_pieceHeight);
        xPos += _pieceWidth;
        if(xPos >= _puzzleWidth){
            xPos = 0;
            yPos += _pieceHeight;
        }
    }

First of all, use the i variable to set up our reference to the current piece object in the loop. Now we populate the xPos and yPos properties I mentioned earlier, which will be 0 in our first iteration.

Now, at long last, we draw our pieces.

The first parameter of drawImage() assigns the source of the image we want to draw from. Then use the piece objects sx and sy properties, along with _pieceWidth and _pieceHeight, to populate the parameters that declare the area of the image in which to draw from. The last four parameters set the area of the canvas where we want to draw. We use the xPos and yPos values that we are both building in the loop and assigning to the object.

Immediately after this we draw a quick stroke around the piece to give it a border, which will separate it nicely from the other pieces.

Now we wait for the user to grab a piece by setting another click listener. This time it will fire an onPuzzleClick() function.

Final HTML5 Puzzle

Step 10: The onPuzzleClick() Function

function onPuzzleClick(e){
    if(e.layerX || e.layerX == 0){
        _mouse.x = e.layerX - _canvas.offsetLeft;
        _mouse.y = e.layerY - _canvas.offsetTop;
    }
    else if(e.offsetX || e.offsetX == 0){
        _mouse.x = e.offsetX - _canvas.offsetLeft;
        _mouse.y = e.offsetY - _canvas.offsetTop;
    }
    _currentPiece = checkPieceClicked();
    if(_currentPiece != null){
        _stage.clearRect(_currentPiece.xPos,_currentPiece.yPos,_pieceWidth,_pieceHeight);
        _stage.save();
        _stage.globalAlpha = .9;
        _stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
        _stage.restore();
        document.onmousemove = updatePuzzle;
        document.onmouseup = pieceDropped;
    }
}

We know that the puzzle was clicked; now we need to determine what piece was clicked on. This simple conditional will get us our mouse position on all modern desktop browsers that support canvas, using either e.layerX and e.layerY or e.offsetX and e.offsetY. Use these values to update our _mouse object by assigning it an x and a y property to hold the current mouse position – in this case, the position where it was clicked.

In line 112 we then immediately set _currentPiece to the returned value from our checkPieceClicked() function. We separate this code because we want to use it later when dragging the puzzle piece. I’ll explain this function in the next step.

If the value returned was null, we simply do nothing, as this implies that the user didn’t actually click on a puzzle piece. However, if we do retrieve a puzzle piece, we want to attach it to the mouse and fade it out a bit to reveal the pieces underneath. So how do we do this?

First we clear the canvas area where the piece sat before we clicked it. We use clearRect() once again, but in this case we pass in only the area obtained from the _currentPiece object. Before we redraw it, we want to save() the context of the canvas before proceeding. This will assure that anything we draw after saving will not simply draw over anything in its way. We do this because we’ll be slightly fading the dragged piece and want to see the pieces under it. If we didn’t call save(), we’d just draw over any graphics in the way – faded or not.

Now we draw the image so its center is positioned at the mouse pointer. The first 5 parameters of drawImage will always be the same throughout the application. When clicking, the next two parameters will be updated to center itself to the pointer of the mouse. The last two parameters, the width and height to draw, will also never change.

Lastly we call the restore() method. This essentially means we are done using the new alpha value and want to restore all properties back to where they were. To wrap up this function we add two more listeners. One for when we move the mouse (dragging the puzzle piece), and one for when we let go (drop the puzzle piece).


Step 11: The checkPieceClicked() Function

function checkPieceClicked(){
    var i;
    var piece;
    for(i = 0;i < _pieces.length;i++){
        piece = _pieces[i];
        if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + _pieceHeight)){
            //PIECE NOT HIT
        }
        else{
            return piece;
        }
    }
    return null;
}

Now we need to backtrack a bit. We were able to determine what piece was clicked, but how did we do it? It’s pretty simple actually. What we need to do is loop through all of the puzzle pieces and determine if the click was within the bounds of any of our objects. If we find one, we return the matched object and end the function. If we find nothing, we return null.


Step 12: The updatePuzzle() Function

function updatePuzzle(e){
    _currentDropPiece = null;
    if(e.layerX || e.layerX == 0){
        _mouse.x = e.layerX - _canvas.offsetLeft;
        _mouse.y = e.layerY - _canvas.offsetTop;
    }
    else if(e.offsetX || e.offsetX == 0){
        _mouse.x = e.offsetX - _canvas.offsetLeft;
        _mouse.y = e.offsetY - _canvas.offsetTop;
    }
    _stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);
    var i;
    var piece;
    for(i = 0;i < _pieces.length;i++){
        piece = _pieces[i];
        if(piece == _currentPiece){
            continue;
        }
        _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
        _stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight);
        if(_currentDropPiece == null){
            if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + _pieceHeight)){
                //NOT OVER
            }
            else{
                _currentDropPiece = piece;
                _stage.save();
                _stage.globalAlpha = .4;
                _stage.fillStyle = PUZZLE_HOVER_TINT;
                _stage.fillRect(_currentDropPiece.xPos,_currentDropPiece.yPos,_pieceWidth, _pieceHeight);
                _stage.restore();
            }
        }
    }
    _stage.save();
    _stage.globalAlpha = .6;
    _stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
    _stage.restore();
    _stage.strokeRect( _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth,_pieceHeight);
}

Now back to the dragging. We call this function when the user moves the mouse. This is the biggest function of the application as it’s doing several things. Let’s begin. I’ll break it down as we go.

    _currentDropPiece = null;
    if(e.layerX || e.layerX == 0){
        _mouse.x = e.layerX - _canvas.offsetLeft;
        _mouse.y = e.layerY - _canvas.offsetTop;
    }
    else if(e.offsetX || e.offsetX == 0){
        _mouse.x = e.offsetX - _canvas.offsetLeft;
        _mouse.y = e.offsetY - _canvas.offsetTop;
    }

Start by setting _currentDropPiece to null. We need to reset this back to null on update because of the chance that our piece was dragged back to its home. We don’t want the previous _currentDropPiece value hanging around. Next we set the _mouse object the same way we did on click.

    _stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);

Here we need to do clear all graphics on the canvas. We essentially need to redraw the puzzle pieces because the object being dragged on top will effect their appearance. If we didn’t do this, we’d see some very strange results following the path of our dragged puzzle piece.

    var i;
    var piece;
    for(i = 0;i < _pieces.length;i++){

Begin by setting up our usual pieces loop.

In the Loop:

        piece = _pieces[i];
        if(piece == _currentPiece){
            continue;
        }

Create our piece reference as usual. Next check if the piece we are currently referencing is the same as piece we are dragging. If so, continue the loop. This will keep the dragged piece’s home slot empty.

        _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
        _stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight);

Moving on, redraw the puzzle piece using its properties exactly the same way we did when first drew them. You’ll need to draw the border as well.

        if(_currentDropPiece == null){
            if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + _pieceHeight)){
                //NOT OVER
            }
            else{
                _currentDropPiece = piece;
                _stage.save();
                _stage.globalAlpha = .4;
                _stage.fillStyle = PUZZLE_HOVER_TINT;
                _stage.fillRect(_currentDropPiece.xPos,_currentDropPiece.yPos,_pieceWidth, _pieceHeight);
                _stage.restore();
            }
        }

Since we have a reference to each object in the loop, we can also use this opportunity to check if the dragged piece is on top of it. We do this because we want to give the user feedback on what piece it can be dropped on. Let’s dig into that code now.

First we want to see if this loop has already produced a drop target. If so, we don’t need to bother since only one drop target can be possible and any given mouse move. If not, _currentDropPiece will be null and we can proceed into the logic. Since our mouse is in the middle of the dragged piece, all we really need to do is determine what other piece our mouse is over.

Next, use our handy checkPieceClicked() function to determine whether the mouse is hovering over the current piece object in the loop. If so, we set the _currentDropPiece variable and draw a tinted box over the puzzle piece, indicating that it is now the drop target.

Remember to save() and restore(). Otherwise you’d get the tinted box and not the image underneath.

Out of the Loop:

    _stage.save();
    _stage.globalAlpha = .6;
    _stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
    _stage.restore();
    _stage.strokeRect( _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth,_pieceHeight);

Last but not least we need to redraw the dragged piece. The code is the same as when we first clicked it, but the mouse has moved so its position will be updated.


Step 13: The pieceDropped() Function

function pieceDropped(e){
    document.onmousemove = null;
    document.onmouseup = null;
    if(_currentDropPiece != null){
        var tmp = {xPos:_currentPiece.xPos,yPos:_currentPiece.yPos};
        _currentPiece.xPos = _currentDropPiece.xPos;
        _currentPiece.yPos = _currentDropPiece.yPos;
        _currentDropPiece.xPos = tmp.xPos;
        _currentDropPiece.yPos = tmp.yPos;
    }
    resetPuzzleAndCheckWin();
}

OK, the worst is behind us. We are now successfully dragging a puzzle piece and even getting visual feedback on where it will be dropped. Now all that is left is to drop the piece. Let’s first remove the listeners right away since nothing is being dragged.

Next, check that _currentDropPiece is not null. If it is, this means that we dragged it back to the piece’s home area and not over another slot. If it’s not null, we continue with the function.

What we do now is simply swap the xPos and yPos of each piece. We make a quick temp object as a buffer to hold one of the object’s values in the swapping process. At this point, the two pieces both have new xPos and yPos values, and will snap into their new homes on the next draw. That’s what we’ll do now, simultaneously checking whether the game has been won.


Step 14: The resetPuzzleAndCheckWin() Function

function resetPuzzleAndCheckWin(){
    _stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);
    var gameWin = true;
    var i;
    var piece;
    for(i = 0;i < _pieces.length;i++){
        piece = _pieces[i];
        _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
        _stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight);
        if(piece.xPos != piece.sx || piece.yPos != piece.sy){
            gameWin = false;
        }
    }
    if(gameWin){
        setTimeout(gameOver,500);
    }
}

Once again, clear the canvas and set up a gameWin variable, setting it to true by default. Now proceed with our all-too-familiar pieces loop.

The code here should look familiar so we won’t go over it. It simply draws the pieces back into their original or new slots. Within this loop, we want to see if each piece is being drawn in its winning position. This is simple: we check to see if our sx and sy properties match up with xPos and yPos. If not, we know we couldn’t possibly win the puzzle and set gameWin to false. If we made it through the loop with everyone in their winning places, we set up a quick timeout to call our gameOver() method. (We set a timeout so the screen doesn’t change so drastically upon dropping the puzzle piece.)


Step 15: The gameOver() Function

function gameOver(){
    document.onmousedown = null;
    document.onmousemove = null;
    document.onmouseup = null;
    initPuzzle();
}

This is our last function! Here we just remove all listeners and call initPuzzle(), which resets all necessary values and waits for the user to play again.


Conclusion

Click here to see the final result.

As you can see, you can do a lot of new creative things in HTML5 using selected bitmap areas of loaded images and drawing. You can easily extend this application by adding scoring and perhaps even a timer to give it more gameplay. Another idea would be to increase the difficulty and select a different image in the gameOver() function, giving the game levels.



View full post on Activetuts+

Page 1 of 11112345...102030...Last »
top