i would like add collisions between my 2 players (in server side) My two players
Video to show what i want (it's from a game named taming.io) : https://www.youtube.com/watch?v=tGb6PwjHao8
Here is my actual code (every time a player connect, it create a new Player class) :
class Player {
static list = new Set()
constructor(id) {
Player.list[id] = this
this.id = id;
this.x = 250;
this.y = 250;
this.pressingUp = false;
this.pressingLeft = false;
this.pressingDown = false;
this.pressingRight = false;
this.moveSpeed = 5;
this.moveAngle = 45;
this.radians = this.moveAngle * Math.PI / 180;
this.vx = Math.cos(this.radians) * this.moveSpeed;
this.vy = Math.sin(this.radians) * this.moveSpeed;
}
//Apply new positions
update() {
//Players collisions
for (const i in Player.list) {
const player = Player.list[i];
const calcDistance = Math.hypot(player.x - this.x, player.y - this.y)
if (calcDistance <= 200 && player != this) {
//What should i put ?
}
}
//Player moves
if (this.pressingUp === true) {
this.y -= this.vy;
}
else if (this.pressingDown === true) {
this.y += this.vy;
}
if (this.pressingRight === true) {
this.x += this.vx;
}
else if (this.pressingLeft === true) {
this.x -= this.vx;
}
}
}
So i'm calculating distance between players with calcDistance const, if calcDistance = 200 (players radius hitbox = 100, so player1 radius hitbox + player2 radius hitbox = 200), it should do something, but i dont know what
Can you please help me ?
Get the distance between the center of the circles using Math.hypot()
like you have. See if that distance is less than the radii of the two circles. Once you have that you can set the x,y and optionally the vx,vy of the player.
The x will be set to obj2.x
plus the two radii combined multiplied by the distance of each x and y value divided by the total distance. More triangle math...
Here's an example
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 500;
class Circle {
constructor(x, y, c) {
this.x = x;
this.y = y;
this.color = c;
this.r = 30;
this.vx = 0;
this.vy = 0;
this.speed = 0.5;
}
draw() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
ctx.fill();
}
update() {
if (controller.left) {
this.vx -= this.speed;
}
if (controller.up) {
this.vy -= this.speed;
}
if (controller.right) {
this.vx += this.speed;
}
if (controller.down) {
this.vy += this.speed
}
this.x += this.vx;
this.y += this.vy;
this.vx *= 0.9;
this.vy *= 0.9;
}
}
class Controller {
constructor() {
this.up = false;
this.right = false;
this.down = false;
this.left = false;
let keyEvent = (e) => {
if (e.code == "ArrowUp") {
this.up = e.type == "keydown";
}
if (e.code == "ArrowRight") {
this.right = e.type == "keydown";
}
if (e.code == "ArrowLeft") {
this.left = e.type == "keydown";
}
if (e.code == "ArrowDown") {
this.down = e.type == "keydown";
}
};
addEventListener("keydown", keyEvent);
addEventListener("keyup", keyEvent);
}
}
let player = new Circle(25, 25, 'blue');
let obstacle = new Circle(canvas.width/2, 150, 'red');
let controller = new Controller();
function collisionDetection(obj1, obj2) {
if (Math.hypot(obj1.x - obj2.x, obj1.y - obj2.y) <= obj1.r + obj2.r) {
collisionResponse(obj1, obj2)
}
}
function collisionResponse(obj1, obj2) {
let dx = obj1.x - obj2.x;
let dy = obj1.y - obj2.y;
let dist = (Math.hypot(obj1.x - obj2.x, obj1.y - obj2.y)) || 1;
let radii = obj1.r + obj2.r;
let x = dx / dist;
let y = dy / dist;
obj1.x = obj2.x + radii * x;
obj1.y = obj2.y + radii * y;
obj1.vx = 0; //optional
obj1.vy = 0; //optional
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
collisionDetection(player, obstacle)
player.update();
player.draw();
obstacle.draw();
requestAnimationFrame(animate);
}
animate();
<canvas id="canvas"></canvas>
Setting the vx and vy are optional and will prevent any overlap from occurring. You can also choose to not set them to 0 and you will have some overlap but the circle will seem to slide off of eachother smoother.