Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for hit function leads to 'too many recursion" #1185

Open
mitija opened this issue Jun 30, 2018 · 2 comments
Open

Documentation for hit function leads to 'too many recursion" #1185

mitija opened this issue Jun 30, 2018 · 2 comments

Comments

@mitija
Copy link

mitija commented Jun 30, 2018

The documentation for the hit function (http://craftyjs.com/api/Collision.html#-hit) provides an example, which I have found may lead to the game entering an infinite recursion if two events are triggered at the same time.

Here is a fix (on a simplified example):

Crafty.e('2D, DOM, Color, Fourway, Collision')
    .attr({ x:0, y:0, w:32, h:32})
    .color('#F00')
    .fourway()
    .bind('Move', function(evt) {
        if (this.hit('wall')) {
            this.x = this.lastOKPosition.x;
            this.y = this.lastOKPosition.y;
        }
        else {
            this.lastOKPosition = {x: this.x, y: this.y};
        }
    });

This relies on the last know OK position, instead of the event position which may also be in collision with 'wall'. I suggest updating the official documentation so that people don't get stuck with this bug.

For information I am working with Firefox

@starwed
Copy link
Member

starwed commented Jun 30, 2018

So the issue is this block?

if (hitData.type === 'SAT') { // SAT, advanced collision resolution
  // move player back by amount of overlap
  this.x -= hitData.overlap * hitData.nx;
  this.y -= hitData.overlap * hitData.ny;
} 

Where backing out the entity by just the amount necessary to end the first collision can cause a second collision?

@mitija
Copy link
Author

mitija commented Jul 1, 2018

No I haven't tried the hitData of type SAT. I have only tried MBR. The issue is with this code:

{ // MBR, simple collision resolution
            // move player to previous position
            this.x = evt._x;
            this.y = evt._y;
}

From what I understand, I got the error when I was pressing both key 'arrow down' and 'arrow left' at the same time, while my entity was just above another item of type wall.

This triggered twice the 'Move' event, one for the key down - which would place the entity one down inside the wall in x0, y0+1, and then one for the key left which would position the entity to x0-1, y0+1. When Crafty would handle the second event, it would position back the entity to x0, y0+1, which is still within the wall; hence the infinite loop. I hope it's clear!

The code which causes the infinite loop is this one:

Crafty.init(500,350, document.getElementById('game'));
Crafty.e('2D, DOM, Color, Fourway, Collision')
    .attr({ x:0, y:0, w:32, h:32})
    .color('#F00')
    .fourway()
    .bind('Move', function(evt) {
        if (this.hit('wall')) {
            this.x = evt._x;
            this.y = evt._y;
        }
    });

Crafty.e('2D, DOM, Color, wall')
    .attr({ x: 200, y:200, w: 100, h:20 })
    .color('#555');

If you run it, you can trigger the bug by hitting the wall while pressing both 'down' and 'left' arrows keys at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants