# [1.1.6] Overlap polygon problem in puzzle game

## Recommended Posts

I'm making a puzzle game with tetris-like blocks. You get a limited amount of different blocks and you have to cover a square-shaped board.

I defined polygons for every block-type in an array of objects:

`var blocksLibrary = [    {slug: '1', polygon: [0,0, 40,0, 40,120, 0,120]},    {slug: 'dash', polygon: [0,0, 80,0, 80,40, 0,40]},    {slug: 'dot', polygon: [0,0, 40,0, 40,40, 0,40]},    {slug: 'i', polygon: [0,0, 160,0, 160,40, 0,40]},    {slug: 'j', polygon: [40,0, 80,0, 80,120, 0,120, 0,80, 40,80]},    {slug: 'l', polygon: [0,0, 40,0, 40,80, 80,80, 80,120, 0,120]},    {slug: 'o', polygon: [0,0, 80,0, 80,80, 0,80]},    {slug: 'r', polygon: [0,0, 80,0, 80,40, 40,40, 40,80, 0,80]},    {slug: 's', polygon: [40,0, 120,0, 120,40, 80,40, 80,80, 0,80, 0,40, 40,40]},    {slug: 't', polygon: [0,0, 120,0, 120,40, 80,40, 80,80, 40,80, 40,40, 0,40]},    {slug: 'z', polygon: [0,0, 80,0, 80,40, 120,40, 120,80, 40,80, 40,40, 0,40]},];`

And then I generate them with such settings:

`// loop over all blocks for current stage// and create draggable and droppable blockscurrentStage.blocks.forEach(function (item) {    // increment the left position    left += leftInterval;    // create block in group    var block = blocks.create(left, 639, item);    block.name = item;    // change collision body to definded polygon    block.body.setPolygon(blocksLibraryLookup[item].polygon);    // make it draggable with enableDrag    // and parameters: lockCenter, bringToTop, pixelPerfect, alphaTreshold    block.inputEnabled = true;    block.input.enableDrag(false, true, true, 255);    // make it snappable with enableSnap    // and parameters: x, y, onDrag, onRelease    block.input.enableSnap(40, 40, false, true);    block.input.snapOffsetX = 352 + 2;    block.input.snapOffsetY = 200 + 2;});`

Then I make a square for every board square, to check if all of them are covered

`// create all squares for current boardfor (var a = 1; a <= boardHeight; a++) {    for (var b = 1; b <= boardWidth; b++) {        // create square sprite        var square = boardSquares.create(boardLeft + 40 * (b - 1), boardTop + 40 * (a - 1), 'blank-40');        square.name = 'square-' + b + '-' + a;        // change collision body to small rectangle        square.body.setRectangle(8, 8, 16, 16);    }}`

In the update function for game I trigger the overlap:

`game.physics.overlap(blocks, boardSquares, blocksOverlapHandler, null, this);`

But the problem is that the overlap is triggered for the whole sprite rectangle and not for the polygon. In the situation below, the overlap shouldn't be triggered, but it does:

I don't know why it's not working as I think it should :/ And maybe there is a better way to do this?

##### Share on other sites

I dug up an older topic with polygon-problem and learned that the polygons must be convex for the overlap to work properly.

So I changed my tactic and now the blocks elements are made out of draggable sprite without the overlap and the points-on-grid group that follows the sprite and has the overlap function applied to its children. Example code below.

Blocks library excerpt:

`var blocksLibrary = [    {        slug: 'j',        width: 2,        height: 3,        points: [[2,1],[2,2],[2,3],[1,3]]    },    {        slug: 'z',        width: 3,        height: 2,        points: [[1,1],[2,1],[2,2],[3,2]]    },];`

And the blocks creation excerpt:

`currentStage.blocks.forEach(function (item) {    // get object from library    var libraryItem = blocksLibraryLookup[item];    // increment the left position    left += leftInterval;    // create block in group    // with distinct name (thanks to count)    var block = blocks.create(left, 639, libraryItem.slug);    // create touch points group    // and set the position of it to the same as block    block.pointsGroup = game.add.group();    block.pointsGroup.x = block.x;    block.pointsGroup.y = block.y;    // create a sprite for each defined touch point    libraryItem.points.forEach(function (itemArray) {        // count the position for the point        // based on the position of parent block        var pointX = 40 * (itemArray[0] - 1);        var pointY = 40 * (itemArray[1] - 1);        var point = block.pointsGroup.create(pointX, pointY, 'blank-40');        // change collision body to small circle        point.body.setCircle(4, 20, 20);    });    // make it draggable with enableDrag    // and parameters: lockCenter, bringToTop, pixelPerfect    block.inputEnabled = true;    block.input.enableDrag(false, true, true);    // make it snappable with enableSnap    // and parameters: x, y, onDrag, onRelease    block.input.enableSnap(40, 40, false, true);    block.input.snapOffsetX = 352 + 2;    block.input.snapOffsetY = 200 + 2;    // on drag-stop fix location (outside of game world check)    // and move the points group accordingly    block.events.onDragStop.add(function (itemBlock) {        // wait for a secure 200 ms for the block to snap        setTimeout(function () {            fixLocation(itemBlock);            // move the points group with the block            itemBlock.pointsGroup.x = itemBlock.x;            itemBlock.pointsGroup.y = itemBlock.y;        }, 200);    });});`

Now the only thing left is to make some smart rotation.