Sign in to follow this  
01271

TypeError: rect is undefined

Recommended Posts

So I have several buttons for on-screen controls. I can add any combination of three buttons but as soon as I add a fourth one I get the error:

TypeError: rect is undefined
It's really weird because if I make each button say its bounds from inside I get the following:

Object { pos: Object, shapeType: "Rectangle", points: Array[4], edges: Array[4], normals: Array[4], _width: 48, _height: 48 }  entities.js:322:5
Object { pos: Object, shapeType: "Rectangle", points: Array[4], edges: Array[4], normals: Array[4], _width: 48, _height: 48 }  entities.js:322:5
Object { pos: Object, shapeType: "Rectangle", points: Array[4], edges: Array[4], normals: Array[4], _width: 48, _height: 48 }  entities.js:322:5
Object { pos: Object, shapeType: "Rectangle", points: Array[4], edges: Array[4], normals: Array[4], _width: 48, _height: 48 }  entities.js:322:5

and the pos is there and it's right.

Checking in-game it's right as well,

var abc = me.game.world.getChildByName('button')[3]
abc.getBounds()
Object { pos: Object, shapeType: "Rectangle", points: Array[4], edges: Array[4], normals: Array[4], _width: 48, _height: 48 }

pos is 100, 100.

Here's the stack trace:

TypeError: rect is undefined[Learn More]  melonjs.js:8890:13
	Quadtree.prototype.getIndex http://localhost:8000/lib/melonjs.js:8890:13
	Quadtree.prototype.insert http://localhost:8000/lib/melonjs.js:8993:25
	Quadtree.prototype.insertContainer http://localhost:8000/lib/melonjs.js:8949:25
	api.update http://localhost:8000/lib/melonjs.js:3814:21
	_renderFrame http://localhost:8000/lib/melonjs.js:13807:13

How and why is this happening?

Share this post


Link to post
Share on other sites

When I change the button Entity I made into a sprite and adapt a few things, the problem goes away. However the pointer events no longer work so that's not the best trade.

Share this post


Link to post
Share on other sites

swapping out with GUI_Object has the same error.

 

I'll post the button code now.

game.ControlButtonEntity = me.Entity.extend({

  init: function(x, y, settings) {
    settings.image = 'buttons';
    settings.width = 48;
    settings.height = 48;
    // settings.framewidth = 48;
    // settings.frameheight = 48;
    this._super(me.Entity, 'init', [x, y, settings]);
    this.renderable.addAnimation('up',[0]);
    this.renderable.addAnimation('right',[1]);
    this.renderable.addAnimation('down',[2]);
    this.renderable.addAnimation('left',[3]);
    this.renderable.addAnimation('A',[4]);
    this.renderable.addAnimation('B',[5]);
    this.renderable.addAnimation('inventory',[6]);
    this.renderable.addAnimation('exitInventory',[7]);
    this.renderable.addAnimation('C',[8]);
    this.renderable.addAnimation('D',[9]);
    this.alwaysUpdate = true;
    this.body.gravity = 0;
    this.buttonID = settings.buttonID;
    this.name = 'button';
    this.alwaysUpdate = true;
    this.body.collisionType = me.collision.types.NO_OBJECT;
    this.animationpause = true;
    // this.isPersistent = true;
    this.pushed = false;
    this.renderable.setCurrentAnimation(settings.buttonID);
    me.input.registerPointerEvent('pointerdown', this, this.startButtonPress.bind(this));
    me.input.registerPointerEvent('pointerup', this, this.endButtonPress.bind(this));
    me.input.registerPointerEvent('pointerleave', this, this.endButtonPress.bind(this));
    var buttonRegistry = {
        up : me.input.KEY.UP,
        down : me.input.KEY.DOWN,
        left : me.input.KEY.LEFT,
        right : me.input.KEY.RIGHT,
        inventory:me.input.KEY.E,
    };
    this.buttonCode = buttonRegistry[settings.buttonID];

  },
  startButtonPress: function() {

         me.input.triggerKeyEvent(this.buttonCode, true);
  },
  endButtonPress: function() {

         me.input.triggerKeyEvent(this.buttonCode, false);
  },

  update: function(dt) {
    if (this.pushed) {
    }
    // this.body.update(dt);
    return (this._super(me.Entity, 'update', [dt]) || true);
  },

});

If I have more than 3 of these on screen at once it breaks the game with the aforementioned error.

    // Add our HUD to the game world, add it last so that this is on top of the rest.
    // Can also be forced by specifying a "Infinity" z value to the addChild function.
    this.HUD = new game.HUD.Container();
    me.game.world.addChild(this.HUD);
    // me.game.world.addChild(me.pool.pull('textbox'));
    if (!game.hasAddedTextarea) {
      this.HUD.addChild(new game.gui.TextArea(0, 300, 960, 250));
      game.hasAddedTextarea = true;
    }

    vpw = me.game.viewport.getBounds().width;
    vph = me.game.viewport.getBounds().height;


    // multiples 48 96 144 192
    me.game.world.addChild(me.pool.pull('buttonEntity', vpw - 144, vph - 144, { buttonID: 'up' }));
    me.game.world.addChild(me.pool.pull('buttonEntity', vpw - 96, vph - 96, { buttonID: 'right' }));
    me.game.world.addChild(me.pool.pull('buttonEntity', vpw - 192, vph - 96, { buttonID: 'left' }));
    // me.game.world.addChild(me.pool.pull('buttonEntity', vpw - 144, vph - 96, { buttonID: 'down' 

 

Share this post


Link to post
Share on other sites

it's hard to understand with "just that" to be honest.... can you share how you declared your buttons, at least the constructor part ? did you use also the basic GUI_Object ? if you use me.Sprite then you have indeed to register on mouse event yourself (which is fine too, it all depends of what you need)

here below is how I defined buttons for the following example

https://github.com/melonjs/melonJS/tree/master/examples/UI/js/entities

more simple one from the platformer :

https://github.com/melonjs/melonJS/blob/master/examples/platformer/js/entities/HUD.js

hope this helps !

Share this post


Link to post
Share on other sites

No even with code for the buttons that's highly inspired by yours I don't have it working.

New button:

game.HUD.FSControl = me.GUI_Object.extend({
  init: function(x, y, settings) {
    settings.image = 'buttons';
    settings.framewidth = 48;
    settings.frameheight = 48;
    settings.width = 480;
    settings.height = 48;
    this._super(me.GUI_Object, "init", [x, y, settings]);
    this.name = 'button2';
    this.addAnimation('up', [0]);
    this.addAnimation('right', [1]);
    this.addAnimation('down', [2]);
    this.addAnimation('left', [3]);
    this.addAnimation('inventory', [6]);
    this.setCurrentAnimation(settings.buttonID);
    this.animationpause = true;
    var buttonRegistry = {
      up: me.input.KEY.UP,
      down: me.input.KEY.DOWN,
      left: me.input.KEY.LEFT,
      right: me.input.KEY.RIGHT,
      inventory: me.input.KEY.E,
    };
    this.buttonCode = buttonRegistry[settings.buttonID];

  },
  update: function() {
    if (this.updated) {
      if (!this.released) {
        me.input.triggerKeyEvent(this.buttonCode, true);
      } else {
        me.input.triggerKeyEvent(this.buttonCode, false);
      }
    }
  }
});

It's a pretty simple button, 20 lines shorter, but if I have one too many it breaks.

Share this post


Link to post
Share on other sites

I removed some of my entities from the screen and the problem stopped. Then I added more buttons and it started again. It's not the buttons doing it it's some kind of entity limit in general. Dang, that's even more complicated.

Share this post


Link to post
Share on other sites

that's weird indeed...

Not sure it will help, but the only reference to rect in the quadtree implementation is in the getIndex method (https://github.com/melonjs/melonJS/blob/master/src/physics/quadtree.js#L135), which means that somehow one object not defining `getBounds()` which means not inheriting at least from the me.Renderable class was added to the game world, and therefore to the quadtree. Which is even weirder since all objects from the game world are added through this function that filter those objects without a getBounds function. 

Share this post


Link to post
Share on other sites

Oh, learning that turned out to be very helpful.

I have a textarea that's beside the game and that's added to the world in the way that parasyte mentioned years ago in a github thread.

Since that one is added in a weird way I commented out the part where it's added to the world and started adding my buttons and a lot of enemies and things didn't break.

Turns out my problem is with a textarea rather than with buttons or enemies.

Go figure :V

 

Now I can focus on just this part. This is what it looks like by the way.

game.gui.TextArea = me.Renderable.extend({
  init: function() {
    this.textarea = document.createElement('textarea');
    this.textarea.id = 'textHistory';
    this.textarea.readOnly = "true";
    this.textarea.disabled = "true";
    me.video.getWrapper().appendChild(this.textarea);
    game.TextArea = this;
    var self = this;
    var videoPos = me.video.getPos();
    self.textarea.style = 'width:' + (window.innerWidth - videoPos.width) + 'px; height:' + videoPos.height + 'px;';
    this.isPersistent = true;

    me.event.subscribe(me.event.WINDOW_ONRESIZE, function() {
      var videoPos = me.video.getPos();
      self.textarea.style = 'width:' + (window.innerWidth - videoPos.width - 10) + 'px; height:' + videoPos.height + 'px;';
    });

  },
  addText: function(text) {
    this.textarea.innerHTML += '\n' + text;
  },
  clear: function() {
    this.textarea.innerHTML = '';
  },
  destroy: function() {},

  // update: function() {
  //   videoPos = me.video.getPos();
  //   this.textarea.style = 'width:' + (window.innerWidth - videoPos.width)  + 'px; height:' + videoPos.height + 'px;';
  // }
});

Shouldn't be hard to get this working. Ultimately it doesn't actually need to be managed by melonjs so I can remove it from the container outright if things get complicated.

Share this post


Link to post
Share on other sites

I see !!!! :):):)

Note that the only (major) thing you are missing in that object then is the call to the parent constructor, that would then initialise the bounding rect used by getBounds(), and also initialise a bunch of other internal properties, like the new `isKinematic` property introduced in melonJS 5.0 (which when If true disable physic collision and input events for this renderable), that would also prevent this kind of object to be added in the first place to the quad tree (since you do not need a text object to be reactive to neither physic nor pointer events).

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.