如何在画布上追踪粘贴者的路径

How to track path of stickman on canvas?

本文关键字:路径 追踪      更新时间:2023-09-26

如果我要移动我的贴纸,我想跟踪它。但是,由于我的贴纸是一堆线,我相信我能做到这一点的唯一方法是检查某些像素是否具有特定颜色。有没有更好的方法来跟踪我的粘贴工在画布上的位置?有人告诉我,如果我的坚持者是一个对象,我的目标会更容易实现。也就是说,我认为我的stickman已经是object literal类型了。任何帮助都将不胜感激,谢谢!

stickman = {head: [200, 200, 10,0,  2*Math.PI ],
body: [195, 210, 178, 250],
rightArm: [192,215,200,230,210,230],
leftArm: [192,215,178 ,222,178,230],
rightLeg: [178, 250,190,260,185,275,192, 275],
leftLeg: [178, 250, 168, 260, 155, 262,153, 268]
} ;
function costume1(){
context.strokeStyle =  "rgb(0,0,0)";
context.beginPath();
//head
context.arc(stickman.head[0], stickman.head[1], stickman.head[2], stickman.head[3], stickman.head[4]);
//body
context.moveTo(stickman.body[0],stickman.body[1]);
context.lineTo(stickman.body[2],stickman.body[3]);
//right arm
context.moveTo(stickman.leftArm[0],stickman.leftArm[1]);
context.lineTo(stickman.leftArm[2] ,stickman.leftArm[3]);
context.lineTo(stickman.leftArm[4], stickman.leftArm[5]);
//left arm
context.moveTo(stickman.rightArm[0], stickman.rightArm[1]);
context.lineTo(stickman.rightArm[2], stickman.rightArm[3]);
context.lineTo(stickman.rightArm[4] , stickman.rightArm[5]);
//left leg
context.moveTo(stickman.rightLeg[0], stickman.rightLeg[1]);
context.lineTo(stickman.rightLeg[2],stickman.rightLeg[3]);
context.lineTo(stickman.rightLeg[4] , stickman.rightLeg[5]);
context.lineTo(stickman.rightLeg[6], stickman.rightLeg[7]);

//right leg
context.moveTo(stickman.leftLeg[0], stickman.leftLeg[1]);
context.lineTo(stickman.leftLeg[2], stickman.leftLeg[3]);
context.lineTo(stickman.leftLeg[4], stickman.leftLeg[5]);
context.lineTo(stickman.leftLeg[6] , stickman.leftLeg[7]);
context.stroke();
}

你是对的,你确实创建了一个stickman对象。但是,如果你想移动/跟踪你的坚持者,最好用一个中心点来定义各个部位(头部、身体等)——例如,你可以使用他的头部中心。然后要移动/跟踪粘贴者,你所需要做的就是更新这些中心点。粘人的其他部分也会跟着走。

以下是我的意思:

// set up a stickman, with a starting x and y
var Stickman = function(x, y) {
  this.update(x, y);
}
// anytime you need to know the new positions for the
// stickman, call .update(newCenterX, newCenterY)
Stickman.prototype.update = function(x, y) {
  this.centerX = x;
  this.centerY = y;
  this.head = [this.centerX, this.centerY, 10,0,  2*Math.PI ]
  this.body = [
    this.centerX-5,
    this.centerY+10,
    this.centerX-22,
    this.centerY+50
  ]
  this.rightArm = [ ];
  this.leftArm = [ ];
  // etc...
}
// here is how to make a new stickman
var man1 = new Stickman(200, 200);
// and move him!
console.log(man1.body);
man1.update(210, 200);
console.log(man1.body);`

希望能有所帮助!(我可能没有得到正确的偏移:-)

您通常使用context.translate将固定坐标标尺移动到不同的位置。

// move the context origin 100px rightward
context.translate(100,0);
// redraw the stickman (it will be 100px rightward of the original)
costume1();

但是,如果你真的想要一个版本的stickman,将你的原始固定坐标更改为新的"移动"固定坐标,你可以将你的初始stickman发送到一个转换函数中,为你更改坐标。

为了更容易追踪任何一个顽固分子,添加一个x:&CCD_ 3属性分配给每个stickman,其指示该stickman如何偏移X&偏离原来的坚持者Y。

以下是示例代码和演示:

var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
stickman = {
    x:0,y:0,
    head: [200, 200, 10,0,  2*Math.PI ],
    body: [195, 210, 178, 250],
    rightArm: [192,215,200,230,210,230],
    leftArm: [192,215,178 ,222,178,230],
    rightLeg: [178, 250,190,260,185,275,192, 275],
    leftLeg: [178, 250, 168, 260, 155, 262,153, 268]
} ;
// draw original stickman
costume1(stickman,'black');
// move the stickman's x,y
stickman.x=-50;
stickman.y=-50;
// get the coordinates of the translated stickman
var stickman1={ x:stickman.x, y:stickman.y };
translateStickman(stickman,stickman1);
// draw the moved stickman1
costume1(stickman1,'red');
function costume1(stickman,strokecolor){
// move the canvas origin to the stickman's x,y
context.translate(stickman.x,stickman.y);
context.strokeStyle = strokecolor;
context.beginPath();
//head
context.arc(stickman.head[0], stickman.head[1], stickman.head[2], stickman.head[3], stickman.head[4]);
//body
context.moveTo(stickman.body[0],stickman.body[1]);
context.lineTo(stickman.body[2],stickman.body[3]);
//right arm
context.moveTo(stickman.leftArm[0],stickman.leftArm[1]);
context.lineTo(stickman.leftArm[2] ,stickman.leftArm[3]);
context.lineTo(stickman.leftArm[4], stickman.leftArm[5]);
//left arm
context.moveTo(stickman.rightArm[0], stickman.rightArm[1]);
context.lineTo(stickman.rightArm[2], stickman.rightArm[3]);
context.lineTo(stickman.rightArm[4] , stickman.rightArm[5]);
//left leg
context.moveTo(stickman.rightLeg[0], stickman.rightLeg[1]);
context.lineTo(stickman.rightLeg[2],stickman.rightLeg[3]);
context.lineTo(stickman.rightLeg[4] , stickman.rightLeg[5]);
context.lineTo(stickman.rightLeg[6], stickman.rightLeg[7]);
//right leg
context.moveTo(stickman.leftLeg[0], stickman.leftLeg[1]);
context.lineTo(stickman.leftLeg[2], stickman.leftLeg[3]);
context.lineTo(stickman.leftLeg[4], stickman.leftLeg[5]);
context.lineTo(stickman.leftLeg[6] , stickman.leftLeg[7]);
context.stroke();
// always clean up, unto the last translate 
//    == move the canvas origin back to 0,0
context.translate(-stickman.x,-stickman.y);
}
// create a new stickman with moved coordinates
function translateStickman(stickman,trxStickman){
    var x=stickman1.x;
    var y=stickman1.y;
    var translate=function(a){
        for(var i=0;i<a.length;i+=2){
            a[i]+=x;
            a[i+1]+=y;
        }
    }
    trxStickman.head=stickman.head.slice();
    trxStickman.body=stickman.body.slice();
    trxStickman.rightArm=stickman.rightArm.slice();
    trxStickman.leftArm=stickman.leftArm.slice();
    trxStickman.rightLeg=stickman.rightLeg.slice();
    trxStickman.leftLeg=stickman.leftLeg.slice();
    trxStickman.head[0]+=x;
    trxStickman.head[1]+=y;
    translate(trxStickman.body);
    translate(trxStickman.rightArm);
    translate(trxStickman.leftArm);
    translate(trxStickman.rightLeg);
    translate(trxStickman.leftLeg);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h4>Black == original stickman, Red == moved stickman</h4>
<canvas id="canvas" width=300 height=300></canvas>