我正在尝试制作一个双人坦克游戏,两个坦克使用键盘相互射击来控制它们。我有两个向前和向后的运动,但是当我尝试旋转它们时它也会旋转另一个。 (目前坦克只是矩形。)
如何在不移动另一个的情况下旋转一个?
var draw;
var context;
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;
function init() {
//canvas = document.getElementById('canvas');
context = $('#myCanvas')[0].getContext('2d'); //sets the canvas as a jquery object to the variable 'context'
WIDTH = $('#myCanvas').width();
HEIGHT = $('#myCanvas').height();
tank1_x = WIDTH * 1 / 4 - tank1_w / 2; //centre width TANK1
tank1_y = HEIGHT * 1 / 4 - tank1_h / 2; //centre height TANK1
tank2_x = WIDTH * 3 / 4 - tank2_w / 2; //centre width TANK2
tank2_y = HEIGHT * 3 /4 - tank2_h / 2; //centre height TANK2
setInterval('draw()', 25); //sets interval for draw method to repeat after
}
function clearCanvas() {
context.clearRect(0,0,WIDTH,HEIGHT); // clears whole canvas
}
tank1 = function fillRect(x,y,w,h) {
context.beginPath();
context.fillRect(WIDTH*1/4, HEIGHT*1/4, tank1_w, tank1_h);
context.endPath();
}
tank2 = function fillRect(x,y,w,h) {
context.beginPath();
context.fillRect(WIDTH*3/4, HEIGHT*3/4, tank2_w, tank2_h);
context.endPath();
}
draw = function() { // redraws rectangle to canvas
clearCanvas();
//TANK1 ROTATION
if (DKey) {
var buffer = document.createElement('canvas');
buffer.width = buffer.height = tank1_w*2;
var bctx = buffer.getContext('2d');
bctx.translate(tank1_x + tank1_w/2, tank1_y + tank1_h/2);
bctx.rotate(5*rad);
bctx.fillRect(tank1_x, tank1_y, tank1_w, tank1_h);
ctx.drawImage(buffer, tank1_x, tank1_y);
}
else if (AKey) {
context.save();
context.clearRect(WIDTH, HEIGHT);
context.translate(tank1_x + tank1_w/2, tank1_y + tank1_h/2); //http://www.williammalone.com/briefs/how-to-rotate-html5-canvas-around-center/ and StackOverflow
context.rotate(5*rad); //Translates origin of rotation to centre of block, then rotates 5 degrees
context.fillRect(tank1_x, tank1_y, tank1_w, tank1_h); //Redraw TANK1
context.rotate(-5*rad);
context.translate(-tank1_x - tank1_w/2, -tank1_y - tank1_h/2); //Translates origin of rotation back to top left of canvas
context.restore();
}
//TANK1 MOVEMENT
if (WKey) tank1_y -= 5;
else if (SKey) tank1_y += 5;
if (tank1_x <= 0) tank1_x = 0;
if ((tank1_x + tank1_w) >= WIDTH) tank1_x = WIDTH - tank1_w;
if (tank1_y <= 0) tank1_y = 0;
if ((tank1_y + tank1_h) >= HEIGHT) tank1_y = HEIGHT - tank1_h;
context.fillRect(tank1_x,tank1_y,tank1_w,tank1_h);
//TANK2 ROTATION
if(RightKey) {
context.translate(tank2_x + tank2_w/2, tank2_y + tank2_h/2);
context.rotate(5*Math.PI/180);
context.translate(-tank2_x - tank2_w/2, -tank2_y - tank2_h/2);
}
else if (LeftKey) {
context.translate(tank2_x + tank2_w/2, tank2_y + tank2_h/2);
context.rotate(-5*Math.PI/180);
context.translate(-tank2_x - tank2_w/2, -tank2_y - tank2_h/2);
}
//TANK2 MOVEMENT
if (UpKey) tank2_y -= 5;
else if (DownKey) tank2_y += 5;
if (tank2_x <= 0) tank2_x = 0;
if ((tank2_x + tank2_w) >= WIDTH) tank2_x = WIDTH - tank2_w;
if (tank2_y <= 0) tank2_y = 0;
if ((tank2_y + tank2_h) >= HEIGHT) tank2_y = HEIGHT - tank2_h;
context.fillRect(tank2_x,tank2_y,tank2_w,tank2_h);
}
function onKeyDown(event) {
//TANK1 (WASD Keys)
if (event.keyCode == 68) DKey = true;
else if (event.keyCode == 65) AKey = true;
if (event.keyCode == 87) WKey = true;
else if (event.keyCode == 83) SKey = true;
//TANK2 (Arrow Keys)
if (event.keyCode == 39) RightKey = true;
else if (event.keyCode == 37) LeftKey = true;
if (event.keyCode == 38) UpKey = true;
else if (event.keyCode == 40) DownKey = true;
}
function onKeyUp(event) {
//TANK1
if (event.keyCode == 68) DKey = false;
else if (event.keyCode == 65) AKey = false;
if (event.keyCode == 87) WKey = false;
else if (event.keyCode == 83) SKey = false;
//TANK2
if (event.keyCode == 39) RightKey = false;
else if (event.keyCode == 37) LeftKey = false;
if (event.keyCode == 38) UpKey = false;
else if (event.keyCode == 40) DownKey = false;
}
$(document).keydown(onKeyDown);
$(document).keyup(onKeyUp);
init();
});
我尝试过使用一个缓冲区并且对我不起作用,也没有清理然后旋转画布,重新绘制第一个坦克,然后向后旋转画布(让坦克旋转),然后重新绘制其余部分,因为它是。我不知道还能做什么。
目前我已经尝试了坦克1旋转中的缓冲区以及Tank2中的画布旋转。
感谢您提前提供任何帮助。
答案 0 :(得分:0)
存储坦克的绝对旋转并使用它而不是累积变换矩阵(只需将旋转角度添加/减去此值,f.ex a tank1_rotation
)。如果你保持它的相对性,你必须改变场景中的所有内容,这使得跟踪事物变得复杂。
旋转并绘制坦克后,此方法/更改将允许您只需调用以下内容即可控制所有内容:
context.setTransform(1,0,0,1,0,0);
这会将转换矩阵重置为初始状态,并且比使用保存/恢复快许多倍。
下次绘制水箱时,只需使用已存储的角度,绘制并重复上述步骤。
答案 1 :(得分: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();
}
感谢大家的帮助和建议