根据旋转角度计算新的圆偏移量?
Calculate new circle offset based on angle of rotation?
我有一个多人 Javascript 游戏,其中玩家是一个圆圈,并且可以在玩家旋转的方向上射击/"eject" 圆圈子弹。我的代码运行良好,除了它从播放器中间射击。我希望圆圈是从枪支所在的玩家右上角位置射击的。问题是当球员轮换发生变化时,你不能简单地将(1,-1)添加到球员的位置。
这是我的代码:
GameServer.prototype.ejectMass = function(client) {
for (var i = 0; i < client.cells.length; i++) {
var cell = client.cells[i]; // the player
var angle = this.toRad(client.rotation); // rotation of the player
var d = new Vec2(Math.sin(angle), Math.cos(-angle)).scale(-180);
var sq = (~~d.sqDist(d));
d.x = sq > 1 ? d.x / sq : 1;
d.y = sq > 1 ? d.y / sq : 0;
// cell.position is the players position
var pos = new Vec2(
cell.position.x + d.x * cell._size,
cell.position.y + d.y * cell._size
);
var ejected = 0;
// Create cell and add it to node list
ejected = new Entity.EjectedMass(this, null, pos, this.config.ejectSize * cell.ejectSize); // the bullet being shot
ejected.setBoostDefault(-this.config.ejectVelocity * cell.ejectSpeed, angle);
ejected.ejectedOwner = cell; // set the person who shot the bullet
this.addNode(ejected); // add the bullet into the game
if (typeof ejected !== 'undefined') {
setTimeout(this.removeNode.bind(this, ejected), 1000); // remove the ejected bullet after 1 second
}
}
};
这是当前工作方式的说明:
您没有提供有关布局的足够详细信息,例如 X 轴和 Y 轴的方向是什么? 0 angle
在哪里? angle
是顺时针还是逆时针?基本思想仍然是相同的。让我们假设 X 轴在右边,Y 轴在下,就像从您的附加图像中看到的那样,并添加 (1, -1) 以获得右上角。还假设 X 轴的 angle = 0
和 angle
是顺时针方向,即 angle = Pi/2
与 Y 轴的正方向对齐 = 向下。当枪指向上时,即 angle = -Pi/2
你的起点是 (1, -1)
,距离 sqrt(2)
并且另外旋转到 Pi/4
对应于枪的方向。这就是您需要知道的全部内容。
var angle = this.toRad(client.rotation); // rotation of the player
var gunStartAngle = angle + Math.PI/4;
var sqrt2 = Math.sqrt(2);
// cell.position is the players position
var pos = new Vec2(
cell.position.x + cell._size * sqrt2 * Math.cos(gunStartAngle),
cell.position.y + cell._size * sqrt2 * Math.sin(gunStartAngle)
);
显然,如果您的布局不同,您应该修正数学的细节,但想法保持不变。
假设玩家(圆圈)位于其自己的本地原点,那么枪支的位置是相对于玩家原点的。假设坐标系是canvas的坐标系,从左到右沿x轴向前,顺时针90度(玩家左侧)是Y轴向下。
图片:C 是局部圆原点 (0,0),Forward 沿红色箭头从 C, Gx 和 Gy 是枪从圆心的局部坐标C。左上角显示 canvas 坐标(世界)系统原点。在下面的代码中,player
位置是相对于那个世界原点的。最后的 gunPos
也是相对于世界坐标的。 B vec是子弹bullet.delta
向量
const bulletSpeed = 10;
var gunPos = {x : 10, Y : 10} // ten units forward ten units left of circle center
var player = {rotation : ?, x : ?, y : ?} // unknown player position and rotation
// get the unit vector of the rotated x axis. Along player forward
var xAx = Math.cos(player.rotation);
var xAy = Math.sin(player.rotation);
// transform the gunpos to absolute position (world coordinates) of rotated player
var rotatedGunPos = {};
rotatedGunPos.x = gunPos.x * xAx - gunPos.y * xAy + player.x;
rotatedGunPos.y = gunPos.x * xAy + gunPos.y * xAx + player.y;
// and fire the bullet from
var bullet = {}
bullet.x = rotatedGunPos.x;
bullet.y = rotatedGunPos.y;
// bullet vector is
bullet.deltaX = xAx * BULLET_SPEED;
bullet.deltaY = xAy * BULLET_SPEED;
我有一个多人 Javascript 游戏,其中玩家是一个圆圈,并且可以在玩家旋转的方向上射击/"eject" 圆圈子弹。我的代码运行良好,除了它从播放器中间射击。我希望圆圈是从枪支所在的玩家右上角位置射击的。问题是当球员轮换发生变化时,你不能简单地将(1,-1)添加到球员的位置。
这是我的代码:
GameServer.prototype.ejectMass = function(client) {
for (var i = 0; i < client.cells.length; i++) {
var cell = client.cells[i]; // the player
var angle = this.toRad(client.rotation); // rotation of the player
var d = new Vec2(Math.sin(angle), Math.cos(-angle)).scale(-180);
var sq = (~~d.sqDist(d));
d.x = sq > 1 ? d.x / sq : 1;
d.y = sq > 1 ? d.y / sq : 0;
// cell.position is the players position
var pos = new Vec2(
cell.position.x + d.x * cell._size,
cell.position.y + d.y * cell._size
);
var ejected = 0;
// Create cell and add it to node list
ejected = new Entity.EjectedMass(this, null, pos, this.config.ejectSize * cell.ejectSize); // the bullet being shot
ejected.setBoostDefault(-this.config.ejectVelocity * cell.ejectSpeed, angle);
ejected.ejectedOwner = cell; // set the person who shot the bullet
this.addNode(ejected); // add the bullet into the game
if (typeof ejected !== 'undefined') {
setTimeout(this.removeNode.bind(this, ejected), 1000); // remove the ejected bullet after 1 second
}
}
};
这是当前工作方式的说明:
您没有提供有关布局的足够详细信息,例如 X 轴和 Y 轴的方向是什么? 0 angle
在哪里? angle
是顺时针还是逆时针?基本思想仍然是相同的。让我们假设 X 轴在右边,Y 轴在下,就像从您的附加图像中看到的那样,并添加 (1, -1) 以获得右上角。还假设 X 轴的 angle = 0
和 angle
是顺时针方向,即 angle = Pi/2
与 Y 轴的正方向对齐 = 向下。当枪指向上时,即 angle = -Pi/2
你的起点是 (1, -1)
,距离 sqrt(2)
并且另外旋转到 Pi/4
对应于枪的方向。这就是您需要知道的全部内容。
var angle = this.toRad(client.rotation); // rotation of the player
var gunStartAngle = angle + Math.PI/4;
var sqrt2 = Math.sqrt(2);
// cell.position is the players position
var pos = new Vec2(
cell.position.x + cell._size * sqrt2 * Math.cos(gunStartAngle),
cell.position.y + cell._size * sqrt2 * Math.sin(gunStartAngle)
);
显然,如果您的布局不同,您应该修正数学的细节,但想法保持不变。
假设玩家(圆圈)位于其自己的本地原点,那么枪支的位置是相对于玩家原点的。假设坐标系是canvas的坐标系,从左到右沿x轴向前,顺时针90度(玩家左侧)是Y轴向下。
player
位置是相对于那个世界原点的。最后的 gunPos
也是相对于世界坐标的。 B vec是子弹bullet.delta
向量
const bulletSpeed = 10;
var gunPos = {x : 10, Y : 10} // ten units forward ten units left of circle center
var player = {rotation : ?, x : ?, y : ?} // unknown player position and rotation
// get the unit vector of the rotated x axis. Along player forward
var xAx = Math.cos(player.rotation);
var xAy = Math.sin(player.rotation);
// transform the gunpos to absolute position (world coordinates) of rotated player
var rotatedGunPos = {};
rotatedGunPos.x = gunPos.x * xAx - gunPos.y * xAy + player.x;
rotatedGunPos.y = gunPos.x * xAy + gunPos.y * xAx + player.y;
// and fire the bullet from
var bullet = {}
bullet.x = rotatedGunPos.x;
bullet.y = rotatedGunPos.y;
// bullet vector is
bullet.deltaX = xAx * BULLET_SPEED;
bullet.deltaY = xAy * BULLET_SPEED;