i am making a javascript shooter game.i want the the player to rotate towards the mouse.it is working, but the rotation was not correct. I tried this with an image, and it works, but with the sprite itself(player1), is not. i have asked this once before but received no answer
I am a beginner in javascript, so help would be appreciated.
I am using the p5.js libraries
Here is my code snippet:
//variables var player1; var gun1; var gun2; function preload(){ img = loadImage('rect1.png'); } function setup(){ //creating sprites player1 = createSprite(200,200,30,30) gun = createSprite(player1.x,player1.y-20,5,30) gun.shapeColor = "black" player1.addImage("player",img) player1.scale = 0.2 } function draw(){ canvas = createCanvas(displayWidth-20, displayHeight-120); background("#32CD32"); push() gun.x = player1.x; gun.y = player1.y-15; // functions to move //up if(keyDown("up")){ player1.y = player1.y - 5; } //down if(keyDown("down")){ player1.y = player1.y + 5; } //right if(keyDown("right")){ player1.x = player1.x + 5; } //left if(keyDown("left")){ player1.x = player1.x - 5; } angleMode(DEGREES) imageMode(CENTER) let a = atan2(mouseY - height / 2, mouseX - width / 2); translate(width/2, height/2); //rotate(a) player1.rotation = a //image(img,0,0,40,40) pop() drawSprites(); }
Advertisement
Answer
I think I’m using a dated version of p5.play, so there’s not much in your code that works for me, but here’s what I think is going on based on what you’re saying.
If you want to understand what the deal is with atan2()
, you first have to understand atan()
. Basically, you have the ordinary trig functions sin, cos, and tan. Then you have the inverse trig functions arcsin, arccos, and arctan (abbreviated asin, acos, and atan). The arctan function is useful because you can input a slope and it will give you the angle of that slope. There’s a catch, though; atan will only give values between -pi/2 and pi/2. This covers all non-vertical lines, but what if you wanted to use it for a vector or something that has direction? atan2()
solves that problem. Instead of taking one input (a ratio: rise/run), it takes two inputs, a rise and a run. This prevents dividing by zero (for vertical lines) and signs of rise and run cancelling. The first input is the rise, and the second is the run. The output is the angle between the vector with those coordinates and the x-axis. So atan2()
will give you some angle between -pi and pi.
Now let’s look at what you have put into the atan2()
function:
atan2(mouseY - height / 2, mouseX - width / 2);
So the vector you’re considering is the vector from the middle of the canvas to the mouse. If this is what you want, great. If it’s not, maybe consider
atan2(mouseY - player1.y, mouseX - player1.y);
which yields the “heading” (not really the heading) of the vector from the player’s position to the mouse.
There are a couple of other potential problems (I can’t figure out which one it is because p5.play isn’t behaving, or I’m doing something else wrong):
- radians/degrees: sometimes this stuff goes wrong. Try printing
a
and seeing if it’s what you’re looking for. If it’s in degrees, consider sayingplayer1.rotation = radians(a)
instead. I know thatp5.Vector.fromAngle()
doesn’t care aboutangleMode
, maybesprite.rotation
doesn’t either? - I don’t know how drawSprites works, but you might consider putting it inside of the
push()/pop()
section. When drawing other shapes, this is how you get a rotation about the point (x, y):
let x = 100; let y = 200; let a = atan2(mouseY - y, mouseX - x); push(); translate(x, y); rotate(a); square(-10, -10, 20); pop();
The square is centered at (x,y), and is rotated about (x,y) toward the cursor. It’s necessary that you do it in this order: push, translate, rotate, shape, pop. If you mix up that order, it doesn’t do it right. But what you have is push, translate, pop, shape. I don’t know how sprite.rotate
works, so maybe it’s supposed to do what you want. But here is another way to do a rotation. (If you’re going to do it this way, I think you’d have to draw player1 “at (0,0)” after the translation and rotation, before pop)
I hope this helped!