如何在画布上追踪火柴人的路径?

时间:2016-05-10 19:27:28

标签: javascript canvas

如果我要移动它,我想跟踪我的火柴人。然而,因为我的火柴人是一堆线,我相信我能做到这一点的唯一方法是检查某些像素是否具有某种颜色。有没有更好的方法来跟踪我的火柴人在画布上的位置?有人告诉我,如果我的火柴人是一个物体,我的目标将更容易达到。也就是说,我认为我的火柴人已经是类型对象文字了。任何帮助将不胜感激,谢谢!

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();
}

2 个答案:

答案 0 :(得分:2)

你是对的 - 你确实创造了一个火柴人对象。但是如果你想移动/跟踪你的火柴人,最好用单个中心点来定义部件(头部,身体等) - 例如你可以使用他的头部中心。然后移动/跟踪火柴人,您需要做的就是更新这些中心点。然后火柴人的其他部分将随之而来。

以下是我的意思:

// 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);`

希望有所帮助! (我可能没有正确的补偿:-))

答案 1 :(得分:1)

您通常使用context.translate将固定坐标火柴人移动到其他位置。

// move the context origin 100px rightward
context.translate(100,0);

// redraw the stickman (it will be 100px rightward of the original)
costume1();

但是如果你真的想要一个版本的火柴人,你的原始固定坐标改为新的“移动”固定坐标,你可以将你的原始火柴人发送到一个改变坐标的转换函数。

要更轻松地跟踪任何火柴人,请添加x:&每个火柴人的y:属性,表明这个火柴人是如何抵消的 - 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>