#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;
}