Adobe Captivate - Drag and Drop - drag-and-drop

I am using Adobe Captivate to produce an online learning activity, We are using the drag and drop which works well. Only issue is that it is not dynamic, therefore once a student has got it correct they can just follow position to get correct again.
Is it possible to shuffle the position of drag or drop objects so as to show that the sudent has understanding of the question and not just following a remembered pattern.

Not out of the box. There's no like "Shuffle Drag Sources" checkbox like there is for say multiple choice answers. It would be possible to achieve something like you are asking by putting this script into your OnEnter action and selecting "Execute Javascript":
$(function () {
var dss = cp.DD.CurrInteractionManager.m_ActiveInteraction.m_dsList;
var ypos = dss.map((i) => {
return $("div[id='" + i.n + "']").css("top");
});
ypos = shuffle(ypos);
dss.forEach((o, i) => {
$("div[id='re-" + o.n + "c']").css("top", ypos[i]);
$("div[id='" + o.n + "']").css("top", ypos[i]);
});
function shuffle(arr) {
for (var i = 0; i < arr.length; i++) {
var randId = Math.floor(Math.random() * arr.length);
var tmp = arr[i];
arr[i] = arr[randId];
arr[randId] = tmp;
}
return arr;
}
});
I didn't put comments in here for copy/paste purposes because that awful Captivate JavaScript window is very flaky with whitespace, so a statement by statement walkthrough is here:
var dss = cp.DD.CurrInteractionManager.m_ActiveInteraction.m_dsList;
Collects all of the drag sources into an array.
var ypos = dss.map((i) => {return $("div[id='" + i.n + "']").css("top")});
Extracts the Y position of each object.
ypos = shuffle(ypos);
Calls the function (defined below) to shuffle the order of the array of Y positions randomly.
dss.forEach((o, i) => {$("div[id='re-" + o.n + "c']").css("top", ypos[i]);
$("div[id='" + o.n + "']").css("top", ypos[i]);});
Cycles through the drag sources and places each into its new position, bringing the canvas along with it.
Couple of caveats here.
If more than one attempt is allowed, the "Reset button will place the
drag sources back to their original locations.
This assumes the drag sources are all lined up with the same
horizontal position. If they are scattered about, the X position
would also need to be accounted for.
I didn't test this on a responsive or flex project, I'm not sure how Adobe does the positioning for object in those cases, this will work on fixed-sized projects.
Arrow functions might not be supported in IE11, if you need to support that, you might need to re-write the callback functions using traditional syntax.

Related

Unity: Ignore collision of a plateform if jump to it from below. Using ContactFilter & rigidBody.Cast()

I am able to avoid a collision between my player and my entire plateform with the use of contactFilter2D.SetLayerMask() + rigidBody2D.Cast(Vector2, contactFilter, ...);
But I don't find a way to avoid the collision only if my player try to acces to the plateform from below it (with a vertical jump).
I'm pretty sure I should use the contactFilter2D.setNormalAngle() (after specify the minAngle and maxAngle) but no matter the size of my angles, I can't pass threw it.
This is how I initialize my contactFilter2D.
protected ContactFilter2D cf;
void Start () {
cf.useTriggers = false;
cf.minNormalAngle = 0;
cf.maxNormalAngle = 180;
cf.SetNormalAngle(cf.minNormalAngle, cf.maxNormalAngle);
cf.useNormalAngle = true;
}
void Update () {
}
I use it with
count = rb.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
Any ideas ? If you want more code, tell me. But I don't think it will be usefull to understand the matter.
unity actualy has a ready made component for this: it is a physics component called "Platform Effector 2D" if you drag and drop it on your platform it will immediately work the way you want, and it has adjustable settings for tweaking the parameters. hope this helps!

Protractor: How to Drag and Drop without using an element?

Normally, drag and drop are done using 2 elements.
But, what if I have a dynamic grid, and I want to select a part of it by click-hold and dragging it then release. (similar to drag and drop)
I was able to get the x and y coordinates already, but I am not sure how to make it work without an element.
It looks like an element is required.
After using the element (body), I was able to make drag and drop work.
var offsetx = dndoffset.x;
var offsety = dndoffset.y;
browser.waitForAngular();
this.getTargetIndex(<ObjectToBeDragged>,function (targetIndex) {
var targetElement = element.all(by.repeater(<ng-repeat value>)).get(targetIndex);
targetElement.getLocation().then(function (location) {
offsetx = Math.round(offsetx + location.x);
browser.actions().mouseMove(<ObjectToBeDragged>)
.mouseDown()
.mouseMove(targetElement)
.mouseMove(targetElement, {x: offsetx, y: offsety})
.mouseUp().perform();
});
browser.waitForAngular();
});
The above is the snippet I am using to drag and drop. You always have element in the DOM (even it is dynamic). You have to pick the right one and place it there.
Since we have the ng-repeat, we are using by.repeater() to locate the element dynamically.

remove graphics from inside a class as3

When I click a button in my game it draws shapes using the graphics in as3. simple shapes such as circles and rectangles.
I want to remove the graphics that have been drawn when something happens in one of my classes.
Basically when there is a hitTestObject (which works fine) I want all graphics on stage to be cleared.
if (gb2.hitTestObject(h1s2))
{
trace ("holed")
ySpeed2=0;
xSpeed2=0;
this.visible=false;
var mcSplash:MovieClip =parent.getChildByName("mcSplash") as MovieClip;
mcSplash.visible=true;
//parent.drawings.graphics.clear();
}
My attempt using parent.drawings.graphics.clear(); was unsuccessful, it gives me this error:
Line 481 1119: Access of possibly undefined property drawings through a reference with static type flash.display:DisplayObjectContainer.
Anyone have any suggestions
UPDATE:
this is how, on the min time line, the drawings occur.
var drawings:Shape = new Shape;
for (i=0; i<numRecs; i++)
{
recStartX = Number(xmlContent.rec[i].startpoint.#ptx);
recStartY = Number(xmlContent.rec[i].startpoint.#pty);
recWidth = Number(xmlContent.rec[i].dimensions.#w);
recHeight = Number(xmlContent.rec[i].dimensions.#h);
fillColor=int(xmlContent.rec[i].look.fillhex);
lineThick = Number(xmlContent.rec[i].look.strokethick);
lineColor = int(xmlContent.rec[i].look.strokehex);
drawings.graphics.lineStyle(lineThick, lineColor);
drawings.graphics.beginFill(fillColor);
drawings.graphics.drawRect(recStartX,recStartY,recWidth,recHeight);
drawings.graphics.endFill();
}
Create an array and push in each shape/rect.
Then iterate through this and remove..
for(var iteration:int = 0; iteration < rectArray.length; iteration++)
this.removeChild(rectArray[iteration]);
or if you are calling this from a class, use
MovieClip(this.root).removeChild(rectArray[iteration]);
Hopefully this is helpful :)
Z
What's drawings?! If you draw in mcSplash, you should use mcSplash.graphics.clear(). If you draw in a child called drawings, you should first get it as a child (after mcSplash get): var drawings = mcSplash.getChildByName('drawings); drawings.graphics.clear();. You could write checks to see what's going on: if (mcSlpash) { if (drawings) {, etc..

A way to check a BufferedImage repaint()?

I'm working in Eclipse and I want to know if I can make an if statement that checks to see if the BufferedImage has been painted/drawn onto the frame. For some reason, it's not painting the correct image because clickable regions are appearing on that picture when they are not supposed to.
For example, when I click the region to go from 4>5 everything is good. When I click from 5 to go to 4 I end up at 6 because the 'regions' from 4 are appearing in 5 (The image should always be painted before the clickable regions are shown) before it's even being painted. I want to restrict this to check if the image has been painted onto the frame first.
I really don't want to use anything else besides what I have right now (so no new classes being implemented to do this task), I really just want a simple yet effective way to resolve this. Here is what I'm talking about:
...
MouseAdapter mouseHandler = new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
repaint();
if(n==0)
{
if(e.getX()>=459 && e.getX()<491 && e.getY()>=111 && e.getY()<133
{
n = 4;
}
return;
}
if(n==5)
{
if(...)
{
n = 4;
}
return();
}
if(n==6)
{
if(...)
{
n = 5;
}
if(...)
{
n = 0;
}
if(...)
{
n = 6;
}
return();
}
}
...
I think you might need to give a little more information. The problem might lie in how you repaint, not whether it was painted.
If you are running another thread as your main program, you might instead want to send the mouse events synchronously to that so that the main thread can process the mouse click and then repaint.
Another solution might be to override the repaint method and paint the buffered images there, but you may have done that.
Also, a little off topic, I noticed that you used for loops to determine if the mouse was clicked in a specific area.
You could shorten the code:
for(int i=459; i<491; i++){
if(e.getX()==i){
for(int j=111; j<133; j++){
if(e.getY()==j){
//action taken
}
}
}
}
To:
if(e.getX()>=459 && e.getX()<491 && e.getY()>=111 && e.getY()<133{
//action taken
}
This would take up less space in your code and less time checking every pixel.
Back to your question.
I dont know of a function to tell if a buffered image has been painted. The ploblem that you are having though might of might not be in the code provided. Posting the rest of your code would be beneficial.
Okay I found the solution, I forgot to come back to this question and let you know. The problem was that the mouse was double clicking for some reason. You could almost say it was 'recursive'. I decided to move the mouseListener from inside the paintComponent to outside of it, and surely enough that fixed it.

Kinect SimpleOpenNI and Processing Range

I need to find a way to have the kinect only recognize objects in a certain Range. The problem is that in our setup there will be viewers around the scene who may disturb the tracking. Therefore I need to set the kinect to a range of a few meters so it won't be disturbed by objects beyond that range. We are using the SimpleOpenNI library for processing.
Is there any possibility to achieve something like that in any way?
Thank you very much in advance.
Matteo
You can get the user's centre of mass(CoM) which retrieves a x,y,z position for a user without skeleton detection:
Based on the z position you should be able to use a basic if statement for your range/threshold.
import SimpleOpenNI.*;
SimpleOpenNI context;//OpenNI context
PVector pos = new PVector();//this will store the position of the user
ArrayList<Integer> users = new ArrayList<Integer>();//this will keep track of the most recent user added
float minZ = 1000;
float maxZ = 1700;
void setup(){
size(640,480);
context = new SimpleOpenNI(this);//initialize
context.enableScene();//enable features we want to use
context.enableUser(SimpleOpenNI.SKEL_PROFILE_NONE);//enable user events, but no skeleton tracking, needed for the CoM functionality
}
void draw(){
context.update();//update openni
image(context.sceneImage(),0,0);
if(users.size() > 0){//if we have at least a user
for(int user : users){//loop through each one and process
context.getCoM(user,pos);//store that user's position
println("user " + user + " is at: " + pos);//print it in the console
if(pos.z > minZ && pos.z < maxZ){//if the user is within a certain range
//do something cool
}
}
}
}
//OpenNI basic user events
void onNewUser(int userId){
println("detected" + userId);
users.add(userId);
}
void onLostUser(int userId){
println("lost: " + userId);
users.remove(userId);
}
You can find more explanation and hopefully useful tips in these workshop notes I posted.