Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development

This chapter is from the book

This chapter is from the book

Working in Director

In this section, you'll learn how to work in Director. You'll learn the importance of the size of your .W3D files, how to set up the score, how to handle visibility and color issues, and finally, how to add Lingo.

File Size Considerations

In this example, the .W3D file consumes a majority of the Director movie's size. This means that the .W3D file size is what you should be concerned with, even before you import it into Director. If it's too large, your users will have an overall bad experience viewing your movie. The movie will take a long time to download, and it might not play smoothly, especially if your viewers don't have hardware-accelerated OpenGL or DirectX type video cards.

The first thing to remember is that when you "get information" (in Macintoshes) or view properties (in Windows), ensure that you are viewing the network file size, not the file size on disk. Although it's usually not a considerable difference, it's best to use accurate information for posting next to the movie, so that users know what they will have to endure in terms of download times [3.29].

Figure 3.29. The download size for this file is 890K, not 872K. Try to make every K count.

Another disadvantage of having a large file is that the majority of Internet users are not on a broadband connection; thus, a 1 megabyte file's download can take a long time. It can become an obsession to see just how small you can get a .W3D or Shockwave 3D file. I tell you about more file-saving tips later in this chapter. First, we'll set up the movie.

Score Setup

After you have imported your .W3D file and any additional assets into Director, you can lay out the score. If you prefer, you can use the house.dir file on the CD-ROM accompanying this book. This file represents a simple movie that has three necessary frames to run the entire movie [3.30].

Figure 3.30. The three frames that this movie uses are for preloading, waiting until the user is ready, and displaying the .W3D movie and interface.

I recommend that you never use the first frame of the score. This isn't a Shockwave 3D tip, but a general rule when working in Director. Director performs a lot of pre-tasks before loading the movie, such as general script initiations for sounds, windows, and video. When Director or runtime versions of your movie, such as DCRs or projectors, have assets in the first frame, you can sometimes run into inconsistencies and erratic behavior when you start the movie. I recommend that you always put sprites in frame 2, and treat frame 2 as if it is frame 1. However, if you need to run initialization scripts, putting those scripts in frame 1 is fine.

Color and Visibility

When you place your .W3D castmember into the score, you will notice a lag as Director pauses for a few seconds to process the Shockwave 3D castmember and load it into memory. The lag time occurs during any time that your playback head is moved off the Shockwave 3D castmember frame and then back on to it again. This delay can become considerably annoying at times because the program appears to hang briefly. You can also get this lag when you are trying to add behaviors to Shockwave 3D castmembers.

To avoid the lag time as you navigate the score, place your Shockwave 3D castmember in the score, and then position it on the stage where you want it to go. Now, go back to the score and turn off the visibility of the channel that contains your Shockwave 3D castmember. You don't need it to be visible to add behaviors and scripts. Now, you can scrub the playback head around the score to navigate without it pausing and hanging over the Shockwave 3D member [3.31].

Figure 3.31. Turn off the visibility of the channel that contains your Shockwave 3D sprite for better score performance.

Another tip is to color your Shockwave 3D member in the score, using the color chips in the lower-left corner of the score. This helps you quickly identify where in the score your castmember is.

Redrawing Issues

When visibility is turned on for a castmember, and you move that member to the stage, redraw issues occur. I have seen these same redraw issues occur in projectors and web browsers, where you have no control over it, because it is occurring outside of Director. This is a Shockwave 3D bug that Macromedia has to resolve in the future.

Another good reason to turn off the visibility of your Shockwave 3D member is because leaving it on can result in some "redrawing funkiness" that is present in Director after an image is redrawn in Director.

To simulate this problem, add your Shockwave 3D castmember to the stage. Then, move the Stage window to another location. The Shockwave 3D sprite does not want to update the image when the Stage window moves [3.32].

Figure 3.32. Moving your stage with a Shockwave 3D sprite can cause redraw issues.

In my opinion, there is currently no ideal work-around for this bug. You can make the redrawing problem go away by turning off the Direct to stage option in the Property Inspector window; however, when you do this, your Shockwave 3D movie is drawn in screen buffer layers, and other castmembers in the score can pass on top of the Shockwave 3D sprite. This causes such a substantial slowdown in the redrawing of the Shockwave 3D sprite that it becomes useless. It's reminiscent of the days when Director's QuickTime functionality was first added to the application. You had the ability to turn off the Direct to Stage function for the QuickTime sprite, but the number of frames per second playback would drop from 24 to approximately 4, making the QuickTime movie useless. However, today you can do this with QuickTime sprites, and the performance isn't as bad as it used to be. Hopefully, redrawing sprites will get better with future improvements.

The real issue is that these redrawing artifacts occur in projectors and browsers. This is bad, because you can't turn off the Direct to Stage option for performance reasons, and you can't let your user move the window around or scroll without causing this redrawing problem. I recommend that you simply stay away from the projector option that lets your movies be in their own window (show title bar). As for working in Director, your only options are to turn off the Shockwave 3D visibility or open and close the stage window and use other windows as "giant erasers" to wipe the screen clean.

Adding Lingo

Yes, it's Lingo time. This movie contains Lingo examples that are either simple or difficult. There is no "middle ground" with these scripts. If you open the house.dir movie from the CD, you will see in the cast that there are four scripts—members 19, 20, 21, and 23. Number 23 is the most difficult if you are new to Lingo.

Each piece of Lingo preloads the Shockwave castmember into memory, waits for the user to continue, pauses the movie in the frame that the Shockwave castmember is in, and finally, performs a form of collision detection known as ray casting.

The first script that handles the preloading is a frame script. The script should be added to one of the Score window's frame script channels. It looks like this (remember, these scripts are on the CD accompanying this book as well):

property p3dMember

on beginSprite (me)
 p3dMember = member("3D")
 p3dMember.preload()
end beginSprite

on exitFrame (me)
 if (p3dMember.state <> 4) then
  go to the frame
 else
  p3dMember.resetWorld()
  go to the frame + 1
 end if
end exitFrame

Member number 19 is a script that preloads the Shockwave 3D castmember into memory (RAM) before it starts playing. The script looks for your Shockwave 3D castmember by name, not by sprite number. Because it looks for the name, be careful. If you copy the script word-for-word, don't forget to use the name of your Shockwave 3D castmember instead of the one in the script, or change the name to 3D.

Before talking about the details of this script, I want to mention Thomas Higgins. Thomas is the author of the scripts in this movie, and he is the author of many movies located at http://www.directordev.com/. Thomas is an employee of Macromedia, and I want to extend my appreciation for his help with this demonstration and his contribution to the book.

---- Preload Shockwave 3D member into memory script ----

property p3dMember -- reference to the 3D member

on beginSprite (me)
 -- stores the 3D members name for reference
 p3dMember = member("3D")
 -- starts the preloading of the castmember
 p3dMember.preload()
end beginSprite

on exitFrame (me)
 -- check the member's state; is it loaded or not?
 if (p3dMember.state <> 4) then 
  -- if it's not loaded, then hold on current frame
  go to the frame
 else
  -- reset member's world
  p3dMember.resetWorld()
  -- if it is loaded then step to next frame
  go to the frame + 1
 end if
end exitFrame
----

The next script that is used in the movie simply pauses it until the user is ready. After the movie has been preloaded, you don't want it to instantly start playing, because the user might not be ready. This script waits until the user clicks on the screen before advancing to the next frame to play the Shockwave 3D movie you just preloaded.

-- This script holds the playback head on a given
-- frame until the user clicks anywhere on stage.
--

on exitFrame
 -- hold on current frame
 go to the frame
end exitFrame


on mouseDown 
 -- step to the next frame
 go to the frame + 1
end mouseDown

There is one additional frame script that is used to pause the Director movie on the frame that the Shockwave 3D castmember is playing on:

on exitFrame
 -- hold on current frame
 go to the frame
end exitFrame

The next Lingo script is attached to the Shockwave 3D sprite and controls the navigation and collision of your camera. It's a very intuitive use of ray casting. (This script is also on the CD.)

What the ray casting script does is project a ray (or think of it as a vector) from the camera in the direction that the camera is moving. The camera has a sphere surrounding it that is invisible. If the camera is moving forward, a ray is being projected forward to determine the distance the camera is from an object in front of it [3.33]. If the ray being projected or cast from the camera is shorter than the distance the camera is to the sphere, the camera is close to the object, if it isn't colliding with it. The script then sets the camera's position back to the path the ray was being cast. This gives the impression that your camera has collided with an object and bounced back off of it.

Figure 3.33. Ray casting is used to determine the camera's distance from an object. A result of ray casting is shown here.

Following is the ray casting Lingo and an explanation of what it is doing.

These are the properties that get initialized for the script. Properties are similar to variables or global variables depending on the programming language you are familiar with:

property pMember	-- 3D member used by this sprite
property pSprite	-- reference to this sprite
property pMouseDown	-- user is pressing the left mouse button
property pRightMouseDown	-- user is pressing the right mouse button
property pCamera	-- the sprite's camera
property pCameraSphere	-- the sphere used to surround the camera
property pCamAnimFlag	-- introduction animation is running?
property pCamAnimInfo	-- perform an introduction animation

The beginSprite handler fills the properties with their functions and any necessary data. It also creates the sphere around the camera and a light that the camera carries with it:

on beginSprite (me)
-- initialize properties
 pMember = sprite(me.spriteNum).member
 pSprite = sprite(me.spriteNum)
 pMouseDown = FALSE
 pRightMouseDown = FALSE
 pCamera = sprite(me.spriteNum).camera
 pCamAnimFlag = TRUE
 -pCamAnimInfo = [#initT: pCamera.transform. _duplicate(), \
         -#f inalT: pMember.camera _("f irst_person").transform. duplicate(), \
         #count: 0]

 -- create the camera's bounding sphere
 mr = pMember.newModelResource("camera_sphere",#sphere)
 mr.radius = 7.5
 pCameraSphere = pMember.newModel("camera_sphere",mr)
 
-- create a light to carry with the camera
 camLight = pMember.newLight("camera_light",#point)
 camLight.color = rgb(170,170,170)
 
-- make the sphere and light children of the camera
 pCamera.addChild(pCameraSphere,#preserveParent)
 pCamera.addChild(camLight,#preserveParent)
 
-- register the camera for the timeMS event in order to perform the intro animation if any
 -pCamera.registerScript(#timeMS,#animateCamera,me, 0,50,51)
 
-- register the member for regular timeMS events in order to respond to user input and resolve camera  
"collisions" -pMember.registerForEvent(#timeMS,#controlCamera, me,2500,50,0) end beginSprite

These mouse handlers switch the Boolean state for the property. If the mouse is down the pMouseDown property is TRUE, for example:

on mouseDown (me)
-- update the mouse down property 
 pMouseDown = TRUE
end mouseDown

on mouseUp (me)
-- update the mouse down property 
 pMouseDown = FALSE
end mouseUp

on rightMouseDown (me)
-- update the right mouse down property 
 pRightMouseDown = TRUE
end rightMouseDown

on rightMouseUp (me)
-- update the right mouse down property 
 pRightMouseDown = FALSE
end rightMouseUp

The animateCamera handler is used to animate the camera automatically over time:

on animateCamera (me)
-- increment the internal counter for the animation
 pCamAnimInfo.count = pCamAnimInfo.count + 1
 
-- determine the interpolation percentage
 pctg = 100.0 _ (pCamAnimInfo.count / 50.0)
 
-- if pctg is greater than 100 end animation sequence
 if (pctg > 100) then 
  pctg = 100
  pCamAnimFlag = FALSE
 end if
 
-- determine the new interpolated camera transform
 -t = pCamAnimInfo.initT.interpolate _(pCamAnimInfo.finalT,pctg)
 
-- apply that transform to the camera
 pCamera.transform = t
end animateCamera

This controlCamera handler is what controls the movement of the camera for each of the four directions. It also controls the collisions with objects:

on controlCamera (me)

-- respond only if the intro camera animation is completed
 if not(pCamAnimFlag) then
  
-- CONTROL THE LEFT/RIGHT ROTATION OF THE CAMERA
-- if the shift key is *not* down then follow the mouse -- to adjust left right looking
  if not(the shiftDown) then
   
-- check for the mouse locH wrt the sprite loc
   deltaH = the mouseH - pSprite.locH
   
-- calculate rotation value to apply
   rotn = -(deltaH/165.0) * 4.0
   
-- apply that rotation
   -pCamera.rotate(pCamera.worldPosition, vector(0,0,1),rotn,#world)
  end if
  

-- CONTROL THE FORWARD/BACKWARD MOVEMENT OF THE CAMERA
-- if the left mouse is down then move the character forward
  if pMouseDown then
   pCamera.translate(0,0,-2.5)
  end if
  
-- if the right mouse is down then move the character backward
  if pRightMouseDown then
   pCamera.translate(0,0,2.5)
  end if

The following part of the script controls the collisions of the camera with the walls or other objects. This casts rays forward or backward depending upon movement, and it will also cast rays to the left and to the right. For each ray that is cast, the script will verify that the distance to the nearest model exceeds the camera's bounding sphere radius; if the distance is less than the bounding sphere's radius, move the camera out of the collision state in a direction perpendicular to the intersected model's surface.

  --- cast one ray fwd/bckwrd depending upon which mouse button is down
  case (TRUE) of
    
-- left mouse down, cast ray forward
   (pMouseDown): 
    
-- cast ray
    -tList = pMember.modelsUnderRay _(pCamera.worldPosition,-pCamera.transform. zAxis,#detailed)
    
-- if there are models in front of the camera, check for collisions
    if (tList.count) then
     me.checkForCollision(tList[1])
    end if
-- right (control+) mouse down, cast ray backward
   (pRightMouseDown): 
    
-- cast ray
    -tList = pMember.modelsUnderRay _(pCamera.worldPosition,pCamera.transform. zAxis,#detailed)
    
-- if there are models in front of the camera, check for collisions
    if (tList.count) then
     me.checkForCollision(tList[1])
    end if
  end case
  
-- cast a ray to the left
  -tList = pMember.modelsUnderRay _(pCamera.worldPosition,-pCamera.transform. xAxis,#detailed)
  
-- if there are models in front of the camera, check  _for collisions
  if (tList.count) then
   me.checkForCollision(tList[1])
  end if
  
-- cast a ray to the right
  -tList = pMember.modelsUnderRay _(pCamera.worldPosition,pCamera.transform.xAxis, #detailed)
  
-- if there are models in front of the camera, check for collisions
  if (tList.count) then
   me.checkForCollision(tList[1])
  end if
 end if
end controlCamera


on checkForCollision (me, thisData)
-- grab the distance value
 dist = thisData.distance
 
-- if distance is smaller than bounding radius, resolve collision
 if (dist < pCameraSphere.resource.radius) then
  
-- get distance of penetration
  diff = pCameraSphere.resource.radius - dist
  
-- calculate vector perpendicular to the wall's surface to move the camera
  tVector = thisData.isectNormal * diff
  
-- move the camera in order to resolve the collision
  pCamera.translate(tVector,#world)
 end if
end checkForCollision

This script controls the navigation for the Shockwave 3D sprite. After the script is attached to your sprite and the movie is started, the cursor position relative to the Shockwave 3D sprite determines the rotation of the camera, even if your cursor isn't rolled over the Shockwave 3D sprite. So, for example, if your cursor is off the screen to the right, your camera will be turning to the right inside your Shockwave movie. Be aware of the functionality, because at some point, your movie will need to explain to your users how to navigate.

With the script controls in order, it's time to test what you have completed.

Peachpit Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from Peachpit and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about Peachpit products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites; develop new products and services; conduct educational research; and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email ask@peachpit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by Adobe Press. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.peachpit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020