How to move the by straight rather than in an angle - javascript

I am developing a game where there are enemies and cars.So currently my cars move towards the enemies in a diagonal shape they hit them and earn points.Now I want to make the hero to make the move in a straight manner(like snake game no diagonal movement) and then hit the enemy and gain points.
So my current way of hitting the enemy is like
function angleBetweenTwoPoints(p1, p2) {
return Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
}
function degreeToRadian(degrees) {
return degrees * (Math.PI / 180);
}
var angle = angleBetweenTwoPoints(this.target.position, this.position);
var cos = Math.cos(degreeToRadian(angle)) * -1;
var sin = Math.sin(degreeToRadian(angle));
this.angle = angle;
this.position.x += cos * this.speed;
this.position.y -= sin * this.speed;
if (distance(this.position, this.target.position) < 10) {
this.target.position.x = Math.random() * mainCanvas.width;
this.target.position.y = Math.random() * mainCanvas.height;
this.hitCount++;
console.log("Hit!");
ctx.fillText("points : " + hitCount, 32, 32);
}
So now I want to make the car move by not diagonally and in a straight manner.
This is my working game.Any help is appreciated.

Use Pixi : http://www.pixijs.com/
And GSAP : https://greensock.com/
You will find easily everything to do it better ;)

Related

rotating a-entity with touch joystick

I am new to this forum although I have been lurking here for help. I am currently messing with AR with A-frame and javascript for fun. I am working on moving my 3d model with a joystick I found on github. fortunately, I was able to move the model around with the joystick, but unfortunately I am unable to figure out how to rotate the model while it moves. Any help would be appreciated!
// turn joystick data into WASD movement in AFRAME
var f;
var ang;
var x_vec;
var y_vec;
var cam;
function updatePosition(data) {
f = data.force;
ang = data.angle.radian
cam = document.getElementById("model");
x_vec = Math.cos(ang + 3.14 / 180 * cam.getAttribute('rotation')['x']);
y_vec = Math.sin(ang + 3.14 / 180 * cam.getAttribute('rotation')['y']);
x = cam.getAttribute("position")["x"] + f / 15 * (x_vec);
y = cam.getAttribute("position")["y"]
z = cam.getAttribute("position")["z"] - f / 15 * (y_vec);
cam.setAttribute('position', `${x} ${y} ${z}`)
cam.setAttribute('rotation', `${x} ${y} ${z}`)
}
Having the new angle, just add it to the current rotation.y(since you're moving on an XZ plane).
The only catch is that the rotation should be in degrees:
ang = data.angle.radian
cam = document.getElementById("model");
// grab the rotation
var rotation = cam.getAttribute("rotation")
rotation.y += ang * 180 / Math.PI
// set the new rotation
cam.setAttribute('rotation', rotation)
A simple example of rotating an entity and moving it forward would be a component like this
AFRAME.registerComponent("joystick-controls", {
init: function() {
// initialize the joystick
this.joystick = new JoyStick("joyDiv");
// grab the rotation and position for later use
this.rot = this.el.getAttribute("rotation");
this.pos = this.el.getAttribute("position");
},
tick: function() {
// wait until the joystick is ready
if (!this.joystick) return;
// handle rotation
this.rot.y -= this.joystick.GetX() / 100;
this.el.setAttribute("rotation", this.rot);
// handle position
var speed = this.joystick.GetY() / 2000;
this.pos.z += speed * Math.cos(this.rot.y * Math.PI / 180);
this.pos.x += speed * Math.sin(this.rot.y * Math.PI / 180);
this.el.setAttribute("position", this.pos);
}
});
Glitch here. I'm using this joystick.

How to properly execute collision detection between two spheres?

Hello world :) Working on a small animation in which a bunch of spheres jump around the canvas, bouncing off of eachother, floors, walls, and ceilings.
Now, this works perfectly with no failures, until I add more spheres than can fit in the area in one level. At this point, the spheres sink to one flat level of spheres, coinjoining into eachother and pushing others through wall boundaries, which doesn't normally happen.
However, it should be stated I don't fully understand the function I am using to achieve the outcome, so that likely has something to do with it. Will post my collision detection functions below, and hopefully one of you can help me get a bit farther :)
Borrowed Functions:
/**
* Rotates coordinate system for velocities
*
* Takes velocities and alters them as if the coordinate system they're on was rotated
*
* #param Object | velocity | The velocity of an individual particle
* #param Float | angle | The angle of collision between two objects in radians
* #return Object | The altered x and y velocities after the coordinate system has been rotated
*/
function rotate(velocity, angle) {
const rotatedVelocities = {
x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle),
y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle)
};
return rotatedVelocities;
}
/**
* Swaps out two colliding particles' x and y velocities after running through
* an elastic collision reaction equation
*
* #param Object | particle | A particle object with x and y coordinates, plus velocity
* #param Object | otherParticle | A particle object with x and y coordinates, plus velocity
* #return Null | Does not return a value
*/
function resolveCollision(particle, otherParticle) {
const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x;
const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y;
console.log("Resolving");
const xDist = otherParticle.x - particle.x;
const yDist = otherParticle.y - particle.y;
// alert(xVelocityDiff * xDist + yVelocityDiff * yDist)
// Prevent accidental overlap of particles
if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
console.log("Resolving IF");
// Grab angle between the two colliding particles
const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x);
// Store mass in var for better readability in collision equation
const m1 = particle.mass;
const m2 = otherParticle.mass;
// Velocity before equation
const u1 = rotate(particle.velocity, angle);
const u2 = rotate(otherParticle.velocity, angle);
// Velocity after 1d collision equation
const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y };
// Final velocity after rotating axis back to original location
const vFinal1 = rotate(v1, -angle);
const vFinal2 = rotate(v2, -angle);
// Swap particle velocities for realistic bounce effect
particle.velocity.x = vFinal1.x;
particle.velocity.y = vFinal1.y;
otherParticle.velocity.x = vFinal2.x;
otherParticle.velocity.y = vFinal2.y;
}
}
Ball Properties:
// Objects
function Ball(x, y, dy, dx, radius, color) {
this.x = x
this.y = y
// this.dy = dy;
// this.dx = dx;
this.velocity = {
x:dx,
y:dy
}
this.radius = radius
this.color = color
this.mass = 1;
this.collision = ()=> {
for (var index = 0; index < objects.length; index++) {
var coin = objects[index];
if (this === coin) {
continue;
}
if (getDistance(this.x, this.y, coin.x, coin.y) - (this.radius + coin.radius) < 0) {
// alert('hi');
console.log("collision:");
resolveCollision(this, coin)
}
}
}
}
Ball.prototype.update = function() {
if (this.y + this.radius + this.velocity.y > canvas.height) {
this.velocity.y = (-this.velocity.y * parseFloat(0.85));
}else {
this.velocity.y += gravity;
}
this.y += this.velocity.y;
this.x += this.velocity.x;
if (this.x + this.radius + this.velocity.x > canvas.width) {
this.velocity.x = -this.velocity.x;
}
if (Math.sign(this.velocity.x) === 1) {
this.velocity.x -= 0.01;
} else if (Math.sign(this.velocity.x) === -1) {
this.velocity.x += 0.01;
}
if (this.x - this.radius - this.velocity.x < 0) {
this.velocity.x = Math.abs(this.velocity.x);
}
this.draw()
}
Any help here really would be most appreciated, I am trying to improve my skills in this field, and feel a strong need to go back and read my geometry books again :D

Move canvas image across circular path

I am currently working on a 2D javascript game and I am doing the movement mechanics right now. I want players to be able to move forward and backward, towards or away from the mouse, while also having the ability to strafe.
I got the mouse following down pretty well but I am stuck on how to implement the strafing. I need my player to move along a dynamic circular path that changes sizes depending on how far away the player is from the mouse.
ex: If the mouse was the red X, I want to move the player along the green circular path.
This path of course will be changing size based on how far away the player is from the mouse.
I am updating the players position by moving whenever the movement keys are pressed so I am really looking for an equation to move the player in the correct circular path that can be implemented in a "position updated every second" sort of way.
I know that for a circular path, the coordinates can be found by:
x = centerX * radius * Math.cos(theta);
y = centerY * radius * Math.sin(theta);
But I am having trouble implementing. Here is some of my framework, but I am afraid all the solutions I have tried haven't even gotten me close so I will not post the broken math I have already deleted
Player.prototype.update = function(delta){
this.playerCenter = [this.x+this.width/2, this.y+this.height/2];
let dX = (GAME.mouse.position.x - this.playerCenter[0]),
dY = (GAME.mouse.position.y - this.playerCenter[1]);
radius = Math.sqrt(dX * dX + dY * dY);
// Movement Forward
if(GAME.keyDown[87] && radius >= 50){
this.x += (dX / radius) * this.movementSpeed * delta;
this.y += (dY / radius) * this.movementSpeed * delta;
}
// Movement Backward
if(GAME.keyDown[83]){
this.x -= (dX / radius) * this.movementSpeed * delta;
this.y -= (dY / radius) * this.movementSpeed * delta;
}
// Strafe left
if(GAME.keyDown[65]){
}
// Strafe right
if(GAME.keyDown[68]){
}
}
You almost have the solution.
You need to go at 90 deg to the forward vector. To rotate a vector 90cw you swap the x,and y and negate the new x.
EG
dx = ?; // forward direction
dy = ?;
// rotate 90 clockwise
dx1 = -dy;
dy1 = dx;
Thus you can update your code as follows
var dX = (GAME.mouse.position.x - this.playerCenter[0]);
var dY = (GAME.mouse.position.y - this.playerCenter[1]);
var radius = Math.sqrt(dX * dX + dY * dY);
//normalise
if(radius > 0){
dX = (dX / radius) * this.movementSpeed * delta;
dY = (dY / radius) * this.movementSpeed * delta;;
}else{
dX = dY = 0; // too close need to set this or you will get NaN propagating through your position variables.
}
if(GAME.keyDown[87] && radius >= 50){ // Movement Forward
this.x += dX;
this.y += dY;
}
if(GAME.keyDown[83]){ // Movement Backward
this.x -= dX;
this.y -= dY;
}
if(GAME.keyDown[65]){ // Strafe left
this.x += -dY; // swap x and y negate new x to rotate vector 90
this.y += dX;
}
if(GAME.keyDown[68]){ // Strafe right
this.x -= -dY; // swap x and y negate new x to rotate vector 90
this.y -= dX;
}

Move X and Y starting point on a moving object in any angle

I'm working on a game with HTML5 Canvas and JavaScript. It's a simple space shooting game with a cannon in the center of the screen. I can rotate the cannon and fire missiles in the same angle as the cannons direction.
But I have a problem. For the missiles X and Y starting point, I'm using the X and Y position of the cannon. This looks weird, because I want the missile to start outside of the cannon, like perhaps 50 pixels in the direction of the angle. How do I calculate that?
With this code I create Missile objects:
var dX = Math.cos(this.playerRotationAngle * Math.PI / 180);
var dY = Math.sin(this.playerRotationAngle * Math.PI / 180);
this.activeMissilesArray.push(new Missile(cannon.posX, cannon.posY, dX, dY));
And this is from the constructor function of the Missile object where I calculate the direction:
this.directionX = dX * this.speed;
this.directionY = dY * this.speed;
The Draw method:
Draw: function(context)
{
context.drawImage(this.missile, this.posX-20, this.posY-20);
}
The Update method:
Update: function()
{
this.posX += this.directionX;
this.posY += this.directionY;
}
Have you tried using your speed formula with a value of 50 to adjust the initial position?
// inside the Missile constructor
// instead of:
// this.posX = x;
// this.posY = y;
// do:
this.posX = x + 50 * dX;
this.posY = y + 50 * dY;

Inelastic collision only moving object to the right

My Rocket is hitting this Inertia object, as defined in handleCollision. I'm passing in a rocket which has a .r value for its theta and .power for its magnitude.
I'm wanting to update my .rotation & .magnitude according to an inelastic collision as defined by Wikipedia
When colliding from the left, my Inertia moves to the right.
But when colliding from the right it errors and moves exactly 180 degrees off. So if the rocket is up and right at a 45 degree angle from the inertia object, the object will move up and right at a 45 degree angle.
What am I missing here? I thought it might be an issue with the atan function so I converted by the y component & x component of the vector to radians first, same issue.
handleCollision(rocket) {
var angle = rocket.r * Math.PI / 180.0;
var rr = this.rotation * Math.PI / 180;
var rocketVector = {'x' : r.power * Math.cos(angle), 'y' : r.power * Math.sin(angle)};
var inertiaVector = {'x' : this.magnitude * Math.cos(rr), 'y' : this.magnitude * Math.sin(rr)};
var rMass = 10;
var shipMass = 10;
var x = (rMass * rocketVector.x) + (shipMass * inertiaVector.x);
var y = (rMass * rocketVector.y) + (shipMass * inertiaVector.y);
var xDividedByMass = x / (rMass + shipMass);
var yDividedByMass = y / (rMass + shipMass);
var yRadians = (yDividedByMass * Math.PI / 180);
var xRadians = (xDividedByMass * Math.PI / 180);
var theta = Math.atan( yRadians / xRadians);
theta = theta * 180 / Math.PI;
console.log(theta);
var hypotenuse = Math.sqrt((xDividedByMass * xDividedByMass) + (yDividedByMass * yDividedByMass));
this.magnitude = hypotenuse;
this.rotation = theta;
if (this.rotation < 0) {
this.rotation += 360;
} else if (this.rotation > 360) {
this.rotation -= 360;
}
}
If xDividedbyMass>0, you are great because you are quadrant I or IV where arctangent kicks out its values. If you do not like the negative angle, okay add 360 like you did.
But if x<0 and y>0, you will get a negative angle and want to add 180 to get to Q II (tangent has a period of 180). And if x<0, and y<0, you are in QIII and again arctan gives you something in Q1 to which you must add 180.
The logic will look something like this.
if ((x > 0) && (y<0)) {
this.rotation += 360;
} else if (x<0) {
this.rotation += 180;
}

Categories