How do I shoot bullets from my Player X and Y towards the mouse x and y?
I can find the angle of the mouse X and Y but I have no idea how to create a bullet which will fly towards the mouse.
The code for the mouse coordinates are (dx, dy).
Also, if you could explain the logic behind what you did and how you did it, I would be greatful.
Thanks!
Fiddle
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var pressingDown = false;
var pressingUp = false;
var pressingLeft = false;
var pressingRight = false;
var mouseX, mouseY;
function Player(x, y) {
this.x = x;
this.y = y;
this.angle;
}
Player.prototype.draw = function() {
context.save();
context.translate(this.x, this.y);
context.rotate(this.angle);
context.beginPath();
context.fillStyle = "green";
context.arc(0, 0, 30, 0, 2 * Math.PI);
context.fill();
context.fillStyle = "red";
context.fillRect(0, -10, 50, 20);
context.restore();
}
Player.prototype.update = function(mouseX, mouseY) {
var dx = mouseX - this.x;
var dy = mouseY - this.y;
this.angle = Math.atan2(dy, dx);
}
canvas.addEventListener('mousemove', mouseMove);
function mouseMove(evt) {
mouseX = evt.x;
mouseY = evt.y;
}
var player = new Player(350, 250);
function updatePlayer() {
context.clearRect(0, 0, canvas.width, canvas.height);
player.draw();
player.update(mouseX, mouseY);
updatePlayerPosition();
}
document.onkeydown = function(event) {
if (event.keyCode === 83) //s
pressingDown = true;
else if (event.keyCode === 87) //w
pressingUp = true;
else if (event.keyCode === 65) //a
pressingLeft = true;
else if (event.keyCode === 68) //d
pressingRight = true;
}
document.onkeyup = function(event) {
if (event.keyCode === 83) //s
pressingDown = false;
else if (event.keyCode === 87) //w
pressingUp = false;
else if (event.keyCode === 65) //a
pressingLeft = false;
else if (event.keyCode === 68) //d
pressingRight = false;
}
updatePlayerPosition = function() {
if (pressingRight)
player.x += 1;
if (pressingLeft)
player.x -= 1;
if (pressingDown)
player.y += 1;
if (pressingUp)
player.y -= 1;
}
function update() {
updatePlayer();
}
setInterval(update, 0)
How do I shoot bullets from my Player X and Y towards the mouse x and y?
I can find the angle of the mouse X and Y but I have no idea how to create a bullet which will fly towards the mouse.
The code for the mouse coordinates are (dx, dy).
Also, if you could explain the logic behind what you did and how you did it, I would be greatful.
Thanks!
Fiddle
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var pressingDown = false;
var pressingUp = false;
var pressingLeft = false;
var pressingRight = false;
var mouseX, mouseY;
function Player(x, y) {
this.x = x;
this.y = y;
this.angle;
}
Player.prototype.draw = function() {
context.save();
context.translate(this.x, this.y);
context.rotate(this.angle);
context.beginPath();
context.fillStyle = "green";
context.arc(0, 0, 30, 0, 2 * Math.PI);
context.fill();
context.fillStyle = "red";
context.fillRect(0, -10, 50, 20);
context.restore();
}
Player.prototype.update = function(mouseX, mouseY) {
var dx = mouseX - this.x;
var dy = mouseY - this.y;
this.angle = Math.atan2(dy, dx);
}
canvas.addEventListener('mousemove', mouseMove);
function mouseMove(evt) {
mouseX = evt.x;
mouseY = evt.y;
}
var player = new Player(350, 250);
function updatePlayer() {
context.clearRect(0, 0, canvas.width, canvas.height);
player.draw();
player.update(mouseX, mouseY);
updatePlayerPosition();
}
document.onkeydown = function(event) {
if (event.keyCode === 83) //s
pressingDown = true;
else if (event.keyCode === 87) //w
pressingUp = true;
else if (event.keyCode === 65) //a
pressingLeft = true;
else if (event.keyCode === 68) //d
pressingRight = true;
}
document.onkeyup = function(event) {
if (event.keyCode === 83) //s
pressingDown = false;
else if (event.keyCode === 87) //w
pressingUp = false;
else if (event.keyCode === 65) //a
pressingLeft = false;
else if (event.keyCode === 68) //d
pressingRight = false;
}
updatePlayerPosition = function() {
if (pressingRight)
player.x += 1;
if (pressingLeft)
player.x -= 1;
if (pressingDown)
player.y += 1;
if (pressingUp)
player.y -= 1;
}
function update() {
updatePlayer();
}
setInterval(update, 0)
Share
asked Jan 29, 2018 at 1:22
BradBrad
1092 silver badges8 bronze badges
1
- For starters you will need on object named bullet. This object you give properties like x, y, speed (speedX, speedY). Than you will need a updateUnit() function to redraw your bullet and a updateUnitPosition function to update your position. I remand storing the bullets into an array and than just implement add element to it every time you fire a bullet. Just keep in mind you will need an if or a timer on the bullet so it get's removed from the array ones it forfilled it's function. – Jens Ingels Commented Jan 29, 2018 at 2:01
2 Answers
Reset to default 9
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
(function() {
"use strict";
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var bounds = null;
var ctx = null;
var mouseX = 0.0;
var mouseY = 0.0;
var player = {
x: (canvasWidth * 0.5) | 0,
y: (canvasHeight * 0.5) | 0,
dx: 0.0,
dy: 0.0,
angle: 0.0,
radius: 17.5,
tick: function() {
this.angle = Math.atan2(mouseY - this.y,mouseX - this.x);
},
render: function() {
ctx.fillStyle = "darkred";
ctx.strokeStyle = "black";
ctx.translate(this.x,this.y);
ctx.rotate(this.angle);
ctx.beginPath();
ctx.moveTo(this.radius,0.0);
ctx.lineTo(-0.5 * this.radius,0.5 * this.radius);
ctx.lineTo(-0.5 * this.radius,-0.5 * this.radius);
ctx.lineTo(this.radius,0.0);
ctx.fill();
ctx.stroke();
ctx.rotate(-this.angle);
ctx.translate(-this.x,-this.y);
}
};
var bullet = {
x: (canvasWidth * 0.5) | 0,
y: (canvasHeight * 0.5) | 0,
dx: 0.0,
dy: 0.0,
radius: 5.0,
tick: function() {
this.x += this.dx;
this.y += this.dy;
if (this.x + this.radius < 0.0
|| this.x - this.radius > canvasWidth
|| this.y + this.radius < 0.0
|| this.y - this.radius > canvasHeight)
{
this.dx = 0.0;
this.dy = 0.0;
}
},
render: function() {
ctx.fillStyle = "darkcyan";
ctx.strokeStyle = "white";
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0.0,2.0*Math.PI,false);
ctx.fill();
ctx.stroke();
}
};
function loop() {
// Tick
bullet.tick();
player.tick();
// Render
ctx.fillStyle = "gray";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
bullet.render();
player.render();
//
requestAnimationFrame(loop);
}
window.onmousedown = function(e) {
// The mouse pos - the player pos gives a vector
// that points from the player toward the mouse
var x = mouseX - player.x;
var y = mouseY - player.y;
// Using pythagoras' theorm to find the distance (the length of the vector)
var l = Math.sqrt(x * x + y * y);
// Dividing by the distance gives a normalized vector whose length is 1
x = x / l;
y = y / l;
// Reset bullet position
bullet.x = player.x;
bullet.y = player.y;
// Get the bullet to travel towards the mouse pos with a new speed of 10.0 (you can change this)
bullet.dx = x * 10.0;
bullet.dy = y * 10.0;
}
window.onmousemove = function(e) {
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
}
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
bounds = canvas.getBoundingClientRect();
ctx = canvas.getContext("2d");
loop();
}
})();
</script>
</body>
</html>
Moving from point to point.
Given two points p1
and p2
, each point as a coordinate (x,y) and a speed
value that is the number of pixels per step, there are two methods you can use to move between them.
Cartesian
Calculate the vector from p1 to p2
var vx = p2.x - p1.x;
var vy = p2.y - p1.y;
Then calculate the delta by getting the length of the vector, normalise it (make the vector 1 pixel long) then multiply by the speed
var dist = Math.sqrt(vx * vx + vy * vy);
var dx = vx / dist;
var dy = vy / dist;
dx *= speed;
dy *= speed;
This can be optimized a little by scaling the speed with the distance.
var scale = speed / Math.sqrt(vx * vx + vy * vy);
var dx = vx / dist;
var dy = vy / dist;
Polar
The other way is to get the direction from p1 to p2 and use that create the deltas
var dir = Math.atan2(p2.y - p1.y, p2.x - p1.x);
var dx = Math.cos(dir) * speed;
var dx = Math.sin(dir) * speed;
Animate
Once you have the delta you just need to update the position via addition.
const bullet = {x : p1.x, y : p1.y}; // set the bullet start pos
// then each frame add the delta
bullet.x += dx;
bullet.y += dy;
// draw the bullet