I have a multiplayer Javascript game where the player is a circle, and is able shoot/"eject" circle bullets in the direction that the player is rotated. My code is working perfectly, except it shoots from the middle of the player. I would like it so that the circles are shot from the top right position of the player, where the gun is located. The issue is that when the players rotation changes, you cannot simply add (1, -1) to the position of the player.
Here is my code:
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
}
}
};
And here is an illustration of the current way it is working:
Assuming that the player (circle) is at its own local origin then the position of the gun is relative to the player's origin. Assuming the coordinate system is that of the canvas with forward along the x axis from left to right, and clockwise 90deg (left of player) is the Y axis going down.
Image: C is local circle origin (0,0) with Forward along the red arrow from C, Gx and Gy are the local coordinates of the gun from the circle center C. Top left shows the canvas coordinate (world) system origin. In code below, The
player
position is relative to that world origin. The final gunPos
is also give relative to the world coordinates. B vec is the bullets bullet.delta
vector
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;