——————————————————————————————
How do I rotate the gun (the gray rectangle) around the player toward the current mouse position? (preferably using vectors or Math.atan2()) Vanila Js
I have tried but it doesn't stay on the player and doesn't rotate toward the mouse position.
Here is the code:
"use strict"
/**
* @type { HTMLCanvasElement }
*/
var scene = document.getElementById("scene");
var ctx = scene.getContext("2d");
scene.width = 1024;
scene.height = 576;
var vWidth = scene.width;
var vHeight = scene.height;
var mouseX = 0;
var mouseY = 0;
var friction = 0.15;
var keysDown = [];
class Player {
constructor(x, y, width, height, color, borderColor = "#000000") {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.borderColor = borderColor;
this.velX = 0;
this.velY = 0;
this.maxSpeed = 5;
this.name = null;
this.angle = 0;
}
}
var walls = [
];
function createWall(x, y, width, height, color = "#000000", id = "") {
walls.push({
x: x,
y: y,
width: width,
height: height,
color: color,
id: id
});
}
function drawGrid(startX, startY, endX, endY, gridCellSize = 50) {
ctx.beginPath();
ctx.lineWidth = 1;
for (var x = startX; x <= endX; x += gridCellSize) {
ctx.moveTo(x, startY);
ctx.lineTo(x, endY);
}
for (var y = startY; y <= endY; y += gridCellSize) {
ctx.moveTo(startX, y);
ctx.lineTo(endX, y);
}
ctx.strokeStyle = "#dedede";
ctx.stroke();
ctx.closePath();
}
var player = new Player(-25, -25, 50, 50, "#ff0000", "#cc0000");
friction = 1 - friction;
scene.width = vWidth;
scene.height = vHeight;
const updateSpeed = 60;
function main() {
if (player.x < -1000) {
player.x = -1000;
player.velX = 0;
}
if (player.y < -1000) {
player.y = -1000;
player.velY = 0;
}
if (player.x + player.width > 1000) {
player.x = 1000 - player.width;
player.velX = 0;
}
if (player.y + player.height > 1000) {
player.y = 1000 - player.height;
player.velY = 0;
}
if (keysDown["w"] || keysDown["ArrowUp"]) {
if (player.velY > player.maxSpeed * -1) {
player.velY--;
}
}
if (keysDown["a"] || keysDown["ArrowLeft"]) {
if (player.velX > player.maxSpeed * -1) {
player.velX--;
}
}
if (keysDown["s"] || keysDown["ArrowDown"]) {
if (player.velY < player.maxSpeed) {
player.velY++;
}
}
if (keysDown["d"] || keysDown["ArrowRight"]) {
if (player.velX < player.maxSpeed) {
player.velX++;
}
}
player.velX *= friction;
player.velY *= friction;
player.x += player.velX;
player.y += player.velY;
ctx.save();
ctx.translate(-player.x - player.width / 2 + vWidth / 2, -player.y - player.height / 2 + vHeight / 2);
// ctx.translate(player.velX, player.velY);
ctx.clearRect(0, 0, vWidth, vHeight);
ctx.beginPath();
ctx.strokeStyle = "#000000";
ctx.fillStyle = "#dedede";
ctx.rect(-2000, -2000, 4000, 4000);
ctx.fill();
// ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle = "#000000";
ctx.fillStyle = "#ffffff";
ctx.rect(-1000, -1000, 2000, 2000);
ctx.fill();
// ctx.stroke();
ctx.closePath();
drawGrid(-1000, -1000, 1000, 1000, 25);
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.lineJoin = "round";
// Make this rectangle rotate around the player pointing toward the mouse position
ctx.save();
ctx.beginPath();
ctx.rotate(player.angle);
ctx.fillStyle = "#cccccc";
ctx.strokeStyle = "#808080";
ctx.roundRect(player.x + player.width / 2, player.y + player.height / 2 - 10, player.height - 5, 20, 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.beginPath();
ctx.strokeStyle = player.borderColor;
ctx.fillStyle = player.color;
ctx.roundRect(player.x, player.y, player.width, player.height, 50);
ctx.fill();
ctx.stroke();
ctx.closePath();
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
ctx.fillStyle = wall.color;
ctx.fillRect(wall.x, wall.y, wall.width, wall.height);
}
ctx.restore();
requestAnimationFrame(main);
}
window.onload = function () {
// setInterval(main, 1000 / updateSpeed);
main();
}
scene.onclick = function () {
scene.requestFullscreen();
}
document.body.addEventListener("keydown", (e) => {
keysDown[e.key] = true;
});
document.body.addEventListener("keyup", (e) => {
keysDown[e.key] = false;
});
document.body.addEventListener("mousemove", (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
player.angle = Math.atan2(mouseY, mouseX);
});
*, *:before, *:after {
font-family: roboto, Arial, Helvetica, sans-serif, system-ui, 'Courier New', Courier, monospace;
padding: 0px 0px;
margin: 0px 0px;
box-sizing: border-box;
}
#scene {
height: 100vh;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2D</title>
</head>
<body>
Use WASD Or Arrow Keys To Move.
<canvas id="scene"></canvas>
</body>
</html>
Figured out this one awhile back, but I decided to answer it here in case anyone else has the similar problem.
Here it is:
"use strict"
/**
* @type { HTMLCanvasElement }
*/
var scene = document.getElementById("scene");
var ctx = scene.getContext("2d");
scene.width = window.innerWidth;
scene.height = window.innerHeight;
var vWidth = window.innerWidth;
var vHeight = window.innerHeight;
var mouseX = 0;
var mouseY = 0;
var friction = 0.15;
var keysDown = [];
class Player {
constructor(x, y, radius, color, borderColor = "#000000") {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.borderColor = borderColor;
this.velX = 0;
this.velY = 0;
this.maxSpeed = 5;
this.name = null;
this.angle = 0;
}
}
var walls = [];
function createWall(x, y, width, height, color = "#000000", id = "") {
walls.push({
x: x,
y: y,
width: width,
height: height,
color: color,
id: id
});
}
function drawGrid(startX, startY, endX, endY, gridCellSize = 50) {
ctx.beginPath();
ctx.lineWidth = 1;
for (var x = startX; x <= endX; x += gridCellSize) {
ctx.moveTo(x, startY);
ctx.lineTo(x, endY);
}
for (var y = startY; y <= endY; y += gridCellSize) {
ctx.moveTo(startX, y);
ctx.lineTo(endX, y);
}
ctx.strokeStyle = "#dedede";
ctx.stroke();
ctx.closePath();
}
var player = new Player(0, 0, 25, "#ff0000", "#cc0000");
friction = 1 - friction;
scene.width = vWidth;
scene.height = vHeight;
const updateSpeed = 60;
function main() {
if (keysDown["w"] || keysDown["ArrowUp"]) {
if (player.velY > player.maxSpeed * -1) {
player.velY--;
}
}
if (keysDown["a"] || keysDown["ArrowLeft"]) {
if (player.velX > player.maxSpeed * -1) {
player.velX--;
}
}
if (keysDown["s"] || keysDown["ArrowDown"]) {
if (player.velY < player.maxSpeed) {
player.velY++;
}
}
if (keysDown["d"] || keysDown["ArrowRight"]) {
if (player.velX < player.maxSpeed) {
player.velX++;
}
}
player.velX *= friction;
player.velY *= friction;
player.x += player.velX;
player.y += player.velY;
ctx.save();
ctx.translate(-player.x + vWidth / 2, -player.y + vHeight / 2);
// ctx.translate(player.velX, player.velY);
ctx.clearRect(0, 0, vWidth, vHeight);
ctx.beginPath();
ctx.strokeStyle = "#000000";
ctx.fillStyle = "#dedede";
ctx.rect(-2000, -2000, 4000, 4000);
ctx.fill();
// ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle = "#000000";
ctx.fillStyle = "#ffffff";
ctx.rect(-1000, -1000, 2000, 2000);
ctx.fill();
// ctx.stroke();
ctx.closePath();
drawGrid(-1000, -1000, 1000, 1000, 25);
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.save();
ctx.beginPath();
ctx.translate(player.x, player.y);
ctx.rotate(player.angle);
ctx.fillStyle = "#cccccc";
ctx.strokeStyle = "#808080";
ctx.roundRect(0, -10, player.radius * 2, 20, 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.beginPath();
ctx.strokeStyle = player.borderColor;
ctx.fillStyle = player.color;
ctx.arc(player.x, player.y, player.radius, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.closePath();
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
ctx.fillStyle = wall.color;
ctx.fillRect(wall.x, wall.y, wall.width, wall.height);
}
ctx.restore();
requestAnimationFrame(main);
}
window.onload = function() {
// setInterval(main, 1000 / updateSpeed);
main();
}
document.body.addEventListener("keydown", (e) => {
keysDown[e.key] = true;
});
document.body.addEventListener("keyup", (e) => {
keysDown[e.key] = false;
});
document.body.addEventListener("mousemove", (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
player.angle = Math.atan2(e.clientY - vHeight / 2, e.clientX - vWidth / 2);
});
window.addEventListener("resize", (e) => {
vWidth = window.innerWidth;
vHeight = window.innerHeight;
scene.width = vWidth;
scene.height = vHeight;
});
*,
*:before,
*:after {
font-family: roboto, Arial, Helvetica, sans-serif, system-ui, 'Courier New', Courier, monospace;
padding: 0px 0px;
margin: 0px 0px;
box-sizing: border-box;
}
#scene {
height: 100vh;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2D</title>
</head>
<body>
<canvas id="scene"></canvas>
</body>
</html>