подключите линию к машине в canvas

#javascript #html #canvas #rotation #matrix-multiplication

#javascript #HTML #canvas #поворот #матрица-умножение

Вопрос:

 var car;
var front;
var back;
var carpoint1;
var carpoint2;
var carpoint3;
var carpoint4;
var img = new Image();
img.src = 'https://cdn4.iconfinder.com/data/icons/transportation-2-4/60/transportation-2-flat-036-racing-car-top-512.png';


function startGame() {
    car = new move(12, 20, "red", 600, 300);
    pg.start();
}

var pg = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 1200;
        this.canvas.height = 600;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateframe, 20);
        window.addEventListener('keydown', function (e) {
            e.preventDefault();
            pg.keys = (pg.keys || []);
            pg.keys[e.keyCode] = (e.type == "keydown");
        })
        window.addEventListener('keyup', function (e) {
            pg.keys[e.keyCode] = (e.type == "keydown");
        })
    },
    stop : function() {
        clearInterval(this.interval);
    },    
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}

function move(width, height, color, x, y, type) {

    this.type = type;
    this.width = width;
    this.height = height;
    this.speed = 0;
    this.angle = 0;
    this.moveAngle = 0;
    this.x = x;
    this.y = y;    
    this.update = function() {
        ctx = pg.context;
        ctx.save();

		getcarpoints(this.x, this.y, this.angle);
        ctx.translate(this.x, this.y);
        ctx.rotate(this.angle);
		ctx.drawImage(img, this.width / -2, this.height / -2,20,40);	

		ctx.restore();
		ctx.beginPath();
		ctx.moveTo(300, 150);
		ctx.lineTo(600, 800);
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(300, 150);
		ctx.lineTo(carpoint1[0], carpoint1[1]);
		ctx.stroke();
    }
    this.newPos = function() {
        this.angle  = this.moveAngle * Math.PI / 180;
        this.x  = this.speed * Math.sin(this.angle);
        this.y -= this.speed * Math.cos(this.angle);

    }
}

function getcarpoints(prex,prey,rotation)
{
	carpoint1=[getrotatedx(prex,prey,rotation), getrotatedy(prex,prey,rotation)];
	carpoint2=[carpoint1[0], carpoint1[1] 40];
	carpoint3=[carpoint2[0] 20, carpoint2[1] 40];
	carpoint4=[carpoint3[0] 20, carpoint3[1]];
//	console.log(carpoint1[0]);
}
function getrotatedx(prex,prey,rotation)
{
	piangle=Math.abs((rotation/ Math.PI * 180)%360);
	newx=Math.cos(piangle)*prex (-(Math.sin(piangle)*prey));
	return newx;
}
function getrotatedy(prex,prey,rotation)
{
	piangle=Math.abs((rotation/ Math.PI * 180)%360);
	newy=Math.sin(piangle)*prex (Math.cos(piangle)*prey);
	return newy;
}

function updateframe() {
    pg.clear();
    car.moveAngle = 0;
    car.speed = 0;
    if (pg.keys amp;amp; pg.keys[37]) { if (pg.keys amp;amp; pg.keys[40]) {car.moveAngle= 5; } if (pg.keys amp;amp; pg.keys[38]){car.moveAngle = -5; } }
    if (pg.keys amp;amp; pg.keys[39]) { if (pg.keys amp;amp; pg.keys[40]) {car.moveAngle= -5; } if (pg.keys amp;amp; pg.keys[38]){car.moveAngle = 5; } }
    if (pg.keys amp;amp; pg.keys[38]) {car.speed= 5; }
    if (pg.keys amp;amp; pg.keys[40]) {car.speed= -5; }
    car.newPos();
    car.update();
}  
 <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
    border:1px solid #d3d3d3;
    background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">

<script src="control.js"></script>
</body>
</html>  

Вот мой полный код в виде фрагмента. Я пытаюсь провести линию от одной точки фиксации до машины … и в этом проблема.

Теперь, когда она горизонтальна в любой точке x, она работает идеально, но в момент поворота автомобиля угол меняется, и все портится! вы можете видеть, что при повороте машины (используйте стрелку и стрелку влево или вправо одновременно) линия прыгает.

Примечание: в моем проекте требуется сделать это с помощью 2d матрицы вращения, что означает, что я не могу создать линию до восстановления canvas.

точки carpoint1, 2, 3, 4 — это углы car, но прямо сейчас я просто работаю с точкой carpoint1.

Сделайте что-нибудь, чтобы getrotatedx и getrotatedy всегда выдавали правильное значение, которое является координатами машины после поворота матрицы.

Ответ №1:

Используйте ctx.lineTo(this.x, this.y); вместо ctx.lineTo(carpoint1[0], carpoint1[1]);

 var car;
var front;
var back;
var carpoint1;
var carpoint2;
var carpoint3;
var carpoint4;
var img = new Image();
img.src = 'https://cdn4.iconfinder.com/data/icons/transportation-2-4/60/transportation-2-flat-036-racing-car-top-512.png';


function startGame() {
    car = new move(12, 20, "red", 600, 300);
    pg.start();
}

var pg = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 1200;
        this.canvas.height = 600;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateframe, 20);
        window.addEventListener('keydown', function (e) {
            e.preventDefault();
            pg.keys = (pg.keys || []);
            pg.keys[e.keyCode] = (e.type == "keydown");
        })
        window.addEventListener('keyup', function (e) {
            pg.keys[e.keyCode] = (e.type == "keydown");
        })
    },
    stop : function() {
        clearInterval(this.interval);
    },    
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}

function move(width, height, color, x, y, type) {

    this.type = type;
    this.width = width;
    this.height = height;
    this.speed = 0;
    this.angle = 0;
    this.moveAngle = 0;
    this.x = x;
    this.y = y;    
    this.update = function() {
        ctx = pg.context;
        ctx.save();

		getcarpoints(this.x, this.y, this.angle);
        ctx.translate(this.x, this.y);
        ctx.rotate(this.angle);
		ctx.drawImage(img, this.width / -2, this.height / -2,20,40);	

		ctx.restore();
		ctx.beginPath();
		ctx.moveTo(300, 150);//fixed point
		ctx.lineTo(600, 800);
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(300, 150);
		ctx.lineTo(this.x, this.y);
		ctx.stroke();
    
    }
    this.newPos = function() {
        this.angle  = this.moveAngle * Math.PI / 180;
        this.x  = this.speed * Math.sin(this.angle);
        this.y -= this.speed * Math.cos(this.angle);

    }
}

function getcarpoints(prex,prey,rotation)
{
	carpoint1=[getrotatedx(prex,prey,rotation), getrotatedy(prex,prey,rotation)];
	carpoint2=[carpoint1[0], carpoint1[1] 40];
	carpoint3=[carpoint2[0] 20, carpoint2[1] 40];
	carpoint4=[carpoint3[0] 20, carpoint3[1]];
//	console.log(carpoint1[0]);
}
function getrotatedx(prex,prey,rotation)
{
	piangle=Math.abs((rotation/ Math.PI * 180)%360);
	newx=Math.cos(piangle)*prex (-(Math.sin(piangle)*prey));
	return newx;
}
function getrotatedy(prex,prey,rotation)
{
	piangle=Math.abs((rotation/ Math.PI * 180)%360);
	newy=Math.sin(piangle)*prex (Math.cos(piangle)*prey);
	return newy;
}

function updateframe() {
    pg.clear();
    car.moveAngle = 0;
    car.speed = 0;
    if (pg.keys amp;amp; pg.keys[37]) { if (pg.keys amp;amp; pg.keys[40]) {car.moveAngle= 5; } if (pg.keys amp;amp; pg.keys[38]){car.moveAngle = -5; } }
    if (pg.keys amp;amp; pg.keys[39]) { if (pg.keys amp;amp; pg.keys[40]) {car.moveAngle= -5; } if (pg.keys amp;amp; pg.keys[38]){car.moveAngle = 5; } }
    if (pg.keys amp;amp; pg.keys[38]) {car.speed= 5; }
    if (pg.keys amp;amp; pg.keys[40]) {car.speed= -5; }
    car.newPos();
    car.update();
}


startGame()  
 canvas {
    border:1px solid #d3d3d3;
    background-color: #f1f1f1;
}