Sign in to follow this  
megamaster

Dynamic function calling

Recommended Posts

So while working on a card game I ran into an issue calling a function for a specific card. I have an array that is randomly shuffled. From that array I want to call the variable and the appropriate sprite for it. In addition, I want to call a function when that specific card is clicked on.

This is what I have so far:

function create() {
    //creating array
    cardarray = shuffle(cardarray);
    cardarray[0] = game.add.sprite(80, 60, 'card'+'cardarray[0]');
    cardarray[0].inputEnabled = true;
    cardarray[0].events.onInputDown.add(toString('cardarray[0]'+'effects', this);
   
}

function card1effects() {
    //whatever function does
}

I don't know the proper syntax for calling a function with a variable that depends on an array.

Thanks

Share this post


Link to post
Share on other sites

use higher-order function
insert a parameter on your function

function cardEffects(index) {...}

call it like this:

cardarray[index].events.onInputDown.add(
   function() {
      cardEffects(index);
   },
   this);

EDIT: I removed index from function() {...}

Share this post


Link to post
Share on other sites

Thanks for the quick response. However, I'm still not sure if I understand how the higher functions work. What I want are defined function names that can be called based on the variable that is selected from an array. The problem is my array is shuffled, so cardarray[0] does not always correspond to the function cardEffects1

What you have suggested works, but I don't see how to make "function(index)" and "cardEffects(index)" refer to the actual variable I am working with. Can you explain your call method to me? (I'm still a programming beginner)

I thought the simplest way to do this would be to pass var card1, which has a string value of cardEffects1, for the function name in the onInputDown.add. Unfortunately that doesn't work because it doesn't recognize it as a function name.

var cardarray = [card1,card2,card3]

 

Share this post


Link to post
Share on other sites

You wouldn't want to declare a function for each card. That's why you include parameter. Instead of card1Effects up to let's say card53Effects, just use cardEffects(index). Index would refer to an integer.

Unfortunately, you cannot specify parameters on onInputDown.add so you enclose your function on another one.

function create() {
    //creating array
    cardarray = shuffle(cardarray);

    for(var i = 0; i < cardarray.length; i++) {
        var card = cardarray[i];
        card = game.add.sprite(80, 60, 'card' + i);
        card = inputEnabled = true;
        card.events.onInputDown.add(
            function() {
                cardEffects(i);
            }, this);
    }   
}

function cardEffects(index) {
   // code
}

 

Share this post


Link to post
Share on other sites
Quote

Unfortunately, you cannot specify parameters on onInputDown.add so you enclose your function on another one.

 


 

I think you can.  The first parameter is the callback, the second the context, the third the signal priority (usually set as 0), next is your own parameter.

Pretty sure this is the order but I'm on my phone so haven't looked at the docs.

Share this post


Link to post
Share on other sites

Thanks for the help s6reinan. I made some tweaks to your advice and came up with the following code:

var card1 = 1
var card2 = 2
var card3 = 3
var cardarray = [card1,card2,card3]

function create() {
    //creating array
    cardarray = shuffle(cardarray);    
    cardarray = cardarray.splice(0,5);
    var card = [];
    for(var i = 0; i < cardarray.length; i++) {
        card[i] = cardarray[i];
        //console.log(cardarray[0])
        //console.log(chip[0])
        card[i] = game.add.sprite(0, 0, 'card' + card[i]);
        card[i].inputEnabled = true;
        card[i].events.onInputDown.add(
        function() {
                cardEffects(cardarray[i]);
            }, this);
    }   

function cardEffects(index) {
    if (index==1) {
    //some operation
    }
    if (index==2) {
    //some operation
    }
    if (index==3) {
    //some operation
    }
    else if () {
    }
}

 

I am still having trouble with the on click events. Each rendered image is clickable but the parameter of the index is not sent to the cardEffects function.

So, when I click on the sprite nothing happens even though the parameter must make one of the statements true. Do you know why this is?

Share this post


Link to post
Share on other sites
var myArray = [];
function doStuff(arr){
  for (var i=0; i< 3; i++){
    arr[i] = function(){
      console.log(i);
    }
  }
}
doStuff(myArray);
myArray[0]();
//3
myArray[1]();
//3

//fix with ES6 let
function doStuffImproved(arr){
  for(let k=0;k < 3; k++){
    arr[k] = function(){
      console.log(k);
    }
  }
}
doStuffImproved(myArray);
myArray[0]();
//0
myArray[1]();
//1

//fix with forEach
function doStuffOther(arr){
  return arr.forEach(function(el,l){
    console.log(l);
  }
}
doStuffOther(myArray);
myArray[0]();
//0
myArray[1]();
//1

//fix with closure
//etc

You need to learn a little bit more javascript to avoid these types of errors.

Share this post


Link to post
Share on other sites

Right, I'm still trying to figure everything out. I had to program in matlab for a college class, but javascript has many of its own commands as well.

Thanks for letting me know about ES6 let! I think that has done the trick

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.