smutnyleszek Posted March 3, 2014 Share Posted March 3, 2014 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? Link to comment Share on other sites More sharing options...
smutnyleszek Posted March 4, 2014 Author Share Posted March 4, 2014 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. Link to comment Share on other sites More sharing options...
Recommended Posts