ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Virtual Reality Tours in Flash
http://www.actionscript.org/resources/articles/152/1/Virtual-Reality-Tours-in-Flash/Page1.html
Matt Byrnes
This user is yet to take control of their account and provide a biography. If you are the author of this article, please contact us via support AT actionscript DOT org. 
By Matt Byrnes
Published on September 9, 2005
 
Tutorial details:
Written by: Matt Byrnes [email:matt@inflash.com] / www.inflash.com
Time: If you're just learning If Then statements, Get Property, and/or Set Variable, give yourself 6 hours. If you've got all those down, give yourself 30 minutes to an hour.
Difficulty Level: Advanced
Requirements: Software Required; Flash 4
Topics Coverred: Take your panoramic picture, import it into Flash, follow the steps below and presto! Instant 360 degree world for conveying depth and perspective to a static environment.
Assumed Knowledge: If Then, Set Variable, Get Property, Set Property, and Buttons directing the action on the timeline.

Page 1 of 3
Tutorial details:
Written by: Matt Byrnes [email:matt@inflash.com] / www.inflash.com
Time: If you're just learning If Then statements, Get Property, and/or Set Variable, give yourself 6 hours. If you've got all those down, give yourself 30 minutes to an hour.
Difficulty Level: Advanced
Requirements: Software Required; Flash 4
Topics Coverred: Take your panoramic picture, import it into Flash, follow the steps below and presto! Instant 360 degree world for conveying depth and perspective to a static environment.
Assumed Knowledge: If Then, Set Variable, Get Property, Set Property, and Buttons directing the action on the timeline. Download the source.

I was able to create a virtual tour of an apartment with the ability to go into different rooms.

With Flash's interactive features, you can have virtual tours for real, not just scrolling. For instance, I have the door to the bedroom be a button that accesses the virtual tour of the bedroom. Same for the kitchen area. I could have done the whole building, if I wanted.

The great thing about this tutorial is that once you get it, if you have a panoramic camera, you can go to any and all real-estate companies and offer your Flash virtual tour services for $. The other great thing is that, if you're anything like me, you'll just want to download the .fla and modify it as little as possible and get the results. The .fla is designed for that, too. Just follow the picture taking and importing steps below.

First, about taking the pictures: you must use a tripod on a flat surface and pay close attention to keeping the camera the same level. The camera I used, an Olympus D-360L, enables you to take a series of pictures and line each picture up so that they can all be assembled into a panoramic photo later. The camera also comes with software that can stitch the photos together seamlessly. You can do this lining up and stitching of photos together yourself without the aid of software, but I haven't done any experiments with that.

Also, with my camera, there always seems to be some mismatching between the last picture at 360 degrees and the first picture at 0 degrees. The seam between the 2 pictures can be pretty apparent, and you might want to hide the seam in an overexposed or underexposed section of the picture or whatever else you can come up with. (I used an extreme close-up of a tree trunk in this example. I was on such un-even ground with a weak tripod, so I had to make do). For the apartment example, the unevenness was much less since I shot it on a hardwood floor. I used the over-exposed doorway to hide the seam.

Alright, onto assembling the flash tour.

  1. Break up the panoramic picture into roughly 3 equal parts. You could do this with 2 pictures that are wide enough each to cover the stage, however, Flash gets funky when the images get too far off the stage. So 3 smaller pictures is a safer bet, and that's what I've coded for.
  2. Place them in the appropriate movie clips: left, center and right. Line them yp in perfect, seamless, alignment. If they're out of aligment to begin with, they'll be perfectly out of alignment throughout.
  3. Keep all the movie clip's widths free of decimal points other than 0. (No '900.7' type widths). Otherwise, you'll get small gaps between your pictures. Remember, the movie clips determine the width of the picture they contain, not the other way around. You could have a picture 1000 pixels wide, but it will get stretched to 1015.5 pixels wide if that's how wide your movie clip is set to.
  4. After that, if you find yourself getting small gaps between your pictures,select each image inside of the movie clip and select the 'break apart' command. ('Break apart' is in the 'Modify' pulldown menu). If you still have gaps, be sure to check point 6 below.

5. If you change the stage's width, be sure to make the variable in the Action Script in Frame 1 reflect that.
6. Last, but not least, once you import your pictures into the movie clips, be sure the picture's x-axis is at zero inside the movie clip. For example:

Inside the movie clip you'll have your image, and you need to relocate it so that it's x-axis is at zero by moving it to the crosshairs like so:

If you don't do that, instead of scrolling in order, your pictures will flop on top of each other. All the pictures top most left corner must be at the x-axis inside of the movie clips. Once outside of the movie clip and on the main stage, line up your pictures by the seams. In other words, make the picture look whole on the main stage.

Page 2 of 3
Alright, for you "just gimme the .fla" types, you're all set. For a walk through of the code, see below.

For reference, a snapshot of the timeline:



In the above code, there's no "playing," in the usual sense. The play head gets sent via "Goto" to different frames only for time delay purposes, and the pictures are repositioned by Action Script's Set Property X Position, etc., creating the effect of motion.

First, I'll introduce the section of script to discuss, then I'll discuss it.

Frame 1's Action Script is some initializing:
[as]
Set Variable: "stagewidth" = 540
Set Variable: "leftmcwidth" = GetProperty ( "/leftmc", _width )
Set Variable: "centermcwidth" = GetProperty ( "/centermc", _width )
Set Variable: "rightmcwidth" = GetProperty ( "/rightmc", _width )
Set Variable: "left" = "slow"
Go to and Play ("left")
[/as]
Code[as]
Set Variable: "stagewidth" = 540
[/as]
Comment
Basically, we're setting a variable 'stagewidth' to the width of the stage. If you change your .fla's stage width, you must make the number here match it.

Code[as]
Set Variable: "leftmcwidth" = GetProperty ( "/leftmc", _width )
Set Variable: "centermcwidth" = GetProperty ( "/centermc", _width )
Set Variable: "rightmcwidth" = GetProperty ( "/rightmc", _width )
[/as]
Comment
We get the width of each movie clip and store it in a variable.

Code[as]
Set Variable: "left" = "slow"
Go to and Play ("left")
[/as]
Comment
The movie is also set to play slow starting in the 'left' direction. We'll take a look at what the computer does with the variable "left" set to the value "slow" at the end of the tutorial.

Let's take a look at how the ActionScript handles repositioning the pictures.
[as]
Frame 8 contains the following code for when the "Right" button is pushed:
Set Variable: "leftmcX" = GetProperty ( "/leftmc", _x )
Set Variable: "centermcX" = GetProperty ( "/centermc", _x )
Set Variable: "rightmcX" = GetProperty ( "/rightmc", _x )
If (rightmcX>=(-1*rightmcwidth) and rightmcX<=stagewidth)
Set Property ("/rightmc", X Position) = rightmcX+10
Set Property ("/centermc", X Position) = (rightmcX-centermcwidth)+10
End If
If (leftmcX>=(-1*leftmcwidth) and leftmcX<=stagewidth)
Set Property ("/leftmc", X Position) = leftmcX+10
Set Property ("/rightmc", X Position) = (leftmcX-rightmcwidth)+10
End If
If (centermcX>=(-1*centermcwidth) and centermcX<=stagewidth)
Set Property ("/centermc", X Position) = centermcX+10
Set Property ("/leftmc", X Position) = (centermcX-leftmcwidth)+10
End If
Play
[/as]

First, the computer determines what the position each movie clip is at on the X-axis. It takes that position and stores it in a variable.
[as]
Set Variable: "leftmcX" = GetProperty ( "/leftmc", _x )
Set Variable: "centermcX" = GetProperty ( "/centermc", _x )
Set Variable: "rightmcX" = GetProperty ( "/rightmc", _x )
[/as]
Thus, the X position of the the movie clip "/leftmc" is stored in the variable, "leftmcX."

Next the computer looks at whether any part of the movie clip is on the stage, starting with the right movie clip.
[as]
If (rightmcX>=(-1*rightmcwidth) and rightmcX<=stagewidth)
Set Property ("/rightmc", X Position) = rightmcX+10
Set Property ("/centermc", X Position) = (rightmcX-centermcwidth)+10
End If
[/as]
Let's look at the first section of the conditional:
[as]
If (rightmcX>=(-1*rightmcwidth)
[/as]
This part of the script is asking, is the movie clip as far left as it is wide? If we take the X position and add the width of the movie clip to the X position, will the tail of the movie clip be on the stage? In other words, if the movie clip's X position is -500, that means it's X position is way off the stage. But if the movie clip is 600 pixels long, that means there are 100 pixels of the movie clip still on the stage. If it's still on the stage it has to be repositioned.

You might be asking yourself, "why is a -1 being multiplied times the width of the movie clip?" I'll try my best to explain it, but math isn't my strong suit. We're only concerned with how far from zero the clip is, not how far each clip is from the other. Negative and positive would be helpful if we were trying to determine which number was 'larger' then the other relative to each other, but we're not, we're trying to determine which is closer to zero, and being negative doesn't mean it's farther away then a positive number, it just means it's to the left. Alright, whatever. We need to convert the movie clip to a negative number to make a correct comparision.
[as]
If (rightmcX>=(-1*rightmcwidth) [/as]

If the X position is closer to zero, return true, if the movie clip width as a negative number is closer to zero, that means it's off the stage and false is returned, and we don't care about it.

The second part of the conditional test:
[as]
and rightmcX<=stagewidth)
[/as]
checks to see if the X position is left of the far right side of the stage. Assuming a stage 540 pixels wide, this could be any number less than 540. If the X position is over 540, skip to the next conditional test. If it is under, then both parts of the conditional test return true and the movie clip must be repositioned for the viewer:
[as]
Set Property ("/rightmc", X Position) = rightmcX+10
Set Property ("/centermc", X Position) = (rightmcX-centermcwidth)+10
[/as]
Just add 10 pixels to the movie clip's X position in the above script and presto! A scrolling effect.
[as]
But what's this here: (rightmcX-centermcwidth)+10
[/as]
The tricky part here is that we're moving the movie clips according to their X position, but we're aligning the tail end of one movie clip to the X position (beginning) of another.

So how do we do this?

Page 3 of 3
So how do we do this?

We can determine the tailend position of a movie clip by taking it's X position and adding that number to the movie clip's width. Thus, a movie clip with an X position of 100 that is 500 pixels wide would have a tail end that would land on the X axis at 600.

That gives us access to lining up the tail end of one movie clip with the X position of another movie clip.

For example, take the center movie clip (centermc) and the right movie clip (rightmc). The computer takes the X position of the right movie clip, we'll say it's 200, subtract that from the width of the center movie clip, we'll say that's 1000, and we get -800. -800 is the x position of the center movie clip for perfect alignment with the right movie clip.

Since the pictures are constantly being positioned relative to one another, it's necessary to line them up at the beginning in perfect alignment. If they're out of aligment to begin with, they'll be perfectly out of alignment throughout. The starting positions are the absolutes that all the relative re-positioning are based on.

To finish up the rest of the conditional statements in the keyframe, which is basically a rehash of everything above.:
[as]
The computer checks the position of each movie clip to the other and will perform the same operations as above if the condition returns true.
If (rightmcX>=(-1*rightmcwidth) and rightmcX<=stagewidth)
Set Property ("/rightmc", X Position) = rightmcX+10
Set Property ("/centermc", X Position) = (rightmcX-centermcwidth)+10
End If
If (leftmcX>=(-1*leftmcwidth) and leftmcX<=stagewidth)
Set Property ("/leftmc", X Position) = leftmcX+10
Set Property ("/rightmc", X Position) = (leftmcX-rightmcwidth)+10
End If
If (centermcX>=(-1*centermcwidth) and centermcX<=stagewidth)
Set Property ("/centermc", X Position) = centermcX+10
Set Property ("/leftmc", X Position) = (centermcX-leftmcwidth)+10
End If
Play
[/as]
Each If statement checks to see if the X position returned indicates any part of the movie clip is on the stage. If the movie clip has any part of itself on stage, then that movie clip is moved to the right 10 pixels. The movie clip to the left of it gets moved to the right 10 pixels as well. (To move the pictures to the left, the movie clips would be repositioned 10 pixels to the left).

Everything gets positioned relative to everything else. However, there are a two absolutes that make all this relativity possible:

The tour starts with leftmc's tailend aligned seamlessly with the beginning of centermc, and centermc's tailend aligns seamlessly with the beginning of rightmc.

At some point, the tailend of rightmc will align seamlessly with the beginning of leftmc.

By programming the code this way, the computer can manage the presentation itself, without you having to re-calculate everything everytime you import new panoramic pictures into the .fla.

The Buttons

A quick step back to the beginning, when the user clicks a button to change the scrolling direction and then we're finished.

The buttons.



In the Fast Forward button is contained the ActionScript:
[as]
On (Release)
Set Variable: "right" = "fast"
Go to and Play (2)
End On
[/as]


So the viewer clicks the Fast Forward to the right button, setting the variable "right" to hold the value "fast." The computer repositions the pictures by executing the code in the keyframe labeled "right" (which we just went over above). Immediately after the keyframe labeled "right" is the keyframe labeled, "Goto right fast." It contains the following code:
[as]
If (right eq "fast")
Go to and Play (2)
Else
Play
End If
[/as]
and in the frame after that (labeled "Goto left slow") is the ActionScript:
[as]
Go to and Play (2)
[/as]
What does all that do? When the viewer clicked on the Fast Forward button, the variable "right" was set to "fast", so the playhead gets sent back to execute the code and reposition the pictures fairly quickly. If "right" isn't set to "fast" it plays another frame before being sent back to execute the code, thus creating a greater delay between the repositioning of the pictures.

I'll let you figure out how to make the pictures go left. It's not much different.

Any questions, let me know!