Jump to content

TypeError: rect is undefined


01271
 Share

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?

Link to comment
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' 

 

Link to comment
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 !

Link to comment
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.

Link to comment
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.

Link to comment
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. 

Link to comment
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.

Link to comment
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).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...