Articulate Storyline & tabletop.js - articulate-storyline

Been trying for hours how to get this for loop to work. Using Tabletop to get info from Google sheet which is working fine when used like this:
function showInfo(data) {
var player = GetPlayer();
player.SetVar("score", data[0].name);
}
GetPlayer() is default Articualte Storyline function which is assigned to a variable player. I try adding a for loop and the code no longer works.
Here is the code with the for loop added:
function showInfo(data) {
for (var i = 0; i < data.length; i++) {
var player = GetPlayer();
player.SetVar("name", data[i].name);
}
}
Finally the whole Javascript code being used in the trigger:
var public_spreadsheet_url = 'http://foo.com';
Tabletop.init({
key: public_spreadsheet_url,
callback: showInfo,
prettyColumnNames: false
});
function showInfo(data) {
for (var i = 0; i < data.length; i++) {
var player = GetPlayer();
player.SetVar("name", data[i].name);
}
}
thanks

Related

Audioworklet loop

I'm trying to create an audioworklet that loops a single instance of a sound to create a sort of sustain effect. No matter how many sections of the input I loop, I keep hearing a blip type skipping sound. How many calls to the processor is one instance?
To give you an idea, this is what I have so far:
constructor() {
super();
this.sound = [];
this.count = 20;
this.step = [0, 0];
}
process(inputs, outputs, parameters) {
if (inputs && inputs.length) {
for (var i = 0; i < inputs[0].length; i++) {
var input = inputs[0][i];
var output = outputs[0][i];
if (!this.sound[i]) {
this.sound[i] = [];
}
if (this.sound[i].length < this.count) {
this.sound[i].push([]);
for (var j = 0; j < input.length; j++) {
this.sound[i][this.sound[i].length - 1][j] = input[j];
}
} else if (this.sound[i]) {
var s = this.sound[i][this.step[i] % this.sound[i].length];
for (var j = 0; j < s.length; j++) {
output[j] = s[j];
}
this.step[i]++;
}
}
}
return true;
}
So the idea is that I capture the incoming input in an array of N length for each channel(in my case there are 2 channels). Then once that array is full, I cycle through that array to fill the output until the node is disabled.
Thanks for the fiddle. Very helpful.
I didn't look to see what was causing the clicks, but I took your example and modified it very slightly like so:
// #channels 2
// #duration 1.0
// #sampleRate 44100
var bufferSize = 4096;
let ctx = context;
let osc = ctx.createOscillator();
osc.start();
let myPCMProcessingNode = ctx.createScriptProcessor(bufferSize, 2, 2);
let _count = 1;
var sound = [];
var count = _count++;
console.log(count)
var hesitate = 0;
var step = [0, 0];
//Logic to pay attention to
myPCMProcessingNode.onaudioprocess = function(e) {
for(var i = 0; i<2; i++){
var input = e.inputBuffer.getChannelData(i);
var output = e.outputBuffer.getChannelData(i);
if (!sound[i]) {
sound[i] = [];
}
if (sound[i].length < count) {
sound[i].push([]);
for (var j = 0; j < input.length; j++) {
sound[i][sound[i].length - 1][j] = input[j];
}
} else if (sound[i]) {
var s = sound[i][step[i] % sound[i].length];
for (var j = 0; j < s.length; j++) {
output[j] = s[j];
}
step[i]++;
}
}
}
//To hear
osc.connect(myPCMProcessingNode).connect(ctx.destination);
I pasted this in the code window at https://hoch.github.io/canopy. Press the top left button (arrow) to the left of the code window, and you can see the rendered audio. You can see that the output (frequency is 10 instead of 440 to make it easier to see) is discontinuous. This causes the clicks you hear. You can also change the frequency to 100 and find discontinuities in the output.
I hope this is enough to help you figure out what's wrong with your buffering.
An alternative is to create an AudioBufferSourceNode with an AudioBuffer of the basic sample. You can set the AudioBufferSourceNode to loop the whole buffer. This doesn't solve the clicking problem, but it is somewhat simpler.
But this is a general problem of looping any buffer. Unless you arrange the last sample to be close to the first sample, you will hear clicks when you wrap around. You either need to grab chunks where the first and last samples are nearly the same, or modified the chunks so they ramp up at the beginning in some way and ramp down at the end in some way.

css/javascript multiple card flip: reset other cards

So I'm currently using this one: http://jsfiddle.net/nawdpj5j/10/
Now what I need is that when I flip one card (doesn't matter which one) and then flip another one the first one resets/turnes back.
I think I need to add something in here:
var init = function() {
var flippers = document.getElementsByClassName("flip");
for(i = 0; i < flippers.length; i++){
flippers[i].addEventListener( 'click', function(){
var cardID = this.dataset.targetid;
var card = document.getElementById(cardID);
card.toggleClassName('flipped');
}, false);
}
};
Thank you in advance!
You can get an array of all flipped cards and flip them back whenever a card is flipped like so:
var init = function() {
var flippers = document.getElementsByClassName("flip");
for (i = 0; i < flippers.length; i++) {
flippers[i].addEventListener('click', function() {
var cardID = this.dataset.targetid;
var card = document.getElementById(cardID);
var flipped = document.getElementsByClassName('flipped');
for (i = 0; i < flipped.length; i++) {
if (card !== flipped[i]) {
flipped[i].toggleClassName('flipped');
}
}
card.toggleClassName('flipped');
}, false);
}
};
window.addEventListener('DOMContentLoaded', init, false);
Here is a link to a working demo JS FIDDLE

FLASH PROFESSIONAL CS6 using ACTIONSCRIPT 3

var theXML:XML = new XML();
theXML.ignoreWhite = true;
theXML.onLoad = function()
{
var nodes = this.firstChild.childNodes;
for(i = 0; i < nodes.length; i++)
{
theList.addItem(nodes[i].firstChild.nodeValue, i);
}
};
theXML.load("http://localhost/xampp/phpflash/account.php");
These are the errors:
-1120: Access of undefined property i.
-1137: Incorrect number of arguments. Expected no more than 1.
I'm so newbie on this subject. Please help me with your kind and consideration.
1: you should declare i.
2: addItem function should only have one argument.
var theXML:XML = new XML();
theXML.ignoreWhite = true;
theXML.onLoad = function()
{
var nodes = this.firstChild.childNodes;
for(var i:int = 0; i < nodes.length; i++)
{
theList.addItem(nodes[i].firstChild.nodeValue);
}
};
theXML.load("http://localhost/xampp/phpflash/account.php");

CreateJS swapping display list containers with the use of classes

This is a 2D Jenga game.
So I am currently making a Jenga game in createjs. When users take a block out from the Jenga building they can move it around, ultimately users are suppose to be able to take the piece and move it to the top like a typical Jenga game. The problem is you can take any piece out move it towards the bottom it appears to be in front of the Jenga building, but once you move a block towards the top it goes behind the building. I have a piece class which creates one block looks like this:
var GamepeiceComponent = (function() {
var assets = {};
var offset;
var gamePeice;
var currentX;
var currentY;
var newContainer;
this.makePiece = function(ingredient) {
gamePeice = new createjs.Container();
assets.peice = new createjs.Bitmap(queue.getResult(ingredient));
gamePeice.on('pressmove', handlePieceDrag);
gamePeice.on("pressup", handlePieceUp);
gamePeice.on("mousedown", handleMouseDown);
gamePeice.cursor = 'pointer';
gamePeice.addChild(assets.peice);
}
function handleMouseDown(e) {
// Game.block.swapChildren(e.currentTarget, Game.block);
for(var i = 0; i < Game.stage.children.length; i++){
console.log(Game.stage.children[i]);
//Game.stage.swapChildren(e.currentTarget, Game.stage.children[i])
}
//Game.stage.addChildAt(gamePeice,1);
offset = {x: e.target.x - e.stageX, y: e.target.y - e.stageY};
createjs.EventDispatcher.initialize(GamepeiceComponent.prototype);
gamePeice.dispatchEvent("pieceClicked");
}
function handlePieceDrag(e) {
e.target.x = e.stageX + offset.x;
e.target.y = e.stageY + offset.y;
}
function handlePieceUp(e) {
e.target.x = 0;
e.target.y = 0;
}
this.addPiece = function() {
return gamePeice;
}
return this;
});
I then have a block class which creates a block using the piece class because it creates 3 pieces per block (just like Jenga) heres what that is:
var GameblockComponent = (function() {
var gameBlock;
this.makeBlock = function(ingredient, yOffset, xOffset) {
gameBlock = new createjs.Container();
for(var i=0;i<3;i++) {
var gamePieces = new GamepeiceComponent();
var makePiece = gamePieces.makePiece(ingredient);
gamePieces.addPiece().y = yOffset * i;
gamePieces.addPiece().x = xOffset * i;
gamePieces.addPiece().on('pieceClicked', handleClick);
gameBlock.addChild(gamePieces.addPiece());
}
}
function handleClick(e) {
console.log('Game Piece Clicked');
}
this.addBlock = function() {
return gameBlock;
}
return this;
});
Lastly I have a building which organizes all the blocks in order:
var GamebuildingComponent = (function(game) {
var jengaContainer;
var left = ['burger_l', 'cheese_l', 'egg_l', 'ham_l', 'lettuce_l', 'onion_l', 'pickle_l', 'salmon_l', 'sausage_l', 'tomato_l'];
var right = ['burger_r', 'cheese_r', 'egg_r', 'ham_r', 'lettuce_r', 'onion_r', 'pickle_r', 'salmon_r', 'sausage_r', 'tomato_r'];
var bread = ['bread_l', 'bread_r'];
var seed = [];
var offsets = {
xOffsetLeft: 15,
yOffsetLeft: -33,
xPosLeft: 170,
xOffsetRight: 17,
yOffsetRight: 33,
yPosRight:100
};
function init() {
jengaContainer = new createjs.Container();
createBread(15);
createSubBlock(40);
createBread(160);
createSubBlock(185);
createBread(305);
}
function createBread(yOffset) {
var block = new GameblockComponent();
var breadLeft = block.makeBlock(bread[0], offsets.xOffsetLeft, offsets.yOffsetLeft);
block.addBlock().x = 170;
block.addBlock().y = yOffset;
jengaContainer.addChildAt(block.addBlock(), 0);
}
// LEFT: left side facing to left
// RIGHT: right side facing to right
function createSubBlock(yOffset) {
for(var i=0;i<5;i++) {
var block = new GameblockComponent();
var random = Math.floor(Math.random()*left.length);
// prevents duplicates
while(seed.indexOf(random) > -1) {
var random = Math.floor(Math.random()*left.length);
}
if(i%2 != 0) {
var ingredient = block.makeBlock(left[random], offsets.xOffsetLeft, offsets.yOffsetLeft);
block.addBlock().x = 170;
} else {
var ingredient = block.makeBlock(right[random], offsets.xOffsetRight, offsets.yOffsetRight);
block.addBlock().x = 105;
}
seed.push(random);
block.addBlock().y = 23 * i + yOffset;
jengaContainer.addChildAt(block.addBlock(), 0);
}
}
this.addBuilding = function() {
return jengaContainer;
}
init();
return this;
});
It all works fine except for when you move a lower piece towards the top the piece goes behind the jenga building, and of course its how the displaylist works, how would I be able to swap the piece correctly and where? I was listing all my child elements that are on the stage and it gave me one child (the jenga building). That child gave me 13 children (each block).
Then I just add the Jenga building to a view, and that view gets called from a controller.
You're probably looking for the setChildIndex method of the Container object.
function handleMouseDown(e) {
Game.block.setChildIndex(e.currentTarget, Game.block.children.length - 1);
}

GWT OpenLayers set sum of values of underlying VectorFeatures on cluster point

I'm using gwt-openlayers-1.0, currently learning this example (Animated Cluster Strategy).
In my project each VectoreFeature has a numeric label and I want to display sums of label values of underlying points on each cluster point. Is there a way to do that?
upd:
According to this article (The “Most Important” Strategy part) in JS it would look like this:
// for each feature:
feature.attributes = { result_count: 10 };
...
var style = new OpenLayers.Style({
...
} , context: {
label: function(feature) {
if (feature.cluster) {
var result_count = 0;
for (var i = 0; i < feature.cluster.length; i++) {
result_count += feature.cluster[i].attributes.result_count;
}
features.attributes.label = result_count.toString();
} else {
features.attributes.label = features.attributes.result_count.toString();
}
}
}
But I can't find a way to implement this in gwt-openlayers:
org.gwtopenmaps.openlayers.client.Style style = new org.gwtopenmaps.openlayers.client.Style();
style.setLabel( ??? );
I don't think this is possible.
I also don't think this is possible in standard OpenLayers with the standard AnimatedCluster.
Your best guess is to first go to https://github.com/acanimal/AnimatedCluster and ask there if what you want is possible (in standard openlayers).
If they say it is possible, and say how come back here and I can look further into it.
If they say it is also not possible in standard openlayers, then it is also not possible in gwt openlayers.
I enhanced the Animated Cluster With Popup example to do what you ask.
Will take some time before this is online though.
Changes I made are :
First I added an attribute to each feature added to the map. This feature just is a random number that we want to display the sum of when clicking a clustered feature :
for (int i = 0; i < points.size(); i++)
{
features[i] = new VectorFeature(points.get(i));
Attributes attributes = new Attributes();
attributes.setAttribute("examplenumber", Random.nextInt(10));
features[i].setAttributes(attributes);
}
Second change is in the public void onFeatureSelected(FeatureSelectedEvent eventObject)
int totalNumber = 0;
VectorFeature[] clusters = eventObject.getVectorFeature().getCluster();
for (int i = 0; i < clusters.length; i++)
{
GWT.log("examplenumber = " + clusters[i].getAttributes().getAttributeAsInt("examplenumber"));
totalNumber += clusters[i].getAttributes().getAttributeAsInt("examplenumber");
}
Now totalnumber contains the sum of all examplenumber attribute values.
I believe this solves your problem ?
In method where I assign strategy to the VectorLayer:
{
org.gwtopenmaps.openlayers.client.Style style = new org.gwtopenmaps.openlayers.client.Style();
style.setJSObject(getOpenLayersStyle());
}
And where the magic is done:
private native JSObject getOpenLayersStyle() /*-{
var style = new $wnd.OpenLayers.Style({
fontColor: "#FFFFFF",
fontSize: "12px",
label: "${countLabel}"
}, { context: {
countLabel: function(feature) {
var countLabel;
if (feature.cluster) {
var result_count = 0;
for (var i = 0; i < feature.cluster.length; i++) {
result_count += feature.cluster[i].attributes.result_count;
}
countLabel = result_count.toString();
} else {
countLabel = feature.attributes.result_count.toString();
}
feature.attributes.label = countLabel;
return countLabel;
}
}
});
return style;
}-*/;