繁体   English   中英

如何旋转画布矩形数组

[英]How to rotate an array of canvas rectangles

我正在为正在参加的班级的最后一个项目创建Pentomino益智游戏。 我已经创建了所有所需的拼图碎片,并且可以将它们拖到这里 而且我尝试了以下代码旋转数组(不使用canvas.rotate()并位于提琴的最底部),在绘制新片段时,它基本上交换了X和Y坐标:

var newPiece = targetPiece;
pieces.splice(pieces.indexOf(targetPiece), 1);
targetPiece = null;
console.log(newPiece);
var geometry = [];
for (var i = 0; i < newPiece.geometry.length; i++) {
    geometry.push([newPiece.geometry[i][3], newPiece.geometry[i][0]]);
}
var offset = [newPiece.offset[1], newPiece.offset[0]];
console.log(geometry);
console.log(offset);
newPiece.geometry = geometry;
newPiece.position = geometry;
newPiece.offset = offset;
pieces.push(newPiece);
console.log(pieces);
for (var j = 0; j < pieces.length; j++) {
    draw(pieces[j]);
}

这不能正常工作,但是很有希望。

这个小提琴中 ,我将问题分解为单个片段,并尝试使用canvas.rotate()通过双击旋转数组,但实际上是在旋转数组的每个片段(我认为),由于数组的每个块都只是一个50x50的矩形,并且旋转一个正方形时,它仍然看起来像一个正方形,因此什么也不会发生。

function doubleClickListener(e) {
var br = canvas.getBoundingClientRect();
mouse_x = (e.clientX - br.left) * (canvas.width / br.width);
mouse_y = (e.clientY - br.top) * (canvas.height / br.height);
var pieceToggle = false;
for (var i = 0; i < pieces.length; i++) {
    if (onTarget(pieces[i], mouse_x, mouse_y)) {
        targetPiece = pieces[i];
        rotate(targetPiece);
    }
}
}

function rotate() {
targetPiece.rotationIndex = targetPiece.rotationIndex === 0 ?
1 : targetPiece.rotationIndex === 1 ?
2 : targetPiece.rotationIndex === 2 ?
3 : 0;
for (var j = 0; j < pieces.length; j++) {
    draw(pieces[j]);
}
}

仅供参考,我曾尝试将拼图块创建为单独的多边形,但无法弄清楚如何通过mousedown事件捕获它并通过mousemove移动它,因此我将其抛弃为相对容易抓取和绘制的画布矩形数组。移动。

有一个蛮力的解决方案,和一个完全重写的解决方案,我都希望避免这两个方案(我已经接近最后期限了)。 蛮力解决方案是为所有可能的零件创建几何形状(旋转和镜像),这需要为12个零件创建63个单独的几何变形并管理这些状态。 重写将使用fabric.js (在类结束后我可能会这样做,因为我想拥有一个功能齐全的难题)。

我想做的是双击双击旋转五个块的数组(不管连续旋转90°,它走哪条路)。


解决一个可用的难题:

@absolom的大量帮助 ,这就是我所拥有的,您可以单击鼠标并拖动,通过双击来旋转作品,并通过右键单击来镜像作品(嗯,大部分情况下,它实际上不会旋转直到您下一个动作为止,我正在努力)。 作品的Z顺序受到操纵,因此您要使用的作品始终位于最上面(它必须是数组中的最后一个作品才能出现在所有其他作品的顶部):

戊糖二


最终的解决方案

我刚刚将游戏进行了评分,感谢所有帮助! 还有很多要做的调整,并且如果我重写它,我仍然会有一些改变,但是我对结果感到非常满意。

戊糖最终

快速与肮脏:

快速而肮脏的解决方案是,当组装2件以上的零件时,您可以使用内存中的画布创建它们的单个图像。 这样,您可以将2张成1张图片作为单个实体移动/旋转。

更合适:

如果稍后必须拆卸2件以上的部件,则您将需要更正确的方式来保持每件的变形状态。 更为合适的方法是为每个片段分配一个转换矩阵。

Stackoverflow贡献者Ken Fyrstenberg(K3N)已编写了一个不错的脚本,该脚本可让您使用变换矩阵跟踪单个多边形(例如,矩形): https : //github.com/epistemex/transformation-matrix-js

这段代码能满足您的需求吗? 现在,rotate方法如下所示:

   function rotate(piece) {
       for (i = 0; i < piece.geometry.length; i++) {
           var x = piece.geometry[i][0];
           var y = piece.geometry[i][2];
           piece.geometry[i][0] = -y;
           piece.geometry[i][3] = x;
       }
       drawAll();
   }

我还简化了如何处理几何和定位。 它并不完美,但是可以为您提供一些有关如何处理问题的提示。

请注意,此解决方案之所以有效,是因为每一块都是由相同颜色的块组成,并且您的旋转角度为90度。 我只移动块来模拟旋转,但是本质上没有旋转。 如果您以不同的方式构建零件,或者需要以不同的角度旋转,则需要采用其他方法,例如变换矩阵。

UPDATE

这是一个更好的解决方案: 提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM