Array of objects & functions

Hi there, first of, english is not my native language so i apoligize if i' making some mistakes, then, in a minigame that i am building w/ the p5.js library, i want to use this array :

 bonuses_array = [
   { name: "Paddle_size +", type: "Bonus", status: false, effect: addPSize(), duration: 30, graphic: Paddle_size_plus()},
   { name: "Paddle_speed +", type: "Bonus", status: false, effect: addPSpeed(), duration: 30, graphic: Paddle_speed_plus()},
   { name: "Ball_speed -", type: "Bonus", status: false, effect: reduceBSpeed(), duration: 30, graphic: Ball_speed_minus()},
   { name: "Paddle_size -", type: "Malus", status: false, effect: reducePSize(), duration: 30, graphic: Paddle_size_minus()},
   { name: "Paddle_speed -", type: "Malus", status: false, effect: reducePSpeed(), duration: 30,graphic: Paddle_speed_minus()},
   { name: "Ball_speed +", type: "Malus", status: false, effect: addBSpeed(), duration: 30, graphic: Ball_speed_plus()},
   { name: "Ball_size -", type: "Malus", status: false, effect: reduceBSize(), duration: 30, graphic: Ball_size_minus()},
  ]

All the functions are defined somewhere else, and the thing i want to achieve is to be able to call bonuses_array[value].graphic(x, y). But it seems that the functions are not defined the right way... Can someone help me ? Thanks !! Ali

Answers

  • edited May 2017 Answer ✓

    It can be done...

    In your array, change the functions names to strings:

    effect: "addPSize",
    

    Then you can use method() to call them:

    method( bonuses_array[value].effect );
    

    The trouble is passing in parameters. One way would be to put them in some globals, then call method(), then have the called function check the globals.

    But really, this is not the best way to do things. Instead, I suggest you write a bonuses_effects() function:

    void bonuses_effect(int type){
      switch(type){
        case 0: addPSize(x,y); break;
        case 1: addPSpeed(x,y); break;
        // etc...
      }
    }
    
    // And then call:
    bonuses_effect(value);
    

    And do similarly for graphics.

  • Answer ✓
    String function_to_call = "doit";
    int num;
    
    void setup(){
      size(200,200);
      num = 8;
      method(function_to_call);
    }
    
    void draw(){}
    
    void doit(){
      println("did it, Result: " + num);
    }
    
  • edited May 2017
    • Doing OOP in JS using regular {} objects is a tad convoluted & messy IMO. 8-|
    • Like in Java, Python, etc., OOP is better organized by defining a class for each "entity": ~O)
      https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class
    • Take a look at my code below, which defines 2 classes: Paddle & Ball. :\">
    • It's just a mock code. You still need to modify it to your specific needs of course: #:-S

    // forum.Processing.org/two/discussion/22783/array-of-objects-functions#Item_3
    // GoToLoop (2017-May-27)
    
    "use strict";
    
    class Paddle {
      constructor(x=width/2-30, y=height-20, vel=1, w=60, h=15, colour=0xff) {
        this.x = x, this.y = y, this.spd = vel;
        this.w = w, this.h = h, this.c = colour;
        this.duration = 30, this.status = false;
      }
    
      display() {
        fill(this.c).rect(this.x, this.y, this.w, this.h);
      }
    
      move(dir=0) {
        this.x += this.spd * dir;
      }
    }
    
    class Ball {
      constructor(x=width/2-5, y=height-25, vx=1, vy=-1, rad=10, colour=0o300) {
        this.x = x, this.y = y;
        this.vx = vx, this.vy = vy;
        this.r = rad, this.c = colour;
        this.duration = 30, this.status = false;
      }
    
      display() {
        fill(this.c).ellipse(this.x, this.y, this.r << 1);
      }
    
      update() {
        this.x += this.vx;
        this.y += this.vy;
      }
    
      bounce() {
        const { x, y, r } = this;
        if (x > width  - r || x < r)  this.x += this.vx *= -1;
        if (y > height - r || y < r)  this.y += this.vy *= -1;
      }
    
      circleToRectCollision(o) {
        const { x, y, r } = this;
        return ; // Not implemented yet!
      }
    }
    
  • Well thanks TfGuy44 for your quick answer, i guess i'll try it that way (i'm using p5.js though, so i'll have to find a way to adapt it) !

    GoToLoop, ofc i made classes for my objects (balls, paddles and such) but in this i was trying something new, and the array i showed earlier seemed to be a good way to store all these informations, because setting up an object for each "bonus" wasn't what i saw as the best idea, but as i do it to train and learn, there are of course tons of things i am not aware of and that's why i'm here asking for help :)

    Anyway thanks both of you for aswering, i guess i have a little bit of work to do ! :)

  • Answer ✓

    @Alivanar - TfGuy's suggestion will work in JS - and is in fact simpler to implement since you don't need to wrap the callback with method():

    var foo = function(bar) {
      console.log(bar);
    };
    var bar = function() {
      return "baaa";
    }
    
    var myArray = [{ id: "fee", effect : foo },
                    {id : "fi", effect: foo},
                    {id: "fo", effect: foo},
                    {id : "fum", effect: foo, value: bar()}];
    
    myArray.forEach(function(el){
      el.effect(el.id);
    });
    
    // compared to:
    console.log(myArray[3].value);
    

    The point is that with the functionName() you're immediately calling the function and assigning any return value to the property; but without the brackets you're passing a reference to the function - which can then later be called.

    The above example is obviously somewhat spurious - as they all call the same function...

  • So based on TFGuy's suggestion i used the "switch" method, with every case depending on the value, and it seem to work perfectly fine !! :D Thanks Blindfish for the answer, this is totally what i was looking for when i posted the question, i did not knew how to then call the function, but now i see :) I'll keep that in mind for my next project :p

Sign In or Register to comment.