Brad
Brad

Reputation: 109

Shooting bullets from player towards mouse?

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)

Upvotes: 3

Views: 2911

Answers (2)

Blindman67
Blindman67

Reputation: 54026

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

Upvotes: 5

Mr. Reddy
Mr. Reddy

Reputation: 1114

<!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>

Upvotes: 9

Related Questions