Canvas 在画布中旋转而不移动所有其他对象?

Canvas 在画布中旋转而不移动所有其他对象?,canvas,rotation,Canvas,Rotation,我正在尝试制作一个两人坦克游戏,两辆坦克用键盘控制彼此射击。我有向前和向后两种运动,但当我试着旋转它们时,它也会旋转另一个。(目前,油箱只是矩形的。) 如何旋转其中一个而不移动另一个 var绘制; var语境; var-DKey=false; var-AKey=false; var-WKey=false; var-SKey=false; var tank1_x; var tank1_y; var tank1_w=30; var tank1_h=30; var-UpKey=false; var D

我正在尝试制作一个两人坦克游戏,两辆坦克用键盘控制彼此射击。我有向前和向后两种运动,但当我试着旋转它们时,它也会旋转另一个。(目前,油箱只是矩形的。)

如何旋转其中一个而不移动另一个

var绘制;
var语境;
var-DKey=false;
var-AKey=false;
var-WKey=false;
var-SKey=false;
var tank1_x;
var tank1_y;
var tank1_w=30;
var tank1_h=30;
var-UpKey=false;
var DownKey=false;
var RightKey=false;
var LeftKey=false;
var tank2_x;
var tank2_y;
var tank2_w=30;
var tank2_h=30;
var rad=Math.PI/180;
函数init(){
//canvas=document.getElementById('canvas');
context=$('#myCanvas')[0]。getContext('2d');//将画布设置为变量“context”的jquery对象
宽度=$('#myCanvas')。宽度();
高度=$('#myCanvas')。高度();
槽1_x=宽度*1/4-槽1_w/2;//中心宽度槽1
油箱1_y=高度*1/4-油箱1_h/2;//油箱1的中心高度
槽2_x=宽度*3/4-槽2_w/2;//中心宽度槽2
储罐2_y=高度*3/4-储罐2_h/2;//储罐2的中心高度
setInterval('draw()',25);//设置draw方法在之后重复的间隔
}
函数clearCanvas(){
clearRect(0,0,宽度,高度);//清除整个画布
}
tank1=函数fillRect(x,y,w,h){
context.beginPath();
context.fillRect(宽度*1/4,高度*1/4,油箱1_w,油箱1_h);
endPath();
}
tank2=函数fillRect(x,y,w,h){
context.beginPath();
context.fillRect(宽度*3/4,高度*3/4,油箱2_w,油箱2_h);
endPath();
}
draw=function(){//将矩形重绘到画布
clearCanvas();
//坦克1轮换
如果(DKey){
var buffer=document.createElement('canvas');
buffer.width=buffer.height=tank1_w*2;
var bctx=buffer.getContext('2d');
bctx.translate(油箱1_x+油箱1_w/2,油箱1_y+油箱1_h/2);
bctx.旋转(5*rad);
bctx.fillRect(油箱1_x、油箱1_y、油箱1_w、油箱1_h);
ctx.drawImage(缓冲区、槽1_x、槽1_y);
}
否则,如果(AKey){
context.save();
clearRect(宽度、高度);
上下文翻译(tank1_x+tank1_w/2,tank1_y+tank1_h/2)//http://www.williammalone.com/briefs/how-to-rotate-html5-canvas-around-center/ 和堆栈溢出
context.rotate(5*rad);//将旋转原点转换为块的中心,然后旋转5度
context.fillRect(tank1_x,tank1_y,tank1_w,tank1_h);//重新绘制tank1
旋转(-5*rad);
translate(-tank1_x-tank1_w/2,-tank1_y-tank1_h/2);//将旋转原点转换回画布的左上角
restore();
}
//坦克1运动
如果(WKey)储罐1_y-=5;
否则,如果(SKey)油箱1_y+=5;
如果(油箱1_x=宽度)油箱1_x=宽度-油箱1_w;
如果(油箱1_y=高度)油箱1_y=高度-油箱1_h;
context.fillRect(tank1_x、tank1_y、tank1_w、tank1_h);
//坦克2轮换
如果(右键){
翻译(tank2_x+tank2_w/2,tank2_y+tank2_h/2);
旋转(5*Math.PI/180);
翻译(-tank2_x-tank2_w/2,-tank2_y-tank2_h/2);
}
else if(LeftKey){
翻译(tank2_x+tank2_w/2,tank2_y+tank2_h/2);
旋转(-5*Math.PI/180);
翻译(-tank2_x-tank2_w/2,-tank2_y-tank2_h/2);
}
//坦克2运动
如果(向上键)油箱2_y-=5;
否则,如果(向下键)油箱2_y+=5;
如果(储罐2_x=宽度)储罐2_x=宽度-储罐2_w;
如果(储罐2_y=高度)储罐2_y=高度-储罐2_h;
context.fillRect(tank2_x、tank2_y、tank2_w、tank2_h);
}
函数onKeyDown(事件){
//坦克1(WASD钥匙)
如果(event.keyCode==68)DKey=true;
如果(event.keyCode==65)AKey=true,则为else;
如果(event.keyCode==87)WKey=true;
如果(event.keyCode==83)SKey=true,则为else;
//坦克2(箭头键)
如果(event.keyCode==39)RightKey=true;
如果(event.keyCode==37)LeftKey=true,则为else;
如果(event.keyCode==38)UpKey=true;
如果(event.keyCode==40)DownKey=true,则为else;
}
函数onKeyUp(事件){
//坦克1
如果(event.keyCode==68)DKey=false;
如果(event.keyCode==65)AKey=false,则为else;
如果(event.keyCode==87)WKey=false;
如果(event.keyCode==83)SKey=false,则为else;
//坦克2
如果(event.keyCode==39)RightKey=false;
如果(event.keyCode==37)LeftKey=false,则为else;
如果(event.keyCode==38)UpKey=false;
如果(event.keyCode==40)DownKey=false,则为else;
}
$(文档).keydown(onKeyDown);
$(文件).keyup(onKeyUp);
init();
});
我试过使用一个缓冲区,但这对我来说不起作用,清理后旋转画布,重画第一个水箱,然后再旋转画布(所以水箱旋转),然后重画其余的水箱。我不知道还能做什么

目前,我已经得到了我在坦克1的旋转中尝试的缓冲区和坦克2的画布旋转

感谢您提前提供的帮助。

存储油箱的绝对旋转,并使用此值而不是累积变换矩阵(只需将旋转角度添加/减去此值即可,f.ex a
tank1\u旋转
)。如果保持相对,则必须相对变换场景中的所有内容,这使得跟踪事物变得复杂

旋转并绘制油箱后,此方法/更改将允许您只需调用以下命令即可检查所有内容:

context.setTransform(1,0,0,1,0,0);
这会将转换矩阵重置为初始状态,并且比使用“保存/还原”快很多倍


下次绘制坦克时,只需使用存储的角度,绘制并重复上述操作。

尝试这些操作后,我发现最简单的方法(我是一名数学学生)是手动绘制坦克的所有点,并使用矩阵相应地旋转每个点

drawTank1 = function(x, y, w, h) {
    cos1 = Math.cos(tank1_angle);
    sin1 = Math.sin(tank1_angle);
    var centre_x = tank1_x;
    var centre_y = tank1_y;
    var corner1_x = - 20 * cos1 - 20 * sin1 + centre_x;
    var corner1_y = 20 * sin1 - 20 * cos1 + centre_y;
    var corner2_x = - 20 * cos1 + 20 * sin1 + centre_x;
    var corner2_y = 20 * sin1 + 20 * cos1 + centre_y;
    var corner3_x = 20 * cos1 + 20 * sin1 + centre_x;
    var corner3_y = - 20 * sin1 + 20 * cos1 + centre_y;
    var corner4_x = 20 * cos1 - 20 * sin1 + centre_x;
    var corner4_y = - 20 * sin1 - 20 * cos1 + centre_y;
    var corner5_x = 5 * cos1 - 20 * sin1 + centre_x;
    var corner5_y = - 5 * sin1 - 20 * cos1 + centre_y;
    var corner6_x = 5 * cos1 - 30 * sin1 + centre_x;
    var corner6_y = - 5 * sin1 - 30 * cos1 + centre_y;
    var corner7_x = - 5 * cos1 - 30 * sin1 + centre_x;
    var corner7_y = 5 * sin1 - 30 * cos1 + centre_y;
    var corner8_x = - 5 * cos1 - 20 * sin1 + centre_x;
    var corner8_y = 5 * sin1 - 20 * cos1 + centre_y;
    context.beginPath();
    context.fillStyle = '#00FF00';
    context.moveTo(corner1_x, corner1_y);
    context.lineTo(corner2_x, corner2_y);
    context.lineTo(corner3_x, corner3_y);
    context.lineTo(corner4_x, corner4_y);
    context.lineTo(corner5_x, corner5_y);
    context.lineTo(corner6_x, corner6_y);
    context.lineTo(corner7_x, corner7_y);
    context.lineTo(corner8_x, corner8_y);
    context.lineTo(corner1_x, corner1_y);
    context.closePath();
    context.fill();
    context.stroke();
}
Th
drawTank1 = function(x, y, w, h) {
    cos1 = Math.cos(tank1_angle);
    sin1 = Math.sin(tank1_angle);
    var centre_x = tank1_x;
    var centre_y = tank1_y;
    var corner1_x = - 20 * cos1 - 20 * sin1 + centre_x;
    var corner1_y = 20 * sin1 - 20 * cos1 + centre_y;
    var corner2_x = - 20 * cos1 + 20 * sin1 + centre_x;
    var corner2_y = 20 * sin1 + 20 * cos1 + centre_y;
    var corner3_x = 20 * cos1 + 20 * sin1 + centre_x;
    var corner3_y = - 20 * sin1 + 20 * cos1 + centre_y;
    var corner4_x = 20 * cos1 - 20 * sin1 + centre_x;
    var corner4_y = - 20 * sin1 - 20 * cos1 + centre_y;
    var corner5_x = 5 * cos1 - 20 * sin1 + centre_x;
    var corner5_y = - 5 * sin1 - 20 * cos1 + centre_y;
    var corner6_x = 5 * cos1 - 30 * sin1 + centre_x;
    var corner6_y = - 5 * sin1 - 30 * cos1 + centre_y;
    var corner7_x = - 5 * cos1 - 30 * sin1 + centre_x;
    var corner7_y = 5 * sin1 - 30 * cos1 + centre_y;
    var corner8_x = - 5 * cos1 - 20 * sin1 + centre_x;
    var corner8_y = 5 * sin1 - 20 * cos1 + centre_y;
    context.beginPath();
    context.fillStyle = '#00FF00';
    context.moveTo(corner1_x, corner1_y);
    context.lineTo(corner2_x, corner2_y);
    context.lineTo(corner3_x, corner3_y);
    context.lineTo(corner4_x, corner4_y);
    context.lineTo(corner5_x, corner5_y);
    context.lineTo(corner6_x, corner6_y);
    context.lineTo(corner7_x, corner7_y);
    context.lineTo(corner8_x, corner8_y);
    context.lineTo(corner1_x, corner1_y);
    context.closePath();
    context.fill();
    context.stroke();
}