Swift SpriteKit can't recursively call function with SKAction - recursion

func Game(){
var actionwait = SKAction.wait(forDuration: 3)
var actionrun = SKAction.run({
var randomIndex1 = Int(arc4random_uniform(UInt32(self.button.count)))
var randomItem1 = self.button[randomIndex1]
self.poupButtonImage.texture = SKTexture(imageNamed: self.images[randomIndex1])
self.popupButtonImage.zPosition += 1
self.continuationSequence.text?.append(randomItem1)
self.winner.zPosition += 1
self.winner.text = (randomItem1)
})
if(self.winner.text == self.buttonPressed.text){
print ("Chicken Dinner")
winner.run(SKAction.sequence([actionwait,actionrun]))
Game()
}
else{
print ("You lost")
}
}
When the Game() function is called in the if block it just keeps printing chicken dinner and the variables in the action run portion of code are never generated after the initial run. I used the debugger but couldn't not figure out the reason for the behavior.

Related

calling .next() recursively from a generator

I'm going through Kyle Simpson's Rethinking Async on Frontend Masters, and in the lecture on async generators, there is an example of calling .next() recursively. The gist of it goes as follows:
function *main() {
var x = (yield setTimeout(function() {return a.next(2)},0));
console.log(x)
}
var a = main();
a.next();
Which prints 2
Correct me if I'm wrong. What I understand from this is that the encounter with yield pauses execution and waits for a value. The functionRef from setTimeout is placed on the stack and is called next, returning the value 2.
Essentially this is the same as
function *main() {
var x = yield ;
console.log(x);
}
var a = main();
a.next()
a.next(2)
Now I try to do the following, thinking the result will be the same:
function *main() {
var x = (yield a.next(2));
console.log(x)
}
var a = main();
a.next();
and it throws the error TypeError: Generator is already running
Why?
Further, I expected this to print 2 but instead in prints undefined
function *main() {
var x = yield 2;
console.log(x)
}
var a = main();
a.next()
a.next()
Evidently, yield behaves rather a bit differently when assigned to a variable versus when it is not, but I can't quite put a finger on it.

Can't access meteor lib helpers from client

I'm trying to understand meteorjs and have a little question.
I wanted to create a getDateTime helper and wanted this helper to be available on the client and the server.
I then inserted this code in lib/helpers
function getDateTime() {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth()+1;
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
if(month.toString().length == 1) {
var month = '0'+month;
}
if(day.toString().length == 1) {
var day = '0'+day;
}
if(hour.toString().length == 1) {
var hour = '0'+hour;
}
if(minute.toString().length == 1) {
var minute = '0'+minute;
}
if(second.toString().length == 1) {
var second = '0'+second;
}
var dateTime = year+'/'+month+'/'+day+' '+hour+':'+minute+':'+second;
return dateTime;
}
Unfortunately this function is not available ( "undefined" ) on the client.
When I look at the source, I can see it but it is encapsulated in:
(function(){ };
I don't quite understand why this is for.
What should I do to access the function?
Each .js file in a Meteor application is enclosed in an immediately-invoked function expression (function () { ... })() to prevent local variables from cluttering the global scope. To make that function accessible in other files, define it like this:
// note: no "var"
getDateTime = function () {
// ...
};

My first ExtendScript... and it doesn't work

I am developing a script for Adobe Bridge CS6. For the moment, all I want to do is to access the size (width and height) of a thumbnail that the user has selected and show it, either on a popup or on the console. Here is my script:
function TestBridge() {
this.requiredContext = "\tAdobe Bridge must be running.\n\tExecute against Bridge as the Target.\n";
}
TestBridge.prototype.run = function() {
if(!this.canRun())
{
return false;
}
var selectedThumbnails = app.document.getSelection();
if (selectedThumbnails.length > 0) {
$.writeln("MEEEEEPT");
var thumb = selectedThumbnails[0];
var x = thumb.core.preview.preview.width;
var y = thumb.core.preview.preview.height;
//alert('MEEEEEPT: x = ' + x + ', y = ' + y);
$.writeln("MEEEEEPT: x = " + x + ", y = " + y);
return true;
}
$.writeln("MOOO");
return false;
}
TestBridge.prototype.canRun = function()
{
// Must be running in Bridge & have a selection
if( (BridgeTalk.appName == "bridge") && (app.document.selectionLength == 1)) {
return true;
}
// Fail if these preconditions are not met.
// Bridge must be running,
// There must be a selection.
$.writeln("ERROR:: Cannot run.");
$.writeln(this.requiredContext);
return false;
}
The only problem is that... well, it doesnt work. I open it on ExtendScript Toolkit, set the target to Bridge CS6, hit "Run"... and all that happens is that the console says "Result: canRun()".
Looking at other code samples from Adobe, I see that the structure of their scripts is pretty much the same as mine, so I don't really know what I'm doing wrong.
Edit: what I needed was to add in the end a line to call the function, like so:
new.TestBridge.run();
Silly, silly mistake.

Switching sprites of a object in different rooms

I am creating a character selection which changes the sprites of the main character.
To do this I have an arrow object which the user clicks to change the sprite of the main character.
global.Mario = true;
global.PrincessPeach = false;
global.Luigi = false;
global.Bowser = false;
if (mouse_check_button_pressed(mb_left)) {
if (global.Mario = true) {
Mario = false;
PrincessPeach= true;
}
if (global.PrincessPeach= true) {
PrincessPeach = true;
Mario = false;
}
if (global.Luigi = true) {
Luigi = false;
Bowser = true;
}
if (global.Bowser = true) {
Bowser = false;
Mario = true;
}
}
Then, on my main character I have a created an event executing code similar to the following:
if (global.Mario = true) {
sprite_index = Mario_NotJumping;
}
if (global.Luigi = true) {
sprite_index = Luigispr;
}
However, when I run my game to test it out, I get the following error:
FATAL ERROR in
action number 1
of Create Event
for object Mario_selection:
Push :: Execution Error - Variable Get -5.Mario(100000, -1)
at gml_Object_Mario_selection_Create_0 (line 1) - if (global.Mario = true) {
The object Mario_selection has the exact create event and same code as the main character. To display changes to the user.
If anyone could help me out, I am fairly new to GameMaker so I have a feeling I'm just misunderstanding global variables.
It looks like the var global.Mario, has not been declared. In the arrow objects create event put,
global.Mario = true;
global.PrincessPeach = false;
global.Luigi = false;
global.Bowser = false;
If i were you, i would save the chosen "image" of the user in 1 simple variable.
Add a few constants;
PLAYER_MARIO = 0;
PLAYER_PEACH = 1;
PLAYER_LUIGI = 2;
PLAYER_BOWSER = 3;
Then you can use those constants and save them in a global variable;
global.player_image = PLAYER_LUIGI;
Then you can use those in your objects like so;
switch (global.player_image) {
case PLAYER_MARIO:
sprite_index = Mario_NotJumping;
break;
case PLAYER_PEACH:
sprite_index = Peach_NotJumping;
break;
case PLAYER_LUIGI:
sprite_index = Luigi_NotJumping;
break;
case PLAYER_BOWSER:
sprite_index = Bowser_NotJumping;
break;
}
The specific error you were getting was because the global variable was not defined at the time of use.
A better method by the way, would be something like this - saving all sprite handles into specific variables, then using those.
Define some constants for readability;
P_LEFT = 0;
P_RIGHT = 1;
P_JUMP = 2;
Then whenever a player switches its character;
//When the user switches to peach;
global.player_sprite[P_LEFT] = spr_Peach_Left;
global.player_sprite[P_RIGHT] = spr_Peach_Right;
global.player_sprite[P_JUMPING] = spr_Peach_Jumping;
And overwrite;
//When the user switches to Luigi;
global.player_sprite[P_LEFT] = spr_Luigi_Left;
global.player_sprite[P_RIGHT] = spr_Luigi_Right;
global.player_sprite[P_JUMPING] = spr_Luigi_Jumping;
Then you can code all code like this;
if (jumping) {
sprite_index = global.player_sprite[P_JUMPING];
} else {
sprite_index = global.player_sprite[P_LEFT];
}
Do you understand what i mean? This way you won't need the switch statements everywhere, and just store the chosen sprites in 1 single array at the beginning of the game.
You can then code the game without having to check what player image the player chose.
Also, always define global variables at the beginning of the game. Global variables will always exist in the game, in every room, at any given moment.
You should use var mario=true; instead.

Node.js: waiting for callbacks in a loop before moving on

I have a loop that has an asynchronous call inside it, with a callback. To be able to move on, I need the callback to fire for the entire loop all the way through, to then display the results of the loop.
Every way I've tried to control this doesn't work (have tried Step, Tame.js, async.js, and others) - any suggestions on how to move forward?
array = ['test', 'of', 'file'];
array2 = ['another', 'array'];
for(i in array) {
item = array[i];
document_ids = new Array();
for (i2 in array2) {
item2 = array2[i2];
// look it up
mongodb.find({item_name: item2}).toArray(function(err, documents {
// because of async,
// the code moves on and calls this back later
console.log('got id');
document_ids.push(document_id);
}))
}
// use document_ids
console.log(document_ids); // shows []
console.log('done');
}
// shows:
// []
// done
// got id
// got id
You're logging document_ids before your callbacks fire. You have to keep track of how many callbacks you've run to know when you're done.
An easy method is to use a counter, and to check the count on each callback.
Taking your example
var array = ['test', 'of', 'file'];
var array2 = ['another', 'array'];
var document_ids = [];
var waiting = 0;
for(i in array) {
item = array[i];
for (i2 in array2) {
item2 = array2[i2];
waiting ++;
mongodb.find({item_name: item2}).toArray(
function(err, document_id) {
waiting --;
document_ids.push(document_id);
complete();
})
);
}
}
function complete() {
if (!waiting) {
console.log(document_ids);
console.log('done');
}
}

Resources