Pipwerks SCORM wrapper not working with Multiple "Scenes"

67 views
Skip to first unread message

Stryker908

unread,
Nov 3, 2009, 3:33:25 PM11/3/09
to eLearning Technology and Development
Hi Phillip and other eLearning Peoples-

I have run into a problem trying to test a SCORM package. I hope
somebody here can help me out, because I'm going a bit crazy trying to
find the problem.

I have used Pipwerks Java files, as well as modified versions of the
IMSManafest file and the HTML file. My module is written using
ActionScript 3.0 and currently has 3 different scenes. When all
"items" have been viewed a "completion" button is made visible, when
that button is "Clicked" it is supposed to send the "complete" command
to the LMS. I have traced the "complete" command and it is firing
properly, but when I test the module on the "Rustici" site the
completion does not work properly.

I have tried making a simplified "click to complete" module just to
make suer I'm not missing some basic step, and that worked FINE... I'm
more then happy to post any code on here for people to review. I would
LOVE some help here....

Thanks!

Regards,
Nathan

Stryker908

unread,
Nov 3, 2009, 4:07:30 PM11/3/09
to eLearning Technology and Development
Adding the ActionScript:

[quote]
stop();

import pipwerks.SCORM;

butterTubGlow.visible=false;
play_mc.visible=false;
playRadio_mc.visible=false;
help_mc.visible=false;
helpText_mc.visible=false;
complete_mc.visible=false;

mute_mc.visible=true;

date20s_mc.alpha=0;


var radioON:Number = new Number(0);
var radio1920:Sound = new Sound();
var truckLeaving:Sound = new Sound();
var skolVikings:Sound = new Sound();
var soundVol:SoundTransform = new SoundTransform();
var changeScene:Timer = new Timer(2200,1);
var helpTimer:Timer = new Timer(1000,1);
var visited1:Boolean;
var visited2:Boolean;
var moduleComplete:Boolean;
var lessonStatus:String;
var lmsConnected:Boolean;
var success:Boolean;
var scorm:SCORM = new SCORM();

butterTub.addEventListener(MouseEvent.MOUSE_OUT, tubGlowOff);
butterTub.addEventListener(MouseEvent.MOUSE_OVER, tubGlowOn);
butterTub.addEventListener(MouseEvent.CLICK, tubPlay);
mic_mc.addEventListener(MouseEvent.CLICK, musicOnOff);
truck_mc.addEventListener(MouseEvent.MOUSE_OVER, truckOver);
truck_mc.addEventListener(MouseEvent.MOUSE_OUT, truckOff);
truck_mc.addEventListener(MouseEvent.CLICK, changeSceneDate20s);
changeScene.addEventListener(TimerEvent.TIMER_COMPLETE,
changeSceneDelay);
play_mc.addEventListener(MouseEvent.CLICK, playRadio);
helpTimer.addEventListener(TimerEvent.TIMER_COMPLETE, displayHelp);
help_mc.addEventListener(MouseEvent.CLICK, displayHelpText);
helpText_mc.addEventListener(MouseEvent.CLICK, hideHelpText);
skol_mc.addEventListener(MouseEvent.CLICK, playSkol);
complete_mc.addEventListener(MouseEvent.CLICK, closeModule);
addEventListener(MouseEvent.MOUSE_MOVE, resetHelpTimer);
addEventListener(Event.ENTER_FRAME, checkStatus);
//addEventListener(Event.ENTER_FRAME, connectLMS);


radio1920.load(new URLRequest("Audio/Audio1920s.mp3"));
truckLeaving.load(new URLRequest("Audio/TruckLeaving.mp3"));
skolVikings.load(new URLRequest("Audio/Skol.mp3"));

radio1920.play();
helpTimer.start();

//function connectLMS(e:Event)

lmsConnected = scorm.connect();

if(lmsConnected)
{
lessonStatus = scorm.get("cmi.core.lesson_status");

if(lessonStatus == "completed" || lessonStatus == "passed")
{
scorm.disconnect();
}
else
{
success = scorm.set("cmi.core.lesson_status",
"incomplete");
}

}
else
{
trace("Could not connect to LMS.");
}
//removeEventListener(Event.ENTER_FRAME, connectLMS);



function tubGlowOn(e:Event)
{
butterTubGlow.visible=true;
}

function tubGlowOff(e:Event)
{
butterTubGlow.visible=false;
}

function tubPlay(e:Event)
{
butterTub.removeEventListener(MouseEvent.MOUSE_OUT, tubGlowOff);
helpTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,
displayHelp);
visited1=true;
gotoAndPlay(1,"creamery");
SoundMixer.stopAll();

}
function musicOnOff(e:Event)
{
mute_mc.visible=false;
playRadio_mc.visible=true;
soundVol.volume=0;
SoundMixer.soundTransform=soundVol;
play_mc.visible=true;
}
function playRadio(e:Event)
{
soundVol.volume=1;
play_mc.visible=false;
playRadio_mc.visible=false;
mute_mc.visible=true;
SoundMixer.soundTransform=soundVol;
}

function truckOver(e:Event)
{
date20s_mc.alpha=100;
}
function truckOff(e:Event)
{
date20s_mc.alpha=0;
}

function changeSceneDate20s(e:MouseEvent)
{
changeScene.start();
SoundMixer.stopAll();
truckLeaving.play();

}

function changeSceneDelay(e:TimerEvent)
{
truck_mc.removeEventListener(MouseEvent.MOUSE_OUT, truckOff);
helpTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,
displayHelp);
visited2=true;
gotoAndPlay(1,"date1920s");
}
function displayHelp(e:TimerEvent)
{
help_mc.visible=true;

}
function resetHelpTimer(e:Event)
{
helpTimer.reset();
helpTimer.start();

}
function displayHelpText(e:Event)
{
helpText_mc.visible=true;
}
function hideHelpText(e:Event)
{
helpText_mc.visible=false;
}
function playSkol(e:MouseEvent):void
{
if(e.ctrlKey)
{
trace("SkolVikings");
SoundMixer.stopAll();
skolVikings.play();
}
}
function checkStatus(e:Event)
{
if(page1Complete==true && page2Complete==true)
{
moduleComplete=true;
complete_mc.visible=true;
/*success = scorm.set("cmi.core.lesson_status", "completed");
butterTub.removeEventListener(MouseEvent.MOUSE_OUT, tubGlowOff);
helpTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,
displayHelp);*/
//gotoAndStop(2);
}



removeEventListener(Event.ENTER_FRAME, checkStatus);
}
function closeModule(e:Event):void
{
success = scorm.set("cmi.core.lesson_status", "completed");
scorm.disconnect();
lmsConnected = false;
}


[/quote]

Abraham

unread,
Nov 3, 2009, 5:55:03 PM11/3/09
to eLearning Technology and Development
Try adding scorm.save(); rigth after you set the "completed" status:

function closeModule(e:Event):void
{
success = scorm.set("cmi.core.lesson_status", "completed");

scorm.save();
scorm.disconnect();
lmsConnected = false;

Stryker908

unread,
Nov 4, 2009, 9:08:24 AM11/4/09
to eLearning Technology and Development
Hi Abraham-

Thank you for the reply, I have tried the save status call (scorm.save
();) but that did not fix the problem.

Last night though I did figure something out. There is a MAIN stage/
Timeline, and 2 secondary timelines. I added a dynamic text field to
tell me when/if I was
still connected to the LMS, I am connected when I first launch the
program, but when I come back to the main time line from one of the
secondary ones the LMS
is no longer connected. I am not sure why it is disconnecting, but
when I "unhide" the completion button and just click it right away the
program completes properly.

Next couple things I'm going to try:

Adding the "connect" statement AFTER the module achieves a complete
status

Adding the "connect" statement to each of the additional timelines.

Although I am still not sure why going from one timeline to another
within the same movie would cause the LMS to drop is connection.....

Ryan Meyer

unread,
Nov 4, 2009, 9:42:58 AM11/4/09
to elearning-technolo...@googlegroups.com
When you say that you are going between multiple "scenes", do you mean actual Scenes in Flash? (I don't even remember if they support that anymore!) If so, then it's possible your "scorm" Actionscript variable has gone out of scope when you try to access it.

Even if you're simply talking about different MovieClips that are active on the stage, you have to be careful with scoping. If you've got code that's responding to a button event within a child clip, you may need to access your "scorm" Actionscript variable on the root timeline explicitly: _root.scorm..set("cmi.core.lesson_status", "completed"); It's been a while since I messed with AS3 though, so I'm not sure if that syntax is still correct. Regardless, use some trace statements (or ideally the debugger if you're familiar with it) to make sure that your "scorm" variable is actually in in scope when you're trying to access it.

-Ryan

Stryker908

unread,
Nov 4, 2009, 12:17:55 PM11/4/09
to eLearning Technology and Development
Hi Ryan-

Actual different scenes-

Got it working this morning, the problem has something to do with
changing scenes for sure.

I waited until the module was complete before calling the "connect to
LMS" code, that way it would
all be on the same scene.

I've had very little formal training so I'm sure my AS syntax is all
over the place
and I KNOW that I do things the "hard way" sometimes, because I don't
know the "proper" way to do them
but its working now :)

Thanks again for everybody's help !

Philip Hutchison

unread,
Nov 4, 2009, 12:27:57 PM11/4/09
to elearning-technolo...@googlegroups.com
Be aware that if you're not connecting to the LMS until after the learner has gone through chunks of the course you will have a heck of a time explaining yourself if the LMS doesn't connect for some reason. :)

It's always best to connect to the LMS right away (first or second frame of your project) then disconnect at the very end. Even if you use scenes, you should be able to set this up.

Always put the scorm code in the main timeline's actionscript to avoid scope issues. If you need to put scorm code in a movieclip for some reason (such as an interaction), you should use references instead:

root:

function setScore(score:Number):void {
   scorm.set(score);
}

in your interaction:

parent.setScore(85);


This ultimately gives you more flexibility and helps avoid scope issues.

- philip

Stryker908

unread,
Nov 4, 2009, 2:27:02 PM11/4/09
to eLearning Technology and Development
Hi Philip-

Thanks for the reply. the original timeline did have the connect code,
as well as the complete code, but the module would not "complete" when
it reached the correct point. to find out what was happing I added a
text field on screen to display the status of the LMS connection. When
the file is first launched the connection is made, but when ever the
user returns to the main scene from one of the alternate scenes the
LMS would loose its connection. As of right now the "module" is
complete when the user has viewed items A, B, and C (similar to your
"planets" example actually). When they have all been viewed a function
is called to "complete" the module. All of these things are happening,
but for some reason it looses the LMS connection prior to sending the
complete status.

To fix the problem for right now when that "complete" function is
called, it connects to the LMS at that point, sets the status to
complete, and exits the module...... Do you have an idea as to why
the module would NOT stay connected when changing scenes? (if you want
to see the full file let me know and I'm more then happy to send it to
you....)

And I apologize, I'm a rookie with flash and ActionScript, and I'm
know NOTHING about Java....

Cheers,
Nathan

Philip Hutchison

unread,
Nov 4, 2009, 3:09:19 PM11/4/09
to elearning-technolo...@googlegroups.com
Hi Nathan

It won't disconnect unless you tell it to, whether it's on purpose or by accident.

Sounds like it's logic somewhere in your code that's causing the problem, either by triggering a disconnect via premature 'completed' or by losing scope and not keeping track of the scorm variable.

The only thing I can recommend is to strip down your course/code to its simplest form, then add course functionality/scenes one-by-one while testing each step.

In my experience problems like this are usually caused by a small typo or oversight someplace, which winds up snowballing and throwing everything out of whack.

- philip

Stryker908

unread,
Nov 4, 2009, 4:03:57 PM11/4/09
to eLearning Technology and Development
<quote>In my experience problems like this are usually caused by a
small typo or
> oversight someplace, which winds up snowballing and throwing everything out
> of whack.</quote>

You sure you haven't seen my code :)

Honestly I have been looking for that glitch for 3 weeks and I haven't
found it. I am
sure when I do it will be glaring.

Cheers!

On Nov 4, 2:09 pm, Philip Hutchison <platelu...@gmail.com> wrote:
> Hi Nathan
>
> It won't disconnect unless you tell it to, whether it's on purpose or by
> accident.
>
> Sounds like it's logic somewhere in your code that's causing the problem,
> either by triggering a disconnect via premature 'completed' or by losing
> scope and not keeping track of the scorm variable.
>
> The only thing I can recommend is to strip down your course/code to its
> simplest form, then add course functionality/scenes one-by-one while testing
> each step.
>
> In my experience problems like this are usually caused by a small typo or
> oversight someplace, which winds up snowballing and throwing everything out
> of whack.
>
> - philip
>

Charles Parcell

unread,
Nov 5, 2009, 12:37:40 AM11/5/09
to elearning-technolo...@googlegroups.com
I am willing to bet I see the issue.

Is the AS script that you provided located in the MAIN timeline as you have indicated?

If so, then when you return to the MAIN timeline, you are running all that code a second time.  While this may seem like a small thing because most of it is within function calls, there is one major problem. Your call to scorm.connect() is bare to the timeline (line 61). This is getting executed a second time (or perhaps more). It is a big no no to attempt a second initialization to the API Adapter.

I believe that TestTrack was built to be forgiving and not throw a lot of errors when the developer messes things up a bit. Perhaps it is simply being quiet about your reinitialization but also completely breaking the API Adapter.

So, this would explain why you are able to get it to work when you either place the Complete button at the start of the project and also when you only attempt to connect within the Complete button's function.

The real problem that you have here is that you do not have a controller that is active throughout your project. By jumping from scene to scene, all the code located in each scene is being created and then destroyed. So, information collected in one scene is lost when you jump to another scene.

Since you are fairly new to Flash I will provide you with a suggestion to modernize your project. Scenes are a really old way of having multiple timelines within a project that are completely independent from one another. You can think of a scene as its own MovieClip. With this in mind you should create a MovieClip in the library for each scene you currently have. Copy all the assets and code from the scene into each new MovieClip. So, rather than jumping from scene to scene, you will instead set the proper MovieClip to be visible and enabled. In this way your MAIN (root/Stage) timeline is a container that holds all your "scene" MovieClips. You are also then able to create variables and functions on the MAIN timeline that will persist for the duration of your project. Case in point, your scorm object.

I hope this helps.

Note: Truth be told, and perhaps a little too advanced for you to tackle all at once, the best way to build this would be to have each of your "scenes" be separate SWF files that are loaded into the project as needed at runtime. So rather than setting a MovieClip to be visible and enabled, you would simply unload the currently displayed MovieClip and then load in the next. While seems a little odd for a project that has one 3 "scenes", this method is very useful when you have 20 or 60 "scenes". The file size for a project that completely encompassed that many "scenes" would be giant and take a long while to load. By breaking it up into small parts you load in small amounts of data at a time, and ultimately only the data that you really need over the life of the project.

And then we can start calling them "screens" or "views" or even "pages", depending on your method of development. The term "scenes" make seasoned Flash developers cringe. ;)

Charles P.

Philip Hutchison

unread,
Nov 5, 2009, 1:11:04 AM11/5/09
to elearning-technolo...@googlegroups.com
I'm not sure about that... I believe when a Flash file containing scenes is published, the scenes become part of the main timeline, and simply use an anchor-style reference to jump around.

Scene 1: 10 frames (frame 1-10)
Scene 2: 10 frames (frame 1-10)

becomes:

Main timeline frames 1-20

(label/anchor here) 1,2,3,4,5,6,7,8,9,10, (label/anchor here) 11,12,13,14,15,16,17,18,19,20

Charles Parcell

unread,
Nov 5, 2009, 1:40:48 AM11/5/09
to elearning-technolo...@googlegroups.com
You are right about them being merged into one Timeline.  I was thinking of the other Flash "feature" called "Screens". Uggg.

But the point still remains. When the user returns to the first "scene", which would be frame 1 ultimately, scorm.connect() is being called a second time.

Charles P.

Philip Hutchison

unread,
Nov 5, 2009, 1:52:29 AM11/5/09
to elearning-technolo...@googlegroups.com
Yup, definitely a lot of room for duplicating calls.

It's always a good idea to use a lot of conditional statements to ensure certain calls aren't made twice, such as:

var LMS_connection_active:Boolean = false;
if(!LMS_connection_active){  LMS_connection_active = scorm.init();  }

It may mean more code and more time to develop, but in the long run it tightens up the code and prevents a bunch of errors.
Reply all
Reply to author
Forward
0 new messages